Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions apps/server/src/mcp/toolInstructions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, expect, it } from "vite-plus/test";
import { buildRuntimeInstructions } from "../provider/RuntimeInstructions.ts";

describe("t3-code tool instructions", () => {
it.each(["Claude Code", "Codex", "Cursor", "Grok", "OpenCode", "Antigravity"])(
"tell %s agents when to use prism_submit and when spawn_thread",
(harness) => {
const instructions = buildRuntimeInstructions({ harness });
expect(instructions).toContain("<t3_code_tool_use>");
expect(instructions).toContain(
"For an authorized job that should end in one PR, call prism_submit",
);
expect(instructions).toContain(
"or when a specific model and effort is wanted, call spawn_thread",
);
},
);

it("keep the Codex runtime entry inside its 1,000-token additional-context cap", () => {
// Codex cuts the middle of any additionalContext value above 1,000 tokens.
// Three characters per token is a conservative bound for this English text.
const instructions = buildRuntimeInstructions({
harness: "Codex",
model: "gpt-5.5",
modelName: "GPT-5.5",
reasoningEffort: "xhigh",
});
expect(instructions.length).toBeLessThan(3_000);
});
});
16 changes: 16 additions & 0 deletions apps/server/src/mcp/toolInstructions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Fork (toolboxmd/t3code#46): when to reach for the `t3-code` tools.
*
* Harnesses that defer tool schemas show agents only tool names, and Grok not
* even those, so an agent never learns when to use `prism_submit` or
* `spawn_thread`. `buildRuntimeInstructions` appends this to every harness's
* launch prompt. MCP server `instructions` (Effect 4.0.0-rc.116+) would reach
* Claude Code, Codex, OpenCode and Grok, but not Cursor over ACP, and
* Antigravity only writes them to a file, so do not move it there. Adding it
* to both would make Claude Code show it twice.
*/
const T3_CODE_TOOL_INSTRUCTIONS =
"Reach for the t3-code tools when work should stay visible in this T3 Code thread: delegating to other agents, testing web or native UI, and linking Issues. Delegate with them, not with agents started in a terminal. For an authorized job that should end in one PR, call prism_submit: Prism picks models, recovers failures and wakes you only for judgment (prism_questions, then prism_answer). For small direct work, or when a specific model and effort is wanted, call spawn_thread, then read_thread and message_thread. For web UI: preview_open, preview_snapshot, then act. For simulators: device_list, then device_open.";

/** The launch-prompt block `buildRuntimeInstructions` appends. */
export const T3_CODE_TOOL_USE_BLOCK = `<t3_code_tool_use>\n${T3_CODE_TOOL_INSTRUCTIONS}\n</t3_code_tool_use>`;
4 changes: 3 additions & 1 deletion apps/server/src/provider/RuntimeInstructions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { T3_CODE_TOOL_USE_BLOCK } from "../mcp/toolInstructions.ts";

const PULL_REQUEST_LINKING_INSTRUCTIONS = `<pull_request_linking>
When the t3-code MCP server exposes link_pull_request, you must use it to register every pull request you create or work on for this thread. Call link_pull_request with the full PR URL immediately after creating a PR or starting work on an existing PR. For a stack, call it for every layer, not just the current branch or the top PR. This applies when creating or updating PRs through gh, gh stack, another CLI, or the host API: those operations do not register the PRs with this thread. Linking an already-linked PR is safe. Before finishing PR work, call list_thread_pull_requests and link any PR from your work that is missing. Do not link unrelated PRs mentioned only as background. If a linking call fails, report that failure instead of claiming the PR is linked.
</pull_request_linking>`;
Expand All @@ -20,7 +22,7 @@ export function buildRuntimeInstructions(runtime: {
modelName && modelName !== model ? `${modelName} (model slug: ${model})` : model;
const modelInfo = model && model !== "auto" && model !== "default" ? `, as ${modelLabel}` : "";
const effortInfo = effort ? ` with ${effort} reasoning effort` : "";
return `<runtime_info>In case you're asked: you are running in T3 Code through the ${harness} harness${modelInfo}${effortInfo}. No need to mention this otherwise. You can embed images and videos in your response using Markdown with absolute file paths.</runtime_info>\n\n${PULL_REQUEST_LINKING_INSTRUCTIONS}`;
return `<runtime_info>In case you're asked: you are running in T3 Code through the ${harness} harness${modelInfo}${effortInfo}. No need to mention this otherwise. You can embed images and videos in your response using Markdown with absolute file paths.</runtime_info>\n\n${PULL_REQUEST_LINKING_INSTRUCTIONS}\n\n${T3_CODE_TOOL_USE_BLOCK}`;
}

function toSingleLine(value: string): string {
Expand Down
23 changes: 23 additions & 0 deletions docs/fork-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,3 +521,26 @@ for per-match decisions and the absorption PR record.
"keywords": ["createEnvironmentQueryAtomFamily", "retryInterruptedRead", "hasInterruptsOnly"]
}
```

## Tool instructions for agents

```json
{
"id": "tool-instructions",
"purpose": "Tell agents when to reach for the t3-code tools, including prism_submit versus spawn_thread, even when harnesses defer tool schemas.",
"issues": ["https://github.com/toolboxmd/t3code/issues/46"],
"prs": ["https://github.com/toolboxmd/t3code/pull/53"],
"newFiles": [
"apps/server/src/mcp/toolInstructions.test.ts",
"apps/server/src/mcp/toolInstructions.ts"
],
"upstreamFiles": ["apps/server/src/provider/RuntimeInstructions.ts"],
"sharedFiles": [],
"keywords": [
"t3_code_tool_use",
"buildRuntimeInstructions",
"McpServer.layerHttp",
"instructions:"
]
}
```
3 changes: 3 additions & 0 deletions scripts/fork-upstream-edits.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ apps/web/src/lib/openPullRequestLink.ts
# Interrupted environment reads are read again (#52)
packages/client-runtime/src/state/runtime.test.ts
packages/client-runtime/src/state/runtime.ts

# Tool instructions for agents (#46)
apps/server/src/provider/RuntimeInstructions.ts
Loading