Merged
Size
L
Change Breakdown
Bug Fix70%
Refactor25%
Testing5%
#61577[Fix] agents.create RPC: support model param, write identity to config

Agent creation RPC now accepts model param, writes identity to config

The agents.create and agents.update RPC methods now persist identity fields to the config instead of IDENTITY.md, making them visible to agents.list and the control UI. agents.create also gains model parameter support.

Creating agents through the RPC layer was a two-step process: call agents.create, then immediately call agents.update to set the model. Even then, identity fields like name, emoji, and avatar were written to a workspace file that the control UI never read from.

The root cause was a data divergence. The create and update handlers appended identity fields to IDENTITY.md, but the gateway's list endpoint reads exclusively from the config. New agents appeared in the UI with no name, emoji, or model — even though the data existed in a file the UI couldn't see.

The fix routes identity writes through applyAgentConfig, the same path the CLI set-identity command uses. This ensures the config stays authoritative while IDENTITY.md remains as a workspace bootstrap file. The merge logic preserves existing content, including richer identity fields like creature, vibe, and theme that existed before this change.

Schema updates add model to the create request and response, and emoji to the update request. The handlers now pass identity and model directly to applyAgentConfig instead of formatting and appending markdown manually.

In the gateway package, RPC handlers handle agent lifecycle. The workspace package manages bootstrap files. The config package stores agent entries. The identity-file package handles markdown parsing and now merging.

View Original GitHub Description

Summary

  • Problem: agents.create RPC didn't accept model param, forcing a follow-up agents.update call to set model at creation time.
  • Problem: Create/update handlers wrote identity fields (name, emoji, avatar) to IDENTITY.md but agents.list (gateway) reads from agents.list[].identity in config — data was silently invisible to the control UI.
  • Why it matters: New agents created via RPC had no visible identity or model in the control UI without workaround calls.
  • What changed: Added model to create schema, emoji to update schema. Replaced IDENTITY.md file I/O with config identity writes via applyAgentConfig. Removed dead helpers (ensureWorkspaceFileReadyOrRespond, appendWorkspaceFileOrRespond). Added unit tests for identity merge logic.
  • What did NOT change (scope boundary): IDENTITY.md bootstrap (still created by ensureAgentWorkspace), avatar upload endpoint, IDENTITY.md removal/migration.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #61559
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: agents.create was shipped without model param (v1 scope cut). Identity write path targeted IDENTITY.md (workspace file) but the gateway list endpoint reads identity from config, creating a silent data divergence.
  • Missing detection / guardrail: No test asserted that RPC-created agent identity was readable through the gateway list endpoint.
  • Contributing context (if known): The CLI set-identity command correctly writes to config; the RPC handlers predated that alignment.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/commands/agents.test.ts, src/gateway/server-methods/agents-mutate.test.ts
  • Scenario the test should lock in: applyAgentConfig merges identity fields correctly; create/update handlers pass identity and model to config instead of IDENTITY.md.
  • Why this is the smallest reliable guardrail: Unit tests verify the merge logic and handler wiring without requiring a running gateway.
  • Existing test that already covers this (if any): Handler tests existed but asserted IDENTITY.md writes; updated to assert config writes.
  • If no new test is added, why not: Two new unit tests added for applyAgentConfig identity merge.

User-visible / Behavior Changes

  • agents.create now accepts optional model param and returns it in the response.
  • agents.update now accepts optional emoji param.
  • Identity fields (name, emoji, avatar) set via RPC are now visible in agents.list and the control UI.

Diagram (if applicable)

Before:
[agents.create name/emoji/avatar] -> [IDENTITY.md] (gateway reads config -> invisible)

After:
[agents.create name/emoji/avatar/model] -> [config.agents.list[].identity] (gateway reads config -> visible)

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / Bun
  • Model/provider: N/A
  • Integration/channel (if any): Gateway RPC
  • Relevant config (redacted): N/A

Steps

  1. Call agents.create with name, model, emoji params
  2. Call agents.list
  3. Verify created agent has correct identity and model

Expected

  • Agent appears in list with name, emoji, and model set

Actual

  • Before fix: identity fields missing from list, model not accepted
  • After fix: all fields present

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

38 tests passing (2 files: agents.test.ts, agents-mutate.test.ts)

Human Verification (required)

  • Verified scenarios: All 38 unit tests pass. Traced all 3 identity read paths (resolveAssistantIdentity, listAgentsForGateway, listConfiguredAgents) — all have config fallback. Verified all 7 applyAgentConfig callers are backwards-compatible.
  • Edge cases checked: Identity merge preserves unmentioned fields (theme). Empty emoji/avatar dropped by resolveOptionalStringParam. Name sanitized consistently via sanitizeIdentityLine for both entry.name and identity.name.
  • What you did not verify: Live gateway RPC round-trip (unit tests only).

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes (additive optional fields only)
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: IDENTITY.md no longer updated by RPC — bootstrap file stays as template for RPC-created agents.
    • Mitigation: By design. resolveAssistantIdentity reads config identity first, falling back to file. Aligns with CLI set-identity behavior. IDENTITY.md remains as agent self-discovery bootstrap file.
© 2026 · via Gitpulse