Skip to content

feat: add the agents and service-accounts command groups - #702

Open
cristianrcv wants to merge 9 commits into
masterfrom
feat/NOTASK-tw-agents
Open

cristianrcv wants to merge 9 commits into
masterfrom
feat/NOTASK-tw-agents

Conversation

@cristianrcv

@cristianrcv cristianrcv commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the tw agents and tw service-accounts command groups, grouped in one PR because agents run under service accounts. Both build on master alone (SDK 1.233.0).

  • Service accounts (API 1.230): list (org or workspace), add, view, update, delete. OrgRole.service_account now shows in members.
  • Agents, which span three API versions:
    • 1.190: CRUD, enable and disable (agentInstructions);
    • 1.200: agents launch (LaunchAgentResponse.agentRunId) and agents runs list|view;
    • 1.230: --service-account-id and --github-app-credentials-id, and showing them.

Changes

  • fix(build): allow PATCH requests on Java 25 (1eaca63)
  • fix(build): open the JDK packages for PATCH in the native image too (a1d9606)
  • feat(service-accounts): add service account commands (d1d6f3f)
  • feat(agents): add agents command (f1bb1ca)
  • feat(agents): add agents launch (fe392a2)
  • feat(agents): add agents runs list and view (cfc4151)
  • feat(agents): set an agent's service account and GitHub App credentials (9ac9cef)
  • docs: document the agents and service accounts commands (65b0765)
  • build(native): register reflection metadata for the agents and service accounts commands (8e8d05e)

Notes for review

  • Why build.gradle changes here: tw service-accounts update is the first PATCH call tw makes. Jersey's SET_METHOD_WORKAROUND reflects into HttpURLConnection.method and HttpsURLConnectionImpl.delegate, and Java 25 blocks that. The JVM reported a bogus "Connection error", and the native binary silently sent POST. Both packages are opened:

    • for the test and run JVMs;
    • in the tw.jar manifest (Add-Opens);
    • as native-image --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

🤖 Generated with Claude Code

@cristianrcv
cristianrcv added this pull request to stack #704 October 5, 2026 16:12
@cristianrcv
cristianrcv removed this pull request from stack #704 October 5, 2026 16:20
@cristianrcv
cristianrcv added this pull request to stack #705 October 5, 2026 16:20

@educalleja educalleja left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 --instructions or --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-workspace

USAGE.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

@cristianrcv
cristianrcv removed this pull request from stack #705 October 7, 2026 13:26
@cristianrcv
cristianrcv force-pushed the fix/COMP-2645-tw-api-1.230 branch from df53985 to c2728fe Compare October 7, 2026 13:39
cristianrcv and others added 5 commits October 7, 2026 15:47
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>
cristianrcv and others added 4 commits October 7, 2026 15:48
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>
@cristianrcv
cristianrcv force-pushed the fix/COMP-2645-tw-api-1.230 branch from c2728fe to 37b345a Compare October 7, 2026 13:50
@cristianrcv
cristianrcv force-pushed the feat/NOTASK-tw-agents branch from 72f3deb to 8e8d05e Compare October 7, 2026 13:50
@cristianrcv
cristianrcv changed the base branch from fix/COMP-2645-tw-api-1.230 to master October 7, 2026 13:50
@cristianrcv cristianrcv changed the title feat(agents): add the agents command group feat: add the agents and service-accounts command groups Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants