Repository navigation
feat: add the agents and service-accounts command groups - #702
cristianrcv wants to merge 9 commits into
Conversation
educalleja
left a comment
There was a problem hiding this comment.
Usage of the new commands
This PR adds the tw agents command group: "Manage AI agents." Agents must be enabled for the workspace's organization. When they're not, the API returns 404 "Agents are not enabled for this organization". Every subcommand requires -w, --workspace.
Commands that act on an existing agent identify it by -i, --id or -n, --name. For view, update, delete, enable and disable, exactly one is required. An unknown name fails with "Unknown agent '<name>' at <workspace> workspace".
Manage agents
tw agents list
Lists agents.
| Option | Description |
|---|---|
-f, --filter |
Filter agents by name |
| Pagination options | Standard --page / --offset / --max |
- The output is a table with ID, Name, Description, Status and Updated.
tw agents view
Shows an agent: ID, Name, Description, Status, Service account, GitHub App credentials, Created by, Created and Updated, followed by its full instructions.
tw agents add
Adds an agent.
| Option | Description |
|---|---|
-n, --name |
Agent name (required). Must be unique per workspace. Names can use letters, numbers, hyphens and underscores |
-d, --description |
Agent description (max 120 characters) |
--instructions |
Agent instructions: the role, behavior, and constraints for the agent |
--instructions-file |
File containing the agent instructions. - reads from stdin |
--service-account-id |
Service account user ID. The agent runs with this service account's permissions in the workspace |
--github-app-credentials-id |
GitHub App credentials ID. Lets the agent clone, commit and push using these credentials |
- You must give exactly one of
--instructionsor--instructions-file.
tw agents update
Updates an agent. Fields you don't pass keep their current value.
| Option | Description |
|---|---|
--new-name |
New agent name |
-d, --description |
New description (max 120 characters) |
--instructions / --instructions-file |
New instructions, inline or from a file (- reads from stdin). Use one or the other |
--service-account-id |
New service account |
--github-app-credentials-id |
New GitHub App credentials |
- Because unchanged fields keep their current value, there's no way to remove a service account or GitHub App credentials from an agent. Passing nothing keeps the old value.
tw agents delete
Deletes an agent.
tw agents enable / tw agents disable
Enables an inactive agent, or disables an active one. A disabled agent can't be launched.
Run agents
tw agents launch
Starts a background agent run.
| Option | Description |
|---|---|
-i, --id / -n, --name |
The configured agent to run. Optional; use one or the other |
--instructions / --instructions-file |
Instructions for this run. Optional; use one or the other |
- With an agent: the run uses the agent's stored instructions. Instructions you pass replace them for this run.
- Without an agent: it's an ad-hoc run as the current user, and instructions are required.
- If you give neither, it fails with "Specify an agent to launch (--id or --name) or the instructions to run (--instructions or --instructions-file)".
- The output is "Agent run '<id>' submitted at <workspace> workspace (status: <status>)".
tw agents runs list
Lists agent runs, newest first.
| Option | Description |
|---|---|
-f, --filter |
Filter by keyword: status (pending, running, completed, failed), agentConfigId, workflowId, sourcePipelineId, serviceAccountId and serviceAccountName. Free text isn't supported. Example: -f status:failed |
| Pagination options | Standard --page / --offset / --max |
- The output is a table with ID, Title, Status, Trigger, Run ID and Created.
tw agents runs view
Shows the status of one agent run.
| Option | Description |
|---|---|
-i, --id |
Agent run ID (required) |
- The output shows ID, Status, Thread ID and Session ID.
Examples (from USAGE.md)
tw agents add -w my-org/my-workspace -n triage --instructions-file triage.md
tw agents launch -w my-org/my-workspace -n triage
tw agents runs list -w my-org/my-workspaceUSAGE.md
A new "Agents" section lists all the operations (list, view, add, update, delete, enable, disable, launch, runs list|view) with the examples above.
🤖 Generated with Claude Code
df53985 to
c2728fe
Compare
Service account update is the first PATCH call in tw. The SDK's ApiClient enables Jersey's SET_METHOD_WORKAROUND, which sets HttpURLConnection.method (and HttpsURLConnectionImpl.delegate for HTTPS) by reflection. On Java 25 that throws InaccessibleObjectException, which tw reported as a connection error. Open both packages to the test and run JVMs, and to java -jar tw.jar through the Add-Opens manifest attribute. The tracing-agent blocks now append to the JVM args instead of replacing them. The native image needs reflection entries for the same fields (next commit). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Native images enforce module encapsulation for setAccessible as well. Even with reflection entries for HttpURLConnection.method and HttpsURLConnectionImpl.delegate, the native binary failed with 'module java.base does not opens java.net'. Pass the same --add-opens to native-image, and register both fields in reflect-config.json: the tracing agent cannot record them, because its access filter only keeps io.seqera callers. Verified with the native binary: service-accounts update sends PATCH over HTTP (MockServer suite) and over HTTPS (local TLS server). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Platform API 1.230.0 (PLAT-6535) made the organization service account
endpoints generally available, but tw had no way to manage them.
Add 'tw service-accounts' with list, add, view, update and delete over
/orgs/{orgId}/service-accounts. 'list --workspace' uses
/orgs/{orgId}/workspaces/{workspaceId}/service-accounts to show the
accounts assigned to one workspace; that endpoint pages with an opaque
token, so every page is fetched and --offset/--max are applied locally.
Members of the new OrgRole.service_account now render as
SERVICE_ACCOUNT in 'tw members list' instead of the raw enum value.
Note: update uses PATCH, which Jersey's HttpURLConnection connector only
sends through a reflective workaround that needs
--add-opens java.base/java.net=ALL-UNNAMED on Java 16+.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Platform API 1.175.0 added workspace agents (CRUD, enable/disable), and 1.190.0 replaced their systemPrompt/templateId fields with agentInstructions/agentInstructionsTemplateId, but tw had no command for any of them. tw agents list/view/add/update/delete/enable/disable cover these operations against the 1.190 agent model. Agents are workspace-scoped and gated per organization by the agent configuration feature, so every command takes a required workspace. The update API replaces the whole agent, so update fetches the agent and resends unchanged fields. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Platform API 1.190.0 added agent launch, but tw had no command for it. tw agents launch starts a background run from a configured agent (--id or --name), from ad hoc instructions, or both. Launching a configured agent sends its stored instructions, like the web UI does. The command reads LaunchAgentResponse.agentRunId, which API 1.200.0 introduced: 1.190 servers send agentId instead, so the run id would print as null against them. That is why launch ships with 1.200 rather than with the rest of the agents command. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Platform API 1.200.0 added agent run listing and run status, but tw had no command for them. tw agents runs list pages through a workspace's runs, newest first, with the API's keyword filter, and tw agents runs view shows a run's status, thread and session. The filter help lists only the keywords API 1.200 accepts; the service-account keywords came later. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
API 1.230.0 lets an agent run as an organization service account and use GitHub App credentials to clone, commit and push, but tw could not set either. - 'agents add|update --service-account-id --github-app-credentials-id' send serviceAccountId and githubAppCredentialId; update keeps the stored values when the options are omitted. - 'agents view' shows the service account, the GitHub App credentials and who created the agent (createdByUserName, API 1.211.0). - 'agents runs list --filter' documents the serviceAccountId and serviceAccountName keywords. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An Agents section (list, view, add, update, delete, enable, disable, launch and runs list|view) and a Service accounts section, with examples. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e accounts commands Entries for the agents and service-accounts commands and responses, plus classes master already lacked, taken from a full test run under the GraalVM tracing agent. Response classes register allDeclaredFields, since Jackson serializes every field for -o json. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
c2728fe to
37b345a
Compare
72f3deb to
8e8d05e
Compare
Summary
Adds the
tw agentsandtw service-accountscommand groups, grouped in one PR because agents run under service accounts. Both build onmasteralone (SDK 1.233.0).list(org or workspace),add,view,update,delete.OrgRole.service_accountnow shows inmembers.agentInstructions);agents launch(LaunchAgentResponse.agentRunId) andagents runs list|view;--service-account-idand--github-app-credentials-id, and showing them.Changes
Notes for review
Why
build.gradlechanges here:tw service-accounts updateis the first PATCH call tw makes. Jersey'sSET_METHOD_WORKAROUNDreflects intoHttpURLConnection.methodandHttpsURLConnectionImpl.delegate, and Java 25 blocks that. The JVM reported a bogus "Connection error", and the native binary silently sent POST. Both packages are opened:tw.jarmanifest (Add-Opens);--add-opens.The two fields are also registered in
reflect-config.json.Agents scoping: every agents command needs
-w. Agents are enabled per organization; when they're off, the API returns 404 "Agents are not enabled for this organization".agents update: the PUT replaces the whole agent, so tw fetches it first and resends every field you don't change.agents launch: with an agent, it sends the agent's stored instructions, as the web UI does. Instructions you pass override them. Without an agent, it's an ad-hoc run as the current user.Verification
./gradlew test: 772 tests, 0 failures, including the service-account PATCH tests (which need the opens).java -jar tw.jar; the server receivedPATCH.🤖 Generated with Claude Code