@agntn/harnesses 0.2.1 → 0.3.1
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/README.md +48 -9
- package/dist/_chunks/agents.mjs +5 -3
- package/dist/_chunks/agents.mjs.map +1 -1
- package/dist/_chunks/mcp-servers.mjs +5 -3
- package/dist/_chunks/mcp-servers.mjs.map +1 -1
- package/dist/_chunks/mcp.mjs +10 -1
- package/dist/_chunks/mcp.mjs.map +1 -1
- package/dist/_chunks/output.mjs +7 -1
- package/dist/_chunks/output.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +4 -2
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/{prompt-sync.d.mts → skills-sync.d.mts} +174 -57
- package/dist/_chunks/skills-sync.d.mts.map +1 -0
- package/dist/_chunks/{prompt-sync.mjs → skills-sync.mjs} +665 -148
- package/dist/_chunks/skills-sync.mjs.map +1 -0
- package/dist/_chunks/skills.mjs +30 -0
- package/dist/_chunks/skills.mjs.map +1 -0
- package/dist/_chunks/tool-operations.mjs +38 -13
- package/dist/_chunks/tool-operations.mjs.map +1 -1
- package/dist/_chunks/tool-schemas.d.mts +22 -13
- package/dist/_chunks/tool-schemas.d.mts.map +1 -1
- package/dist/_chunks/tool-schemas.mjs +18 -11
- package/dist/_chunks/tool-schemas.mjs.map +1 -1
- package/dist/_chunks/types.mjs +5 -2
- package/dist/_chunks/types.mjs.map +1 -1
- package/dist/cli.mjs +29 -9
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +16 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -3
- package/dist/index.mjs.map +1 -1
- package/dist/mcp.d.mts +2 -0
- package/dist/mcp.d.mts.map +1 -1
- package/dist/mcp.mjs +6261 -5
- package/dist/mcp.mjs.map +1 -1
- package/dist/tool-operations.d.mts +21 -4
- package/dist/tool-operations.d.mts.map +1 -1
- package/dist/tool-operations.mjs +3 -3
- package/dist/tool-schemas.d.mts +2 -2
- package/dist/tool-schemas.mjs +1 -1
- package/dist/typebox.LICENSE +23 -0
- package/package.json +18 -18
- package/packages/omp/extensions/harnesses.ts +19 -1
- package/packages/pi/extensions/harnesses.ts +27 -46
- package/packages/shared/tui.ts +13 -0
- package/dist/THIRD-PARTY-LICENSES.md +0 -36
- package/dist/_chunks/libs/typebox.mjs +0 -5439
- package/dist/_chunks/libs/typebox.mjs.map +0 -1
- package/dist/_chunks/prompt-sync.d.mts.map +0 -1
- package/dist/_chunks/prompt-sync.mjs.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { p as skillsSync } from "./tool-operations.mjs";
|
|
2
|
+
import { n as formatArgs, r as report } from "./output.mjs";
|
|
3
|
+
import { defineCommand } from "citty";
|
|
4
|
+
//#region src/commands/skills.ts
|
|
5
|
+
var skills_default = defineCommand({
|
|
6
|
+
meta: { description: "Manage shared skills across harnesses" },
|
|
7
|
+
subCommands: { sync: defineCommand({
|
|
8
|
+
meta: { description: "Link harness skills directories to the skills folder in the agntn XDG data directory" },
|
|
9
|
+
args: {
|
|
10
|
+
id: {
|
|
11
|
+
type: "positional",
|
|
12
|
+
description: "Harness id",
|
|
13
|
+
required: false
|
|
14
|
+
},
|
|
15
|
+
check: {
|
|
16
|
+
type: "boolean",
|
|
17
|
+
description: "Report what would change without writing anything"
|
|
18
|
+
},
|
|
19
|
+
...formatArgs
|
|
20
|
+
},
|
|
21
|
+
run({ args }) {
|
|
22
|
+
const id = args.id === void 0 ? void 0 : args.id;
|
|
23
|
+
report(skillsSync(id, args.check === true), args);
|
|
24
|
+
}
|
|
25
|
+
}) }
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
export { skills_default as default };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=skills.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.mjs","names":[],"sources":["../../src/commands/skills.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { skillsSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nexport default defineCommand({\n meta: { description: \"Manage shared skills across harnesses\" },\n subCommands: {\n sync: defineCommand({\n meta: {\n description:\n \"Link harness skills directories to the skills folder in the agntn XDG data directory\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n check: {\n type: \"boolean\" as const,\n description: \"Report what would change without writing anything\",\n },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : (args.id as string);\n report(skillsSync(id, args.check === true), args);\n },\n }),\n },\n});\n"],"mappings":";;;;AAIA,IAAA,iBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,wCAAwC;CAC7D,aAAa,EACX,MAAM,cAAc;EAClB,MAAM,EACJ,aACE,uFACJ;EACA,MAAM;GACJ,IAAI;IAAE,MAAM;IAAuB,aAAa;IAAc,UAAU;GAAM;GAC9E,OAAO;IACL,MAAM;IACN,aAAa;GACf;GACA,GAAG;EACL;EACA,IAAI,EAAE,QAAQ;GACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAa,KAAK;GACrD,OAAO,WAAW,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;EAClD;CACF,CAAC,EACH;AACF,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as getHarness, d as removeMcpServer, f as syncMcpServers, g as getAllHarnesses, i as syncAgentsFiles, n as syncPromptTemplates, o as addMcpServer, r as readAgentsConfig, s as listMcpServers, t as syncSkills, u as readMasterMcpServers, v as isHarnessId, y as listHarnesses } from "./skills-sync.mjs";
|
|
2
2
|
import "./tool-schemas.mjs";
|
|
3
3
|
import { stripVTControlCharacters } from "node:util";
|
|
4
4
|
import { encode } from "@toon-format/toon";
|
|
5
|
+
//#region src/tool-operations.ts
|
|
5
6
|
const RUN_DEFAULT_TIMEOUT_SECONDS = 600;
|
|
6
7
|
const RUN_MAX_OUTPUT_CHARS = 8e3;
|
|
7
8
|
function text(data) {
|
|
@@ -28,9 +29,6 @@ function truncate(output) {
|
|
|
28
29
|
if (output.length <= 8e3) return output;
|
|
29
30
|
return `${output.slice(0, RUN_MAX_OUTPUT_CHARS)}\n[truncated ${output.length - RUN_MAX_OUTPUT_CHARS} of ${output.length} characters]`;
|
|
30
31
|
}
|
|
31
|
-
function modelListingUnavailable(harness, id) {
|
|
32
|
-
return { error: harness.modelListing ? `Harness ${id} does not support filtering its model listing` : `Harness ${id} does not support model listing` };
|
|
33
|
-
}
|
|
34
32
|
const ALTERNATE_INVOCATION_MODE = {
|
|
35
33
|
advisor: "agent",
|
|
36
34
|
advisorStructured: "agentStructured",
|
|
@@ -81,7 +79,8 @@ function completedRun(harness, result, options, templateArgs) {
|
|
|
81
79
|
readOnly: options.readOnly,
|
|
82
80
|
exitCode: result.exitCode,
|
|
83
81
|
timedOut: result.timedOut,
|
|
84
|
-
aborted: result.aborted
|
|
82
|
+
aborted: result.aborted,
|
|
83
|
+
...result.idleMs === void 0 ? {} : { idleMs: result.idleMs }
|
|
85
84
|
};
|
|
86
85
|
const stdout = truncate(result.stdout);
|
|
87
86
|
const stderr = truncate(result.stderr);
|
|
@@ -159,10 +158,13 @@ function harnessInfoResult(id) {
|
|
|
159
158
|
sessions: harness.sessions,
|
|
160
159
|
instructions: harness.instructions,
|
|
161
160
|
skills: harness.skills,
|
|
161
|
+
skillsSyncTarget: harness.skillsSyncTarget,
|
|
162
162
|
commands: harness.commands,
|
|
163
163
|
promptTemplates: harness.promptTemplates,
|
|
164
164
|
promptTemplateSyncTarget: harness.promptTemplateSyncTarget,
|
|
165
165
|
hooks: harness.hooks,
|
|
166
|
+
temp: harness.temp,
|
|
167
|
+
envOverrides: harness.envOverrides,
|
|
166
168
|
persistence: harness.persistence,
|
|
167
169
|
detection: harness.detection,
|
|
168
170
|
resolved: harness.resolve()
|
|
@@ -170,7 +172,7 @@ function harnessInfoResult(id) {
|
|
|
170
172
|
}
|
|
171
173
|
function harnessInfoText(result) {
|
|
172
174
|
if ("error" in result) return result;
|
|
173
|
-
const { id, name, binaries, capabilities, invocationModes, modelListing, modelSelection, persistence, detection, resolved } = result;
|
|
175
|
+
const { id, name, binaries, capabilities, invocationModes, modelListing, modelSelection, envOverrides, persistence, detection, resolved } = result;
|
|
174
176
|
return {
|
|
175
177
|
id,
|
|
176
178
|
name,
|
|
@@ -179,6 +181,7 @@ function harnessInfoText(result) {
|
|
|
179
181
|
invocationModes,
|
|
180
182
|
modelListing,
|
|
181
183
|
modelSelection,
|
|
184
|
+
envOverrides: getHarness(id).resolveCandidates(envOverrides),
|
|
182
185
|
persistence,
|
|
183
186
|
detection,
|
|
184
187
|
resolved
|
|
@@ -212,7 +215,7 @@ async function listHarnessModels(id, options = {}) {
|
|
|
212
215
|
if (!isHarnessId(id)) return unknownHarness(id);
|
|
213
216
|
const harness = getHarness(id);
|
|
214
217
|
if (!harness.buildModelListInvocation(options.search)) {
|
|
215
|
-
const details =
|
|
218
|
+
const details = { error: `Harness ${id} does not support model listing` };
|
|
216
219
|
return {
|
|
217
220
|
content: text(details),
|
|
218
221
|
details,
|
|
@@ -236,15 +239,19 @@ async function listHarnessModels(id, options = {}) {
|
|
|
236
239
|
isError: true
|
|
237
240
|
};
|
|
238
241
|
}
|
|
242
|
+
return completedListing(harness.id, result, result.models, options.search);
|
|
243
|
+
}
|
|
244
|
+
function completedListing(id, result, models, search) {
|
|
239
245
|
const details = {
|
|
240
|
-
id
|
|
246
|
+
id,
|
|
241
247
|
command: result.command,
|
|
242
|
-
args: result.args,
|
|
243
|
-
...
|
|
244
|
-
models:
|
|
248
|
+
args: [...result.args],
|
|
249
|
+
...search === void 0 ? {} : { search },
|
|
250
|
+
models: [...models],
|
|
245
251
|
exitCode: result.exitCode,
|
|
246
252
|
timedOut: result.timedOut,
|
|
247
253
|
aborted: result.aborted,
|
|
254
|
+
...result.idleMs === void 0 ? {} : { idleMs: result.idleMs },
|
|
248
255
|
stderr: truncate(result.stderr)
|
|
249
256
|
};
|
|
250
257
|
return {
|
|
@@ -257,7 +264,7 @@ function normalizedRunAccess(options) {
|
|
|
257
264
|
const readOnly = options.readOnly ?? false;
|
|
258
265
|
return {
|
|
259
266
|
readOnly,
|
|
260
|
-
tools:
|
|
267
|
+
tools: options.tools ?? readOnly
|
|
261
268
|
};
|
|
262
269
|
}
|
|
263
270
|
async function runHarness(id, prompt, options = {}) {
|
|
@@ -447,6 +454,24 @@ function promptsSync(id, check = false) {
|
|
|
447
454
|
};
|
|
448
455
|
}
|
|
449
456
|
}
|
|
450
|
-
|
|
457
|
+
function skillsSync(id, check = false) {
|
|
458
|
+
if (id !== void 0 && !isHarnessId(id)) return unknownHarness(id);
|
|
459
|
+
try {
|
|
460
|
+
const details = syncSkills(id !== void 0 && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(), check);
|
|
461
|
+
return {
|
|
462
|
+
content: text(details),
|
|
463
|
+
details
|
|
464
|
+
};
|
|
465
|
+
} catch (error) {
|
|
466
|
+
const details = { error: errorMessage(error) };
|
|
467
|
+
return {
|
|
468
|
+
content: text(details),
|
|
469
|
+
details,
|
|
470
|
+
isError: true
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
//#endregion
|
|
475
|
+
export { harnessInfo as a, mcpList as c, promptsSync as d, runHarness as f, detectHarnesses as i, mcpRemove as l, toMcpServerConfig as m, RUN_MAX_OUTPUT_CHARS as n, listHarnessModels as o, skillsSync as p, agentsSync as r, mcpAdd as s, RUN_DEFAULT_TIMEOUT_SECONDS as t, mcpSync as u };
|
|
451
476
|
|
|
452
477
|
//# sourceMappingURL=tool-operations.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-operations.mjs","names":["toToon"],"sources":["../../src/tool-operations.ts"],"sourcesContent":["/**\n * Tool executors behind the agent extensions.\n *\n * Each executor returns the text a caller reads plus the structured details a\n * harness can attach to the call. The text is TOON-encoded so the model sees\n * the same compact shape the CLI's --toon flag prints. A run's output is the\n * exception: it follows the status block as plain text, not as one TOON string.\n */\nimport { stripVTControlCharacters } from \"node:util\";\nimport { encode as toToon } from \"@toon-format/toon\";\nimport { getAllHarnesses, getHarness, isHarnessId, listHarnesses } from \"./registry.ts\";\nimport {\n addMcpServer,\n listMcpServers,\n readMasterMcpServers,\n removeMcpServer,\n syncMcpServers,\n} from \"./mcp-servers.ts\";\nimport type { McpConfigListing, SyncReport } from \"./mcp-servers.ts\";\nimport { readAgentsConfig, syncAgentsFiles } from \"./agents-sync.ts\";\nimport type { AgentsSyncReport } from \"./agents-sync.ts\";\nexport type { AgentsSyncReport } from \"./agents-sync.ts\";\nexport type { SyncReport } from \"./mcp-servers.ts\";\nexport type { PromptSyncReport } from \"./prompt-sync.ts\";\nexport type { HarnessInvocationModes } from \"./types.ts\";\nimport { syncPromptTemplates } from \"./prompt-sync.ts\";\nimport type { PromptSyncReport } from \"./prompt-sync.ts\";\nimport type { Harness } from \"./harness.ts\";\nimport type {\n AvailableModel,\n HarnessCapabilities,\n HarnessDetection,\n HarnessId,\n HarnessInvocationModes,\n InvokeResult,\n ListModelsResult,\n McpServerConfig,\n PathCandidate,\n PromptTemplateSyncTarget,\n ResolvedPaths,\n StorageDescriptor,\n} from \"./types.ts\";\n\n/** Text for the model plus details for the harness, shared by every tool surface. */\nexport interface ToolResult<Details> {\n content: Array<{ type: \"text\"; text: string }>;\n details: Details;\n /** Set when the tool could not answer. */\n isError?: boolean;\n}\n\n/** Install state of one harness on this machine. */\nexport interface HarnessStatus {\n id: HarnessId;\n name: string;\n installed: boolean;\n version: string | null;\n}\n\n/** Every registered harness with its install state, as scanned by {@link detectHarnesses}. */\nexport interface HarnessListing {\n harnesses: HarnessStatus[];\n}\n\n/** Full metadata for one harness, including paths resolved for this platform. */\nexport interface HarnessMetadata {\n id: HarnessId;\n name: string;\n binaries: string[];\n capabilities: HarnessCapabilities;\n invocationModes: HarnessInvocationModes;\n modelListing: boolean;\n modelSelection: boolean;\n config: PathCandidate[];\n sessions: PathCandidate[];\n instructions: PathCandidate[];\n skills: PathCandidate[];\n commands: PathCandidate[];\n promptTemplates: PathCandidate[];\n promptTemplateSyncTarget: PromptTemplateSyncTarget | null;\n hooks: PathCandidate[];\n persistence: StorageDescriptor[];\n detection: HarnessDetection;\n resolved: ResolvedPaths;\n}\n\n/** Returned when the requested harness id is not registered. */\nexport interface UnknownHarness {\n error: string;\n known: HarnessId[];\n}\n\n/** Returned when a direct batch call bypasses the tool schema limits. */\nexport interface HarnessInfoInputError {\n error: string;\n}\n\n/** One harness lookup result. */\nexport type HarnessInfoResult = HarnessMetadata | UnknownHarness;\n\n/** Scalar, batch, or rejected batch details from {@link harnessInfo}. */\nexport type HarnessInfoDetails = HarnessInfoResult | HarnessInfoResult[] | HarnessInfoInputError;\n\nimport { HARNESS_INFO_MAX_ITEMS, RUN_TIMEOUT_DEFAULT_SECONDS } from \"./tool-schemas.ts\";\nexport { HARNESS_INFO_MAX_ITEMS } from \"./tool-schemas.ts\";\n\n/** Default wall-clock budget for one harness run, in seconds. */\nexport const RUN_DEFAULT_TIMEOUT_SECONDS = RUN_TIMEOUT_DEFAULT_SECONDS;\n\n/** The run tool's per-stream cap: harness output is unbounded, model context is not. */\nexport const RUN_MAX_OUTPUT_CHARS = 8000;\n\nfunction text(data: unknown): Array<{ type: \"text\"; text: string }> {\n return [{ type: \"text\", text: toToon(data) }];\n}\n\nfunction unknownHarness(id: string): ToolResult<UnknownHarness> {\n const details: UnknownHarness = { error: `Unknown harness: ${id}`, known: listHarnesses() };\n return { content: text(details), details, isError: true };\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction truncate(output: string): string {\n if (output.length <= RUN_MAX_OUTPUT_CHARS) return output;\n return `${output.slice(0, RUN_MAX_OUTPUT_CHARS)}\\n[truncated ${output.length - RUN_MAX_OUTPUT_CHARS} of ${output.length} characters]`;\n}\n\nfunction modelListingUnavailable(harness: Harness, id: string): RunFailure {\n return {\n error: harness.modelListing\n ? `Harness ${id} does not support filtering its model listing`\n : `Harness ${id} does not support model listing`,\n };\n}\n\ntype RunInvocationOptions = Readonly<{\n model?: string;\n structured: boolean;\n tools: boolean;\n readOnly: boolean;\n}>;\n\ntype InvocationMode = keyof HarnessInvocationModes;\n\nconst ALTERNATE_INVOCATION_MODE: Partial<Record<InvocationMode, InvocationMode>> = {\n advisor: \"agent\",\n advisorStructured: \"agentStructured\",\n agent: \"advisor\",\n agentStructured: \"advisorStructured\",\n};\n\nfunction selectedInvocationMode(\n structured: boolean,\n tools: boolean,\n readOnly: boolean,\n): InvocationMode {\n if (readOnly) return structured ? \"readOnlyStructured\" : \"readOnly\";\n if (tools) return structured ? \"agentStructured\" : \"agent\";\n return structured ? \"advisorStructured\" : \"advisor\";\n}\n\nfunction invocationRetry(\n invocationModes: Readonly<HarnessInvocationModes>,\n mode: InvocationMode,\n options: RunInvocationOptions,\n): RunFailure[\"retry\"] {\n const withoutStructured = selectedInvocationMode(false, options.tools, options.readOnly);\n if (options.structured) {\n if (invocationModes[withoutStructured]) return { structured: false };\n const alternateWithoutStructured = ALTERNATE_INVOCATION_MODE[withoutStructured];\n if (alternateWithoutStructured && invocationModes[alternateWithoutStructured]) {\n return { structured: false, tools: !options.tools };\n }\n }\n\n const alternateMode = ALTERNATE_INVOCATION_MODE[mode];\n return alternateMode !== undefined && invocationModes[alternateMode]\n ? { tools: !options.tools }\n : undefined;\n}\n\n/** The run as its status block shows it: everything but the two streams. */\ntype RunStatus = Readonly<Omit<RunOutcome, \"args\" | \"stdout\" | \"stderr\">> & {\n readonly args: readonly string[];\n};\n\ntype RunStreams = Readonly<Partial<Pick<RunOutcome, \"stdout\" | \"stderr\">>>;\n\n// oxlint-disable-next-line no-control-regex -- Terminal control bytes are precisely what this boundary removes.\nconst OUTPUT_CONTROLS = /[\\u0000-\\u0008\\u000B-\\u001F\\u007F-\\u009F]/g;\n\n/**\n * Strips what TOON quoting used to escape: terminal sequences and control bytes; CRLF becomes LF.\n *\n * @param output - One capped stream.\n * @returns {string} The stream as plain text.\n */\nfunction plainOutput(output: string): string {\n return stripVTControlCharacters(output).replaceAll(\"\\r\\n\", \"\\n\").replace(OUTPUT_CONTROLS, \" \");\n}\n\n/**\n * Lays the run out for the model: the TOON status block, then each stream under\n * its name as plain text, since quoting a markdown answer into one TOON string\n * escaped every code block and cost about a tenth more tokens.\n *\n * @param outcome - The run without its output.\n * @param streams - The capped streams; empty ones are left out.\n * @returns {Array<{ type: \"text\"; text: string }>} The text handed to the model.\n */\nfunction runText(outcome: RunStatus, streams: RunStreams): Array<{ type: \"text\"; text: string }> {\n const blocks = [toToon(outcome)];\n for (const name of [\"stdout\", \"stderr\"] as const) {\n const output = streams[name];\n if (output !== undefined && output.length > 0) blocks.push(`${name}:\\n${plainOutput(output)}`);\n }\n return [{ type: \"text\", text: blocks.join(\"\\n\\n\") }];\n}\n\nfunction completedRun(\n harness: Harness,\n result: InvokeResult,\n options: RunInvocationOptions,\n templateArgs: readonly string[],\n): ToolResult<RunOutcome> {\n const contentOutcome: Omit<RunOutcome, \"stdout\" | \"stderr\"> = {\n id: harness.id,\n command: result.command,\n args: [...templateArgs],\n ...(options.model === undefined ? {} : { model: options.model }),\n structured: options.structured,\n tools: options.tools,\n readOnly: options.readOnly,\n exitCode: result.exitCode,\n timedOut: result.timedOut,\n aborted: result.aborted,\n };\n const stdout = truncate(result.stdout);\n const stderr = truncate(result.stderr);\n const details: RunOutcome = { ...contentOutcome, args: result.args, stdout, stderr };\n if (result.timedOut || result.exitCode !== 0) {\n return { content: runText(contentOutcome, { stdout, stderr }), details, isError: true };\n }\n return {\n content: runText(contentOutcome, stdout.length > 0 ? { stdout } : { stderr }),\n details,\n };\n}\n\nfunction unsupportedInvocation(\n harness: Harness,\n id: string,\n options: RunInvocationOptions,\n): ToolResult<RunFailure> {\n const error = harness.invocationError(options) ?? `Invalid ${id} invocation`;\n const invocationModes = harness.invocationModes;\n const mode = selectedInvocationMode(options.structured, options.tools, options.readOnly);\n const modelUnsupported =\n options.model !== undefined && harness.invocation?.modelArgs === undefined;\n if (invocationModes[mode] || harness.invocation === null || modelUnsupported) {\n const details: RunFailure = { error };\n return { content: text(details), details, isError: true };\n }\n\n const retry = invocationRetry(invocationModes, mode, options);\n const details: RunFailure = {\n error,\n invocationModes,\n ...(retry === undefined ? {} : { retry }),\n };\n return { content: text(details), details, isError: true };\n}\n\n/**\n * Scans every registered harness for its binaries and version.\n *\n * @returns {ToolResult<HarnessListing>} The complete installation listing.\n */\nexport function detectHarnesses(): ToolResult<HarnessListing> {\n const details: HarnessListing = {\n harnesses: getAllHarnesses().map((harness) => {\n const installed = harness.isInstalled();\n return {\n id: harness.id,\n name: harness.name,\n installed,\n version: installed ? harness.version : null,\n };\n }),\n };\n\n return { content: text(details), details };\n}\n\nfunction harnessInfoResult(id: string): HarnessInfoResult {\n if (!isHarnessId(id)) return unknownHarness(id).details;\n\n const harness = getHarness(id);\n return {\n id: harness.id,\n name: harness.name,\n binaries: harness.binaries,\n capabilities: harness.capabilities,\n invocationModes: harness.invocationModes,\n modelListing: harness.modelListing !== null,\n modelSelection: harness.invocation?.modelArgs !== undefined,\n config: harness.config,\n sessions: harness.sessions,\n instructions: harness.instructions,\n skills: harness.skills,\n commands: harness.commands,\n promptTemplates: harness.promptTemplates,\n promptTemplateSyncTarget: harness.promptTemplateSyncTarget,\n hooks: harness.hooks,\n persistence: harness.persistence,\n detection: harness.detection,\n resolved: harness.resolve(),\n };\n}\n\n/** One lookup as the model reads it: every path list once, in {@link HarnessMetadata.resolved}. */\ntype HarnessInfoText =\n | Omit<\n HarnessMetadata,\n | \"config\"\n | \"sessions\"\n | \"instructions\"\n | \"skills\"\n | \"commands\"\n | \"promptTemplates\"\n | \"promptTemplateSyncTarget\"\n | \"hooks\"\n >\n | UnknownHarness;\n\n/**\n * Leaves the path templates out of the text: `resolved` already carries each\n * of them for this machine, so they only doubled every answer.\n *\n * @param result - One lookup result.\n * @returns {HarnessInfoText} The lookup with its path lists shown once.\n */\nfunction harnessInfoText(result: HarnessInfoResult): HarnessInfoText {\n if (\"error\" in result) return result;\n const {\n id,\n name,\n binaries,\n capabilities,\n invocationModes,\n modelListing,\n modelSelection,\n persistence,\n detection,\n resolved,\n } = result;\n return {\n id,\n name,\n binaries,\n capabilities,\n invocationModes,\n modelListing,\n modelSelection,\n persistence,\n detection,\n resolved,\n };\n}\n\n/** Full metadata for one harness, with paths resolved for the current platform. */\nexport function harnessInfo(id: string): ToolResult<HarnessInfoResult>;\n/** Full metadata for several harnesses, preserving input order and errors for each item. */\nexport function harnessInfo(\n ids: readonly string[],\n): ToolResult<HarnessInfoResult[] | HarnessInfoInputError>;\nexport function harnessInfo(input: string | readonly string[]): ToolResult<HarnessInfoDetails>;\nexport function harnessInfo(input: string | readonly string[]): ToolResult<HarnessInfoDetails> {\n if (typeof input === \"string\") {\n const details = harnessInfoResult(input);\n return {\n content: text(harnessInfoText(details)),\n details,\n ...(\"error\" in details ? { isError: true } : {}),\n };\n }\n\n if (input.length < 1 || input.length > HARNESS_INFO_MAX_ITEMS) {\n const details: HarnessInfoInputError = {\n error: `harnesses_info accepts between 1 and ${HARNESS_INFO_MAX_ITEMS} ids`,\n };\n return { content: text(details), details, isError: true };\n }\n\n const details = input.map(harnessInfoResult);\n return {\n content: text(details.map(harnessInfoText)),\n details,\n ...(details.some((result) => \"error\" in result) ? { isError: true } : {}),\n };\n}\n\n/** Options accepted by {@link listHarnessModels}. */\nexport interface ModelsOptions {\n search?: string;\n cwd?: string;\n /** Wall-clock budget in seconds; defaults to {@link RUN_DEFAULT_TIMEOUT_SECONDS}. */\n timeoutSeconds?: number;\n /** Cancel the owned command through the host request signal. */\n signal?: AbortSignal;\n}\n\n/** One completed native model-listing query. */\nexport interface ModelsOutcome {\n id: HarnessId;\n command: string;\n args: string[];\n search?: string;\n models: AvailableModel[];\n exitCode: number | null;\n timedOut: boolean;\n aborted: boolean;\n stderr: string;\n}\n\n/**\n * Lists the models currently available to one harness through its native CLI.\n *\n * @param id - Harness id to query.\n * @param options - Search, working-directory, and timeout options.\n * @returns {Promise<ToolResult<ModelsOutcome | RunFailure>>} The model listing or failure.\n */\nexport async function listHarnessModels(\n id: string,\n options: ModelsOptions = {},\n): Promise<ToolResult<ModelsOutcome | RunFailure>> {\n if (!isHarnessId(id)) return unknownHarness(id);\n\n const harness = getHarness(id);\n const built = harness.buildModelListInvocation(options.search);\n if (!built) {\n const details = modelListingUnavailable(harness, id);\n return { content: text(details), details, isError: true };\n }\n\n const timeoutSeconds = options.timeoutSeconds ?? RUN_DEFAULT_TIMEOUT_SECONDS;\n let result: ListModelsResult;\n try {\n result = await harness.listModels({\n search: options.search,\n cwd: options.cwd,\n timeoutMs: timeoutSeconds * 1000,\n signal: options.signal,\n });\n } catch (error) {\n const details: RunFailure = { error: `Failed to list ${id} models: ${errorMessage(error)}` };\n return { content: text(details), details, isError: true };\n }\n\n const details: ModelsOutcome = {\n id: harness.id,\n command: result.command,\n args: result.args,\n ...(options.search === undefined ? {} : { search: options.search }),\n models: result.models,\n exitCode: result.exitCode,\n timedOut: result.timedOut,\n aborted: result.aborted,\n stderr: truncate(result.stderr),\n };\n\n return {\n content: text(details),\n details,\n ...(result.timedOut || result.exitCode !== 0 ? { isError: true } : {}),\n };\n}\n\n/** Options accepted by {@link runHarness}. */\nexport interface RunOptions {\n cwd?: string;\n /** Harness-native model id or selector. */\n model?: string;\n /** Wall-clock budget in seconds; defaults to {@link RUN_DEFAULT_TIMEOUT_SECONDS}. */\n timeoutSeconds?: number;\n /** Cancel the owned command through the host request signal. */\n signal?: AbortSignal;\n /** Use the harness's structured (JSON) output mode instead of plain text. */\n structured?: boolean;\n /** Enable tools; defaults to a native advisor without tools invocation. */\n tools?: boolean;\n /** Require native enforcement of read-only tool access. Implies tools. */\n readOnly?: boolean;\n}\n\n/** One completed (or failed) harness run, with output capped for the model. */\nexport interface RunOutcome {\n id: HarnessId;\n command: string;\n /** Expanded arguments; the model's text keeps \"{prompt}\" instead, it wrote the prompt itself. */\n args: string[];\n model?: string;\n structured: boolean;\n tools: boolean;\n readOnly: boolean;\n exitCode: number | null;\n timedOut: boolean;\n aborted: boolean;\n stdout: string;\n stderr: string;\n}\n\n/** Returned when the harness cannot be run at all. */\nexport interface RunFailure {\n error: string;\n known?: HarnessId[];\n /** Modes accepted by the selected harness when invocation mode caused the failure. */\n invocationModes?: HarnessInvocationModes;\n /** Explicit mode change that makes the same invocation shape executable. */\n retry?: { structured: false; tools?: boolean } | { tools: boolean };\n}\n\nfunction normalizedRunAccess(options: Readonly<RunOptions>): {\n tools: boolean;\n readOnly: boolean;\n} {\n const readOnly = options.readOnly ?? false;\n return { readOnly, tools: readOnly ? true : (options.tools ?? false) };\n}\n\n/**\n * Runs one prompt through a harness's normalized non-interactive invocation.\n *\n * Tool use defaults to a native advisor without tools invocation. Harnesses that\n * cannot disable tools reject that mode; setting `tools` selects their full\n * agent invocation. `model` is translated through the harness-specific recipe.\n * This layer also closes stdin, enforces the timeout, caps the echoed output,\n * and leaves the prompt out of the echoed invocation.\n *\n * @param id - Harness id to run.\n * @param prompt - Prompt sent to the selected harness.\n * @param options - Model, mode, working-directory, and timeout options.\n * @returns {Promise<ToolResult<RunOutcome | RunFailure>>} The capped run outcome or failure.\n */\nexport async function runHarness(\n id: string,\n prompt: string,\n options: RunOptions = {},\n): Promise<ToolResult<RunOutcome | RunFailure>> {\n if (!isHarnessId(id)) return unknownHarness(id);\n\n const harness = getHarness(id);\n const structured = options.structured ?? false;\n const { tools, readOnly } = normalizedRunAccess(options);\n const invocationOptions = { model: options.model, structured, tools, readOnly };\n const template = harness.buildInvocation(\"{prompt}\", invocationOptions);\n if (!template) {\n return unsupportedInvocation(harness, id, invocationOptions);\n }\n\n const timeoutSeconds = options.timeoutSeconds ?? RUN_DEFAULT_TIMEOUT_SECONDS;\n\n let result: InvokeResult;\n try {\n result = await harness.invoke(prompt, {\n cwd: options.cwd,\n model: options.model,\n timeoutMs: timeoutSeconds * 1000,\n signal: options.signal,\n structured,\n tools,\n readOnly,\n });\n } catch (error) {\n const details: RunFailure = { error: `Failed to run ${id}: ${errorMessage(error)}` };\n return { content: text(details), details, isError: true };\n }\n\n return completedRun(harness, result, invocationOptions, template.args);\n}\n\n/** MCP server listings for one harness or all of them. */\nexport interface McpListing {\n harnesses: Array<{ id: HarnessId; configs: McpConfigListing[] }>;\n}\n\n/** Marker used only at the tool and CLI boundary, leaving config reads lossless for edits. */\nconst MCP_REDACTED_VALUE = \"<redacted>\";\nconst MCP_CONFIG_ERROR = \"Unable to read or parse MCP config\";\n\nfunction redactMcpValues(values: Readonly<Record<string, string>>): Record<string, string> {\n return Object.fromEntries(Object.keys(values).map((key) => [key, MCP_REDACTED_VALUE]));\n}\n\n/** Result of one MCP config mutation. */\nexport interface McpMutation {\n id: HarnessId;\n path: string;\n action: \"added\" | \"replaced\" | \"removed\" | \"noop\";\n}\n\n/** Flat tool parameters describing one MCP server, shared by every surface. */\nexport interface McpServerParams {\n name: string;\n transport?: McpServerConfig[\"transport\"];\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Builds the normalized server shape from flat tool parameters.\n *\n * @param params - Flat MCP server parameters.\n * @returns {McpServerConfig} The normalized server configuration.\n */\nexport function toMcpServerConfig(params: McpServerParams): McpServerConfig {\n const server: McpServerConfig = {\n name: params.name,\n transport: params.transport ?? (params.url ? \"http\" : \"stdio\"),\n };\n if (params.command !== undefined) server.command = params.command;\n if (params.args !== undefined) server.args = params.args;\n if (params.env !== undefined) server.env = params.env;\n if (params.url !== undefined) server.url = params.url;\n if (params.headers !== undefined) server.headers = params.headers;\n return server;\n}\n\n/**\n * Lists configured MCP servers, normalized across harness config dialects.\n *\n * @param id - Optional harness id; omission lists every harness.\n * @returns {ToolResult<McpListing | UnknownHarness>} The normalized listing or id error.\n */\nexport function mcpList(id?: string): ToolResult<McpListing | UnknownHarness> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n const targets = id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses();\n const details: McpListing = {\n harnesses: targets\n .map((harness) => ({\n id: harness.id,\n configs: listMcpServers(harness).map((listing) => ({\n ...listing,\n ...(listing.error === undefined ? {} : { error: MCP_CONFIG_ERROR }),\n servers: listing.servers.map((server) => ({\n ...server,\n ...(server.env === undefined ? {} : { env: redactMcpValues(server.env) }),\n ...(server.headers === undefined ? {} : { headers: redactMcpValues(server.headers) }),\n })),\n })),\n }))\n .filter((entry) => entry.configs.length > 0),\n };\n\n return { content: text(details), details };\n}\n\nfunction mcpMutate(\n id: string,\n mutate: (harness: Harness) => { path: string; action: McpMutation[\"action\"] },\n): ToolResult<McpMutation | RunFailure> {\n if (!isHarnessId(id)) return unknownHarness(id);\n\n try {\n const { path, action } = mutate(getHarness(id));\n const details: McpMutation = { id, path, action };\n return { content: text(details), details, ...(action === \"noop\" ? { isError: true } : {}) };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Adds or replaces one MCP server in a harness's config.\n *\n * @param id - Target harness id.\n * @param params - Server parameters to normalize and write.\n * @param scope - User or project config scope.\n * @returns {ToolResult<McpMutation | RunFailure>} The mutation outcome or failure.\n */\nexport function mcpAdd(\n id: string,\n params: McpServerParams,\n scope: \"user\" | \"project\" = \"user\",\n): ToolResult<McpMutation | RunFailure> {\n return mcpMutate(id, (harness) => {\n const { path, replaced } = addMcpServer(harness, toMcpServerConfig(params), scope);\n return { path, action: replaced ? \"replaced\" : \"added\" };\n });\n}\n\n/**\n * Removes one MCP server from a harness's config.\n *\n * @param id - Target harness id.\n * @param name - Server name to remove.\n * @param scope - User or project config scope.\n * @returns {ToolResult<McpMutation | RunFailure>} The mutation outcome or failure.\n */\nexport function mcpRemove(\n id: string,\n name: string,\n scope: \"user\" | \"project\" = \"user\",\n): ToolResult<McpMutation | RunFailure> {\n return mcpMutate(id, (harness) => {\n const { path, removed } = removeMcpServer(harness, name, scope);\n return { path, action: removed ? \"removed\" : \"noop\" };\n });\n}\n\n/**\n * Pushes the master MCP list from ~/.config/agntn/mcp.jsonc into harness configs.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @returns {ToolResult<SyncReport | RunFailure>} The sync report or failure.\n */\nexport function mcpSync(id?: string): ToolResult<SyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n // Preflight before any write: a typo in excludes must fail the whole run,\n // not silently leave the misspelled harness unprotected.\n const unknown = readMasterMcpServers().excludes.filter((entry) => !isHarnessId(entry));\n if (unknown.length > 0) {\n const details: RunFailure = {\n error: `Master MCP list excludes unknown harnesses: ${unknown.join(\", \")}`,\n known: listHarnesses(),\n };\n return { content: text(details), details, isError: true };\n }\n const details = syncMcpServers(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Links every harness's global instructions file to the master AGENTS.md.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @param check - Report intended changes without writing them.\n * @returns {ToolResult<AgentsSyncReport | RunFailure>} The sync report or failure.\n */\nexport function agentsSync(id?: string, check = false): ToolResult<AgentsSyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n // Preflight before any write: a typo in excludes must fail the whole run,\n // not silently adopt the harness it was meant to protect.\n const unknown = readAgentsConfig().excludes.filter((entry) => !isHarnessId(entry));\n if (unknown.length > 0) {\n const details: RunFailure = {\n error: `Agents config excludes unknown harnesses: ${unknown.join(\", \")}`,\n known: listHarnesses(),\n };\n return { content: text(details), details, isError: true };\n }\n const details = syncAgentsFiles(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n check,\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Synchronizes canonical Markdown prompt templates into harness destinations.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @param check - Report intended changes without writing them.\n * @returns {ToolResult<PromptSyncReport | RunFailure>} The sync report or failure.\n */\nexport function promptsSync(id?: string, check = false): ToolResult<PromptSyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n const details = syncPromptTemplates(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n check,\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tool-operations.mjs","names":["toToon"],"sources":["../../src/tool-operations.ts"],"sourcesContent":["/**\n * Tool executors behind the agent extensions.\n *\n * Each executor returns the text a caller reads plus the structured details a\n * harness can attach to the call. The text is TOON-encoded so the model sees\n * the same compact shape the CLI's --toon flag prints. A run's output is the\n * exception: it follows the status block as plain text, not as one TOON string.\n */\nimport { stripVTControlCharacters } from \"node:util\";\nimport { encode as toToon } from \"@toon-format/toon\";\nimport { getAllHarnesses, getHarness, isHarnessId, listHarnesses } from \"./registry.ts\";\nimport {\n addMcpServer,\n listMcpServers,\n readMasterMcpServers,\n removeMcpServer,\n syncMcpServers,\n} from \"./mcp-servers.ts\";\nimport type { McpConfigListing, SyncReport } from \"./mcp-servers.ts\";\nimport { readAgentsConfig, syncAgentsFiles } from \"./agents-sync.ts\";\nimport type { AgentsSyncReport } from \"./agents-sync.ts\";\nexport type { AgentsSyncReport } from \"./agents-sync.ts\";\nexport type { SyncReport } from \"./mcp-servers.ts\";\nexport type { PromptSyncReport } from \"./prompt-sync.ts\";\nexport type { HarnessInvocationModes } from \"./types.ts\";\nimport { syncPromptTemplates } from \"./prompt-sync.ts\";\nimport type { PromptSyncReport } from \"./prompt-sync.ts\";\nexport type { SkillsSyncReport } from \"./skills-sync.ts\";\nimport { syncSkills } from \"./skills-sync.ts\";\nimport type { SkillsSyncReport } from \"./skills-sync.ts\";\nimport type { Harness } from \"./harness.ts\";\nimport type {\n AvailableModel,\n EnvOverride,\n HarnessCapabilities,\n HarnessDetection,\n HarnessId,\n HarnessInvocationModes,\n InvokeResult,\n ListModelsResult,\n McpServerConfig,\n PathCandidate,\n PromptTemplateSyncTarget,\n ResolvedPaths,\n SkillsSyncTarget,\n StorageDescriptor,\n} from \"./types.ts\";\n\n/** Text for the model plus details for the harness, shared by every tool surface. */\nexport interface ToolResult<Details> {\n content: Array<{ type: \"text\"; text: string }>;\n details: Details;\n /** Set when the tool could not answer. */\n isError?: boolean;\n}\n\n/** Install state of one harness on this machine. */\nexport interface HarnessStatus {\n id: HarnessId;\n name: string;\n installed: boolean;\n version: string | null;\n}\n\n/** Every registered harness with its install state, as scanned by {@link detectHarnesses}. */\nexport interface HarnessListing {\n harnesses: HarnessStatus[];\n}\n\n/** Full metadata for one harness, including paths resolved for this platform. */\nexport interface HarnessMetadata {\n id: HarnessId;\n name: string;\n binaries: string[];\n capabilities: HarnessCapabilities;\n invocationModes: HarnessInvocationModes;\n modelListing: boolean;\n modelSelection: boolean;\n config: PathCandidate[];\n sessions: PathCandidate[];\n instructions: PathCandidate[];\n skills: PathCandidate[];\n skillsSyncTarget: SkillsSyncTarget | null;\n commands: PathCandidate[];\n promptTemplates: PathCandidate[];\n promptTemplateSyncTarget: PromptTemplateSyncTarget | null;\n hooks: PathCandidate[];\n temp: PathCandidate[];\n envOverrides: EnvOverride[];\n persistence: StorageDescriptor[];\n detection: HarnessDetection;\n resolved: ResolvedPaths;\n}\n\n/** Returned when the requested harness id is not registered. */\nexport interface UnknownHarness {\n error: string;\n known: HarnessId[];\n}\n\n/** Returned when a direct batch call bypasses the tool schema limits. */\nexport interface HarnessInfoInputError {\n error: string;\n}\n\n/** One harness lookup result. */\nexport type HarnessInfoResult = HarnessMetadata | UnknownHarness;\n\n/** Scalar, batch, or rejected batch details from {@link harnessInfo}. */\nexport type HarnessInfoDetails = HarnessInfoResult | HarnessInfoResult[] | HarnessInfoInputError;\n\nimport { HARNESS_INFO_MAX_ITEMS, RUN_TIMEOUT_DEFAULT_SECONDS } from \"./tool-schemas.ts\";\nexport { HARNESS_INFO_MAX_ITEMS } from \"./tool-schemas.ts\";\n\n/** Default wall-clock budget for one harness run, in seconds. */\nexport const RUN_DEFAULT_TIMEOUT_SECONDS = RUN_TIMEOUT_DEFAULT_SECONDS;\n\n/** The run tool's per-stream cap: harness output is unbounded, model context is not. */\nexport const RUN_MAX_OUTPUT_CHARS = 8000;\n\nfunction text(data: unknown): Array<{ type: \"text\"; text: string }> {\n return [{ type: \"text\", text: toToon(data) }];\n}\n\nfunction unknownHarness(id: string): ToolResult<UnknownHarness> {\n const details: UnknownHarness = { error: `Unknown harness: ${id}`, known: listHarnesses() };\n return { content: text(details), details, isError: true };\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction truncate(output: string): string {\n if (output.length <= RUN_MAX_OUTPUT_CHARS) return output;\n return `${output.slice(0, RUN_MAX_OUTPUT_CHARS)}\\n[truncated ${output.length - RUN_MAX_OUTPUT_CHARS} of ${output.length} characters]`;\n}\n\ntype RunInvocationOptions = Readonly<{\n model?: string;\n structured: boolean;\n tools: boolean;\n readOnly: boolean;\n}>;\n\ntype InvocationMode = keyof HarnessInvocationModes;\n\nconst ALTERNATE_INVOCATION_MODE: Partial<Record<InvocationMode, InvocationMode>> = {\n advisor: \"agent\",\n advisorStructured: \"agentStructured\",\n agent: \"advisor\",\n agentStructured: \"advisorStructured\",\n};\n\nfunction selectedInvocationMode(\n structured: boolean,\n tools: boolean,\n readOnly: boolean,\n): InvocationMode {\n if (readOnly) return structured ? \"readOnlyStructured\" : \"readOnly\";\n if (tools) return structured ? \"agentStructured\" : \"agent\";\n return structured ? \"advisorStructured\" : \"advisor\";\n}\n\nfunction invocationRetry(\n invocationModes: Readonly<HarnessInvocationModes>,\n mode: InvocationMode,\n options: RunInvocationOptions,\n): RunFailure[\"retry\"] {\n const withoutStructured = selectedInvocationMode(false, options.tools, options.readOnly);\n if (options.structured) {\n if (invocationModes[withoutStructured]) return { structured: false };\n const alternateWithoutStructured = ALTERNATE_INVOCATION_MODE[withoutStructured];\n if (alternateWithoutStructured && invocationModes[alternateWithoutStructured]) {\n return { structured: false, tools: !options.tools };\n }\n }\n\n const alternateMode = ALTERNATE_INVOCATION_MODE[mode];\n return alternateMode !== undefined && invocationModes[alternateMode]\n ? { tools: !options.tools }\n : undefined;\n}\n\n/** The run as its status block shows it: everything but the two streams. */\ntype RunStatus = Readonly<Omit<RunOutcome, \"args\" | \"stdout\" | \"stderr\">> & {\n readonly args: readonly string[];\n};\n\ntype RunStreams = Readonly<Partial<Pick<RunOutcome, \"stdout\" | \"stderr\">>>;\n\n// oxlint-disable-next-line no-control-regex -- Terminal control bytes are precisely what this boundary removes.\nconst OUTPUT_CONTROLS = /[\\u0000-\\u0008\\u000B-\\u001F\\u007F-\\u009F]/g;\n\n/**\n * Strips what TOON quoting used to escape: terminal sequences and control bytes; CRLF becomes LF.\n *\n * @param output - One capped stream.\n * @returns {string} The stream as plain text.\n */\nfunction plainOutput(output: string): string {\n return stripVTControlCharacters(output).replaceAll(\"\\r\\n\", \"\\n\").replace(OUTPUT_CONTROLS, \" \");\n}\n\n/**\n * Lays the run out for the model: the TOON status block, then each stream under\n * its name as plain text, since quoting a markdown answer into one TOON string\n * escaped every code block and cost about a tenth more tokens.\n *\n * @param outcome - The run without its output.\n * @param streams - The capped streams; empty ones are left out.\n * @returns {Array<{ type: \"text\"; text: string }>} The text handed to the model.\n */\nfunction runText(outcome: RunStatus, streams: RunStreams): Array<{ type: \"text\"; text: string }> {\n const blocks = [toToon(outcome)];\n for (const name of [\"stdout\", \"stderr\"] as const) {\n const output = streams[name];\n if (output !== undefined && output.length > 0) blocks.push(`${name}:\\n${plainOutput(output)}`);\n }\n return [{ type: \"text\", text: blocks.join(\"\\n\\n\") }];\n}\n\nfunction completedRun(\n harness: Harness,\n result: InvokeResult,\n options: RunInvocationOptions,\n templateArgs: readonly string[],\n): ToolResult<RunOutcome> {\n const contentOutcome: Omit<RunOutcome, \"stdout\" | \"stderr\"> = {\n id: harness.id,\n command: result.command,\n args: [...templateArgs],\n ...(options.model === undefined ? {} : { model: options.model }),\n structured: options.structured,\n tools: options.tools,\n readOnly: options.readOnly,\n exitCode: result.exitCode,\n timedOut: result.timedOut,\n aborted: result.aborted,\n ...(result.idleMs === undefined ? {} : { idleMs: result.idleMs }),\n };\n const stdout = truncate(result.stdout);\n const stderr = truncate(result.stderr);\n const details: RunOutcome = { ...contentOutcome, args: result.args, stdout, stderr };\n if (result.timedOut || result.exitCode !== 0) {\n return { content: runText(contentOutcome, { stdout, stderr }), details, isError: true };\n }\n return {\n content: runText(contentOutcome, stdout.length > 0 ? { stdout } : { stderr }),\n details,\n };\n}\n\nfunction unsupportedInvocation(\n harness: Harness,\n id: string,\n options: RunInvocationOptions,\n): ToolResult<RunFailure> {\n const error = harness.invocationError(options) ?? `Invalid ${id} invocation`;\n const invocationModes = harness.invocationModes;\n const mode = selectedInvocationMode(options.structured, options.tools, options.readOnly);\n const modelUnsupported =\n options.model !== undefined && harness.invocation?.modelArgs === undefined;\n if (invocationModes[mode] || harness.invocation === null || modelUnsupported) {\n const details: RunFailure = { error };\n return { content: text(details), details, isError: true };\n }\n\n const retry = invocationRetry(invocationModes, mode, options);\n const details: RunFailure = {\n error,\n invocationModes,\n ...(retry === undefined ? {} : { retry }),\n };\n return { content: text(details), details, isError: true };\n}\n\n/**\n * Scans every registered harness for its binaries and version.\n *\n * @returns {ToolResult<HarnessListing>} The complete installation listing.\n */\nexport function detectHarnesses(): ToolResult<HarnessListing> {\n const details: HarnessListing = {\n harnesses: getAllHarnesses().map((harness) => {\n const installed = harness.isInstalled();\n return {\n id: harness.id,\n name: harness.name,\n installed,\n version: installed ? harness.version : null,\n };\n }),\n };\n\n return { content: text(details), details };\n}\n\nfunction harnessInfoResult(id: string): HarnessInfoResult {\n if (!isHarnessId(id)) return unknownHarness(id).details;\n\n const harness = getHarness(id);\n return {\n id: harness.id,\n name: harness.name,\n binaries: harness.binaries,\n capabilities: harness.capabilities,\n invocationModes: harness.invocationModes,\n modelListing: harness.modelListing !== null,\n modelSelection: harness.invocation?.modelArgs !== undefined,\n config: harness.config,\n sessions: harness.sessions,\n instructions: harness.instructions,\n skills: harness.skills,\n skillsSyncTarget: harness.skillsSyncTarget,\n commands: harness.commands,\n promptTemplates: harness.promptTemplates,\n promptTemplateSyncTarget: harness.promptTemplateSyncTarget,\n hooks: harness.hooks,\n temp: harness.temp,\n envOverrides: harness.envOverrides,\n persistence: harness.persistence,\n detection: harness.detection,\n resolved: harness.resolve(),\n };\n}\n\n/**\n * One lookup as the model reads it: every path list once, in\n * {@link HarnessMetadata.resolved}, and the env overrides with their default\n * roots resolved the same way.\n */\ntype HarnessInfoText =\n | Omit<\n HarnessMetadata,\n | \"config\"\n | \"sessions\"\n | \"instructions\"\n | \"skills\"\n | \"skillsSyncTarget\"\n | \"commands\"\n | \"promptTemplates\"\n | \"promptTemplateSyncTarget\"\n | \"hooks\"\n | \"temp\"\n >\n | UnknownHarness;\n\n/**\n * Leaves the path templates out of the text: `resolved` already carries each\n * of them for this machine, so they only doubled every answer. Env overrides\n * have no resolved copy, so their own roots are resolved in place.\n *\n * @param result - One lookup result.\n * @returns {HarnessInfoText} The lookup with its path lists shown once.\n */\nfunction harnessInfoText(result: HarnessInfoResult): HarnessInfoText {\n if (\"error\" in result) return result;\n const {\n id,\n name,\n binaries,\n capabilities,\n invocationModes,\n modelListing,\n modelSelection,\n envOverrides,\n persistence,\n detection,\n resolved,\n } = result;\n return {\n id,\n name,\n binaries,\n capabilities,\n invocationModes,\n modelListing,\n modelSelection,\n envOverrides: getHarness(id).resolveCandidates(envOverrides),\n persistence,\n detection,\n resolved,\n };\n}\n\n/** Full metadata for one harness, with paths resolved for the current platform. */\nexport function harnessInfo(id: string): ToolResult<HarnessInfoResult>;\n/** Full metadata for several harnesses, preserving input order and errors for each item. */\nexport function harnessInfo(\n ids: readonly string[],\n): ToolResult<HarnessInfoResult[] | HarnessInfoInputError>;\nexport function harnessInfo(input: string | readonly string[]): ToolResult<HarnessInfoDetails>;\nexport function harnessInfo(input: string | readonly string[]): ToolResult<HarnessInfoDetails> {\n if (typeof input === \"string\") {\n const details = harnessInfoResult(input);\n return {\n content: text(harnessInfoText(details)),\n details,\n ...(\"error\" in details ? { isError: true } : {}),\n };\n }\n\n if (input.length < 1 || input.length > HARNESS_INFO_MAX_ITEMS) {\n const details: HarnessInfoInputError = {\n error: `harnesses_info accepts between 1 and ${HARNESS_INFO_MAX_ITEMS} ids`,\n };\n return { content: text(details), details, isError: true };\n }\n\n const details = input.map(harnessInfoResult);\n return {\n content: text(details.map(harnessInfoText)),\n details,\n ...(details.some((result) => \"error\" in result) ? { isError: true } : {}),\n };\n}\n\n/** Options accepted by {@link listHarnessModels}. */\nexport interface ModelsOptions {\n search?: string;\n cwd?: string;\n /** Wall-clock budget in seconds; defaults to {@link RUN_DEFAULT_TIMEOUT_SECONDS}. */\n timeoutSeconds?: number;\n /** Cancel the owned command through the host request signal. */\n signal?: AbortSignal;\n}\n\n/** One completed native model-listing query. */\nexport interface ModelsOutcome {\n id: HarnessId;\n command: string;\n args: string[];\n search?: string;\n models: AvailableModel[];\n exitCode: number | null;\n timedOut: boolean;\n aborted: boolean;\n /** Milliseconds without output before the listing was stopped; absent when it exited on its own. */\n idleMs?: number;\n stderr: string;\n}\n\n/**\n * Lists the models currently available to one harness through its native CLI.\n *\n * @param id - Harness id to query.\n * @param options - Search, working-directory, and timeout options.\n * @returns {Promise<ToolResult<ModelsOutcome | RunFailure>>} The model listing or failure.\n */\nexport async function listHarnessModels(\n id: string,\n options: ModelsOptions = {},\n): Promise<ToolResult<ModelsOutcome | RunFailure>> {\n if (!isHarnessId(id)) return unknownHarness(id);\n\n const harness = getHarness(id);\n const built = harness.buildModelListInvocation(options.search);\n if (!built) {\n const details: RunFailure = { error: `Harness ${id} does not support model listing` };\n return { content: text(details), details, isError: true };\n }\n\n const timeoutSeconds = options.timeoutSeconds ?? RUN_DEFAULT_TIMEOUT_SECONDS;\n let result: ListModelsResult;\n try {\n result = await harness.listModels({\n search: options.search,\n cwd: options.cwd,\n timeoutMs: timeoutSeconds * 1000,\n signal: options.signal,\n });\n } catch (error) {\n const details: RunFailure = { error: `Failed to list ${id} models: ${errorMessage(error)}` };\n return { content: text(details), details, isError: true };\n }\n\n return completedListing(harness.id, result, result.models, options.search);\n}\n\nfunction completedListing(\n id: HarnessId,\n result: InvokeResult,\n models: readonly Readonly<AvailableModel>[],\n search: string | undefined,\n): ToolResult<ModelsOutcome> {\n const details: ModelsOutcome = {\n id,\n command: result.command,\n args: [...result.args],\n ...(search === undefined ? {} : { search }),\n models: [...models],\n exitCode: result.exitCode,\n timedOut: result.timedOut,\n aborted: result.aborted,\n ...(result.idleMs === undefined ? {} : { idleMs: result.idleMs }),\n stderr: truncate(result.stderr),\n };\n\n return {\n content: text(details),\n details,\n ...(result.timedOut || result.exitCode !== 0 ? { isError: true } : {}),\n };\n}\n\n/** Options accepted by {@link runHarness}. */\nexport interface RunOptions {\n cwd?: string;\n /** Harness-native model id or selector. */\n model?: string;\n /** Wall-clock budget in seconds; defaults to {@link RUN_DEFAULT_TIMEOUT_SECONDS}. */\n timeoutSeconds?: number;\n /** Cancel the owned command through the host request signal. */\n signal?: AbortSignal;\n /** Use the harness's structured (JSON) output mode instead of plain text. */\n structured?: boolean;\n /** Enable tools; defaults to a native advisor without tools invocation. */\n tools?: boolean;\n /** Require native enforcement of read-only tool access. Implies tools when `tools` is omitted; `tools: false` rejects the run. */\n readOnly?: boolean;\n}\n\n/** One completed (or failed) harness run, with output capped for the model. */\nexport interface RunOutcome {\n id: HarnessId;\n command: string;\n /** Expanded arguments; the model's text keeps \"{prompt}\" instead, it wrote the prompt itself. */\n args: string[];\n model?: string;\n structured: boolean;\n tools: boolean;\n readOnly: boolean;\n exitCode: number | null;\n timedOut: boolean;\n aborted: boolean;\n /** Milliseconds without output before the run was stopped; absent when it exited on its own. */\n idleMs?: number;\n stdout: string;\n stderr: string;\n}\n\n/** Returned when the harness cannot be run at all. */\nexport interface RunFailure {\n error: string;\n known?: HarnessId[];\n /** Modes accepted by the selected harness when invocation mode caused the failure. */\n invocationModes?: HarnessInvocationModes;\n /** Explicit mode change that makes the same invocation shape executable. */\n retry?: { structured: false; tools?: boolean } | { tools: boolean };\n}\n\nfunction normalizedRunAccess(options: Readonly<RunOptions>): {\n tools: boolean;\n readOnly: boolean;\n} {\n const readOnly = options.readOnly ?? false;\n return { readOnly, tools: options.tools ?? readOnly };\n}\n\n/**\n * Runs one prompt through a harness's normalized non-interactive invocation.\n *\n * Tool use defaults to a native advisor without tools invocation. Harnesses that\n * cannot disable tools reject that mode; setting `tools` selects their full\n * agent invocation. `model` is translated through the harness-specific recipe.\n * This layer also closes stdin, enforces the timeout, caps the echoed output,\n * and leaves the prompt out of the echoed invocation.\n *\n * @param id - Harness id to run.\n * @param prompt - Prompt sent to the selected harness.\n * @param options - Model, mode, working-directory, and timeout options.\n * @returns {Promise<ToolResult<RunOutcome | RunFailure>>} The capped run outcome or failure.\n */\nexport async function runHarness(\n id: string,\n prompt: string,\n options: RunOptions = {},\n): Promise<ToolResult<RunOutcome | RunFailure>> {\n if (!isHarnessId(id)) return unknownHarness(id);\n\n const harness = getHarness(id);\n const structured = options.structured ?? false;\n const { tools, readOnly } = normalizedRunAccess(options);\n const invocationOptions = { model: options.model, structured, tools, readOnly };\n const template = harness.buildInvocation(\"{prompt}\", invocationOptions);\n if (!template) {\n return unsupportedInvocation(harness, id, invocationOptions);\n }\n\n const timeoutSeconds = options.timeoutSeconds ?? RUN_DEFAULT_TIMEOUT_SECONDS;\n\n let result: InvokeResult;\n try {\n result = await harness.invoke(prompt, {\n cwd: options.cwd,\n model: options.model,\n timeoutMs: timeoutSeconds * 1000,\n signal: options.signal,\n structured,\n tools,\n readOnly,\n });\n } catch (error) {\n const details: RunFailure = { error: `Failed to run ${id}: ${errorMessage(error)}` };\n return { content: text(details), details, isError: true };\n }\n\n return completedRun(harness, result, invocationOptions, template.args);\n}\n\n/** MCP server listings for one harness or all of them. */\nexport interface McpListing {\n harnesses: Array<{ id: HarnessId; configs: McpConfigListing[] }>;\n}\n\n/** Marker used only at the tool and CLI boundary, leaving config reads lossless for edits. */\nconst MCP_REDACTED_VALUE = \"<redacted>\";\nconst MCP_CONFIG_ERROR = \"Unable to read or parse MCP config\";\n\nfunction redactMcpValues(values: Readonly<Record<string, string>>): Record<string, string> {\n return Object.fromEntries(Object.keys(values).map((key) => [key, MCP_REDACTED_VALUE]));\n}\n\n/** Result of one MCP config mutation. */\nexport interface McpMutation {\n id: HarnessId;\n path: string;\n action: \"added\" | \"replaced\" | \"removed\" | \"noop\";\n}\n\n/** Flat tool parameters describing one MCP server, shared by every surface. */\nexport interface McpServerParams {\n name: string;\n transport?: McpServerConfig[\"transport\"];\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Builds the normalized server shape from flat tool parameters.\n *\n * @param params - Flat MCP server parameters.\n * @returns {McpServerConfig} The normalized server configuration.\n */\nexport function toMcpServerConfig(params: McpServerParams): McpServerConfig {\n const server: McpServerConfig = {\n name: params.name,\n transport: params.transport ?? (params.url ? \"http\" : \"stdio\"),\n };\n if (params.command !== undefined) server.command = params.command;\n if (params.args !== undefined) server.args = params.args;\n if (params.env !== undefined) server.env = params.env;\n if (params.url !== undefined) server.url = params.url;\n if (params.headers !== undefined) server.headers = params.headers;\n return server;\n}\n\n/**\n * Lists configured MCP servers, normalized across harness config dialects.\n *\n * @param id - Optional harness id; omission lists every harness.\n * @returns {ToolResult<McpListing | UnknownHarness>} The normalized listing or id error.\n */\nexport function mcpList(id?: string): ToolResult<McpListing | UnknownHarness> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n const targets = id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses();\n const details: McpListing = {\n harnesses: targets\n .map((harness) => ({\n id: harness.id,\n configs: listMcpServers(harness).map((listing) => ({\n ...listing,\n ...(listing.error === undefined ? {} : { error: MCP_CONFIG_ERROR }),\n servers: listing.servers.map((server) => ({\n ...server,\n ...(server.env === undefined ? {} : { env: redactMcpValues(server.env) }),\n ...(server.headers === undefined ? {} : { headers: redactMcpValues(server.headers) }),\n })),\n })),\n }))\n .filter((entry) => entry.configs.length > 0),\n };\n\n return { content: text(details), details };\n}\n\nfunction mcpMutate(\n id: string,\n mutate: (harness: Harness) => { path: string; action: McpMutation[\"action\"] },\n): ToolResult<McpMutation | RunFailure> {\n if (!isHarnessId(id)) return unknownHarness(id);\n\n try {\n const { path, action } = mutate(getHarness(id));\n const details: McpMutation = { id, path, action };\n return { content: text(details), details, ...(action === \"noop\" ? { isError: true } : {}) };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Adds or replaces one MCP server in a harness's config.\n *\n * @param id - Target harness id.\n * @param params - Server parameters to normalize and write.\n * @param scope - User or project config scope.\n * @returns {ToolResult<McpMutation | RunFailure>} The mutation outcome or failure.\n */\nexport function mcpAdd(\n id: string,\n params: McpServerParams,\n scope: \"user\" | \"project\" = \"user\",\n): ToolResult<McpMutation | RunFailure> {\n return mcpMutate(id, (harness) => {\n const { path, replaced } = addMcpServer(harness, toMcpServerConfig(params), scope);\n return { path, action: replaced ? \"replaced\" : \"added\" };\n });\n}\n\n/**\n * Removes one MCP server from a harness's config.\n *\n * @param id - Target harness id.\n * @param name - Server name to remove.\n * @param scope - User or project config scope.\n * @returns {ToolResult<McpMutation | RunFailure>} The mutation outcome or failure.\n */\nexport function mcpRemove(\n id: string,\n name: string,\n scope: \"user\" | \"project\" = \"user\",\n): ToolResult<McpMutation | RunFailure> {\n return mcpMutate(id, (harness) => {\n const { path, removed } = removeMcpServer(harness, name, scope);\n return { path, action: removed ? \"removed\" : \"noop\" };\n });\n}\n\n/**\n * Pushes the master MCP list from ~/.config/agntn/mcp.jsonc into harness configs.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @returns {ToolResult<SyncReport | RunFailure>} The sync report or failure.\n */\nexport function mcpSync(id?: string): ToolResult<SyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n // Preflight before any write: a typo in excludes must fail the whole run,\n // not silently leave the misspelled harness unprotected.\n const unknown = readMasterMcpServers().excludes.filter((entry) => !isHarnessId(entry));\n if (unknown.length > 0) {\n const details: RunFailure = {\n error: `Master MCP list excludes unknown harnesses: ${unknown.join(\", \")}`,\n known: listHarnesses(),\n };\n return { content: text(details), details, isError: true };\n }\n const details = syncMcpServers(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Links every harness's global instructions file to the master AGENTS.md.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @param check - Report intended changes without writing them.\n * @returns {ToolResult<AgentsSyncReport | RunFailure>} The sync report or failure.\n */\nexport function agentsSync(id?: string, check = false): ToolResult<AgentsSyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n // Preflight before any write: a typo in excludes must fail the whole run,\n // not silently adopt the harness it was meant to protect.\n const unknown = readAgentsConfig().excludes.filter((entry) => !isHarnessId(entry));\n if (unknown.length > 0) {\n const details: RunFailure = {\n error: `Agents config excludes unknown harnesses: ${unknown.join(\", \")}`,\n known: listHarnesses(),\n };\n return { content: text(details), details, isError: true };\n }\n const details = syncAgentsFiles(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n check,\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Synchronizes canonical Markdown prompt templates into harness destinations.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @param check - Report intended changes without writing them.\n * @returns {ToolResult<PromptSyncReport | RunFailure>} The sync report or failure.\n */\nexport function promptsSync(id?: string, check = false): ToolResult<PromptSyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n const details = syncPromptTemplates(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n check,\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n\n/**\n * Links harness skills directories to the canonical skills directory.\n *\n * @param id - Optional harness id; omission targets every harness.\n * @param check - Report intended changes without writing them.\n * @returns {ToolResult<SkillsSyncReport | RunFailure>} The sync report or failure.\n */\nexport function skillsSync(id?: string, check = false): ToolResult<SkillsSyncReport | RunFailure> {\n if (id !== undefined && !isHarnessId(id)) return unknownHarness(id);\n\n try {\n const details = syncSkills(\n id !== undefined && isHarnessId(id) ? [getHarness(id)] : getAllHarnesses(),\n check,\n );\n return { content: text(details), details };\n } catch (error) {\n const details: RunFailure = { error: errorMessage(error) };\n return { content: text(details), details, isError: true };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/tool-schemas.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* Tool parameter schemas shared by every surface (MCP server, Pi and OMP
|
|
3
4
|
* extensions). Each surface owns a different TypeBox build (the extensions
|
|
@@ -10,7 +11,7 @@
|
|
|
10
11
|
* returns; OMP's facade accepts its own `AnySchema` while producing schemas
|
|
11
12
|
* that satisfy the host's stricter `TSchema`.
|
|
12
13
|
*/
|
|
13
|
-
|
|
14
|
+
interface McpSchemaBuilder<I, S> {
|
|
14
15
|
Object(properties: Readonly<Record<string, I>>, options?: object): S;
|
|
15
16
|
String(options?: object): I;
|
|
16
17
|
Integer(options?: object): I;
|
|
@@ -21,15 +22,16 @@ export interface McpSchemaBuilder<I, S> {
|
|
|
21
22
|
Literal(value: string, options?: object): I;
|
|
22
23
|
Optional(schema: I): I;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
declare const HARNESS_INFO_MAX_ITEMS = 20;
|
|
26
|
+
declare const RUN_TIMEOUT_DEFAULT_SECONDS = 600;
|
|
26
27
|
/**
|
|
27
28
|
* Builds the parameter schemas for all harness tools with the host's TypeBox.
|
|
28
29
|
*
|
|
29
30
|
* @param Type - Host-provided TypeBox-compatible schema builder.
|
|
30
31
|
* @returns {Record<string, S>} Schemas keyed by harness tool operation.
|
|
31
32
|
*/
|
|
32
|
-
|
|
33
|
+
declare function harnessToolSchemas<I, S>(Type: McpSchemaBuilder<I, S>): {
|
|
34
|
+
/** Open on purpose: nothing to misread, and some models send a placeholder `_` here. */
|
|
33
35
|
detect: S;
|
|
34
36
|
info: S;
|
|
35
37
|
models: S;
|
|
@@ -38,6 +40,7 @@ export declare function harnessToolSchemas<I, S>(Type: McpSchemaBuilder<I, S>):
|
|
|
38
40
|
mcpSync: S;
|
|
39
41
|
agentsSync: S;
|
|
40
42
|
promptsSync: S;
|
|
43
|
+
skillsSync: S;
|
|
41
44
|
mcpAdd: S;
|
|
42
45
|
mcpRemove: S;
|
|
43
46
|
};
|
|
@@ -46,16 +49,16 @@ export declare function harnessToolSchemas<I, S>(Type: McpSchemaBuilder<I, S>):
|
|
|
46
49
|
* builders' literal types, so hosts annotate their execute callbacks with
|
|
47
50
|
* these instead of TypeBox Static inference.
|
|
48
51
|
*/
|
|
49
|
-
|
|
52
|
+
interface InfoParams {
|
|
50
53
|
id: string | string[];
|
|
51
54
|
}
|
|
52
|
-
|
|
55
|
+
interface ModelsParams {
|
|
53
56
|
id: string;
|
|
54
57
|
search?: string;
|
|
55
58
|
cwd?: string;
|
|
56
59
|
timeoutSeconds?: number;
|
|
57
60
|
}
|
|
58
|
-
|
|
61
|
+
interface RunParams {
|
|
59
62
|
id: string;
|
|
60
63
|
prompt: string;
|
|
61
64
|
cwd?: string;
|
|
@@ -65,21 +68,25 @@ export interface RunParams {
|
|
|
65
68
|
tools: boolean;
|
|
66
69
|
readOnly?: boolean;
|
|
67
70
|
}
|
|
68
|
-
|
|
71
|
+
interface McpListParams {
|
|
69
72
|
id?: string;
|
|
70
73
|
}
|
|
71
|
-
|
|
74
|
+
interface McpSyncParams {
|
|
72
75
|
id?: string;
|
|
73
76
|
}
|
|
74
|
-
|
|
77
|
+
interface AgentsSyncParams {
|
|
75
78
|
id?: string;
|
|
76
79
|
check?: boolean;
|
|
77
80
|
}
|
|
78
|
-
|
|
81
|
+
interface PromptsSyncParams {
|
|
79
82
|
id?: string;
|
|
80
83
|
check?: boolean;
|
|
81
84
|
}
|
|
82
|
-
|
|
85
|
+
interface SkillsSyncParams {
|
|
86
|
+
id?: string;
|
|
87
|
+
check?: boolean;
|
|
88
|
+
}
|
|
89
|
+
interface McpAddParams {
|
|
83
90
|
id: string;
|
|
84
91
|
name: string;
|
|
85
92
|
command?: string;
|
|
@@ -90,9 +97,11 @@ export interface McpAddParams {
|
|
|
90
97
|
headers?: Record<string, string>;
|
|
91
98
|
scope?: "user" | "project";
|
|
92
99
|
}
|
|
93
|
-
|
|
100
|
+
interface McpRemoveParams {
|
|
94
101
|
id: string;
|
|
95
102
|
name: string;
|
|
96
103
|
scope?: "user" | "project";
|
|
97
104
|
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { McpListParams as a, McpSyncParams as c, RUN_TIMEOUT_DEFAULT_SECONDS as d, RunParams as f, McpAddParams as i, ModelsParams as l, harnessToolSchemas as m, HARNESS_INFO_MAX_ITEMS as n, McpRemoveParams as o, SkillsSyncParams as p, InfoParams as r, McpSchemaBuilder as s, AgentsSyncParams as t, PromptsSyncParams as u };
|
|
98
107
|
//# sourceMappingURL=tool-schemas.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-schemas.d.mts","names":[],"sources":["../../src/tool-schemas.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool-schemas.d.mts","names":[],"sources":["../../src/tool-schemas.ts"],"mappings":";;;;;;;;;;;;;UAaiB,iBAAiB,GAAG;EACnC,OAAO,YAAY,SAAS,eAAe,KAAK,mBAAmB;EACnE,OAAO,mBAAmB;EAC1B,QAAQ,mBAAmB;EAC3B,QAAQ,mBAAmB;EAC3B,MAAM,MAAM,GAAG,mBAAmB;EAClC,OAAO,KAAK,GAAG,OAAO,GAAG,mBAAmB;EAC5C,MAAM,kBAAkB,KAAK,mBAAmB;EAChD,QAAQ,eAAe,mBAAmB;EAC1C,SAAS,QAAQ,IAAI;;cAGV;cACA;;;;;;;iBAQG,mBAAmB,GAAG,GAAG,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;UAkLlD;EACf;;UAGe;EACf;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;;UAGe;EACf;;UAGe;EACf;EACA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA,UAAU;EACV;;UAGe;EACf;EACA;EACA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/tool-schemas.ts
|
|
1
2
|
const HARNESS_INFO_MAX_ITEMS = 20;
|
|
2
3
|
const RUN_TIMEOUT_DEFAULT_SECONDS = 600;
|
|
3
4
|
function harnessToolSchemas(Type) {
|
|
@@ -8,17 +9,18 @@ function harnessToolSchemas(Type) {
|
|
|
8
9
|
pattern: "^[a-z][a-z0-9-]*$"
|
|
9
10
|
});
|
|
10
11
|
const stringRecord = (description) => Type.Record(Type.String({ maxLength: 256 }), Type.String({ maxLength: 4096 }), { description });
|
|
12
|
+
const closed = (properties) => Type.Object(properties, { additionalProperties: false });
|
|
11
13
|
const scope = Type.Optional(Type.Union([Type.Literal("user"), Type.Literal("project")], { description: "Which config file to target (default user)" }));
|
|
12
14
|
return {
|
|
13
15
|
detect: Type.Object({}),
|
|
14
|
-
info:
|
|
16
|
+
info: closed({ id: Type.Union([harnessId("Harness id"), Type.Array(harnessId("Harness id"), {
|
|
15
17
|
minItems: 1,
|
|
16
18
|
maxItems: 20
|
|
17
19
|
})], { description: "Harness id, or a list of ids to inspect in one call" }) }),
|
|
18
|
-
models:
|
|
20
|
+
models: closed({
|
|
19
21
|
id: harnessId("Harness id"),
|
|
20
22
|
search: Type.Optional(Type.String({
|
|
21
|
-
description: "Optional
|
|
23
|
+
description: "Optional model search filter; without a native one, ids match ignoring case",
|
|
22
24
|
minLength: 1,
|
|
23
25
|
maxLength: 1024
|
|
24
26
|
})),
|
|
@@ -33,7 +35,7 @@ function harnessToolSchemas(Type) {
|
|
|
33
35
|
maximum: 3600
|
|
34
36
|
}))
|
|
35
37
|
}),
|
|
36
|
-
run:
|
|
38
|
+
run: closed({
|
|
37
39
|
id: harnessId("Harness id"),
|
|
38
40
|
prompt: Type.String({
|
|
39
41
|
description: "Prompt to send to the harness",
|
|
@@ -59,17 +61,21 @@ function harnessToolSchemas(Type) {
|
|
|
59
61
|
tools: Type.Boolean({ description: "Explicit execution mode. Set true when the task needs any harness tools, including Grok native X search. Set false only for an advisor without tools." }),
|
|
60
62
|
readOnly: Type.Optional(Type.Boolean({ description: "Set with tools=true to require native read-only tool enforcement. Unsupported harnesses reject the run instead of widening access." }))
|
|
61
63
|
}),
|
|
62
|
-
mcpList:
|
|
63
|
-
mcpSync:
|
|
64
|
-
agentsSync:
|
|
64
|
+
mcpList: closed({ id: Type.Optional(harnessId("Harness id; omit to list every harness")) }),
|
|
65
|
+
mcpSync: closed({ id: Type.Optional(harnessId("Harness id; omit to sync every harness")) }),
|
|
66
|
+
agentsSync: closed({
|
|
65
67
|
id: Type.Optional(harnessId("Harness id; omit to sync every harness")),
|
|
66
68
|
check: Type.Optional(Type.Boolean({ description: "Report what would change without writing anything" }))
|
|
67
69
|
}),
|
|
68
|
-
promptsSync:
|
|
70
|
+
promptsSync: closed({
|
|
69
71
|
id: Type.Optional(harnessId("Harness id; omit to sync every harness")),
|
|
70
72
|
check: Type.Optional(Type.Boolean({ description: "Report what would change without writing anything" }))
|
|
71
73
|
}),
|
|
72
|
-
|
|
74
|
+
skillsSync: closed({
|
|
75
|
+
id: Type.Optional(harnessId("Harness id; omit to sync every harness")),
|
|
76
|
+
check: Type.Optional(Type.Boolean({ description: "Report what would change without writing anything" }))
|
|
77
|
+
}),
|
|
78
|
+
mcpAdd: closed({
|
|
73
79
|
id: harnessId("Harness id"),
|
|
74
80
|
name: Type.String({
|
|
75
81
|
description: "Server name",
|
|
@@ -100,7 +106,7 @@ function harnessToolSchemas(Type) {
|
|
|
100
106
|
headers: Type.Optional(stringRecord("Headers for an http/sse server")),
|
|
101
107
|
scope
|
|
102
108
|
}),
|
|
103
|
-
mcpRemove:
|
|
109
|
+
mcpRemove: closed({
|
|
104
110
|
id: harnessId("Harness id"),
|
|
105
111
|
name: Type.String({
|
|
106
112
|
description: "Server name",
|
|
@@ -111,6 +117,7 @@ function harnessToolSchemas(Type) {
|
|
|
111
117
|
})
|
|
112
118
|
};
|
|
113
119
|
}
|
|
114
|
-
|
|
120
|
+
//#endregion
|
|
121
|
+
export { RUN_TIMEOUT_DEFAULT_SECONDS as n, harnessToolSchemas as r, HARNESS_INFO_MAX_ITEMS as t };
|
|
115
122
|
|
|
116
123
|
//# sourceMappingURL=tool-schemas.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-schemas.mjs","names":[],"sources":["../../src/tool-schemas.ts"],"sourcesContent":["/**\n * Tool parameter schemas shared by every surface (MCP server, Pi and OMP\n * extensions). Each surface owns a different TypeBox build (the extensions\n * must use their host's facade), so the schemas are a factory over a minimal\n * structural builder instead of importing typebox here.\n */\n\n/**\n * The subset of the TypeBox builder the tool schemas need. `I` is the schema\n * type the builder accepts as input, `S` the (possibly narrower) type it\n * returns; OMP's facade accepts its own `AnySchema` while producing schemas\n * that satisfy the host's stricter `TSchema`.\n */\nexport interface McpSchemaBuilder<I, S> {\n Object(properties: Readonly<Record<string, I>>, options?: object): S;\n String(options?: object): I;\n Integer(options?: object): I;\n Boolean(options?: object): I;\n Array(item: I, options?: object): I;\n Record(key: I, value: I, options?: object): I;\n Union(schemas: readonly I[], options?: object): I;\n Literal(value: string, options?: object): I;\n Optional(schema: I): I;\n}\n\nexport const HARNESS_INFO_MAX_ITEMS = 20;\nexport const RUN_TIMEOUT_DEFAULT_SECONDS = 600;\n\n/**\n * Builds the parameter schemas for all harness tools with the host's TypeBox.\n *\n * @param Type - Host-provided TypeBox-compatible schema builder.\n * @returns {Record<string, S>} Schemas keyed by harness tool operation.\n */\nexport function harnessToolSchemas<I, S>(Type: McpSchemaBuilder<I, S>) {\n const harnessId = (description: string) =>\n Type.String({ description, minLength: 1, maxLength: 50, pattern: \"^[a-z][a-z0-9-]*$\" });\n\n const stringRecord = (description: string) =>\n Type.Record(Type.String({ maxLength: 256 }), Type.String({ maxLength: 4096 }), {\n description,\n });\n\n const scope = Type.Optional(\n Type.Union([Type.Literal(\"user\"), Type.Literal(\"project\")], {\n description: \"Which config file to target (default user)\",\n }),\n );\n\n return {\n detect: Type.Object({}),\n info: Type.Object({\n id: Type.Union(\n [\n harnessId(\"Harness id\"),\n Type.Array(harnessId(\"Harness id\"), {\n minItems: 1,\n maxItems: HARNESS_INFO_MAX_ITEMS,\n }),\n ],\n { description: \"Harness id, or a list of ids to inspect in one call\" },\n ),\n }),\n models: Type.Object({\n id: harnessId(\"Harness id\"),\n search: Type.Optional(\n Type.String({\n description: \"Optional native model search filter\",\n minLength: 1,\n maxLength: 1024,\n }),\n ),\n cwd: Type.Optional(\n Type.String({\n description: \"Working directory used while loading harness configuration\",\n minLength: 1,\n maxLength: 4096,\n }),\n ),\n timeoutSeconds: Type.Optional(\n Type.Integer({\n description: `Wall-clock budget in seconds (default ${RUN_TIMEOUT_DEFAULT_SECONDS})`,\n minimum: 1,\n maximum: 3600,\n }),\n ),\n }),\n run: Type.Object({\n id: harnessId(\"Harness id\"),\n prompt: Type.String({\n description: \"Prompt to send to the harness\",\n minLength: 1,\n maxLength: 100000,\n }),\n cwd: Type.Optional(\n Type.String({\n description: \"Working directory for the run\",\n minLength: 1,\n maxLength: 4096,\n }),\n ),\n model: Type.Optional(\n Type.String({\n description: \"Harness-native model id or selector\",\n minLength: 1,\n maxLength: 512,\n }),\n ),\n timeoutSeconds: Type.Optional(\n Type.Integer({\n description: `Wall-clock budget in seconds (default ${RUN_TIMEOUT_DEFAULT_SECONDS})`,\n minimum: 1,\n maximum: 3600,\n }),\n ),\n structured: Type.Optional(\n Type.Boolean({\n description: \"Use the harness's structured (JSON) output mode instead of plain text\",\n }),\n ),\n tools: Type.Boolean({\n description:\n \"Explicit execution mode. Set true when the task needs any harness tools, including Grok native X search. Set false only for an advisor without tools.\",\n }),\n readOnly: Type.Optional(\n Type.Boolean({\n description:\n \"Set with tools=true to require native read-only tool enforcement. Unsupported harnesses reject the run instead of widening access.\",\n }),\n ),\n }),\n mcpList: Type.Object({\n id: Type.Optional(harnessId(\"Harness id; omit to list every harness\")),\n }),\n mcpSync: Type.Object({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n }),\n agentsSync: Type.Object({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n check: Type.Optional(\n Type.Boolean({ description: \"Report what would change without writing anything\" }),\n ),\n }),\n promptsSync: Type.Object({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n check: Type.Optional(\n Type.Boolean({ description: \"Report what would change without writing anything\" }),\n ),\n }),\n mcpAdd: Type.Object({\n id: harnessId(\"Harness id\"),\n name: Type.String({\n description: \"Server name\",\n minLength: 1,\n maxLength: 100,\n pattern: \"^[A-Za-z0-9][A-Za-z0-9_-]*$\",\n }),\n command: Type.Optional(\n Type.String({ description: \"Binary for a stdio server\", minLength: 1, maxLength: 4096 }),\n ),\n args: Type.Optional(\n Type.Array(Type.String({ maxLength: 4096 }), {\n description: \"Arguments for a stdio server\",\n maxItems: 64,\n }),\n ),\n env: Type.Optional(stringRecord(\"Environment variables for a stdio server\")),\n url: Type.Optional(\n Type.String({ description: \"URL for an http/sse server\", minLength: 1, maxLength: 4096 }),\n ),\n transport: Type.Optional(\n Type.Union([Type.Literal(\"stdio\"), Type.Literal(\"http\"), Type.Literal(\"sse\")], {\n description: \"Transport; inferred from url/command when omitted\",\n }),\n ),\n headers: Type.Optional(stringRecord(\"Headers for an http/sse server\")),\n scope,\n }),\n mcpRemove: Type.Object({\n id: harnessId(\"Harness id\"),\n name: Type.String({\n description: \"Server name\",\n minLength: 1,\n maxLength: 100,\n }),\n scope,\n }),\n };\n}\n\n/**\n * Parameter types matching the schemas above. The generic factory erases the\n * builders' literal types, so hosts annotate their execute callbacks with\n * these instead of TypeBox Static inference.\n */\nexport interface InfoParams {\n id: string | string[];\n}\n\nexport interface ModelsParams {\n id: string;\n search?: string;\n cwd?: string;\n timeoutSeconds?: number;\n}\n\nexport interface RunParams {\n id: string;\n prompt: string;\n cwd?: string;\n model?: string;\n timeoutSeconds?: number;\n structured?: boolean;\n tools: boolean;\n readOnly?: boolean;\n}\n\nexport interface McpListParams {\n id?: string;\n}\n\nexport interface McpSyncParams {\n id?: string;\n}\n\nexport interface AgentsSyncParams {\n id?: string;\n check?: boolean;\n}\n\nexport interface PromptsSyncParams {\n id?: string;\n check?: boolean;\n}\n\nexport interface McpAddParams {\n id: string;\n name: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n transport?: \"stdio\" | \"http\" | \"sse\";\n headers?: Record<string, string>;\n scope?: \"user\" | \"project\";\n}\n\nexport interface McpRemoveParams {\n id: string;\n name: string;\n scope?: \"user\" | \"project\";\n}\n"],"mappings":"AAyBA,MAAa,yBAAyB;AACtC,MAAa,8BAA8B;;;;;;EAQ3C,SAAgB;CACd,CAAA;CACgB,MAAA,gBAAA,gBAAA,KAAA,OAAA,KAAA,OAAA,EAAA,WAAA,IAAA,CAAA,GAAA,KAAA,OAAA,EAAA,WAAA,KAAA,CAAA,GAAA,EAAA,YAAA,CAAA;CAAa,MAAA,QAAW,KAAA,SAAA,KAAA,MAAA,CAAA,KAAA,QAAA,MAAA,GAAA,KAAA,QAAA,SAAA,CAAA,GAAA,EAAA,aAAA,6CAAA,CAAA,CAAA;CAAG,OAAA;EAAe,QAAA,KAAS,OAAA,CAAA,CAAA;EAAqB,MAAA,KAAA,OAAA,EAAA,IAAA,KAAA,MAAA,CAAA,UAAA,YAAA,GAAA,KAAA,MAAA,UAAA,YAAA,GAAA;GAExF,UAAM;GAKN,UAAM;EAMN,CAAA,CAAA,GAAA,EAAO,aAAA,sDAAA,CAAA,EAAA,CAAA;EACL,QAAQ,KAAK,OAAO;GACpB,IAAA,UAAW,YACL;GAIE,QAAA,KAAU,SAAA,KAAA,OAAA;IACV,aAAA;IAEJ,WACE;IAGN,WAAa;GACX,CAAA,CAAA;GACA,KAAA,KAAQ,SAAK,KACX,OAAK;IACH,aAAa;IACb,WAAW;IACX,WAAW;GACb,CAAC,CACH;GACA,gBAAU,KACR,SAAK,KAAO,QAAA;IACV,aAAa;IACb,SAAA;IACA,SAAA;GACF,CAAC,CACH;EACA,CAAA;EAEI,KAAA,KAAA,OAAa;GACb,IAAA,UAAS,YAAA;GACT,QAAA,KAAS,OAAA;IACV,aACH;IACD,WAAA;IACD,WAAU;GACR,CAAA;GACA,KAAA,KAAQ,SAAK,KAAO,OAAA;IAClB,aAAa;IACb,WAAW;IACX,WAAW;GACb,CAAC,CAAA;GACD,OAAK,KAAK,SACR,KAAK,OAAO;IACV,aAAa;IACb,WAAW;IACX,WAAW;GACb,CAAC,CACH;GACA,gBAAY,KACV,SAAK,KAAO,QAAA;IACV,aAAa;IACb,SAAA;IACA,SAAA;GACF,CAAC,CACH;GACA,YAAA,KAAgB,SAAK,KACnB,QAAK,EAAA,aAAQ,wEAAA,CAAA,CAAA;GACX,OAAA,KAAA,QAAa,EAAA,aAAA,wJAAqE,CAAA;GAClF,UAAS,KAAA,SAAA,KAAA,QAAA,EAAA,aAAA,qIAAA,CAAA,CAAA;EACT,CAAA;EACF,SACF,KAAA,OAAA,EAAA,IAAA,KAAA,SAAA,UAAA,wCAAA,CAAA,EAAA,CAAA;EACA,SAAA,KAAY,OAAK,EAAA,IACf,KAAK,SAAQ,UACX,wCAAa,CAAA,EAAA,CAAA;EAGjB,YAAO,KAAK,OACV;GAGF,IAAA,KAAA,SAAe,UACb,wCAEI,CAAA;GAGP,OAAA,KAAA,SAAA,KAAA,QAAA,EAAA,aAAA,oDAAA,CAAA,CAAA;EACD,CAAA;EAGA,aAAS,KAAK,OACZ;GAEF,IAAA,KAAA,SAAiB,UAAO,wCAAA,CAAA;GACtB,OAAI,KAAK,SAAS,KAAA,QAAU,EAAA,aAAA,oDAAyC,CAAA,CAAA;EACrE,CAAA;EAGF,QAAC,KAAA,OAAA;GACD,IAAA,UAAa,YAAY;GACvB,MAAI,KAAK,OAAS;IAClB,aAAY;IAGb,WAAA;IACD,WAAa;IACX,SAAI;GACJ,CAAA;GACE,SAAA,KAAa,SAAA,KAAA,OAAA;IACb,aAAW;IACX,WAAW;IACX,WAAS;GACX,CAAC,CAAA;GACD,MAAA,KAAS,SAAK,KACZ,MAAK,KAAO,OAAA,EAAA,WAAA,KAAA,CAAA,GAAA;IAAE,aAAa;IAA6B,UAAA;GAAc,CAAA,CAAA;GAAgB,KACxF,KAAA,SAAA,aAAA,0CAAA,CAAA;GACA,KAAA,KAAM,SAAK,KACT,OAAW;IACT,aAAa;IACb,WAAU;IACX,WACH;GACA,CAAA,CAAA;GACA,WAAU,KAAA,SACH,KAAA,MAAO;IAAE,KAAA,QAAa,OAAA;IAA8B,KAAA,QAAW,MAAA;IAAG,KAAA,QAAW,KAAA;GAAK,GACzF,EAAA,aAAA,oDAAA,CAAA,CAAA;GACA,SAAA,KAAW,SAAK,aACH,gCAAA,CAAA;GAAC;EAAuB,CAAA;EAAsB,WAAK,KAAQ,OAAK;GAAC,IAAG,UAC7E,YAAa;GAGjB,MAAA,KAAS,OAAK;IACd,aAAA;IACD,WAAA;IACD,WAAW;GACT,CAAA;GACA;EACE,CAAA;CACA;AACA;AAEF,SAAA,wBAAA,6BAAA"}
|
|
1
|
+
{"version":3,"file":"tool-schemas.mjs","names":[],"sources":["../../src/tool-schemas.ts"],"sourcesContent":["/**\n * Tool parameter schemas shared by every surface (MCP server, Pi and OMP\n * extensions). Each surface owns a different TypeBox build (the extensions\n * must use their host's facade), so the schemas are a factory over a minimal\n * structural builder instead of importing typebox here.\n */\n\n/**\n * The subset of the TypeBox builder the tool schemas need. `I` is the schema\n * type the builder accepts as input, `S` the (possibly narrower) type it\n * returns; OMP's facade accepts its own `AnySchema` while producing schemas\n * that satisfy the host's stricter `TSchema`.\n */\nexport interface McpSchemaBuilder<I, S> {\n Object(properties: Readonly<Record<string, I>>, options?: object): S;\n String(options?: object): I;\n Integer(options?: object): I;\n Boolean(options?: object): I;\n Array(item: I, options?: object): I;\n Record(key: I, value: I, options?: object): I;\n Union(schemas: readonly I[], options?: object): I;\n Literal(value: string, options?: object): I;\n Optional(schema: I): I;\n}\n\nexport const HARNESS_INFO_MAX_ITEMS = 20;\nexport const RUN_TIMEOUT_DEFAULT_SECONDS = 600;\n\n/**\n * Builds the parameter schemas for all harness tools with the host's TypeBox.\n *\n * @param Type - Host-provided TypeBox-compatible schema builder.\n * @returns {Record<string, S>} Schemas keyed by harness tool operation.\n */\nexport function harnessToolSchemas<I, S>(Type: McpSchemaBuilder<I, S>) {\n const harnessId = (description: string) =>\n Type.String({ description, minLength: 1, maxLength: 50, pattern: \"^[a-z][a-z0-9-]*$\" });\n\n const stringRecord = (description: string) =>\n Type.Record(Type.String({ maxLength: 256 }), Type.String({ maxLength: 4096 }), {\n description,\n });\n\n /**\n * A closed object rejects a stray `read_only` instead of quietly running with every tool.\n *\n * @param properties - Declared tool arguments.\n * @returns {S} An object schema that refuses undeclared keys.\n */\n const closed = (properties: Readonly<Record<string, I>>) =>\n Type.Object(properties, { additionalProperties: false });\n\n const scope = Type.Optional(\n Type.Union([Type.Literal(\"user\"), Type.Literal(\"project\")], {\n description: \"Which config file to target (default user)\",\n }),\n );\n\n return {\n /** Open on purpose: nothing to misread, and some models send a placeholder `_` here. */\n detect: Type.Object({}),\n info: closed({\n id: Type.Union(\n [\n harnessId(\"Harness id\"),\n Type.Array(harnessId(\"Harness id\"), {\n minItems: 1,\n maxItems: HARNESS_INFO_MAX_ITEMS,\n }),\n ],\n { description: \"Harness id, or a list of ids to inspect in one call\" },\n ),\n }),\n models: closed({\n id: harnessId(\"Harness id\"),\n search: Type.Optional(\n Type.String({\n description:\n \"Optional model search filter; without a native one, ids match ignoring case\",\n minLength: 1,\n maxLength: 1024,\n }),\n ),\n cwd: Type.Optional(\n Type.String({\n description: \"Working directory used while loading harness configuration\",\n minLength: 1,\n maxLength: 4096,\n }),\n ),\n timeoutSeconds: Type.Optional(\n Type.Integer({\n description: `Wall-clock budget in seconds (default ${RUN_TIMEOUT_DEFAULT_SECONDS})`,\n minimum: 1,\n maximum: 3600,\n }),\n ),\n }),\n run: closed({\n id: harnessId(\"Harness id\"),\n prompt: Type.String({\n description: \"Prompt to send to the harness\",\n minLength: 1,\n maxLength: 100000,\n }),\n cwd: Type.Optional(\n Type.String({\n description: \"Working directory for the run\",\n minLength: 1,\n maxLength: 4096,\n }),\n ),\n model: Type.Optional(\n Type.String({\n description: \"Harness-native model id or selector\",\n minLength: 1,\n maxLength: 512,\n }),\n ),\n timeoutSeconds: Type.Optional(\n Type.Integer({\n description: `Wall-clock budget in seconds (default ${RUN_TIMEOUT_DEFAULT_SECONDS})`,\n minimum: 1,\n maximum: 3600,\n }),\n ),\n structured: Type.Optional(\n Type.Boolean({\n description: \"Use the harness's structured (JSON) output mode instead of plain text\",\n }),\n ),\n tools: Type.Boolean({\n description:\n \"Explicit execution mode. Set true when the task needs any harness tools, including Grok native X search. Set false only for an advisor without tools.\",\n }),\n readOnly: Type.Optional(\n Type.Boolean({\n description:\n \"Set with tools=true to require native read-only tool enforcement. Unsupported harnesses reject the run instead of widening access.\",\n }),\n ),\n }),\n mcpList: closed({\n id: Type.Optional(harnessId(\"Harness id; omit to list every harness\")),\n }),\n mcpSync: closed({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n }),\n agentsSync: closed({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n check: Type.Optional(\n Type.Boolean({ description: \"Report what would change without writing anything\" }),\n ),\n }),\n promptsSync: closed({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n check: Type.Optional(\n Type.Boolean({ description: \"Report what would change without writing anything\" }),\n ),\n }),\n skillsSync: closed({\n id: Type.Optional(harnessId(\"Harness id; omit to sync every harness\")),\n check: Type.Optional(\n Type.Boolean({ description: \"Report what would change without writing anything\" }),\n ),\n }),\n mcpAdd: closed({\n id: harnessId(\"Harness id\"),\n name: Type.String({\n description: \"Server name\",\n minLength: 1,\n maxLength: 100,\n pattern: \"^[A-Za-z0-9][A-Za-z0-9_-]*$\",\n }),\n command: Type.Optional(\n Type.String({ description: \"Binary for a stdio server\", minLength: 1, maxLength: 4096 }),\n ),\n args: Type.Optional(\n Type.Array(Type.String({ maxLength: 4096 }), {\n description: \"Arguments for a stdio server\",\n maxItems: 64,\n }),\n ),\n env: Type.Optional(stringRecord(\"Environment variables for a stdio server\")),\n url: Type.Optional(\n Type.String({ description: \"URL for an http/sse server\", minLength: 1, maxLength: 4096 }),\n ),\n transport: Type.Optional(\n Type.Union([Type.Literal(\"stdio\"), Type.Literal(\"http\"), Type.Literal(\"sse\")], {\n description: \"Transport; inferred from url/command when omitted\",\n }),\n ),\n headers: Type.Optional(stringRecord(\"Headers for an http/sse server\")),\n scope,\n }),\n mcpRemove: closed({\n id: harnessId(\"Harness id\"),\n name: Type.String({\n description: \"Server name\",\n minLength: 1,\n maxLength: 100,\n }),\n scope,\n }),\n };\n}\n\n/**\n * Parameter types matching the schemas above. The generic factory erases the\n * builders' literal types, so hosts annotate their execute callbacks with\n * these instead of TypeBox Static inference.\n */\nexport interface InfoParams {\n id: string | string[];\n}\n\nexport interface ModelsParams {\n id: string;\n search?: string;\n cwd?: string;\n timeoutSeconds?: number;\n}\n\nexport interface RunParams {\n id: string;\n prompt: string;\n cwd?: string;\n model?: string;\n timeoutSeconds?: number;\n structured?: boolean;\n tools: boolean;\n readOnly?: boolean;\n}\n\nexport interface McpListParams {\n id?: string;\n}\n\nexport interface McpSyncParams {\n id?: string;\n}\n\nexport interface AgentsSyncParams {\n id?: string;\n check?: boolean;\n}\n\nexport interface PromptsSyncParams {\n id?: string;\n check?: boolean;\n}\n\nexport interface SkillsSyncParams {\n id?: string;\n check?: boolean;\n}\n\nexport interface McpAddParams {\n id: string;\n name: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n transport?: \"stdio\" | \"http\" | \"sse\";\n headers?: Record<string, string>;\n scope?: \"user\" | \"project\";\n}\n\nexport interface McpRemoveParams {\n id: string;\n name: string;\n scope?: \"user\" | \"project\";\n}\n"],"mappings":"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"}
|