Skip to content

feat(sdk): let a client send context with a user message - #36

Merged
matej21 merged 2 commits into
mainfrom
feat/user-chat-message-context
Sep 13, 2026
Merged

feat(sdk): let a client send context with a user message#36
matej21 merged 2 commits into
mainfrom
feat/user-chat-message-context

Conversation

@matej21

@matej21 matej21 commented Sep 13, 2026

Copy link
Copy Markdown
Member

Problem

A client often knows something the user does not type: the page shown in a preview, a selected element, the editor state. The agent needs this to understand messages like "make this heading bigger".

@roj-ai/client-react already has a place for it. useSessionStore has messageContext and setMessageContext. But sendMessage never reads the value, and user-chat.sendMessage has no field that could carry it. The context is computed and then dropped. A production consumer shipped a "select an element and ask the agent" feature on top of this store, and the agent never received the selection.

Change

  • user-chat.sendMessage takes an optional context: string.
  • The user_chat_message_received event and UserChatMessage get an optional context. The field is omitted when the client sends none, so events and state for plain messages do not change.
  • The LLM receives the context after the message text:
    [User]: Make this heading bigger
    <user_context>
    Page: /about
    </user_context>
    
  • content stays what the user typed. A UI that renders content does not show the context.
  • The hard limit (MESSAGE_MAX_TOKENS) counts content and context together. Soft truncation still applies to content only.
  • client-react: sendMessage sends messageContext as context.

Compatibility

  • The field is optional, so existing callers do not change.
  • An older agent server strips the unknown context key (z.object), so a new client works with an old server. The agent then does not see the context, as before.

Tests

  • New tests in user-chat.integration.test.ts:
    • A message with context: the LLM request contains the <user_context> block. The chat history keeps the context apart from content.
    • A message without context: the LLM request has no block, and the event has no context key.
  • bun run test: 1606 pass, 77 skip, 0 fail.
  • bun run ts:build, bun run lint and tsc -p packages/sdk/tsconfig.test.json are clean.
  • Demo e2e (snapshot replay): 2 pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_012fX9ohNay3XuPYkKGdGZ3i

matej21 and others added 2 commits September 13, 2026 13:42
`user-chat.sendMessage` takes an optional `context`: what the client knew
when the user sent the message (the page on screen, a selected element).
The LLM gets it in a `<user_context>` block after the message. The chat
history keeps it in a separate field, so a UI that renders `content`
does not show it. The hard token limit counts content and context together.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012fX9ohNay3XuPYkKGdGZ3i
`setMessageContext` stored the context, but `sendMessage` never read it,
so the agent did not receive it. Send it as the new `context` field.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012fX9ohNay3XuPYkKGdGZ3i
@matej21
matej21 merged commit 5a9b940 into main Sep 13, 2026
1 check passed
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