@cursor/july 0.1.34 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/404.html +1 -1
- package/dist/docs/ab.html +2 -2
- package/dist/docs/assets/{app.FPupl4SP.js → app.D5Mv1T0U.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.Cu7b6o1D.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.Cd182Cu0.js → VPLocalSearchBox.CMq_BQce.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BEM3Okcd.js → theme.C6D9UPLK.js} +2 -2
- package/dist/docs/building-with-agents.html +2 -2
- package/dist/docs/concepts.html +2 -2
- package/dist/docs/deployment.html +2 -2
- package/dist/docs/evals.html +2 -2
- package/dist/docs/example-agents/approval-buddy.html +2 -2
- package/dist/docs/example-agents/benny.html +2 -2
- package/dist/docs/example-agents/bugbot.html +2 -2
- package/dist/docs/example-agents/codebase-wiki.html +2 -2
- package/dist/docs/example-agents/codeowners-review.html +2 -2
- package/dist/docs/example-agents/concierge.html +2 -2
- package/dist/docs/example-agents/fsd.html +2 -2
- package/dist/docs/example-agents/index.html +2 -2
- package/dist/docs/example-agents/knowledge-base.html +2 -2
- package/dist/docs/example-agents/oncall.html +2 -2
- package/dist/docs/example-agents/security-reviewer.html +2 -2
- package/dist/docs/example-agents/slack-agent.html +2 -2
- package/dist/docs/example-agents/weather-agent.html +2 -2
- package/dist/docs/guides/agent-to-agent.html +2 -2
- package/dist/docs/guides/cloud-runtime.html +2 -2
- package/dist/docs/guides/github.html +2 -2
- package/dist/docs/guides/human-in-the-loop.html +2 -2
- package/dist/docs/guides/mcp-oauth.html +2 -2
- package/dist/docs/guides/slack.html +2 -2
- package/dist/docs/guides/webhooks.html +2 -2
- package/dist/docs/hillclimbing.html +2 -2
- package/dist/docs/index.html +2 -2
- package/dist/docs/quickstart.html +2 -2
- package/dist/docs/reference/agent-config.html +2 -2
- package/dist/docs/reference/channels.html +2 -2
- package/dist/docs/reference/cli.html +2 -2
- package/dist/docs/reference/connections.html +2 -2
- package/dist/docs/reference/hooks.html +2 -2
- package/dist/docs/reference/http-api.html +2 -2
- package/dist/docs/reference/instructions.html +2 -2
- package/dist/docs/reference/playground.html +2 -2
- package/dist/docs/reference/project-layout.html +2 -2
- package/dist/docs/reference/prompt.html +2 -2
- package/dist/docs/reference/schedules.html +2 -2
- package/dist/docs/reference/sessions.html +2 -2
- package/dist/docs/reference/skills.html +2 -2
- package/dist/docs/reference/subagents.html +2 -2
- package/dist/docs/reference/tools.html +2 -2
- package/dist/docs/scaffolding-agents.html +2 -2
- package/dist/docs/storage.html +2 -2
- package/dist/docs/troubleshooting.html +2 -2
- package/dist/internal/host-kv.d.ts +6 -2
- package/dist/internal/host-kv.d.ts.map +1 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +15 -6
- package/dist/internal/storage-coordinator.d.ts +9 -1
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +7 -0
- package/dist/internal/storage-roles.d.ts +78 -0
- package/dist/internal/storage-roles.d.ts.map +1 -0
- package/dist/internal/storage-roles.js +24 -0
- package/dist/internal/workspace.d.ts +26 -0
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +53 -0
- package/dist/playground/assets/{index-CDDWw0YX.js → index-D7OV8B_H.js} +40 -40
- package/dist/playground/assets/index-DOb96C0M.css +1 -0
- package/dist/playground/index.html +2 -2
- package/package.json +1 -1
- package/src/internal/host-kv.ts +6 -2
- package/src/internal/session-engine.ts +20 -8
- package/src/internal/storage-coordinator.ts +15 -1
- package/src/internal/storage-roles.ts +86 -0
- package/src/internal/workspace.ts +62 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.WoYunhnT.js +0 -1
- package/dist/playground/assets/index-MVuNTd8v.css +0 -1
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
/>
|
|
9
9
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
10
10
|
<title>agent-serve playground</title>
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-D7OV8B_H.js"></script>
|
|
12
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DOb96C0M.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor/july",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
4
4
|
"description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"repository": {
|
package/src/internal/host-kv.ts
CHANGED
|
@@ -11,12 +11,16 @@ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { storageKeys } from "../storage.js";
|
|
13
13
|
import type { HostKvApi, JsonValue } from "../types.js";
|
|
14
|
-
import type {
|
|
14
|
+
import type { AuthorKvStore } from "./storage-roles.js";
|
|
15
15
|
|
|
16
16
|
export interface CreateHostKvApiOptions {
|
|
17
17
|
agentName: string;
|
|
18
18
|
stateRoot: string;
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Author KV backend. Narrowed to {@link AuthorKvStore} so this path cannot
|
|
21
|
+
* reach framework session state, which is headed somewhere else entirely.
|
|
22
|
+
*/
|
|
23
|
+
storage?: AuthorKvStore;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
/** Build the host KV API for one agent process. */
|
|
@@ -103,6 +103,7 @@ import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections
|
|
|
103
103
|
import type { AgentRunner } from "./sdk-runner.js";
|
|
104
104
|
import { SessionStore } from "./session-store.js";
|
|
105
105
|
import { StorageCoordinator } from "./storage-coordinator.js";
|
|
106
|
+
import type { FrameworkSessionStore } from "./storage-roles.js";
|
|
106
107
|
import { normalizeToolResult, toolCallErrorMessage } from "./tool-result.js";
|
|
107
108
|
import {
|
|
108
109
|
type EstimateTurnCostFn,
|
|
@@ -115,6 +116,7 @@ import {
|
|
|
115
116
|
buildCloudMemorySection,
|
|
116
117
|
isNestedInGitRepo,
|
|
117
118
|
materializeWorkspace,
|
|
119
|
+
SERVER_TOOLS_MCP_SERVER_NAME,
|
|
118
120
|
writeWorkspaceFiles,
|
|
119
121
|
} from "./workspace.js";
|
|
120
122
|
|
|
@@ -1463,8 +1465,18 @@ export class SessionEngine {
|
|
|
1463
1465
|
if (runtime === "cloud") {
|
|
1464
1466
|
// Cloud VMs have no materialized workspace: ship the full context,
|
|
1465
1467
|
// including agent tool script bodies. On hosted deployments the
|
|
1466
|
-
// shared memory journal is on the store mount — say where.
|
|
1467
|
-
|
|
1468
|
+
// shared memory journal is on the store mount — say where. When the
|
|
1469
|
+
// turn carries the session-bound server-tool MCP endpoint, the
|
|
1470
|
+
// preamble also catalogs server tools under that MCP server name;
|
|
1471
|
+
// without it a model told to "use <server tool>" finds no script
|
|
1472
|
+
// and improvises a local substitute instead of calling the host.
|
|
1473
|
+
const preamble = buildAgentsMdContent(agent, {
|
|
1474
|
+
includeScripts: true,
|
|
1475
|
+
serverToolsMcpName:
|
|
1476
|
+
this.cloudServerToolsConnection === undefined
|
|
1477
|
+
? undefined
|
|
1478
|
+
: SERVER_TOOLS_MCP_SERVER_NAME,
|
|
1479
|
+
});
|
|
1468
1480
|
const memorySection = isCursorHostedFilesAvailable()
|
|
1469
1481
|
? `\n\n${buildCloudMemorySection(this.project.name)}`
|
|
1470
1482
|
: "";
|
|
@@ -1677,16 +1689,16 @@ export class SessionEngine {
|
|
|
1677
1689
|
this.cloudServerToolsConnection !== undefined &&
|
|
1678
1690
|
this.project.agent.tools.some((tool) => tool.execution === "server")
|
|
1679
1691
|
) {
|
|
1680
|
-
if (servers[
|
|
1692
|
+
if (servers[SERVER_TOOLS_MCP_SERVER_NAME] !== undefined) {
|
|
1681
1693
|
throw new Error(
|
|
1682
|
-
|
|
1694
|
+
`MCP connection name "${SERVER_TOOLS_MCP_SERVER_NAME}" is reserved for authored server tools on cloud turns.`
|
|
1683
1695
|
);
|
|
1684
1696
|
}
|
|
1685
1697
|
const connection = this.cloudServerToolsConnection;
|
|
1686
1698
|
if ("url" in connection) {
|
|
1687
1699
|
const url = new URL(connection.url);
|
|
1688
1700
|
url.searchParams.set("agentkitSessionId", sessionId);
|
|
1689
|
-
servers[
|
|
1701
|
+
servers[SERVER_TOOLS_MCP_SERVER_NAME] = {
|
|
1690
1702
|
...connection,
|
|
1691
1703
|
url: url.toString(),
|
|
1692
1704
|
};
|
|
@@ -2938,7 +2950,7 @@ export class SessionEngine {
|
|
|
2938
2950
|
}
|
|
2939
2951
|
|
|
2940
2952
|
private async runBulkRestore(
|
|
2941
|
-
storage:
|
|
2953
|
+
storage: FrameworkSessionStore,
|
|
2942
2954
|
policy: { maxSessions: number; maxAgeMs: number; maxTotalBytes: number }
|
|
2943
2955
|
): Promise<void> {
|
|
2944
2956
|
const loaded = await storage.listSessions();
|
|
@@ -3099,7 +3111,7 @@ export class SessionEngine {
|
|
|
3099
3111
|
}
|
|
3100
3112
|
|
|
3101
3113
|
private async loadAndMaterializeByContinuation(
|
|
3102
|
-
storage:
|
|
3114
|
+
storage: FrameworkSessionStore,
|
|
3103
3115
|
channelId: string,
|
|
3104
3116
|
continuationKey: string
|
|
3105
3117
|
): Promise<SessionRecord | undefined> {
|
|
@@ -3115,7 +3127,7 @@ export class SessionEngine {
|
|
|
3115
3127
|
}
|
|
3116
3128
|
|
|
3117
3129
|
private async loadAndMaterializeById(
|
|
3118
|
-
storage:
|
|
3130
|
+
storage: FrameworkSessionStore,
|
|
3119
3131
|
sessionId: string
|
|
3120
3132
|
): Promise<SessionRecord | undefined> {
|
|
3121
3133
|
const record = await storage.getSessionById(sessionId);
|
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
* and A/B metrics go to their dedicated tables (`evals` / `abs`).
|
|
15
15
|
* Reminder documents live on the control plane. Everything shares one
|
|
16
16
|
* bounded, serialized queue.
|
|
17
|
+
*
|
|
18
|
+
* It does three unrelated jobs, declared separately as
|
|
19
|
+
* {@link FrameworkSessionStore}, {@link AuthorKvStore}, and
|
|
20
|
+
* {@link EvalAbStore} — see `storage-roles.ts` for why they differ and where
|
|
21
|
+
* each is headed. The queue stays shared: it is one bounded, serialized chain
|
|
22
|
+
* per agent, and splitting it would change backpressure behavior, which this
|
|
23
|
+
* seam deliberately does not touch.
|
|
17
24
|
*/
|
|
18
25
|
|
|
19
26
|
import type { ABMetricSample } from "../ab.js";
|
|
@@ -30,6 +37,11 @@ import type { JsonValue, SessionEvent, SessionRecord } from "../types.js";
|
|
|
30
37
|
import type { ABSnapshot } from "./ab-snapshot.js";
|
|
31
38
|
import { describeError } from "./describe-error.js";
|
|
32
39
|
import type { EvalRunStorage } from "./eval-run-store.js";
|
|
40
|
+
import type {
|
|
41
|
+
AuthorKvStore,
|
|
42
|
+
EvalAbStore,
|
|
43
|
+
FrameworkSessionStore,
|
|
44
|
+
} from "./storage-roles.js";
|
|
33
45
|
|
|
34
46
|
/** Event types that close a unit of work — flush point for turn-end batching. */
|
|
35
47
|
const TURN_BOUNDARY_EVENTS: ReadonlySet<SessionEvent["type"]> = new Set([
|
|
@@ -85,7 +97,9 @@ interface SessionBuffer {
|
|
|
85
97
|
debounceTimer?: ReturnType<typeof setTimeout>;
|
|
86
98
|
}
|
|
87
99
|
|
|
88
|
-
export class StorageCoordinator
|
|
100
|
+
export class StorageCoordinator
|
|
101
|
+
implements FrameworkSessionStore, AuthorKvStore, EvalAbStore
|
|
102
|
+
{
|
|
89
103
|
readonly policy: ResolvedStoragePolicy;
|
|
90
104
|
|
|
91
105
|
private readonly definition: StorageDefinition;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three unrelated jobs `defineStorage` currently does, named separately.
|
|
3
|
+
*
|
|
4
|
+
* {@link import("./storage-coordinator.js").StorageCoordinator} implements all
|
|
5
|
+
* three today over one sink and one delivery queue. Splitting the *types* is
|
|
6
|
+
* the seam that lets each job change independently:
|
|
7
|
+
*
|
|
8
|
+
* - {@link FrameworkSessionStore} is framework state. Session records, event
|
|
9
|
+
* chunks, and the continuation index are how a session survives the process,
|
|
10
|
+
* so they belong to Agent Serve, not to the agent. Today they persist only
|
|
11
|
+
* when the author writes `agent/storage.ts` — the defect this seam exists to
|
|
12
|
+
* let us fix, by giving the framework its own provider that is automatic and
|
|
13
|
+
* not author-configurable.
|
|
14
|
+
* - {@link AuthorKvStore} is author state: whatever `ctx.host.kv` was handed.
|
|
15
|
+
* It converges onto the author file plane, which is a different destination
|
|
16
|
+
* from the one above.
|
|
17
|
+
* - {@link EvalAbStore} is playground/experiment bookkeeping with its own
|
|
18
|
+
* dedicated tables, and follows neither.
|
|
19
|
+
*
|
|
20
|
+
* Consumers should depend on the narrowest role they use. That is what keeps a
|
|
21
|
+
* later change to framework persistence from silently reaching author KV, and
|
|
22
|
+
* it is why these are interfaces rather than a comment on one class.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { ABMetricSample } from "../ab.js";
|
|
26
|
+
import type { StorageContext } from "../storage.js";
|
|
27
|
+
import type { JsonValue, SessionEvent, SessionRecord } from "../types.js";
|
|
28
|
+
import type { ABSnapshot } from "./ab-snapshot.js";
|
|
29
|
+
import type { EvalRunStorage } from "./eval-run-store.js";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Framework-owned session durability: what has to be true for a session to
|
|
33
|
+
* outlive the process that served it.
|
|
34
|
+
*
|
|
35
|
+
* Writes are fire-and-forget by design — a throwing backend is logged and its
|
|
36
|
+
* write dropped, because storage must never stall or fail a turn. That is
|
|
37
|
+
* at-most-once, and it is the property Track F later has to tighten, since a
|
|
38
|
+
* dropped record is a session that cannot be restored.
|
|
39
|
+
*/
|
|
40
|
+
export interface FrameworkSessionStore {
|
|
41
|
+
/** Durable session-record update; coalesced until the next flush. */
|
|
42
|
+
sessionRecord(record: SessionRecord): void;
|
|
43
|
+
/** One appended session event; batched per turn or debounce window. */
|
|
44
|
+
event(event: SessionEvent): void;
|
|
45
|
+
/** Marks an event delivered, for backends that track dispatch. */
|
|
46
|
+
eventDispatched(event: SessionEvent): void;
|
|
47
|
+
/** Flush everything buffered for one session (ordered: events, record). */
|
|
48
|
+
flushSession(sessionId: string, reason?: StorageContext["reason"]): void;
|
|
49
|
+
|
|
50
|
+
/** True when the backend can list every session in one bulk read. */
|
|
51
|
+
readonly canBulkRestore: boolean;
|
|
52
|
+
/** True when the backend is the Cursor-hosted one rather than an authored sink. */
|
|
53
|
+
readonly isCursorHosted: boolean;
|
|
54
|
+
|
|
55
|
+
listSessions(): Promise<SessionRecord[]>;
|
|
56
|
+
listSessionsFromSink(): Promise<SessionRecord[]>;
|
|
57
|
+
listSessionEvents(sessionId: string): Promise<SessionEvent[]>;
|
|
58
|
+
getSessionById(sessionId: string): Promise<SessionRecord | undefined>;
|
|
59
|
+
getSessionByContinuation(
|
|
60
|
+
channelId: string,
|
|
61
|
+
continuationKey: string
|
|
62
|
+
): Promise<SessionRecord | undefined>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Author-facing durable JSON behind `ctx.host.kv`.
|
|
67
|
+
*
|
|
68
|
+
* Deployment-wide on purpose: the point is state an author saves in one
|
|
69
|
+
* session and reads back in a later one, so unlike `ctx.host.files` there is
|
|
70
|
+
* no session scope to default to.
|
|
71
|
+
*/
|
|
72
|
+
export interface AuthorKvStore {
|
|
73
|
+
/** False when no backend is configured; callers fall back to local disk. */
|
|
74
|
+
readonly supportsAuthorKv: boolean;
|
|
75
|
+
kvGet(authorKey: string): Promise<JsonValue | undefined>;
|
|
76
|
+
kvPut(authorKey: string, value: JsonValue): Promise<void>;
|
|
77
|
+
kvDelete(authorKey: string): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Playground eval batches and live A/B metrics, on their own tables. */
|
|
81
|
+
export interface EvalAbStore {
|
|
82
|
+
evalRuns(): EvalRunStorage | undefined;
|
|
83
|
+
abSample(sample: ABMetricSample): void;
|
|
84
|
+
abSnapshot(snapshot: ABSnapshot): void;
|
|
85
|
+
getLatestAbSnapshot(): Promise<ABSnapshot | undefined>;
|
|
86
|
+
}
|
|
@@ -66,6 +66,14 @@ export function agentToolScriptPath(toolName: string): string {
|
|
|
66
66
|
return `.agent-serve/tools/${toolName}.sh`;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Reserved MCP connection name under which authored server tools are served
|
|
71
|
+
* to cloud turns (the session-bound tool MCP endpoint). Shared between the
|
|
72
|
+
* turn's MCP config and the first-prompt server-tool catalog so the model is
|
|
73
|
+
* told exactly where those tools live.
|
|
74
|
+
*/
|
|
75
|
+
export const SERVER_TOOLS_MCP_SERVER_NAME = "agentsdk-tools";
|
|
76
|
+
|
|
69
77
|
/**
|
|
70
78
|
* Always-on identity line prepended when composing instructions. Sourced from
|
|
71
79
|
* {@link ResolvedAgent.name} (`defineAgent({ name })`, else package/dir name)
|
|
@@ -157,16 +165,64 @@ export function buildAgentToolsCatalog(
|
|
|
157
165
|
return `${parts.join("\n").trimEnd()}\n`;
|
|
158
166
|
}
|
|
159
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Markdown catalog of authored server tools for the cloud first prompt.
|
|
170
|
+
*
|
|
171
|
+
* Server tools execute on the serve host and reach cloud turns only as MCP
|
|
172
|
+
* tools on {@link SERVER_TOOLS_MCP_SERVER_NAME}. Instructions reference them
|
|
173
|
+
* by bare name, and the agent-tool catalog teaches a "recreate the script if
|
|
174
|
+
* missing" pattern — without this section a cloud model that cannot find a
|
|
175
|
+
* script for a server tool improvises a local substitute instead of calling
|
|
176
|
+
* the real tool, so its host-side effects silently never happen.
|
|
177
|
+
*/
|
|
178
|
+
export function buildServerToolsCatalog(
|
|
179
|
+
tools: DiscoveredTool[],
|
|
180
|
+
options: { mcpServerName: string }
|
|
181
|
+
): string {
|
|
182
|
+
const serverTools = tools.filter((tool) => tool.execution === "server");
|
|
183
|
+
if (serverTools.length === 0) {
|
|
184
|
+
return "";
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const parts: string[] = [
|
|
188
|
+
"## Server tools",
|
|
189
|
+
"",
|
|
190
|
+
`These tools execute on the agent-serve host, not in this environment. They are available ONLY as MCP tools on the \`${options.mcpServerName}\` MCP server — list that server's tools and call them by name through your MCP tooling.`,
|
|
191
|
+
"There are no local scripts for these tools. NEVER create, edit, or run a local script or other substitute for them: a local re-implementation cannot produce their real effects on the host.",
|
|
192
|
+
"",
|
|
193
|
+
];
|
|
194
|
+
|
|
195
|
+
for (const tool of serverTools) {
|
|
196
|
+
parts.push(`### \`${tool.name}\``);
|
|
197
|
+
parts.push("");
|
|
198
|
+
parts.push(tool.description.trim());
|
|
199
|
+
parts.push("");
|
|
200
|
+
parts.push("Input schema:");
|
|
201
|
+
parts.push("");
|
|
202
|
+
parts.push("```json");
|
|
203
|
+
parts.push(JSON.stringify(tool.inputSchema, null, 2));
|
|
204
|
+
parts.push("```");
|
|
205
|
+
parts.push("");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return `${parts.join("\n").trimEnd()}\n`;
|
|
209
|
+
}
|
|
210
|
+
|
|
160
211
|
/**
|
|
161
212
|
* The full AGENTS.md-equivalent context for an agent: instructions, identity
|
|
162
213
|
* section, and the agent-side tool catalog. Written to the session workspace
|
|
163
214
|
* as `AGENTS.md`, and inlined into the first turn's prompt when the harness
|
|
164
215
|
* cannot discover that file (cloud runtime, or a local workspace the harness
|
|
165
216
|
* will not treat as the project root — see {@link isNestedInGitRepo}).
|
|
217
|
+
*
|
|
218
|
+
* `serverToolsMcpName` is cloud-only: when the turn's MCP config carries the
|
|
219
|
+
* session-bound server-tool endpoint, the catalog names that server so the
|
|
220
|
+
* model calls the real tools instead of inventing local stand-ins. Local
|
|
221
|
+
* runtimes omit it — there the harness exposes server tools natively.
|
|
166
222
|
*/
|
|
167
223
|
export function buildAgentsMdContent(
|
|
168
224
|
agent: ResolvedAgent,
|
|
169
|
-
options: { includeScripts: boolean }
|
|
225
|
+
options: { includeScripts: boolean; serverToolsMcpName?: string }
|
|
170
226
|
): string {
|
|
171
227
|
return [
|
|
172
228
|
agent.instructions?.trim() ?? "",
|
|
@@ -174,6 +230,11 @@ export function buildAgentsMdContent(
|
|
|
174
230
|
buildAgentToolsCatalog(agent.tools, {
|
|
175
231
|
includeScripts: options.includeScripts,
|
|
176
232
|
}),
|
|
233
|
+
options.serverToolsMcpName === undefined
|
|
234
|
+
? ""
|
|
235
|
+
: buildServerToolsCatalog(agent.tools, {
|
|
236
|
+
mcpServerName: options.serverToolsMcpName,
|
|
237
|
+
}),
|
|
177
238
|
]
|
|
178
239
|
.filter((part) => part !== "")
|
|
179
240
|
.join("\n\n");
|