Skip to content

tags being injected into user prompt #713

@Halcyonhal9

Description

@Halcyonhal9

tags being injected into user prompt

Problem

The CLI binary (v1.0.2) injects prompt context tags associated with built in tools into user messages sent to the model API. When using excludedTools to disable the built-in tools, the tags still appear.

For example, excluding the sql tool prevents the model from calling it, but the CLI still injects <reminder><sql_tables>...</sql_tables></reminder> into every user message:

{
  "role": "user",
  "content": "<current_datetime>2026-03-08T04:10:52.287Z</current_datetime>\n\nSay hello\n\n<reminder>\n<sql_tables>No tables currently exist. Default tables (todos, todo_deps) will be created automatically when you first use the SQL tool.</sql_tables>\n</reminder>"
}

Session config:

session = await client.create_session({
    "model": "...",
    "excluded_tools": [
        "bash", "write_bash", "read_bash", "stop_bash", "list_bash",
        "view", "create", "edit", "report_intent", "skill", "sql",
        "read_agent", "list_agents", "grep", "glob", "task",
    ],
    "on_permission_request": PermissionHandler.approve_all,
})

The sql tool is excluded from the tools list in the API request (verified via debug proxy traces). However, the <reminder><sql_tables> tag is still injected into user messages.

I also tested with available_tools: [] (empty whitelist) — the tags still appear.

Expected Behavior

When a tool is excluded via excludedTools or not included in availableTools, its associated prompt context tags should also be suppressed. There is no value in telling the model about SQL tables when it cannot access them.

Impact

  • Model confusion: Models reference and reason about the SQL tool despite it being unavailable, leading to unhelpful responses.
  • No workaround: There is no SessionConfig option to control prompt tag injection independently of tool availability. SDK consumers building non-CLI applications have no way to prevent this.
  • Wasted tokens: The <reminder><sql_tables>...</sql_tables></reminder> block is injected on every user message, consuming input tokens for context the model cannot act on.

Reproduction

  1. Create a session with excluded_tools: ["sql"] (or available_tools: [])
  2. Send any user message
  3. Inspect the outgoing API request body (e.g., via a debug proxy between the CLI and the model endpoint)
  4. Observe that the user message content contains <reminder><sql_tables>...</sql_tables></reminder> despite sql being excluded

Notes

The SDK test harness already accounts for this behavior — test/harness/replayingCapiProxy.ts strips these tags in normalizeUserMessage() for snapshot comparison:

function normalizeUserMessage(content: string): string {
  return content
    .replace(/<current_datetime>.*?<\/current_datetime>/g, "")
    .replace(/<reminder>[\s\S]*?<\/reminder>/g, "")
    ...
}

This confirms the tags are universally injected regardless of tool config, and the test infrastructure works around it rather than preventing it.

Suggested Fix

Option A: Suppress context tags for excluded/unavailable tools at the prompt enrichment stage in the CLI.

Option B: Add a SessionConfig option (e.g., disablePromptTags: true or promptContext: { datetime: true, reminder: false }) to give SDK consumers explicit control over prompt enrichment.

Environment

  • SDK version: 0.1.32
  • CLI binary version: 1.0.2
  • Language: Python
  • Provider: OpenAI, GitHub, Azure

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions