Skip to content

fix(runtime): apply agent custom system prompt on the web chat path#445

Closed
LikiosSedo wants to merge 1 commit into
mainfrom
fix/chat-custom-system-prompt
Closed

fix(runtime): apply agent custom system prompt on the web chat path#445
LikiosSedo wants to merge 1 commit into
mainfrom
fix/chat-custom-system-prompt

Conversation

@LikiosSedo

Copy link
Copy Markdown
Collaborator

Problem

A custom agent's system_prompt was silently dropped on the sicore web chat path: in the browser the agent introduced itself with the default SRE persona and ignored the custom prompt's rules. The same agent worked over Feishu/DingTalk.

Root cause (confirmed)

  1. sicore's chat proxy sends chat.send without a systemPrompt param (proxy/handler.go).
  2. The runtime's chat.send handler only honored params.systemPrompt (src/gateway/server.ts) → absent → undefined → AgentBox falls back to its built-in default SRE template.
  3. The resolver resolveAgentSystemPrompt(agentId, frontendClient) (config.getAgentagents.system_prompt) already existed, but was wired only into the channel / coordinator / delegate paths (dingtalk.ts, lark.ts, task-coordinator.ts, delegate-api.ts) — not the web chat main path.

So: sicore doesn't send it → the runtime only read the param → the channel paths had already resolved it while the web path never did.

Fix (runtime-side fallback, sicore unchanged)

In chat.send, when the caller does not forward systemPrompt, fall back to resolveAgentSystemPrompt(agentId, frontendClient):

  • An explicitly forwarded prompt (the portal-standalone path stamps it from the agent's model binding) still wins as-is — no behavior change there, and the fallback lookup is skipped entirely.
  • Best-effort: resolveAgentSystemPrompt swallows RPC errors and returns undefined on failure / no custom prompt → built-in default. A lookup failure therefore never turns into a chat failure (the send still acks ok).

Session-reuse semantics

AgentBox applies the template only at session creation, so this affects new sessions; a warm multi-turn session keeps the prompt it was created with — matching the existing channel-path behavior. No hot-update is introduced.

chat.send is the only prompt-creating entry point in server.ts; chat.steer targets an already-running session via steerSession, so no other handler needs the fallback.

Tests

  • New src/gateway/server-chat-system-prompt.test.ts (drives the real chat.send handler from startRuntime):
    • explicit systemPrompt param wins as-is and skips config.getAgent;
    • omitted param → resolves and applies the agent's custom prompt (the sicore web path);
    • no custom prompt (system_prompt: null) → undefined (built-in default);
    • config.getAgent throws → undefined default, and the send still returns { ok: true }.
  • tsc --noEmit clean; full src/gateway suite green (993 tests).

chat.send only read params.systemPrompt when building the box prompt.
sicore's web-chat proxy never forwards that param, so a custom-prompt
agent silently fell back to AgentBox's built-in default SRE persona on
sicore web chat — while channel paths (dingtalk/lark) resolved the
agent's own template and worked.

Root-cause chain:
- sicore sends chat.send without systemPrompt (proxy/handler.go).
- runtime chat.send only honored params.systemPrompt -> undefined ->
  box uses the default template.
- resolveAgentSystemPrompt (config.getAgent -> agents.system_prompt)
  already existed but was wired only into dingtalk/lark/task-coordinator/
  delegate paths, not the web chat main path.

Fix (runtime-side fallback, sicore unchanged): when the caller does not
forward systemPrompt, chat.send falls back to resolveAgentSystemPrompt.
An explicitly forwarded prompt (portal-standalone) still wins as-is; a
resolve failure / no custom prompt falls back to undefined = built-in
default, so a lookup failure never turns a chat into a failure.

Session-reuse semantics unchanged: AgentBox applies the template only at
session creation, so this affects NEW sessions; a warm multi-turn session
keeps the prompt it was created with. chat.send is the only prompt-
creating entry point (chat.steer targets an already-running session via
steerSession), so no other handler needs the fallback.

Adds server-chat-system-prompt.test.ts covering: explicit param wins and
skips the lookup; omitted param resolves the agent's custom prompt; no
custom prompt / lookup failure -> undefined default (send still acks ok).
@LikiosSedo

Copy link
Copy Markdown
Collaborator Author

Consolidated into #446 per owner request; review history stays here. This PR will be closed once the batch merges.

@LikiosSedo

Copy link
Copy Markdown
Collaborator Author

Superseded by #446 (platform hardening batch); branch retained.

@LikiosSedo LikiosSedo closed this Jul 23, 2026
pull Bot pushed a commit to TheTechOddBug/siclaw that referenced this pull request Jul 23, 2026
Apply agent custom system prompt fallback on the web chat path (gateway chat.send).
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