feat(coding-agent/tools): added examples to coding-agent tools
- Added `examples` support to `StringEnum` schemas and propagated it to tool metadata. - Added concise descriptions and example values across coding-agent tool schemas for clearer guidance. - Documented the new StringEnum examples capability in `packages/ai/CHANGELOG.md`. - Cast `real` to `HASHLINE_BIGRAMS` elements in `staleBigramFor` test setup.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added an `examples` option to `StringEnum` to include example values in the generated schema
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed parsing of JSON tool arguments containing raw control characters inside string values (such as embedded newlines) by escaping them before JSON parsing
|
||||
|
||||
@@ -17,13 +17,14 @@ import { isJsonObject } from "./types";
|
||||
*/
|
||||
export function StringEnum<const T extends readonly string[]>(
|
||||
values: T,
|
||||
options?: { description?: string; default?: T[number] },
|
||||
options?: { description?: string; default?: T[number]; examples?: readonly T[number][] },
|
||||
): TUnsafe<T[number]> {
|
||||
return Type.Unsafe<T[number]>({
|
||||
type: "string",
|
||||
enum: values as unknown as string[],
|
||||
...(options?.description && { description: options.description }),
|
||||
...(options?.default && { default: options.default }),
|
||||
...(options?.examples && { examples: options.examples }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@ import {
|
||||
// Schema
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const linesSchema = Type.Union([Type.Array(Type.String()), Type.String()]);
|
||||
const linesSchema = Type.Union([Type.Array(Type.String()), Type.String()], {
|
||||
description: "replacement lines",
|
||||
});
|
||||
|
||||
/**
|
||||
* Flat entry shape: every op key is optional, and the runtime validator
|
||||
@@ -65,7 +67,7 @@ const linesSchema = Type.Union([Type.Array(Type.String()), Type.String()]);
|
||||
*/
|
||||
export const atomEditSchema = Type.Object(
|
||||
{
|
||||
path: Type.Optional(Type.String({ description: "file path override" })),
|
||||
path: Type.Optional(Type.String({ description: "file path override", examples: ["src/foo.ts"] })),
|
||||
// Exactly one of the following op keys is required per entry:
|
||||
set: Type.Optional(
|
||||
Type.Union([
|
||||
@@ -81,15 +83,23 @@ export const atomEditSchema = Type.Object(
|
||||
del: Type.Optional(Type.String({ description: "line anchor to delete", examples: ["5#aa"] })),
|
||||
sub: Type.Optional(Type.String({ description: "line anchor to rewrite", examples: ["5#aa"] })),
|
||||
ins: Type.Optional(
|
||||
Type.String({ description: "line anchor to overwrite from a substring to end-of-line", examples: ["5#aa"] }),
|
||||
Type.String({ description: "line anchor to overwrite", examples: ["5#aa"] }),
|
||||
),
|
||||
append: Type.Optional(
|
||||
Type.Union([Type.Array(Type.String()), Type.String()], { description: "lines to append at EOF" }),
|
||||
),
|
||||
prepend: Type.Optional(
|
||||
Type.Union([Type.Array(Type.String()), Type.String()], { description: "lines to prepend at BOF" }),
|
||||
),
|
||||
append: Type.Optional(linesSchema),
|
||||
prepend: Type.Optional(linesSchema),
|
||||
// Payload (used by set/before/after/sub/ins/append/prepend):
|
||||
lines: Type.Optional(linesSchema),
|
||||
lines: Type.Optional(
|
||||
Type.Union([Type.Array(Type.String()), Type.String()], {
|
||||
description: "replacement payload",
|
||||
}),
|
||||
),
|
||||
find: Type.Optional(
|
||||
Type.String({
|
||||
description: "shortest substring on the anchored line that must occur exactly once",
|
||||
description: "unique substring on anchor line",
|
||||
examples: ["if("],
|
||||
}),
|
||||
),
|
||||
@@ -99,8 +109,8 @@ export const atomEditSchema = Type.Object(
|
||||
|
||||
export const atomEditParamsSchema = Type.Object(
|
||||
{
|
||||
path: Type.Optional(Type.String({ description: "Default file path used when an edit omits its own `path`" })),
|
||||
edits: Type.Array(atomEditSchema, { description: "edits" }),
|
||||
path: Type.Optional(Type.String({ description: "default file path for edits" })),
|
||||
edits: Type.Array(atomEditSchema, { description: "edit ops" }),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
@@ -32,19 +32,19 @@ import { ToolAbortError } from "./tool-errors";
|
||||
// =============================================================================
|
||||
|
||||
const OptionItem = Type.Object({
|
||||
label: Type.String({ description: "Display label" }),
|
||||
label: Type.String({ description: "display label" }),
|
||||
});
|
||||
|
||||
const QuestionItem = Type.Object({
|
||||
id: Type.String({ description: "Question ID, e.g. 'auth', 'cache'" }),
|
||||
question: Type.String({ description: "Question text" }),
|
||||
options: Type.Array(OptionItem, { description: "Available options" }),
|
||||
multi: Type.Optional(Type.Boolean({ description: "Allow multiple selections" })),
|
||||
recommended: Type.Optional(Type.Number({ description: "Index of recommended option (0-indexed)" })),
|
||||
id: Type.String({ description: "question id", examples: ["auth", "cache"] }),
|
||||
question: Type.String({ description: "question text" }),
|
||||
options: Type.Array(OptionItem, { description: "available options" }),
|
||||
multi: Type.Optional(Type.Boolean({ description: "allow multiple selections" })),
|
||||
recommended: Type.Optional(Type.Number({ description: "recommended option index" })),
|
||||
});
|
||||
|
||||
const askSchema = Type.Object({
|
||||
questions: Type.Array(QuestionItem, { description: "Questions to ask", minItems: 1 }),
|
||||
questions: Type.Array(QuestionItem, { description: "questions to ask", minItems: 1 }),
|
||||
});
|
||||
|
||||
export type AskToolInput = Static<typeof askSchema>;
|
||||
|
||||
@@ -36,20 +36,30 @@ import { ToolError } from "./tool-errors";
|
||||
import { toolResult } from "./tool-result";
|
||||
|
||||
const astEditOpSchema = Type.Object({
|
||||
pat: Type.String({ description: "AST pattern to match" }),
|
||||
out: Type.String({ description: "Replacement template" }),
|
||||
pat: Type.String({ description: "ast pattern", examples: ["oldFn($$$ARGS)"] }),
|
||||
out: Type.String({ description: "replacement template", examples: ["newFn($$$ARGS)"] }),
|
||||
});
|
||||
|
||||
const astEditSchema = Type.Object({
|
||||
ops: Type.Array(astEditOpSchema, {
|
||||
minItems: 1,
|
||||
description: "Rewrite ops as [{ pat, out }]",
|
||||
description: "rewrite ops",
|
||||
}),
|
||||
lang: Type.Optional(Type.String({ description: "Language override" })),
|
||||
path: Type.Optional(Type.String({ description: "File, directory, or glob pattern to rewrite (default: cwd)" })),
|
||||
glob: Type.Optional(Type.String({ description: "Optional glob filter relative to path" })),
|
||||
sel: Type.Optional(Type.String({ description: "Optional selector for contextual pattern mode" })),
|
||||
limit: Type.Optional(Type.Number({ description: "Max total replacements" })),
|
||||
lang: Type.Optional(Type.String({ description: "language override", examples: ["typescript", "python"] })),
|
||||
path: Type.Optional(
|
||||
Type.String({
|
||||
description: "path or glob to rewrite",
|
||||
examples: ["src/", "src/foo.ts"],
|
||||
}),
|
||||
),
|
||||
glob: Type.Optional(Type.String({ description: "glob filter", examples: ["**/*.ts"] })),
|
||||
sel: Type.Optional(
|
||||
Type.String({
|
||||
description: "contextual pattern selector",
|
||||
examples: ["function_declaration", "call_expression", "identifier"],
|
||||
}),
|
||||
),
|
||||
limit: Type.Optional(Type.Number({ description: "max replacements" })),
|
||||
});
|
||||
|
||||
export interface AstEditToolDetails {
|
||||
|
||||
@@ -35,14 +35,28 @@ import { ToolError } from "./tool-errors";
|
||||
import { toolResult } from "./tool-result";
|
||||
|
||||
const astGrepSchema = Type.Object({
|
||||
pat: Type.Array(Type.String(), { minItems: 1, description: "AST patterns to match" }),
|
||||
lang: Type.Optional(Type.String({ description: "Language override" })),
|
||||
path: Type.Optional(Type.String({ description: "File, directory, or glob pattern to search (default: cwd)" })),
|
||||
glob: Type.Optional(Type.String({ description: "Optional glob filter relative to path" })),
|
||||
sel: Type.Optional(Type.String({ description: "Optional selector for contextual pattern mode" })),
|
||||
limit: Type.Optional(Type.Number({ description: "Max matches", default: 50 })),
|
||||
offset: Type.Optional(Type.Number({ description: "Skip first N matches", default: 0 })),
|
||||
context: Type.Optional(Type.Number({ description: "Context lines around each match" })),
|
||||
pat: Type.Array(Type.String(), {
|
||||
minItems: 1,
|
||||
description: "ast patterns",
|
||||
examples: [["console.log($$$)"]],
|
||||
}),
|
||||
lang: Type.Optional(Type.String({ description: "language override", examples: ["typescript", "python"] })),
|
||||
path: Type.Optional(
|
||||
Type.String({
|
||||
description: "path or glob to search",
|
||||
examples: ["src/", "src/foo.ts"],
|
||||
}),
|
||||
),
|
||||
glob: Type.Optional(Type.String({ description: "glob filter", examples: ["**/*.ts"] })),
|
||||
sel: Type.Optional(
|
||||
Type.String({
|
||||
description: "contextual pattern selector",
|
||||
examples: ["function_declaration", "call_expression", "identifier"],
|
||||
}),
|
||||
),
|
||||
limit: Type.Optional(Type.Number({ description: "max matches", default: 50 })),
|
||||
offset: Type.Optional(Type.Number({ description: "skip first n matches", default: 0 })),
|
||||
context: Type.Optional(Type.Number({ description: "context lines" })),
|
||||
});
|
||||
|
||||
export interface AstGrepToolDetails {
|
||||
|
||||
@@ -42,20 +42,19 @@ async function saveBashOriginalArtifact(session: ToolSession, originalText: stri
|
||||
}
|
||||
|
||||
const bashSchemaBase = Type.Object({
|
||||
command: Type.String({ description: "Command to execute" }),
|
||||
command: Type.String({ description: "command to execute", examples: ["ls -la", "echo hi"] }),
|
||||
env: Type.Optional(
|
||||
Type.Record(Type.String({ pattern: BASH_ENV_NAME_PATTERN.source }), Type.String(), {
|
||||
description:
|
||||
"Additional environment variables passed to the command and rendered inline as shell assignments; prefer this for multiline or quote-heavy content",
|
||||
description: "extra env vars",
|
||||
}),
|
||||
),
|
||||
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds", default: 300 })),
|
||||
cwd: Type.Optional(Type.String({ description: "Working directory (default: cwd)" })),
|
||||
head: Type.Optional(Type.Number({ description: "Return only first N lines of output" })),
|
||||
tail: Type.Optional(Type.Number({ description: "Return only last N lines of output" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "timeout in seconds", default: 300 })),
|
||||
cwd: Type.Optional(Type.String({ description: "working directory", examples: ["src/", "/tmp"] })),
|
||||
head: Type.Optional(Type.Number({ description: "first n lines of output" })),
|
||||
tail: Type.Optional(Type.Number({ description: "last n lines of output" })),
|
||||
pty: Type.Optional(
|
||||
Type.Boolean({
|
||||
description: "Run in PTY mode when command needs a real terminal (e.g. sudo/ssh/top/less); default: false",
|
||||
description: "run in pty mode",
|
||||
}),
|
||||
),
|
||||
});
|
||||
@@ -64,7 +63,7 @@ const bashSchemaWithAsync = Type.Object({
|
||||
...bashSchemaBase.properties,
|
||||
async: Type.Optional(
|
||||
Type.Boolean({
|
||||
description: "Run in background; returns immediately with a job ID. Result delivered as follow-up.",
|
||||
description: "run in background",
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -361,12 +361,12 @@ function resolvePageClient(page: Page): PuppeteerCdpClient | null {
|
||||
const puppeteerGetArgsSchema = Type.Array(
|
||||
Type.Object({
|
||||
selector: Type.String({
|
||||
description:
|
||||
"Selector for the target element (CSS, or puppeteer query handler like aria/, text/, xpath/, pierce/; also accepts legacy p- prefixes)",
|
||||
description: "target element selector",
|
||||
examples: ["aria/Sign in", "text/Continue", "xpath/...", "pierce/..."],
|
||||
}),
|
||||
attribute: Type.Optional(Type.String({ description: "Attribute name (get_attribute)" })),
|
||||
attribute: Type.Optional(Type.String({ description: "attribute name", examples: ["href", "data-id"] })),
|
||||
}),
|
||||
{ description: "Batch arguments for get_* actions", minItems: 1 },
|
||||
{ description: "batch get_* args", minItems: 1 },
|
||||
);
|
||||
|
||||
const browserSchema = Type.Object({
|
||||
@@ -393,56 +393,56 @@ const browserSchema = Type.Object({
|
||||
"screenshot",
|
||||
"close",
|
||||
],
|
||||
{ description: "Action to perform" },
|
||||
{ description: "action to perform" },
|
||||
),
|
||||
url: Type.Optional(Type.String({ description: "URL to navigate to (goto)" })),
|
||||
url: Type.Optional(Type.String({ description: "url to navigate to", examples: ["https://example.com"] })),
|
||||
selector: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Selector for the target element (CSS, or puppeteer query handler like aria/, text/, xpath/, pierce/; also accepts legacy p- prefixes)",
|
||||
description: "target element selector",
|
||||
examples: ["aria/Sign in", "text/Continue", "xpath/...", "pierce/..."],
|
||||
}),
|
||||
),
|
||||
element_id: Type.Optional(Type.Number({ description: "Element ID from observe" })),
|
||||
include_all: Type.Optional(Type.Boolean({ description: "Include non-interactive nodes in observe" })),
|
||||
viewport_only: Type.Optional(Type.Boolean({ description: "Limit observe output to elements in the viewport" })),
|
||||
element_id: Type.Optional(Type.Number({ description: "observed element id" })),
|
||||
include_all: Type.Optional(Type.Boolean({ description: "include non-interactive nodes" })),
|
||||
viewport_only: Type.Optional(Type.Boolean({ description: "limit to viewport" })),
|
||||
args: Type.Optional(puppeteerGetArgsSchema),
|
||||
script: Type.Optional(Type.String({ description: "JavaScript to evaluate (evaluate)" })),
|
||||
text: Type.Optional(Type.String({ description: "Text to type (type)" })),
|
||||
value: Type.Optional(Type.String({ description: "Value to set (fill)" })),
|
||||
attribute: Type.Optional(Type.String({ description: "Attribute name to read (get_attribute)" })),
|
||||
key: Type.Optional(Type.String({ description: "Keyboard key to press (press)" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds", default: 30 })),
|
||||
script: Type.Optional(Type.String({ description: "javascript expression", examples: ["document.title", "window.location.href"] })),
|
||||
text: Type.Optional(Type.String({ description: "text to type", examples: ["hello world"] })),
|
||||
value: Type.Optional(Type.String({ description: "value to set", examples: ["hello"] })),
|
||||
attribute: Type.Optional(Type.String({ description: "attribute to read", examples: ["href", "data-id"] })),
|
||||
key: Type.Optional(Type.String({ description: "keyboard key", examples: ["Enter", "Tab", "Escape"] })),
|
||||
timeout: Type.Optional(Type.Number({ description: "timeout in seconds", default: 30 })),
|
||||
wait_until: Type.Optional(
|
||||
StringEnum(["load", "domcontentloaded", "networkidle0", "networkidle2"], {
|
||||
description: "Navigation wait condition (goto)",
|
||||
description: "navigation wait condition",
|
||||
}),
|
||||
),
|
||||
full_page: Type.Optional(Type.Boolean({ description: "Capture full page screenshot (screenshot)" })),
|
||||
full_page: Type.Optional(Type.Boolean({ description: "full page screenshot" })),
|
||||
format: Type.Optional(
|
||||
StringEnum(["text", "markdown"], {
|
||||
description: "Output format for extract_readable (text/markdown)",
|
||||
description: "output format",
|
||||
}),
|
||||
),
|
||||
path: Type.Optional(Type.String({ description: "Optional path to save screenshot (relative to cwd)" })),
|
||||
path: Type.Optional(Type.String({ description: "screenshot save path", examples: ["out.png"] })),
|
||||
viewport: Type.Optional(
|
||||
Type.Object({
|
||||
width: Type.Number({ description: "Viewport width in pixels" }),
|
||||
height: Type.Number({ description: "Viewport height in pixels" }),
|
||||
device_scale_factor: Type.Optional(Type.Number({ description: "Device scale factor" })),
|
||||
width: Type.Number({ description: "viewport width" }),
|
||||
height: Type.Number({ description: "viewport height" }),
|
||||
device_scale_factor: Type.Optional(Type.Number({ description: "device scale factor" })),
|
||||
}),
|
||||
),
|
||||
delta_x: Type.Optional(Type.Number({ description: "Scroll delta X (scroll)" })),
|
||||
delta_y: Type.Optional(Type.Number({ description: "Scroll delta Y (scroll)" })),
|
||||
delta_x: Type.Optional(Type.Number({ description: "scroll delta x" })),
|
||||
delta_y: Type.Optional(Type.Number({ description: "scroll delta y" })),
|
||||
from_selector: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Drag start selector (CSS, or puppeteer query handler like aria/, text/, xpath/, pierce/; also accepts legacy p- prefixes)",
|
||||
description: "drag start selector",
|
||||
examples: ["aria/Drag handle"],
|
||||
}),
|
||||
),
|
||||
to_selector: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Drag end selector (CSS, or puppeteer query handler like aria/, text/, xpath/, pierce/; also accepts legacy p- prefixes)",
|
||||
description: "drag end selector",
|
||||
examples: ["text/Drop zone"],
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -31,11 +31,11 @@ type Token =
|
||||
const calculatorSchema = Type.Object({
|
||||
calculations: Type.Array(
|
||||
Type.Object({
|
||||
expression: Type.String({ description: "Math expression to evaluate" }),
|
||||
prefix: Type.String({ description: "Text to prepend to the result" }),
|
||||
suffix: Type.String({ description: "Text to append to the result" }),
|
||||
expression: Type.String({ description: "math expression", examples: ["2 + 2", "sqrt(16)"] }),
|
||||
prefix: Type.String({ description: "prefix text" }),
|
||||
suffix: Type.String({ description: "suffix text" }),
|
||||
}),
|
||||
{ description: "List of calculations to evaluate" },
|
||||
{ description: "calculations to evaluate" },
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import cancelJobDescription from "../prompts/tools/cancel-job.md" with { type: "
|
||||
import type { ToolSession } from "./index";
|
||||
|
||||
const cancelJobSchema = Type.Object({
|
||||
job_id: Type.String({ description: "Background job ID" }),
|
||||
job_id: Type.String({ description: "background job id", examples: ["job-1234"] }),
|
||||
});
|
||||
|
||||
type CancelJobParams = Static<typeof cancelJobSchema>;
|
||||
|
||||
@@ -18,13 +18,13 @@ export interface CheckpointState {
|
||||
}
|
||||
|
||||
const checkpointSchema = Type.Object({
|
||||
goal: Type.String({ description: "What you are investigating and why" }),
|
||||
goal: Type.String({ description: "investigation goal", examples: ["investigate retry logic"] }),
|
||||
});
|
||||
|
||||
type CheckpointParams = Static<typeof checkpointSchema>;
|
||||
|
||||
const rewindSchema = Type.Object({
|
||||
report: Type.String({ description: "Concise investigation findings to retain after rewind" }),
|
||||
report: Type.String({ description: "investigation findings" }),
|
||||
});
|
||||
|
||||
type RewindParams = Static<typeof rewindSchema>;
|
||||
|
||||
@@ -83,51 +83,51 @@ const debugSchema = Type.Object({
|
||||
"terminate",
|
||||
"sessions",
|
||||
],
|
||||
{ description: "DAP debugger action" },
|
||||
{ description: "dap debugger action" },
|
||||
),
|
||||
program: Type.Optional(Type.String({ description: "Program or script path for launch" })),
|
||||
args: Type.Optional(Type.Array(Type.String(), { description: "Program arguments for launch" })),
|
||||
adapter: Type.Optional(Type.String({ description: "Debugger adapter override (gdb, lldb-dap, debugpy, dlv)" })),
|
||||
cwd: Type.Optional(Type.String({ description: "Working directory for launch or attach" })),
|
||||
file: Type.Optional(Type.String({ description: "Source file for source breakpoints" })),
|
||||
line: Type.Optional(Type.Number({ description: "1-indexed source line for source breakpoints" })),
|
||||
function: Type.Optional(Type.String({ description: "Function name for function breakpoints" })),
|
||||
name: Type.Optional(Type.String({ description: "Variable or data name for data breakpoint info" })),
|
||||
condition: Type.Optional(Type.String({ description: "Breakpoint condition expression" })),
|
||||
hit_condition: Type.Optional(Type.String({ description: "Breakpoint hit condition expression" })),
|
||||
expression: Type.Optional(Type.String({ description: "Expression to evaluate in debugger context" })),
|
||||
context: Type.Optional(Type.String({ description: "Evaluate context (watch, repl, hover, variables, clipboard)" })),
|
||||
frame_id: Type.Optional(Type.Number({ description: "Stack frame ID for scopes/evaluate" })),
|
||||
scope_id: Type.Optional(Type.Number({ description: "Scope variablesReference for variables requests" })),
|
||||
variable_ref: Type.Optional(Type.Number({ description: "Variable reference for variables requests" })),
|
||||
pid: Type.Optional(Type.Number({ description: "Process ID for attach" })),
|
||||
port: Type.Optional(Type.Number({ description: "Port for remote attach when adapter supports it" })),
|
||||
host: Type.Optional(Type.String({ description: "Host for remote attach when adapter supports it" })),
|
||||
levels: Type.Optional(Type.Number({ description: "Maximum stack frames to fetch" })),
|
||||
memory_reference: Type.Optional(Type.String({ description: "Memory reference or address" })),
|
||||
program: Type.Optional(Type.String({ description: "program path", examples: ["./my_app", "src/main.py"] })),
|
||||
args: Type.Optional(Type.Array(Type.String(), { description: "program arguments", examples: [["--verbose"]] })),
|
||||
adapter: Type.Optional(Type.String({ description: "debugger adapter", examples: ["gdb", "lldb-dap", "debugpy", "dlv"] })),
|
||||
cwd: Type.Optional(Type.String({ description: "working directory", examples: ["src/"] })),
|
||||
file: Type.Optional(Type.String({ description: "source file", examples: ["src/main.c"] })),
|
||||
line: Type.Optional(Type.Number({ description: "source line", examples: [42] })),
|
||||
function: Type.Optional(Type.String({ description: "function name", examples: ["main", "handle_request"] })),
|
||||
name: Type.Optional(Type.String({ description: "variable or data name", examples: ["counter", "buffer"] })),
|
||||
condition: Type.Optional(Type.String({ description: "breakpoint condition", examples: ["i == 10", "x > 0"] })),
|
||||
hit_condition: Type.Optional(Type.String({ description: "hit condition" })),
|
||||
expression: Type.Optional(Type.String({ description: "expression to evaluate", examples: ["x + 1", "obj.field"] })),
|
||||
context: Type.Optional(Type.String({ description: "evaluate context", examples: ["watch", "repl", "hover", "variables", "clipboard"] })),
|
||||
frame_id: Type.Optional(Type.Number({ description: "stack frame id" })),
|
||||
scope_id: Type.Optional(Type.Number({ description: "scope variables reference" })),
|
||||
variable_ref: Type.Optional(Type.Number({ description: "variable reference" })),
|
||||
pid: Type.Optional(Type.Number({ description: "process id for attach", examples: [12345] })),
|
||||
port: Type.Optional(Type.Number({ description: "remote attach port", examples: [4711] })),
|
||||
host: Type.Optional(Type.String({ description: "remote attach host", examples: ["127.0.0.1"] })),
|
||||
levels: Type.Optional(Type.Number({ description: "max stack frames" })),
|
||||
memory_reference: Type.Optional(Type.String({ description: "memory reference or address", examples: ["0x7ffd1234"] })),
|
||||
instruction_reference: Type.Optional(
|
||||
Type.String({ description: "Instruction address/reference for instruction breakpoints" }),
|
||||
Type.String({ description: "instruction address or reference" }),
|
||||
),
|
||||
instruction_count: Type.Optional(Type.Number({ description: "Number of instructions to disassemble" })),
|
||||
instruction_offset: Type.Optional(Type.Number({ description: "Instruction offset for disassembly" })),
|
||||
count: Type.Optional(Type.Number({ description: "Number of bytes to read from memory" })),
|
||||
data: Type.Optional(Type.String({ description: "Base64-encoded memory payload for write_memory" })),
|
||||
data_id: Type.Optional(Type.String({ description: "DAP data breakpoint identifier" })),
|
||||
instruction_count: Type.Optional(Type.Number({ description: "instructions to disassemble" })),
|
||||
instruction_offset: Type.Optional(Type.Number({ description: "instruction offset" })),
|
||||
count: Type.Optional(Type.Number({ description: "bytes to read" })),
|
||||
data: Type.Optional(Type.String({ description: "base64 memory payload" })),
|
||||
data_id: Type.Optional(Type.String({ description: "data breakpoint id" })),
|
||||
access_type: Type.Optional(
|
||||
StringEnum(["read", "write", "readWrite"], { description: "Data breakpoint access type" }),
|
||||
StringEnum(["read", "write", "readWrite"], { description: "data breakpoint access type" }),
|
||||
),
|
||||
command: Type.Optional(Type.String({ description: "Custom DAP request command" })),
|
||||
command: Type.Optional(Type.String({ description: "custom dap request command" })),
|
||||
arguments: Type.Optional(
|
||||
Type.Record(Type.String(), Type.Any(), {
|
||||
description: "Arguments object for custom_request",
|
||||
description: "custom request arguments",
|
||||
}),
|
||||
),
|
||||
offset: Type.Optional(Type.Number({ description: "Memory or instruction offset" })),
|
||||
resolve_symbols: Type.Optional(Type.Boolean({ description: "Resolve symbols during disassembly" })),
|
||||
allow_partial: Type.Optional(Type.Boolean({ description: "Allow partial writes for write_memory" })),
|
||||
start_module: Type.Optional(Type.Number({ description: "Modules request start index" })),
|
||||
module_count: Type.Optional(Type.Number({ description: "Maximum modules to fetch" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "Per-request timeout in seconds" })),
|
||||
offset: Type.Optional(Type.Number({ description: "memory or instruction offset" })),
|
||||
resolve_symbols: Type.Optional(Type.Boolean({ description: "resolve symbols during disassembly" })),
|
||||
allow_partial: Type.Optional(Type.Boolean({ description: "allow partial writes" })),
|
||||
start_module: Type.Optional(Type.Number({ description: "modules start index" })),
|
||||
module_count: Type.Optional(Type.Number({ description: "max modules to fetch" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "per-request timeout seconds" })),
|
||||
});
|
||||
|
||||
export type DebugParams = Static<typeof debugSchema>;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { resolvePlanPath } from "./plan-mode-guard";
|
||||
import { ToolError } from "./tool-errors";
|
||||
|
||||
const exitPlanModeSchema = Type.Object({
|
||||
title: Type.String({ description: "Final plan title, e.g. WP_MIGRATION_PLAN" }),
|
||||
title: Type.String({ description: "final plan title", examples: ["WP_MIGRATION_PLAN"] }),
|
||||
});
|
||||
|
||||
type ExitPlanModeParams = Static<typeof exitPlanModeSchema>;
|
||||
|
||||
@@ -30,11 +30,11 @@ import { toolResult } from "./tool-result";
|
||||
|
||||
const findSchema = Type.Object({
|
||||
pattern: Type.String({
|
||||
description:
|
||||
"Glob pattern including the search path (no separate path param), e.g. 'src/**/*.ts', 'lib/*.json'. Supports comma-separated lists like 'apps/,packages/,phases/'. Simple patterns like '*.ts' recurse from cwd.",
|
||||
description: "glob including search path",
|
||||
examples: ["src/**/*.ts", "lib/*.json", "apps/,packages/", "*.ts"],
|
||||
}),
|
||||
hidden: Type.Optional(Type.Boolean({ description: "Include hidden files and directories", default: true })),
|
||||
limit: Type.Optional(Type.Number({ description: "Max results", default: 1000 })),
|
||||
hidden: Type.Optional(Type.Boolean({ description: "include hidden files", default: true })),
|
||||
limit: Type.Optional(Type.Number({ description: "max results", default: 1000 })),
|
||||
});
|
||||
|
||||
export type FindToolInput = Static<typeof findSchema>;
|
||||
|
||||
@@ -36,17 +36,19 @@ interface ImageApiKey {
|
||||
|
||||
const responseModalitySchema = StringEnum(["IMAGE", "TEXT"]);
|
||||
const aspectRatioSchema = StringEnum(["1:1", "3:4", "4:3", "9:16", "16:9"], {
|
||||
description: "Aspect ratio (1:1, 3:4, 4:3, 9:16, 16:9).",
|
||||
description: "aspect ratio",
|
||||
examples: ["1:1", "3:4", "16:9"],
|
||||
});
|
||||
const imageSizeSchema = StringEnum(["1024x1024", "1536x1024", "1024x1536"], {
|
||||
description: "Image size, mainly for gemini-3-pro-image-preview.",
|
||||
description: "image size",
|
||||
examples: ["1024x1024", "1536x1024"],
|
||||
});
|
||||
|
||||
const inputImageSchema = Type.Object(
|
||||
{
|
||||
path: Type.Optional(Type.String({ description: "Path to an input image file." })),
|
||||
data: Type.Optional(Type.String({ description: "Base64 image data or a data: URL." })),
|
||||
mime_type: Type.Optional(Type.String({ description: "Required for raw base64 data." })),
|
||||
path: Type.Optional(Type.String({ description: "input image path" })),
|
||||
data: Type.Optional(Type.String({ description: "base64 image data" })),
|
||||
mime_type: Type.Optional(Type.String({ description: "mime type" })),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
@@ -54,55 +56,56 @@ const inputImageSchema = Type.Object(
|
||||
const baseImageSchema = Type.Object(
|
||||
{
|
||||
subject: Type.String({
|
||||
description:
|
||||
"Main subject with key descriptors (e.g., 'A stoic robot barista with glowing blue optics', 'A weathered lighthouse on a rocky cliff').",
|
||||
description: "main subject",
|
||||
examples: ["a stoic robot barista", "a weathered lighthouse"],
|
||||
}),
|
||||
action: Type.Optional(
|
||||
Type.String({
|
||||
description: "What the subject is doing (e.g., 'pouring latte art', 'standing against crashing waves').",
|
||||
description: "what subject is doing",
|
||||
examples: ["pouring latte art", "standing against waves"],
|
||||
}),
|
||||
),
|
||||
scene: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Location or environment (e.g., 'in a futuristic café on Mars', 'during a violent thunderstorm at dusk').",
|
||||
description: "location or environment",
|
||||
examples: ["futuristic café on mars", "thunderstorm at dusk"],
|
||||
}),
|
||||
),
|
||||
composition: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Camera angle, framing, depth of field (e.g., 'low-angle close-up, shallow depth of field', 'wide establishing shot').",
|
||||
description: "camera angle and framing",
|
||||
examples: ["low-angle close-up", "wide establishing shot"],
|
||||
}),
|
||||
),
|
||||
lighting: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Lighting setup and mood (e.g., 'warm rim lighting', 'golden hour backlight', 'hard noon shadows').",
|
||||
description: "lighting setup",
|
||||
examples: ["warm rim lighting", "golden hour backlight"],
|
||||
}),
|
||||
),
|
||||
style: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Artistic style, mood, color grading, camera (e.g., 'film noir mood, cinematic color grading', 'Studio Ghibli watercolor', 'photorealistic').",
|
||||
description: "artistic style",
|
||||
examples: ["film noir", "studio ghibli watercolor", "photorealistic"],
|
||||
}),
|
||||
),
|
||||
text: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Text to render in image with specs: exact wording in quotes, font style, color, placement (e.g., 'Headline \"URBAN EXPLORER\" in bold white sans-serif at top center').",
|
||||
description: "text to render",
|
||||
examples: ["headline 'urban explorer' top center"],
|
||||
}),
|
||||
),
|
||||
changes: Type.Optional(
|
||||
Type.Array(Type.String(), {
|
||||
description:
|
||||
"For edits: specific changes to make, as well as, what to keep unchanged (e.g., ['Change the tie to green', 'Remove the car in background']). Use with input_images.",
|
||||
description: "edits to make",
|
||||
examples: [["change tie to green", "remove car"]],
|
||||
}),
|
||||
),
|
||||
aspect_ratio: Type.Optional(aspectRatioSchema),
|
||||
image_size: Type.Optional(imageSizeSchema),
|
||||
input: Type.Optional(
|
||||
Type.Array(inputImageSchema, {
|
||||
description: "Optional input images for edits or variations.",
|
||||
description: "input images",
|
||||
}),
|
||||
),
|
||||
},
|
||||
|
||||
@@ -138,70 +138,62 @@ const JOB_FAILURE_CONCLUSIONS = new Set(["failure", "timed_out", "cancelled", "a
|
||||
const ghRepoViewSchema = Type.Object({
|
||||
repo: Type.Optional(
|
||||
Type.String({
|
||||
description: "Repository in OWNER/REPO format. Defaults to the current GitHub repository context.",
|
||||
description: "owner/repo",
|
||||
examples: ["facebook/react"],
|
||||
}),
|
||||
),
|
||||
branch: Type.Optional(Type.String({ description: "Branch name to inspect instead of the default branch." })),
|
||||
branch: Type.Optional(Type.String({ description: "branch to inspect", examples: ["main", "develop"] })),
|
||||
});
|
||||
|
||||
const ghIssueViewSchema = Type.Object({
|
||||
issue: Type.String({ description: "Issue number or full GitHub issue URL." }),
|
||||
issue: Type.String({ description: "issue number or url", examples: ["123", "https://github.com/owner/repo/issues/123"] }),
|
||||
repo: Type.Optional(
|
||||
Type.String({ description: "Repository in OWNER/REPO format. Omit when passing a full issue URL." }),
|
||||
Type.String({ description: "owner/repo", examples: ["facebook/react"] }),
|
||||
),
|
||||
comments: Type.Optional(Type.Boolean({ description: "Include issue comments.", default: true })),
|
||||
comments: Type.Optional(Type.Boolean({ description: "include issue comments", default: true })),
|
||||
});
|
||||
|
||||
const ghPrViewSchema = Type.Object({
|
||||
pr: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Pull request number, full GitHub pull request URL, or branch name. Defaults to the current branch PR.",
|
||||
}),
|
||||
Type.String({ description: "pr number, url, or branch", examples: ["123", "feature-branch"] }),
|
||||
),
|
||||
repo: Type.Optional(
|
||||
Type.String({ description: "Repository in OWNER/REPO format. Omit when passing a full pull request URL." }),
|
||||
Type.String({ description: "owner/repo", examples: ["facebook/react"] }),
|
||||
),
|
||||
comments: Type.Optional(Type.Boolean({ description: "Include pull request comments.", default: true })),
|
||||
comments: Type.Optional(Type.Boolean({ description: "include pr comments", default: true })),
|
||||
});
|
||||
|
||||
const ghPrDiffSchema = Type.Object({
|
||||
pr: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Pull request number, full GitHub pull request URL, or branch name. Defaults to the current branch PR.",
|
||||
}),
|
||||
Type.String({ description: "pr number, url, or branch", examples: ["123", "feature-branch"] }),
|
||||
),
|
||||
repo: Type.Optional(
|
||||
Type.String({ description: "Repository in OWNER/REPO format. Omit when passing a full pull request URL." }),
|
||||
Type.String({ description: "owner/repo", examples: ["facebook/react"] }),
|
||||
),
|
||||
nameOnly: Type.Optional(
|
||||
Type.Boolean({ description: "Return only changed file names instead of unified diff output." }),
|
||||
Type.Boolean({ description: "return file names only" }),
|
||||
),
|
||||
exclude: Type.Optional(
|
||||
Type.Array(Type.String({ description: "Glob pattern for files to exclude from the diff." }), {
|
||||
description: "File globs to exclude from the diff output.",
|
||||
Type.Array(Type.String({ description: "glob to exclude" }), {
|
||||
description: "file globs to exclude",
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const ghPrCheckoutSchema = Type.Object({
|
||||
pr: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Pull request number, full GitHub pull request URL, or branch name. Defaults to the current branch PR.",
|
||||
}),
|
||||
Type.String({ description: "pr number, url, or branch", examples: ["123", "feature-branch"] }),
|
||||
),
|
||||
repo: Type.Optional(
|
||||
Type.String({ description: "Repository in OWNER/REPO format. Omit when passing a full pull request URL." }),
|
||||
Type.String({ description: "owner/repo", examples: ["facebook/react"] }),
|
||||
),
|
||||
branch: Type.Optional(Type.String({ description: "Local branch name to create or reuse (default: pr-<number>)." })),
|
||||
branch: Type.Optional(Type.String({ description: "local branch name", examples: ["main", "develop"] })),
|
||||
worktree: Type.Optional(
|
||||
Type.String({ description: "Worktree path to create. Defaults to <repo>/.worktrees/<branch>." }),
|
||||
Type.String({ description: "worktree path" }),
|
||||
),
|
||||
force: Type.Optional(
|
||||
Type.Boolean({
|
||||
description: "Reset an existing local branch to the PR head when it is not already checked out elsewhere.",
|
||||
description: "reset existing local branch",
|
||||
}),
|
||||
),
|
||||
});
|
||||
@@ -209,38 +201,37 @@ const ghPrCheckoutSchema = Type.Object({
|
||||
const ghPrPushSchema = Type.Object({
|
||||
branch: Type.Optional(
|
||||
Type.String({
|
||||
description: "Local branch name to push. Defaults to the current checked-out git branch.",
|
||||
description: "local branch name",
|
||||
examples: ["main", "develop"],
|
||||
}),
|
||||
),
|
||||
forceWithLease: Type.Optional(Type.Boolean({ description: "Use --force-with-lease when pushing the PR branch." })),
|
||||
forceWithLease: Type.Optional(Type.Boolean({ description: "force-with-lease push" })),
|
||||
});
|
||||
|
||||
const ghSearchIssuesSchema = Type.Object({
|
||||
query: Type.String({ description: "GitHub issue search query. Supports GitHub search syntax." }),
|
||||
repo: Type.Optional(Type.String({ description: "Repository in OWNER/REPO format to scope the search." })),
|
||||
limit: Type.Optional(Type.Number({ description: "Maximum results to return (max: 50).", default: 10 })),
|
||||
query: Type.String({ description: "issue search query", examples: ["is:open label:bug"] }),
|
||||
repo: Type.Optional(Type.String({ description: "scope to owner/repo" })),
|
||||
limit: Type.Optional(Type.Number({ description: "max results", default: 10 })),
|
||||
});
|
||||
|
||||
const ghSearchPrsSchema = Type.Object({
|
||||
query: Type.String({ description: "GitHub pull request search query. Supports GitHub search syntax." }),
|
||||
repo: Type.Optional(Type.String({ description: "Repository in OWNER/REPO format to scope the search." })),
|
||||
limit: Type.Optional(Type.Number({ description: "Maximum results to return (max: 50).", default: 10 })),
|
||||
query: Type.String({ description: "pr search query", examples: ["is:open label:bug"] }),
|
||||
repo: Type.Optional(Type.String({ description: "scope to owner/repo" })),
|
||||
limit: Type.Optional(Type.Number({ description: "max results", default: 10 })),
|
||||
});
|
||||
|
||||
const ghRunWatchSchema = Type.Object({
|
||||
run: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"GitHub Actions run ID or full run URL. Omitting this watches the workflow runs for the current HEAD commit on the selected branch.",
|
||||
}),
|
||||
Type.String({ description: "actions run id or url", examples: ["123456"] }),
|
||||
),
|
||||
branch: Type.Optional(
|
||||
Type.String({
|
||||
description: "Branch to inspect when omitting `run`. Defaults to the current checked-out git branch.",
|
||||
description: "branch to inspect",
|
||||
examples: ["main", "develop"],
|
||||
}),
|
||||
),
|
||||
tail: Type.Optional(
|
||||
Type.Number({ description: "Number of log lines to include per failed job (max: 200).", default: 15 }),
|
||||
Type.Number({ description: "log lines per failed job", default: 15 }),
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -31,17 +31,17 @@ import { ToolError } from "./tool-errors";
|
||||
import { toolResult } from "./tool-result";
|
||||
|
||||
const grepSchema = Type.Object({
|
||||
pattern: Type.String({ description: "Regex pattern to search for" }),
|
||||
path: Type.Optional(Type.String({ description: "File or directory to search (default: cwd)" })),
|
||||
glob: Type.Optional(Type.String({ description: "Filter files by glob pattern (e.g., '*.js')" })),
|
||||
type: Type.Optional(Type.String({ description: "Filter by file type (e.g., js, py, rust)" })),
|
||||
i: Type.Optional(Type.Boolean({ description: "Case-insensitive search", default: false })),
|
||||
pre: Type.Optional(Type.Number({ description: "Lines of context before matches" })),
|
||||
post: Type.Optional(Type.Number({ description: "Lines of context after matches" })),
|
||||
multiline: Type.Optional(Type.Boolean({ description: "Enable multiline matching" })),
|
||||
gitignore: Type.Optional(Type.Boolean({ description: "Respect .gitignore files during search", default: true })),
|
||||
limit: Type.Optional(Type.Number({ description: "Limit output to first N matches", default: 20 })),
|
||||
offset: Type.Optional(Type.Number({ description: "Skip first N entries before applying limit", default: 0 })),
|
||||
pattern: Type.String({ description: "regex pattern", examples: ["function\\s+\\w+", "TODO"] }),
|
||||
path: Type.Optional(Type.String({ description: "path to search", examples: ["src/", "src/foo.ts"] })),
|
||||
glob: Type.Optional(Type.String({ description: "glob filter", examples: ["*.js"] })),
|
||||
type: Type.Optional(Type.String({ description: "file type filter", examples: ["js", "py", "rust"] })),
|
||||
i: Type.Optional(Type.Boolean({ description: "case-insensitive search", default: false })),
|
||||
pre: Type.Optional(Type.Number({ description: "lines before matches" })),
|
||||
post: Type.Optional(Type.Number({ description: "lines after matches" })),
|
||||
multiline: Type.Optional(Type.Boolean({ description: "multiline matching" })),
|
||||
gitignore: Type.Optional(Type.Boolean({ description: "respect gitignore", default: true })),
|
||||
limit: Type.Optional(Type.Number({ description: "max matches", default: 20 })),
|
||||
offset: Type.Optional(Type.Number({ description: "skip first n matches", default: 0 })),
|
||||
});
|
||||
|
||||
export type GrepToolInput = Static<typeof grepSchema>;
|
||||
|
||||
@@ -16,8 +16,8 @@ import { ToolError } from "./tool-errors";
|
||||
|
||||
const inspectImageSchema = Type.Object(
|
||||
{
|
||||
path: Type.String({ description: "Filesystem path to an image" }),
|
||||
question: Type.String({ description: "Question to ask about the image" }),
|
||||
path: Type.String({ description: "image path", examples: ["image.png"] }),
|
||||
question: Type.String({ description: "question about image", examples: ["What is in this image?"] }),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
@@ -13,14 +13,16 @@ import { formatCount, formatErrorMessage, PREVIEW_LIMITS } from "./render-utils"
|
||||
|
||||
const notebookSchema = Type.Object({
|
||||
action: StringEnum(["edit", "insert", "delete"], {
|
||||
description: "Action to perform on the notebook cell",
|
||||
description: "cell action",
|
||||
examples: ["edit", "insert", "delete"],
|
||||
}),
|
||||
notebook_path: Type.String({ description: "Path to the .ipynb file" }),
|
||||
cell_index: Type.Number({ description: "0-based index of the cell to operate on" }),
|
||||
content: Type.Optional(Type.String({ description: "New cell content (required for edit/insert)" })),
|
||||
notebook_path: Type.String({ description: "notebook path", examples: ["analysis.ipynb"] }),
|
||||
cell_index: Type.Number({ description: "cell index", examples: [0, 1] }),
|
||||
content: Type.Optional(Type.String({ description: "new cell content" })),
|
||||
cell_type: Type.Optional(
|
||||
StringEnum(["code", "markdown"], {
|
||||
description: "Cell type for insert (default: code)",
|
||||
description: "cell type",
|
||||
examples: ["code", "markdown"],
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -8,7 +8,8 @@ import type { ToolSession } from "./index";
|
||||
const pollSchema = Type.Object({
|
||||
jobs: Type.Optional(
|
||||
Type.Array(Type.String(), {
|
||||
description: "Specific job IDs to wait for. If omitted, waits for any running job.",
|
||||
description: "job ids to wait for",
|
||||
examples: [["job-1234"]],
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -47,14 +47,14 @@ function groupPreludeHelpers(helpers: PreludeHelper[]): PreludeCategory[] {
|
||||
export const pythonSchema = Type.Object({
|
||||
cells: Type.Array(
|
||||
Type.Object({
|
||||
code: Type.String({ description: "Python code to execute" }),
|
||||
title: Type.Optional(Type.String({ description: "Cell label, e.g. 'imports', 'helper'" })),
|
||||
code: Type.String({ description: "python code", examples: ["print('hello')", "import json"] }),
|
||||
title: Type.Optional(Type.String({ description: "cell label", examples: ["imports", "helper"] })),
|
||||
}),
|
||||
{ description: "Cells to execute sequentially in persistent kernel" },
|
||||
{ description: "cells to execute" },
|
||||
),
|
||||
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds", default: 30 })),
|
||||
cwd: Type.Optional(Type.String({ description: "Working directory (default: cwd)" })),
|
||||
reset: Type.Optional(Type.Boolean({ description: "Restart kernel before execution" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "timeout in seconds", default: 30 })),
|
||||
cwd: Type.Optional(Type.String({ description: "working directory", examples: ["src/"] })),
|
||||
reset: Type.Optional(Type.Boolean({ description: "restart kernel" })),
|
||||
});
|
||||
export type PythonToolParams = Static<typeof pythonSchema>;
|
||||
|
||||
|
||||
@@ -369,9 +369,9 @@ function prependSuffixResolutionNotice(text: string, suffixResolution?: { from:
|
||||
}
|
||||
|
||||
const readSchema = Type.Object({
|
||||
path: Type.String({ description: "Path or URL to read" }),
|
||||
sel: Type.Optional(Type.String({ description: "Selector" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds", default: 20 })),
|
||||
path: Type.String({ description: "path or url", examples: ["src/foo.ts", "https://example.com"] }),
|
||||
sel: Type.Optional(Type.String({ description: "line range or mode", examples: ["L50", "L50-L120", "raw"] })),
|
||||
timeout: Type.Optional(Type.Number({ description: "timeout in seconds", default: 20 })),
|
||||
});
|
||||
|
||||
export type ReadToolInput = Static<typeof readSchema>;
|
||||
|
||||
@@ -5,7 +5,7 @@ import renderMermaidDescription from "../prompts/tools/render-mermaid.md" with {
|
||||
import type { ToolSession } from "./index";
|
||||
|
||||
const renderMermaidSchema = Type.Object({
|
||||
mermaid: Type.String({ description: "Mermaid graph source text" }),
|
||||
mermaid: Type.String({ description: "mermaid source", examples: ["graph TD; A-->B"] }),
|
||||
config: Type.Optional(
|
||||
Type.Object({
|
||||
useAscii: Type.Optional(Type.Boolean()),
|
||||
|
||||
@@ -14,8 +14,8 @@ import type { Settings } from "..";
|
||||
import type { ToolSession } from "./index";
|
||||
|
||||
const ReportToolIssueParams = Type.Object({
|
||||
tool: Type.String({ description: "Name of the tool that behaved unexpectedly" }),
|
||||
report: Type.String({ description: "Description of what was unexpected about the tool's behavior" }),
|
||||
tool: Type.String({ description: "tool name", examples: ["bash", "read"] }),
|
||||
report: Type.String({ description: "unexpected behavior" }),
|
||||
});
|
||||
|
||||
export function isAutoQaEnabled(settings?: Settings): boolean {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { ToolError } from "./tool-errors";
|
||||
|
||||
const resolveSchema = Type.Object({
|
||||
action: Type.Union([Type.Literal("apply"), Type.Literal("discard")]),
|
||||
reason: Type.String({ description: "Why you're applying or discarding" }),
|
||||
reason: Type.String({ description: "reason for action", examples: ["approved by user"] }),
|
||||
});
|
||||
|
||||
type ResolveParams = Static<typeof resolveSchema>;
|
||||
|
||||
@@ -55,22 +55,24 @@ function getPriorityDisplay(
|
||||
// report_finding schema
|
||||
const ReportFindingParams = Type.Object({
|
||||
title: Type.String({
|
||||
description: "≤80 chars, imperative, prefixed with [P0-P3]. E.g., '[P1] Un-padding slices along wrong dimension'",
|
||||
description: "prefixed imperative title",
|
||||
examples: ["[P1] un-padding wrong dimension"],
|
||||
}),
|
||||
body: Type.String({
|
||||
description: "Markdown explaining why this is a problem. One paragraph max.",
|
||||
description: "problem explanation",
|
||||
}),
|
||||
priority: StringEnum(["P0", "P1", "P2", "P3"], {
|
||||
description: "0=P0 (critical), 1=P1 (urgent), 2=P2 (normal), 3=P3 (low)",
|
||||
description: "priority 0-3",
|
||||
}),
|
||||
confidence: Type.Number({
|
||||
minimum: 0,
|
||||
maximum: 1,
|
||||
description: "Confidence score 0.0-1.0",
|
||||
description: "confidence score",
|
||||
examples: [0.0, 0.5, 1.0],
|
||||
}),
|
||||
file_path: Type.String({ description: "Path to the file" }),
|
||||
line_start: Type.Number({ description: "Start line of the issue" }),
|
||||
line_end: Type.Number({ description: "End line of the issue" }),
|
||||
file_path: Type.String({ description: "file path" }),
|
||||
line_start: Type.Number({ description: "start line" }),
|
||||
line_end: Type.Number({ description: "end line" }),
|
||||
});
|
||||
|
||||
interface ReportFindingDetails {
|
||||
|
||||
@@ -25,9 +25,9 @@ const MATCH_LABEL_LEN = 72;
|
||||
const MATCH_DESCRIPTION_LEN = 96;
|
||||
|
||||
const searchToolBm25Schema = Type.Object({
|
||||
query: Type.String({ description: "Search query for hidden MCP tool metadata" }),
|
||||
query: Type.String({ description: "mcp search query", examples: ["kubernetes pod", "image processing"] }),
|
||||
limit: Type.Optional(
|
||||
Type.Integer({ description: "Max matching tools to activate and return (default 8)", minimum: 1 }),
|
||||
Type.Integer({ description: "max matches", minimum: 1 }),
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ import { toolResult } from "./tool-result";
|
||||
import { clampTimeout } from "./tool-timeouts";
|
||||
|
||||
const sshSchema = Type.Object({
|
||||
host: Type.String({ description: "Host name from managed SSH config or discovered ssh.json files" }),
|
||||
command: Type.String({ description: "Command to execute on the remote host" }),
|
||||
cwd: Type.Optional(Type.String({ description: "Remote working directory (optional)" })),
|
||||
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds", default: 60 })),
|
||||
host: Type.String({ description: "ssh host", examples: ["my-server", "prod-1"] }),
|
||||
command: Type.String({ description: "remote command", examples: ["ls -la", "uptime"] }),
|
||||
cwd: Type.Optional(Type.String({ description: "remote working directory", examples: ["/var/log"] })),
|
||||
timeout: Type.Optional(Type.Number({ description: "timeout in seconds", default: 60 })),
|
||||
});
|
||||
|
||||
export interface SSHToolDetails {
|
||||
|
||||
@@ -43,41 +43,41 @@ export interface TodoWriteToolDetails {
|
||||
// =============================================================================
|
||||
|
||||
const InputTask = Type.Object({
|
||||
content: Type.String({ description: "Task description" }),
|
||||
content: Type.String({ description: "task description", examples: ["Add unit tests"] }),
|
||||
status: Type.Optional(
|
||||
StringEnum(["pending", "in_progress", "completed", "abandoned"] as const, {
|
||||
description: "Task status",
|
||||
description: "task status",
|
||||
}),
|
||||
),
|
||||
details: Type.Optional(
|
||||
Type.String({ description: "Implementation details, file paths, and specifics (shown only when active)" }),
|
||||
Type.String({ description: "implementation details" }),
|
||||
),
|
||||
});
|
||||
|
||||
const InputPhase = Type.Object({
|
||||
name: Type.String({ description: "Phase name" }),
|
||||
name: Type.String({ description: "phase name", examples: ["Investigation", "Implementation"] }),
|
||||
tasks: Type.Optional(Type.Array(InputTask)),
|
||||
});
|
||||
|
||||
const AddNoteEntry = Type.Object({
|
||||
id: Type.String({ description: "Task ID, e.g. task-3" }),
|
||||
notes: Type.String({ description: "Notes to append" }),
|
||||
id: Type.String({ description: "task id", examples: ["task-3"] }),
|
||||
notes: Type.String({ description: "notes to append" }),
|
||||
});
|
||||
|
||||
const AddTaskEntry = Type.Object({
|
||||
phase: Type.String({ description: "Phase name or ID" }),
|
||||
content: Type.String({ description: "Task description" }),
|
||||
details: Type.Optional(Type.String({ description: "Implementation details, file paths, and specifics" })),
|
||||
phase: Type.String({ description: "phase name or id", examples: ["Investigation", "phase-1"] }),
|
||||
content: Type.String({ description: "task description", examples: ["Add unit tests"] }),
|
||||
details: Type.Optional(Type.String({ description: "implementation details" })),
|
||||
});
|
||||
|
||||
const todoWriteSchema = Type.Object({
|
||||
phases: Type.Optional(Type.Array(InputPhase, { description: "Replace entire todo list with these phases" })),
|
||||
start: Type.Optional(Type.String({ description: "Task ID to start, e.g. task-3" })),
|
||||
complete: Type.Optional(Type.Array(Type.String(), { description: "Task IDs to mark completed" })),
|
||||
abandon: Type.Optional(Type.Array(Type.String(), { description: "Task IDs to mark abandoned" })),
|
||||
remove: Type.Optional(Type.Array(Type.String(), { description: "Task IDs to remove" })),
|
||||
add_notes: Type.Optional(Type.Array(AddNoteEntry, { description: "Notes to append to tasks" })),
|
||||
add_tasks: Type.Optional(Type.Array(AddTaskEntry, { description: "Tasks to add" })),
|
||||
phases: Type.Optional(Type.Array(InputPhase, { description: "replace todo list" })),
|
||||
start: Type.Optional(Type.String({ description: "task id to start", examples: ["task-3"] })),
|
||||
complete: Type.Optional(Type.Array(Type.String(), { description: "task ids to complete" })),
|
||||
abandon: Type.Optional(Type.Array(Type.String(), { description: "task ids to abandon" })),
|
||||
remove: Type.Optional(Type.Array(Type.String(), { description: "task ids to remove" })),
|
||||
add_notes: Type.Optional(Type.Array(AddNoteEntry, { description: "notes to append" })),
|
||||
add_tasks: Type.Optional(Type.Array(AddTaskEntry, { description: "tasks to add" })),
|
||||
add_phase: Type.Optional(InputPhase),
|
||||
});
|
||||
|
||||
|
||||
@@ -38,28 +38,27 @@ const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
||||
|
||||
const vimStepSchema = Type.Object({
|
||||
kbd: Type.Array(Type.String(), {
|
||||
description: "Vim key sequences ONLY (e.g. ggdGi, 3Go, dd). NEVER put file content here — use insert for text.",
|
||||
description: "vim key sequences",
|
||||
examples: [["ggdGi"], ["3Go"], ["dd"]],
|
||||
}),
|
||||
insert: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Raw text to type into the buffer. kbd must leave INSERT mode active first (e.g. via o, O, i, cc).",
|
||||
description: "raw text to insert",
|
||||
examples: ["hello world"],
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const vimSchema = Type.Object({
|
||||
file: Type.String({ description: "File path to edit." }),
|
||||
file: Type.String({ description: "file path", examples: ["src/foo.ts"] }),
|
||||
steps: Type.Optional(
|
||||
Type.Array(vimStepSchema, {
|
||||
description:
|
||||
"Ordered editing steps. Each step executes kbd sequences, then optionally inserts text. INSERT mode is auto-exited between steps.",
|
||||
description: "editing steps",
|
||||
}),
|
||||
),
|
||||
pause: Type.Optional(
|
||||
Type.Boolean({
|
||||
description:
|
||||
"Advanced: skip auto-save after the last step. Rarely needed. Omit or set false for normal use — edits auto-save.",
|
||||
description: "skip auto-save",
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -44,8 +44,8 @@ import { ToolError } from "./tool-errors";
|
||||
import { toolResult } from "./tool-result";
|
||||
|
||||
const writeSchema = Type.Object({
|
||||
path: Type.String({ description: "Path to the file to write" }),
|
||||
content: Type.String({ description: "Content to write to the file" }),
|
||||
path: Type.String({ description: "file path", examples: ["src/new.ts"] }),
|
||||
content: Type.String({ description: "file content" }),
|
||||
});
|
||||
|
||||
export type WriteToolInput = Static<typeof writeSchema>;
|
||||
|
||||
@@ -59,15 +59,15 @@ export class YieldTool implements AgentTool<TSchema, YieldDetails> {
|
||||
Type.Object(
|
||||
{
|
||||
result: Type.Union([
|
||||
Type.Object({ data: dataSchema }, { description: "Successfully completed the task" }),
|
||||
Type.Object({ data: dataSchema }, { description: "task succeeded" }),
|
||||
Type.Object({
|
||||
error: Type.String({ description: "Error message when the task cannot be completed" }),
|
||||
error: Type.String({ description: "error message" }),
|
||||
}),
|
||||
]),
|
||||
},
|
||||
{
|
||||
additionalProperties: false,
|
||||
description: "Submit either `data` for success or `error` for failure",
|
||||
description: "submit data or error",
|
||||
},
|
||||
) as TSchema;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ function makeTag(line: number, content: string): Anchor {
|
||||
/** Returns a valid bigram that's guaranteed NOT to equal the real hash of `(line, content)`. */
|
||||
function staleBigramFor(line: number, content: string): string {
|
||||
const real = computeLineHash(line, content);
|
||||
const idx = HASHLINE_BIGRAMS.indexOf(real);
|
||||
const idx = HASHLINE_BIGRAMS.indexOf(real as (typeof HASHLINE_BIGRAMS)[number]);
|
||||
return HASHLINE_BIGRAMS[(idx + 1) % HASHLINE_BIGRAMS_COUNT];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user