fix(agentapi): update tests for coder-utils pattern and rewrite README
- test-util.ts: find coder_script by run_on_start to pick the coder-utils install script instead of the shutdown script - main.test.ts: mock coder CLI for coder exp sync calls - README.md: rewrite in the style of claude-code and codex READMEs with feature list, examples, and troubleshooting section
This commit is contained in:
parent
b8ae549102
commit
28a4d4a4e3
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
display_name: AgentAPI
|
display_name: AgentAPI
|
||||||
description: Building block for modules that need to run an AgentAPI server
|
description: Building block for modules that need to run an AgentAPI server.
|
||||||
icon: ../../../../.icons/coder.svg
|
icon: ../../../../.icons/coder.svg
|
||||||
verified: true
|
verified: true
|
||||||
tags: [internal, library]
|
tags: [internal, library]
|
||||||
@ -11,47 +11,47 @@ tags: [internal, library]
|
|||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> We do not recommend using this module directly. Instead, please consider using one of our [Tasks-compatible AI agent modules](https://registry.coder.com/modules?search=tag%3Atasks).
|
> We do not recommend using this module directly. Instead, please consider using one of our [Tasks-compatible AI agent modules](https://registry.coder.com/modules?search=tag%3Atasks).
|
||||||
|
|
||||||
The AgentAPI module is a building block for modules that need to run an AgentAPI server. It is intended primarily for internal use by Coder to create modules compatible with Tasks.
|
The AgentAPI module is a building block for modules that need to run an [AgentAPI](https://github.com/coder/agentapi) server. It is intended primarily for internal use by Coder to create modules compatible with [Tasks](https://coder.com/docs/ai-coder/tasks).
|
||||||
|
|
||||||
```tf
|
```tf
|
||||||
module "agentapi" {
|
module "agentapi" {
|
||||||
source = "registry.coder.com/coder/agentapi/coder"
|
source = "registry.coder.com/coder/agentapi/coder"
|
||||||
version = "2.4.0"
|
version = "2.5.0"
|
||||||
|
|
||||||
agent_id = var.agent_id
|
agent_id = var.agent_id
|
||||||
web_app_slug = local.app_slug
|
web_app_slug = local.app_slug
|
||||||
web_app_order = var.order
|
|
||||||
web_app_group = var.group
|
|
||||||
web_app_icon = var.icon
|
web_app_icon = var.icon
|
||||||
web_app_display_name = "Goose"
|
web_app_display_name = "Goose"
|
||||||
cli_app_slug = "goose-cli"
|
|
||||||
cli_app_display_name = "Goose CLI"
|
cli_app_display_name = "Goose CLI"
|
||||||
|
cli_app_slug = "goose-cli"
|
||||||
module_directory = local.module_directory
|
module_directory = local.module_directory
|
||||||
install_agentapi = var.install_agentapi
|
install_agentapi = var.install_agentapi
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Task log snapshot
|
## Features
|
||||||
|
|
||||||
Captures the last 10 messages from AgentAPI when a task workspace stops. This allows viewing conversation history while the task is paused.
|
- **Web and CLI apps**: creates `coder_app` resources for browser-based chat and terminal attachment
|
||||||
|
- **Task log snapshot**: captures the last 10 conversation messages when a workspace stops, enabling offline viewing while the task is paused
|
||||||
|
- **State persistence**: optionally saves and restores AgentAPI conversation state across workspace restarts (requires agentapi >= v0.12.0)
|
||||||
|
- **Script orchestration**: uses [coder-utils](https://registry.coder.com/modules/coder/coder-utils) for `coder exp sync` based script ordering so downstream modules can serialize their own scripts behind this module
|
||||||
|
|
||||||
To enable for task workspaces:
|
## Examples
|
||||||
|
|
||||||
|
### Task log snapshot
|
||||||
|
|
||||||
|
Enabled by default. Captures the last 10 messages from AgentAPI when a task workspace stops.
|
||||||
|
|
||||||
```tf
|
```tf
|
||||||
module "agentapi" {
|
module "agentapi" {
|
||||||
# ... other config
|
# ... other config
|
||||||
task_log_snapshot = true # default: true
|
task_log_snapshot = true # default
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## State Persistence
|
### State persistence
|
||||||
|
|
||||||
AgentAPI can save and restore conversation state across workspace restarts.
|
Disabled by default. Requires agentapi >= v0.12.0.
|
||||||
This is disabled by default and requires agentapi binary >= v0.12.0.
|
|
||||||
|
|
||||||
State and PID files are stored in the `module_directory` alongside other module files (e.g. `$HOME/.coder-modules/coder/claude-code/agentapi-state.json`).
|
|
||||||
|
|
||||||
To enable:
|
|
||||||
|
|
||||||
```tf
|
```tf
|
||||||
module "agentapi" {
|
module "agentapi" {
|
||||||
@ -60,16 +60,38 @@ module "agentapi" {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To override file paths:
|
Custom file paths:
|
||||||
|
|
||||||
```tf
|
```tf
|
||||||
module "agentapi" {
|
module "agentapi" {
|
||||||
# ... other config
|
# ... other config
|
||||||
|
enable_state_persistence = true
|
||||||
state_file_path = "/custom/path/state.json"
|
state_file_path = "/custom/path/state.json"
|
||||||
pid_file_path = "/custom/path/agentapi.pid"
|
pid_file_path = "/custom/path/agentapi.pid"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Script serialization
|
||||||
|
|
||||||
|
The module outputs `scripts`, an ordered list of `coder exp sync` names. Downstream modules can use these to serialize their own `coder_script` resources behind the install pipeline:
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "agentapi" {
|
||||||
|
source = "registry.coder.com/coder/agentapi/coder"
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
|
||||||
|
output "scripts" {
|
||||||
|
value = module.agentapi.scripts
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## For module developers
|
## For module developers
|
||||||
|
|
||||||
For a complete example of how to use this module, see the [Goose module](https://github.com/coder/registry/blob/main/registry/coder/modules/goose/main.tf).
|
For a complete example of how to build a module on top of AgentAPI, see the [Goose module](https://github.com/coder/registry/blob/main/registry/coder/modules/goose/main.tf).
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- Install logs are written to `~/.coder-modules/coder/agentapi/logs/install.log`
|
||||||
|
- AgentAPI server logs are written to `~/.coder-modules/coder/agentapi/agentapi-start.log`
|
||||||
|
- Check `agentapi --version` to verify the installed binary version
|
||||||
|
|||||||
@ -67,6 +67,13 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
|||||||
skipAgentAPIMock: props?.skipAgentAPIMock,
|
skipAgentAPIMock: props?.skipAgentAPIMock,
|
||||||
moduleDir: import.meta.dir,
|
moduleDir: import.meta.dir,
|
||||||
});
|
});
|
||||||
|
// Mock `coder` CLI so `coder exp sync` calls from coder-utils wrappers
|
||||||
|
// succeed without a real control plane.
|
||||||
|
await writeExecutable({
|
||||||
|
containerId: id,
|
||||||
|
filePath: "/usr/bin/coder",
|
||||||
|
content: "#!/bin/bash\nexit 0\n",
|
||||||
|
});
|
||||||
await writeExecutable({
|
await writeExecutable({
|
||||||
containerId: id,
|
containerId: id,
|
||||||
filePath: "/usr/bin/aiagent",
|
filePath: "/usr/bin/aiagent",
|
||||||
|
|||||||
@ -46,7 +46,25 @@ export const setupContainer = async ({
|
|||||||
agent_id: "foo",
|
agent_id: "foo",
|
||||||
...vars,
|
...vars,
|
||||||
});
|
});
|
||||||
const coderScript = findResourceInstance(state, "coder_script");
|
// Find the run_on_start script. With coder-utils the install script lives
|
||||||
|
// inside a module and the shutdown script is a separate resource, so we
|
||||||
|
// pick the first coder_script that has run_on_start = true.
|
||||||
|
let coderScript: { script: string; [k: string]: unknown } | undefined;
|
||||||
|
for (const resource of state.resources) {
|
||||||
|
if (resource.type !== "coder_script") continue;
|
||||||
|
for (const instance of resource.instances) {
|
||||||
|
const attrs = instance.attributes as Record<string, unknown>;
|
||||||
|
if (attrs.run_on_start === true) {
|
||||||
|
coderScript = attrs as { script: string; [k: string]: unknown };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (coderScript) break;
|
||||||
|
}
|
||||||
|
if (!coderScript) {
|
||||||
|
// Fallback to original behavior for backwards compatibility.
|
||||||
|
coderScript = findResourceInstance(state, "coder_script");
|
||||||
|
}
|
||||||
const coderEnvVars = extractCoderEnvVars(state);
|
const coderEnvVars = extractCoderEnvVars(state);
|
||||||
const id = await runContainer(image ?? "codercom/enterprise-node:latest");
|
const id = await runContainer(image ?? "codercom/enterprise-node:latest");
|
||||||
return {
|
return {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user