Skip to content

feat(agents): add system prompt option when creating agents#215

Merged
jlia0 merged 2 commits intomainfrom
jlia0/agent-add-system-prompt
Mar 15, 2026
Merged

feat(agents): add system prompt option when creating agents#215
jlia0 merged 2 commits intomainfrom
jlia0/agent-add-system-prompt

Conversation

@jlia0
Copy link
Collaborator

@jlia0 jlia0 commented Mar 14, 2026

Description

Add optional system_prompt parameter to agent creation in both CLI and API. When provided, the system prompt is written to AGENTS.md in the agent's workspace during provisioning, allowing agents to be configured with custom instructions at creation time.

Changes

  • CLI: Add system prompt text input during agentAdd() workflow
  • API: Accept system_prompt in PUT request body and write to AGENTS.md if provided
  • Docs: Update tinyclaw-admin skill with example of creating agent with system prompt

Testing

  • TypeScript type checking passes
  • Changes are backwards compatible (system_prompt is optional)
  • When system_prompt is provided, it overwrites the empty AGENTS.md created during provisioning

Add optional system_prompt parameter to agent creation in both CLI and API. When provided, the system prompt is written to AGENTS.md in the agent's workspace during provisioning, allowing agents to be configured with custom instructions at creation time.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tinyoffice Ready Ready Preview, Comment Mar 15, 2026 3:50pm

Request Review

@greptile-apps
Copy link

greptile-apps bot commented Mar 14, 2026

Greptile Summary

This PR adds an optional system_prompt parameter to both the CLI agentAdd() wizard and the PUT /api/agents/:id REST endpoint. When provided at creation time, the value is written to AGENTS.md in the agent's workspace directory, giving users a convenient way to seed custom instructions without a separate API call. Documentation in SKILL.md is updated accordingly.

Key changes:

  • packages/cli/src/agent.ts: Adds an optional p.text() prompt for system prompt; writes to AGENTS.md only when non-empty.
  • packages/server/src/routes/agents.ts: Saves system_prompt to settings.json on all PUTs, but only writes AGENTS.md when the agent is new — creating a silent divergence for updates on existing agents.
  • .agents/skills/tinyclaw-admin/SKILL.md: Adds a curl example demonstrating the new field.

Issues found:

  • system_prompt is unconditionally persisted to settings.json for all PUT requests (new and existing agents), but AGENTS.md is only written during initial provisioning. Updating an existing agent's system_prompt via PUT will silently update the settings record while leaving the AGENTS.md file the agent actually reads unchanged, causing GET /api/agents/:id and GET /api/agents/:id/system-prompt to return inconsistent values.

Confidence Score: 3/5

  • Safe to merge for new-agent workflows; the existing-agent update path has a logic bug causing settings and AGENTS.md to diverge silently.
  • The CLI path is clean and correct. The server path correctly handles the provisioning case. However, the unconditional save of system_prompt to settings for existing agents — without updating AGENTS.md — creates a real inconsistency that could mislead users and callers of the system-prompt read endpoint.
  • packages/server/src/routes/agents.ts — the system_prompt handling in the PUT /api/agents/:id route needs attention for the non-new-agent case.

Important Files Changed

Filename Overview
packages/server/src/routes/agents.ts Adds system_prompt write to AGENTS.md on provisioning; has a logic issue where system_prompt is persisted to settings for all PUTs but AGENTS.md is only updated for new agents, causing silent divergence on updates.
packages/cli/src/agent.ts Adds optional system prompt input to the interactive agentAdd() wizard; writes to AGENTS.md only when non-empty. Straightforward and consistent with the rest of the CLI flow.
.agents/skills/tinyclaw-admin/SKILL.md Documentation update adding a curl example for the new system_prompt field; correct and aligned with the implementation.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as PUT /api/agents/:id
    participant Settings as settings.json
    participant FS as AGENTS.md (filesystem)

    Client->>API: PUT /api/agents/coder {system_prompt: "..."}

    alt Agent is NEW (isNew = true)
        API->>Settings: mutateSettings — saves system_prompt ✅
        API->>FS: ensureAgentDirectory() — creates empty AGENTS.md
        API->>FS: writeFileSync(AGENTS.md, system_prompt) ✅
        API-->>Client: {ok: true, provisioned: true}
    else Agent ALREADY EXISTS (isNew = false)
        API->>Settings: mutateSettings — saves system_prompt ✅
        Note over FS: AGENTS.md NOT updated ⚠️
        API-->>Client: {ok: true, provisioned: false}
    end

    Client->>API: GET /api/agents/coder/system-prompt
    API->>FS: readFileSync(AGENTS.md)
    Note over API,FS: Returns stale value for existing agents
    API-->>Client: {content: "old prompt"} ⚠️
Loading

Comments Outside Diff (1)

  1. packages/server/src/routes/agents.ts, line 56-78 (link)

    system_prompt saved to settings but AGENTS.md not updated on existing agents

    system_prompt is always persisted to settings.json (line 63) for both new and existing agents. However, the AGENTS.md write is gated behind if (isNew) (line 68), meaning a PUT on an existing agent with a new system_prompt will silently update the settings record but leave the file the agent actually reads unchanged.

    This creates a divergence: GET /api/agents/coder will return the updated system_prompt field from settings, while GET /api/agents/coder/system-prompt (which reads AGENTS.md) will still return the old value. Users who update an existing agent expecting its behavior to change will be silently confused.

    Two options to resolve this:

    Option A – Also write AGENTS.md outside the isNew block when system_prompt is provided:

    // outside the isNew block:
    if (body.system_prompt) {
        fs.writeFileSync(path.join(workingDir, 'AGENTS.md'), body.system_prompt, 'utf8');
    }
    

    Option B – Strip system_prompt from the settings mutation so the file is the single source of truth and the stored value never goes stale:

    s.agents[agentId] = {
        name: body.name!,
        provider: body.provider!,
        model: body.model!,
        working_directory: workingDir,
        // system_prompt intentionally omitted — canonical value lives in AGENTS.md
        ...(body.prompt_file ? { prompt_file: body.prompt_file } : {}),
    };

Last reviewed commit: 3f87233

Strip system_prompt from settings.json persistence to prevent stale
values. Write AGENTS.md on both new and existing agent PUT requests.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@jlia0 jlia0 merged commit 24988a7 into main Mar 15, 2026
2 checks passed
@jlia0 jlia0 deleted the jlia0/agent-add-system-prompt branch March 15, 2026 15:51
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.

1 participant