@gajae-code/coding-agent 0.18.5 → 0.18.7
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/CHANGELOG.md +140 -0
- package/dist/types/capability/types.d.ts +4 -0
- package/dist/types/cli-commands.d.ts +10 -0
- package/dist/types/cli-ordinary.d.ts +13 -0
- package/dist/types/cli.d.ts +12 -3
- package/dist/types/commands/contribution-prep.d.ts +0 -3
- package/dist/types/commands/sdk.d.ts +3 -0
- package/dist/types/commands/update.d.ts +1 -0
- package/dist/types/config/model-profile-activation.d.ts +19 -0
- package/dist/types/config/settings.d.ts +4 -0
- package/dist/types/coordinator-mcp/session-reaper.d.ts +5 -0
- package/dist/types/discovery/helpers.d.ts +2 -2
- package/dist/types/edit/modes/replace.d.ts +3 -3
- package/dist/types/edit/streaming.d.ts +2 -2
- package/dist/types/exec/bash-shell-supervisor.d.ts +12 -0
- package/dist/types/runtime-mcp/elicitation.d.ts +12 -0
- package/dist/types/sdk/broker/discovery.d.ts +8 -0
- package/dist/types/sdk/broker/ensure.d.ts +1 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +4 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +9 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/broker/task-artifact-owner-validation.d.ts +55 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +4 -2
- package/dist/types/sdk/cli/diagnostics-cli.d.ts +18 -0
- package/dist/types/sdk/diagnostics/observe-broker.d.ts +185 -0
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +6 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +9 -0
- package/dist/types/sdk/session.d.ts +13 -0
- package/dist/types/session/agent-session.d.ts +5 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +11 -1
- package/dist/types/session/internal/task-artifact-owner-access.d.ts +17 -0
- package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +3 -0
- package/dist/types/session/session-retirement.d.ts +47 -0
- package/dist/types/session/session-storage.d.ts +0 -46
- package/dist/types/session/session-transcript-header.d.ts +2 -0
- package/dist/types/session/task-artifact-owner-codec.d.ts +107 -0
- package/dist/types/session/task-artifact-owner-retirement.d.ts +7 -0
- package/dist/types/session/task-artifact-owner.d.ts +10 -0
- package/dist/types/tools/ask-contract.d.ts +75 -254
- package/dist/types/tools/bash.d.ts +1 -1
- package/package.json +7 -7
- package/scripts/build-sdk-package-smoke.ts +5 -0
- package/scripts/resident-memory-bench.ts +174 -20
- package/src/capability/index.ts +1 -0
- package/src/capability/types.ts +4 -0
- package/src/cli/config-cli.ts +8 -18
- package/src/cli/public-command-entry.ts +5 -0
- package/src/cli/ssh-cli.ts +6 -3
- package/src/cli/web-search-cli.ts +9 -3
- package/src/cli-commands.ts +14 -0
- package/src/cli-main.ts +7 -8
- package/src/cli-ordinary.ts +197 -0
- package/src/cli.ts +25 -182
- package/src/commands/contribution-prep.ts +1 -3
- package/src/commands/sdk.ts +171 -21
- package/src/commands/update.ts +15 -1
- package/src/config/file-lock.ts +91 -2
- package/src/config/model-profile-activation.ts +70 -4
- package/src/config/model-profile-contract.ts +4 -1
- package/src/config/model-profiles.ts +23 -31
- package/src/config/model-resolver.ts +9 -1
- package/src/config/settings.ts +44 -4
- package/src/coordinator-mcp/event-webhook.ts +19 -14
- package/src/coordinator-mcp/policy.ts +14 -4
- package/src/coordinator-mcp/server.ts +142 -7
- package/src/coordinator-mcp/session-reaper.ts +9 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/discovery/helpers.ts +9 -3
- package/src/discovery/ssh.ts +8 -3
- package/src/edit/modes/replace.ts +6 -6
- package/src/edit/streaming.ts +15 -15
- package/src/exec/bash-shell-supervisor.ts +60 -3
- package/src/gjc-runtime/gc-runtime.ts +2 -1
- package/src/hindsight/config.ts +9 -3
- package/src/internal-urls/docs-index.generated.ts +11 -10
- package/src/memories/index.ts +8 -2
- package/src/modes/acp/acp-agent.ts +724 -370
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/prompts/tools/ask.md +2 -0
- package/src/runtime-mcp/client.ts +13 -4
- package/src/runtime-mcp/elicitation.ts +142 -0
- package/src/sdk/broker/broker.ts +54 -1
- package/src/sdk/broker/daemon-entry.ts +67 -6
- package/src/sdk/broker/discovery.ts +8 -0
- package/src/sdk/broker/ensure.ts +156 -20
- package/src/sdk/broker/lifecycle-ledger.ts +110 -12
- package/src/sdk/broker/lifecycle.ts +334 -348
- package/src/sdk/broker/runtime.ts +5 -1
- package/src/sdk/broker/task-artifact-owner-validation.ts +259 -0
- package/src/sdk/broker/transport.ts +5 -1
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +3 -0
- package/src/sdk/bus/index.ts +3 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/bus/telegram-daemon-control.ts +15 -12
- package/src/sdk/bus/telegram-daemon.ts +38 -3
- package/src/sdk/cli/diagnostics-cli.ts +247 -0
- package/src/sdk/diagnostics/observe-broker.ts +654 -0
- package/src/sdk/host/control/dispatch.ts +52 -4
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/host.ts +6 -0
- package/src/sdk/host/session-runtime.test.ts +83 -4
- package/src/sdk/host/session-runtime.ts +15 -7
- package/src/sdk/index.ts +1 -0
- package/src/sdk/lifecycle-session.ts +1 -0
- package/src/sdk/mcp/server.ts +15 -3
- package/src/sdk/protocol/operation-registry.ts +1 -1
- package/src/sdk/router/session-router.ts +26 -3
- package/src/sdk/session.ts +51 -8
- package/src/session/agent-session.ts +169 -43
- package/src/session/blob-store.ts +78 -33
- package/src/session/internal/managed-session-storage.ts +203 -4
- package/src/session/internal/task-artifact-owner-access.ts +229 -0
- package/src/session/internal/task-artifact-owner-transcript.ts +68 -0
- package/src/session/session-retirement.ts +155 -0
- package/src/session/session-storage.ts +1 -160
- package/src/session/session-transcript-header.ts +17 -0
- package/src/session/task-artifact-owner-codec.ts +578 -0
- package/src/session/task-artifact-owner-retirement.ts +475 -0
- package/src/session/task-artifact-owner.ts +289 -0
- package/src/setup/hermes/templates/operator-instructions.v1.md +19 -1
- package/src/setup/hermes-setup.ts +4 -1
- package/src/slash-commands/builtin-registry.ts +8 -5
- package/src/tools/ask-contract.test.ts +76 -1
- package/src/tools/ask-contract.ts +57 -6
- package/src/tools/ask.ts +16 -7
- package/src/tools/bash.ts +38 -29
- package/src/tools/descriptors.test.ts +29 -0
- package/src/tools/tool-catalog.generated.ts +7 -4
- package/src/web/search/index.ts +2 -2
package/src/tools/bash.ts
CHANGED
|
@@ -19,8 +19,10 @@ import {
|
|
|
19
19
|
} from "../gjc-runtime/managed-owner-admission";
|
|
20
20
|
import {
|
|
21
21
|
MANAGED_OWNER_CHILD_TOKEN_ENV,
|
|
22
|
+
MANAGED_OWNER_COMMAND_ENV,
|
|
22
23
|
MANAGED_OWNER_GENERATION_ENV,
|
|
23
24
|
MANAGED_OWNER_INCARNATION_ENV,
|
|
25
|
+
MANAGED_OWNER_REDACT_COMMAND_ENV,
|
|
24
26
|
MANAGED_OWNER_RUN_ID_ENV,
|
|
25
27
|
MANAGED_OWNER_STATE_DIR_ENV,
|
|
26
28
|
} from "../gjc-runtime/managed-owner-supervisor";
|
|
@@ -118,6 +120,8 @@ export const MANAGED_OWNER_BASH_ENV = [
|
|
|
118
120
|
MANAGED_OWNER_RUN_ID_ENV,
|
|
119
121
|
MANAGED_OWNER_INCARNATION_ENV,
|
|
120
122
|
MANAGED_OWNER_CHILD_TOKEN_ENV,
|
|
123
|
+
MANAGED_OWNER_COMMAND_ENV,
|
|
124
|
+
MANAGED_OWNER_REDACT_COMMAND_ENV,
|
|
121
125
|
MANAGED_OWNER_PREDECESSOR_TOKEN_ENV,
|
|
122
126
|
MANAGED_OWNER_PREDECESSOR_GENERATION_ENV,
|
|
123
127
|
MANAGED_OWNER_PREDECESSOR_RUN_ID_ENV,
|
|
@@ -1278,7 +1282,7 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
|
1278
1282
|
*/
|
|
1279
1283
|
async #waitForManagedBashJob(
|
|
1280
1284
|
job: ManagedBashJobHandle,
|
|
1281
|
-
thresholdMs: number,
|
|
1285
|
+
thresholdMs: number | undefined,
|
|
1282
1286
|
signal?: AbortSignal,
|
|
1283
1287
|
backgroundRequest?: Promise<FoldReason>,
|
|
1284
1288
|
foldAdapter?: FoldAdapter,
|
|
@@ -1288,31 +1292,36 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
|
1288
1292
|
}
|
|
1289
1293
|
|
|
1290
1294
|
const startedAt = Date.now();
|
|
1291
|
-
const threshold =
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1295
|
+
const threshold =
|
|
1296
|
+
thresholdMs === undefined ? undefined : Promise.withResolvers<{ kind: "running"; reason: FoldReason }>();
|
|
1297
|
+
const thresholdTimer =
|
|
1298
|
+
threshold === undefined
|
|
1299
|
+
? undefined
|
|
1300
|
+
: setTimeout(
|
|
1301
|
+
() => {
|
|
1302
|
+
const requestFold = this.session.requestForegroundBashBackground;
|
|
1303
|
+
if (!foldAdapter || !requestFold) {
|
|
1304
|
+
threshold.resolve({ kind: "running", reason: "timer" });
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
void requestFold("timer", foldAdapter)
|
|
1308
|
+
.then(folded => {
|
|
1309
|
+
if (!folded) threshold.resolve({ kind: "running", reason: "timer" });
|
|
1310
|
+
})
|
|
1311
|
+
.catch(error => {
|
|
1312
|
+
logger.warn("Timer-triggered fold failed", {
|
|
1313
|
+
jobId: foldAdapter.jobId,
|
|
1314
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1315
|
+
});
|
|
1316
|
+
threshold.resolve({ kind: "running", reason: "timer" });
|
|
1317
|
+
});
|
|
1318
|
+
},
|
|
1319
|
+
Math.max(0, thresholdMs ?? 0),
|
|
1320
|
+
);
|
|
1313
1321
|
const waiters: Array<
|
|
1314
1322
|
Promise<ManagedBashJobCompletion | { kind: "running"; reason: FoldReason } | { kind: "aborted" }>
|
|
1315
|
-
> = [job.completion
|
|
1323
|
+
> = [job.completion];
|
|
1324
|
+
if (threshold) waiters.push(threshold.promise);
|
|
1316
1325
|
if (backgroundRequest) {
|
|
1317
1326
|
waiters.push(backgroundRequest.then(reason => ({ kind: "running" as const, reason })));
|
|
1318
1327
|
}
|
|
@@ -1333,7 +1342,7 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
|
1333
1342
|
return await Promise.race(waiters);
|
|
1334
1343
|
} finally {
|
|
1335
1344
|
stopSteerWatch();
|
|
1336
|
-
clearTimeout(thresholdTimer);
|
|
1345
|
+
if (thresholdTimer !== undefined) clearTimeout(thresholdTimer);
|
|
1337
1346
|
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
1338
1347
|
}
|
|
1339
1348
|
}
|
|
@@ -1894,11 +1903,11 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
|
1894
1903
|
// longer has to be bypassed to make folding work. A capable ACP session keeps
|
|
1895
1904
|
// its terminal contract and still folds.
|
|
1896
1905
|
if (!pty && ownedManager && !clientTerminalActive) {
|
|
1897
|
-
// With auto-background off, wait
|
|
1898
|
-
// leaves the foreground on an explicit Ctrl+B
|
|
1906
|
+
// With auto-background off, the foreground wait has no timer threshold, so the job
|
|
1907
|
+
// only leaves the foreground on an explicit Ctrl+B or steer fold.
|
|
1899
1908
|
const autoBackgroundWaitMs = this.#autoBackgroundEnabled
|
|
1900
1909
|
? this.#resolveAutoBackgroundWaitMs(timeoutMs)
|
|
1901
|
-
:
|
|
1910
|
+
: undefined;
|
|
1902
1911
|
const startBackgrounded = autoBackgroundWaitMs === 0;
|
|
1903
1912
|
let managedForegroundSettled = false;
|
|
1904
1913
|
const job = this.#startManagedBashJob({
|
|
@@ -2600,7 +2609,7 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
|
2600
2609
|
try {
|
|
2601
2610
|
bridgeWait = await this.#waitForManagedBashJob(
|
|
2602
2611
|
bridgeHandle,
|
|
2603
|
-
this.#autoBackgroundEnabled ? this.#resolveAutoBackgroundWaitMs(timeoutMs) :
|
|
2612
|
+
this.#autoBackgroundEnabled ? this.#resolveAutoBackgroundWaitMs(timeoutMs) : undefined,
|
|
2604
2613
|
signal,
|
|
2605
2614
|
bridgeFoldRequest.promise,
|
|
2606
2615
|
bridgeFoldAdapter,
|
|
@@ -736,6 +736,35 @@ describe("tool descriptor compatibility gate", () => {
|
|
|
736
736
|
}),
|
|
737
737
|
).toThrow('Validation failed for tool "ask"');
|
|
738
738
|
});
|
|
739
|
+
test("loaded and deferred asks reject missing interview metadata and empty siblings with actionable corrections", async () => {
|
|
740
|
+
for (const stage of ["topology", "post-topology"] as const) {
|
|
741
|
+
const session = makeSession({ "tools.discoveryMode": "all" });
|
|
742
|
+
session.hasUI = true;
|
|
743
|
+
session.getDeepInterviewAskStage = () => stage;
|
|
744
|
+
const eager = await BUILTIN_TOOL_DESCRIPTORS.ask.load(session);
|
|
745
|
+
const lazy = (await createTools(session)).find(tool => tool.name === "ask");
|
|
746
|
+
if (!eager || !lazy) throw new Error("expected eager and deferred asks");
|
|
747
|
+
const ordinary = {
|
|
748
|
+
id: "dot-gjc-topology",
|
|
749
|
+
question: "Round 0 | Topology confirmation\n\nDoes this scope match?",
|
|
750
|
+
options: [{ label: "Looks right" }],
|
|
751
|
+
workflowGate: { stage: "deep-interview", kind: "question" },
|
|
752
|
+
};
|
|
753
|
+
for (const [arguments_, correction] of [
|
|
754
|
+
[{ questions: [ordinary] }, "require structured deepInterview metadata"],
|
|
755
|
+
[{ questions: [{ ...ordinary, deepInterview: null }] }, "require structured deepInterview metadata"],
|
|
756
|
+
[{ questions: [ordinary, { id: "metadata", question: "", options: [] }] }, "remove empty extra questions"],
|
|
757
|
+
[{ questions: [ordinary, ordinary] }, "require exactly one question"],
|
|
758
|
+
] as const) {
|
|
759
|
+
for (const tool of [eager, lazy]) {
|
|
760
|
+
expect(() =>
|
|
761
|
+
validateToolArguments(tool, { type: "toolCall", id: "incident", name: "ask", arguments: arguments_ }),
|
|
762
|
+
).toThrow(correction);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
|
|
739
768
|
test("deferred ask validation matches eager AskTool on adversarial contracts", async () => {
|
|
740
769
|
const session = makeSession({ "tools.discoveryMode": "all" });
|
|
741
770
|
session.hasUI = true;
|
|
@@ -310,7 +310,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
310
310
|
"ask": {
|
|
311
311
|
"name": "ask",
|
|
312
312
|
"label": "Ask",
|
|
313
|
-
"description": "Asks user when you need clarification or input during task execution.\n\n<conditions>\n- Multiple approaches exist with significantly different tradeoffs user should weigh\n</conditions>\n\n<instruction>\n- Use `recommended: <index>` to mark default (0-indexed); \" (Recommended)\" added automatically\n- Use `questions` for multiple related questions instead of asking one at a time\n- Set `multi: true` on question to allow multiple selections\n</instruction>\n\n<caution>\n- Provide 2-5 concise, distinct options\n</caution>\n\n<critical>\n- **Default to action.** Resolve ambiguity yourself using repo conventions, existing patterns, and reasonable defaults. Exhaust existing sources (code, configs, docs, history) before asking. Only ask when options have materially different tradeoffs the user must decide.\n- **If multiple choices are acceptable**, pick the most conservative/standard option and proceed; state the choice.\n- **Do NOT include the automatic custom-input control or labels that imitate it** such as \"Other (type your own)\", \"Other (specify)\", \"type your own\", \"custom input\", or \"직접 입력\" — UI automatically adds \"Other (type your own)\" to every question. A plain domain value such as \"Other\" is allowed when it is a genuine answer, not a request for free text. To collect free text, ask for it in the question body and rely on the automatic Other/custom-input control instead of adding a fake option.\n</critical>\n\n<examples>\n# Single question\nquestions: [{\"id\": \"auth_method\", \"question\": \"Which authentication method should this API use?\", \"options\": [{\"label\": \"JWT\"}, {\"label\": \"OAuth2\"}, {\"label\": \"Session cookies\"}], \"recommended\": 0}]\n\n# Multiple questions\nquestions: [{\"id\": \"storage_type\", \"question\": \"Which storage backend?\", \"options\": [{\"label\": \"SQLite\"}, {\"label\": \"PostgreSQL\"}]}, {\"id\": \"auth_method\", \"question\": \"Which auth method?\", \"options\": [{\"label\": \"JWT\"}, {\"label\": \"Session cookies\"}]}]\n</examples>",
|
|
313
|
+
"description": "Asks user when you need clarification or input during task execution.\n\n<conditions>\n- Multiple approaches exist with significantly different tradeoffs user should weigh\n</conditions>\n\n<instruction>\n- Use `recommended: <index>` to mark default (0-indexed); \" (Recommended)\" added automatically\n- Use `questions` for multiple related questions instead of asking one at a time\n- Set `multi: true` on question to allow multiple selections\n- Every question body must contain meaningful, non-whitespace text. Never add empty `metadata`/`ignore` questions.\n- While deep-interview is in the `interviewing` phase, submit exactly one question with the required `deepInterview` metadata on that question. Round 0 needs `round: 0`, `component: \"review-topology\"`, `dimension: \"topology\"`, `ambiguity`, and `intent_contract` containing the displayed items and affirmative labels. Later questions need a positive round, component, dimension, and ambiguity. Question prose and `workflowGate` alone cannot record an interview answer. After final-spec persistence transitions to `handoff`, next-workflow/approval choices are ordinary asks without interview round metadata.\n</instruction>\n\n<caution>\n- Provide 2-5 concise, distinct options\n</caution>\n\n<critical>\n- **Default to action.** Resolve ambiguity yourself using repo conventions, existing patterns, and reasonable defaults. Exhaust existing sources (code, configs, docs, history) before asking. Only ask when options have materially different tradeoffs the user must decide.\n- **If multiple choices are acceptable**, pick the most conservative/standard option and proceed; state the choice.\n- **Do NOT include the automatic custom-input control or labels that imitate it** such as \"Other (type your own)\", \"Other (specify)\", \"type your own\", \"custom input\", or \"직접 입력\" — UI automatically adds \"Other (type your own)\" to every question. A plain domain value such as \"Other\" is allowed when it is a genuine answer, not a request for free text. To collect free text, ask for it in the question body and rely on the automatic Other/custom-input control instead of adding a fake option.\n</critical>\n\n<examples>\n# Single question\nquestions: [{\"id\": \"auth_method\", \"question\": \"Which authentication method should this API use?\", \"options\": [{\"label\": \"JWT\"}, {\"label\": \"OAuth2\"}, {\"label\": \"Session cookies\"}], \"recommended\": 0}]\n\n# Multiple questions\nquestions: [{\"id\": \"storage_type\", \"question\": \"Which storage backend?\", \"options\": [{\"label\": \"SQLite\"}, {\"label\": \"PostgreSQL\"}]}, {\"id\": \"auth_method\", \"question\": \"Which auth method?\", \"options\": [{\"label\": \"JWT\"}, {\"label\": \"Session cookies\"}]}]\n</examples>",
|
|
314
314
|
"parameters": {
|
|
315
315
|
"type": "object",
|
|
316
316
|
"properties": {
|
|
@@ -326,7 +326,8 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
326
326
|
},
|
|
327
327
|
"question": {
|
|
328
328
|
"type": "string",
|
|
329
|
-
"
|
|
329
|
+
"minLength": 1,
|
|
330
|
+
"description": "non-empty question text"
|
|
330
331
|
},
|
|
331
332
|
"options": {
|
|
332
333
|
"type": "array",
|
|
@@ -2660,7 +2661,8 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2660
2661
|
"description": "recency filter"
|
|
2661
2662
|
},
|
|
2662
2663
|
"limit": {
|
|
2663
|
-
"type": "
|
|
2664
|
+
"type": "integer",
|
|
2665
|
+
"minimum": 1,
|
|
2664
2666
|
"description": "max results"
|
|
2665
2667
|
},
|
|
2666
2668
|
"max_tokens": {
|
|
@@ -2672,7 +2674,8 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2672
2674
|
"description": "sampling temperature"
|
|
2673
2675
|
},
|
|
2674
2676
|
"num_search_results": {
|
|
2675
|
-
"type": "
|
|
2677
|
+
"type": "integer",
|
|
2678
|
+
"minimum": 1,
|
|
2676
2679
|
"description": "number of search results"
|
|
2677
2680
|
},
|
|
2678
2681
|
"xai_search_mode": {
|
package/src/web/search/index.ts
CHANGED
|
@@ -44,10 +44,10 @@ import {
|
|
|
44
44
|
export const webSearchSchema = z.object({
|
|
45
45
|
query: z.string().describe("search query"),
|
|
46
46
|
recency: z.enum(["day", "week", "month", "year"]).describe("recency filter").optional(),
|
|
47
|
-
limit: z.number().describe("max results").optional(),
|
|
47
|
+
limit: z.number().int().min(1).describe("max results").optional(),
|
|
48
48
|
max_tokens: z.number().describe("max output tokens").optional(),
|
|
49
49
|
temperature: z.number().describe("sampling temperature").optional(),
|
|
50
|
-
num_search_results: z.number().describe("number of search results").optional(),
|
|
50
|
+
num_search_results: z.number().int().min(1).describe("number of search results").optional(),
|
|
51
51
|
xai_search_mode: z
|
|
52
52
|
.enum(["web", "x", "web_and_x"])
|
|
53
53
|
.describe("xAI only: use web_search, x_search, or both")
|