From d1b52a063b75b89b655d14d5312306d8744948fc Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 7 Jul 2026 21:06:14 +0800 Subject: [PATCH] fix review findings: own-property and plain-JSON discipline in the schema subset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three Codex findings on json-schema.ts, one discipline: - required-declared and every value check now use Object.hasOwn — 'in' let inherited names (toString) satisfy required, dodge additionalProperties: false, and validate a declared property against the value's prototype member instead of a carried one - isObjectLike now means PLAIN JSON object (proto chain of at most one link, realm-agnostic): a Date annotation or a Map-as-properties no longer passes structurally and serializes lossily — they fail loud as subset violations - startInProcessRun asserts BEFORE the defensive structuredClone, so a hostile schema fails as OutputSchemaError, never a raw DataCloneError Also the type-equiv catalog gap: tools.md gains the structured-output subset vocabulary (4 blocks) with matching manifest entries. The driver index also drops the runtime internals from its public re-export (runs acquire it internally; no external consumer remains — see the following commit). --- docs/core-data-structures/tools.md | 34 ++ packages/core/tools/src/json-schema.ts | 35 +- packages/core/tools/tests/json-schema.spec.ts | 50 ++ .../subagent/subagent-inprocess/src/index.ts | 22 +- scripts/type-equiv.manifest.json | 449 +++++++++++++++--- 5 files changed, 495 insertions(+), 95 deletions(-) diff --git a/docs/core-data-structures/tools.md b/docs/core-data-structures/tools.md index a05ffb3966..a38a5b9c15 100644 --- a/docs/core-data-structures/tools.md +++ b/docs/core-data-structures/tools.md @@ -138,6 +138,40 @@ type PostToolDecision = Call `next()` to delegate to the default (allow / accept-unchanged), or return a decision to short-circuit. A `pre-execute` `deny` (or `ask`, which degrades to deny until the permission system lands) skips dispatch and yields an `isError` result; input rewrite is deliberately NOT offered on `PreToolDecision` (it would desync the pre-execution audit/history/UI from what ran — its own proposed RFC). A `post-execute` `accept` may replace the model-facing `content` (clean, because `tool/result` is logged after `execute()` returns); a `block` turns the call into an `isError` whose content is the corrective `feedback`. Core dispatch sits between the waterfalls as plain code; the tool body keeps its own try/catch so a thrown tool still reaches `post-execute` as an `isError`. An unregistered tool routes through the same catch as a tool-thrown error, so both failure classes get a structured `{ name, code }` (`ToolNotFoundError` → `UNKNOWN_TOOL`) — the loop records a failed tool call instead of failing the whole turn. +## The structured-output schema subset + +The vocabulary a caller uses to demand a machine-readable result from a subagent (`SubagentStartRequest.outputSchema`, [subagent.md](subagent.md#the-start-request)) or a workflow `agent()` call. It is deliberately NOT full JSON Schema: the schema travels verbatim to the model as a forced tool's `parameters`, and the produced value is validated client-side by `validateStructuredValue` — so every accepted keyword must be one the validator actually enforces, and `assertSupportedOutputSchema` rejects anything else loud (`OutputSchemaError`, listing every violation). Both walkers reason over own enumerable properties only (JSON carries nothing else) and reject non-plain objects (`Date`, `Map`) that would serialize lossily. + +```ts type-equiv +type StructuredScalar = string | number | boolean | null +``` + +```ts type-equiv +type StructuredSchemaType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null' +``` + +```ts type-equiv +interface StructuredSchemaNode { + type: StructuredSchemaType + properties?: Record + required?: string[] + additionalProperties?: boolean + items?: StructuredSchemaNode + enum?: StructuredScalar[] + const?: StructuredScalar + description?: string + title?: string + default?: unknown + examples?: unknown +} +``` + +A schema is an object-rooted node (`enum`/`const` are scalar-only; `description`/`title`/`default`/`examples` are annotations, allowed and ignored but still required to be JSON data — they ride the wire): + +```ts type-equiv +type StructuredOutputSchema = StructuredSchemaNode & { type: 'object' } +``` + ## Tool-presentation UI vocabulary How a tool wants its call shown in a UI (an editor tool-call card, a CLI log line), provider-neutral so a tool describes itself without depending on any client protocol. `presentCall`/`presentResult` return a **`card`-tagged render intent** — a discriminated union a UI bridge switches on: diff --git a/packages/core/tools/src/json-schema.ts b/packages/core/tools/src/json-schema.ts index 35eeb240a4..bc0da537e1 100644 --- a/packages/core/tools/src/json-schema.ts +++ b/packages/core/tools/src/json-schema.ts @@ -91,9 +91,20 @@ const ANNOTATION_KEYWORDS = new Set(['description', 'title', 'default', 'example const SCHEMA_TYPES: readonly StructuredSchemaType[] = ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'] -/** Whether a value is a non-null, non-array object (structural, realm-agnostic). */ +/** + * Whether a value is a PLAIN JSON object — non-null, non-array, and with a + * prototype chain of at most one link (`null`-proto, or any realm's + * `Object.prototype`, whose own prototype is `null`). Realm-agnostic on + * purpose: a schema materialized in another realm carries THAT realm's + * `Object.prototype`, which an identity check would wrongly reject. Exotic + * hosts (`Date`, `Map`, class instances) have longer chains and are rejected — + * they would serialize lossily (`Date` → string, `Map` → `{}`) instead of + * failing loud. + */ function isObjectLike(value: unknown): value is Record { - return typeof value === 'object' && value !== null && !Array.isArray(value) + if (typeof value !== 'object' || value === null || Array.isArray(value)) return false + const proto: unknown = Object.getPrototypeOf(value) + return proto === null || Object.getPrototypeOf(proto) === null } /** Whether a value is a supported scalar (`enum`/`const` member): string, finite number, boolean, or null. */ @@ -116,6 +127,9 @@ function isJsonData(value: unknown, seen: Set): boolean { seen.add(value) try { if (Array.isArray(value)) return value.every(entry => isJsonData(entry, seen)) + // A non-plain object (Date, Map, class instance) is NOT JSON data even when + // it has no enumerable values — it would serialize lossily, not loudly. + if (!isObjectLike(value)) return false return Object.values(value).every(entry => isJsonData(entry, seen)) } finally { seen.delete(value) @@ -194,8 +208,11 @@ function checkSchemaNode(node: unknown, path: string, violations: string[], seen violations.push(`${path}.required must be an array of strings`) } else { const declared = isObjectLike(properties) ? properties : {} - for (const key of required) { - if (!(key in declared)) violations.push(`${path}.required names "${key}" which is not in properties`) + // The guard above proved every entry is a string. + for (const key of required as string[]) { + // Own-property check: `in` would let inherited names (`toString`) + // satisfy the declared-in-properties contract via the prototype. + if (!Object.hasOwn(declared, key)) violations.push(`${path}.required names "${key}" which is not in properties`) } } } @@ -256,16 +273,20 @@ function checkValue(node: StructuredSchemaNode, value: unknown, path: string): s if (!isObjectLike(value)) return [`"${path}" must be an object`] const violations: string[] = [] const properties = node.properties ?? {} + // Own-property discipline throughout: JSON carries own enumerable + // properties only, so an inherited `toString` must not satisfy + // `required`, dodge `additionalProperties: false`, or be validated as if + // the value carried it. for (const key of node.required ?? []) { - if (value[key] === undefined) violations.push(`missing required property "${path}.${key}"`) + if (!Object.hasOwn(value, key) || value[key] === undefined) violations.push(`missing required property "${path}.${key}"`) } for (const [key, child] of Object.entries(properties)) { - if (value[key] === undefined) continue + if (!Object.hasOwn(value, key) || value[key] === undefined) continue violations.push(...checkValue(child, value[key], `${path}.${key}`)) } if (node.additionalProperties === false) { for (const key of Object.keys(value)) { - if (!(key in properties)) violations.push(`"${path}.${key}" is not a declared property (additionalProperties: false)`) + if (!Object.hasOwn(properties, key)) violations.push(`"${path}.${key}" is not a declared property (additionalProperties: false)`) } } return violations diff --git a/packages/core/tools/tests/json-schema.spec.ts b/packages/core/tools/tests/json-schema.spec.ts index e7635b06f3..6fa895288e 100644 --- a/packages/core/tools/tests/json-schema.spec.ts +++ b/packages/core/tools/tests/json-schema.spec.ts @@ -154,6 +154,30 @@ describe('assertSupportedOutputSchema', () => { const leaf = { type: 'string' } asserted({ type: 'object', properties: { a: leaf, b: leaf } }) }) + + it('required cannot be satisfied by INHERITED names — `toString` is not a declared property', () => { + // `'toString' in {}` is true via Object.prototype; the declared-property + // contract must be an own-property check. + expect(violationsOf({ type: 'object', properties: {}, required: ['toString'] })) + .toEqual(['schema.required names "toString" which is not in properties']) + }) + + it('rejects exotic host objects where the subset expects plain JSON structure', () => { + // A Map as `properties` has no own enumerable entries: structurally it + // would read as "no properties" and serialize to {} — lossy, not loud. + expect(violationsOf({ type: 'object', properties: new Map() })) + .toEqual(['schema.properties must be an object of schemas']) + // A Date node is not a schema object even though Object.values(date) is []. + expect(violationsOf({ type: 'object', properties: { at: new Date(0) } })) + .toEqual(['schema.properties.at must be a schema object']) + }) + + it('rejects exotic annotation payloads that would serialize lossily', () => { + expect(violationsOf({ type: 'object', default: new Date(0) })) + .toEqual(['schema.default annotation must be JSON data']) + expect(violationsOf({ type: 'object', examples: [new Map()] })) + .toEqual(['schema.examples annotation must be JSON data']) + }) }) describe('validateStructuredValue', () => { @@ -223,6 +247,32 @@ describe('validateStructuredValue', () => { expect(validateStructuredValue(schema, { file: undefined })).toEqual(['missing required property "value.file"']) }) + it('inherited properties satisfy nothing: required, additionalProperties, and recursion are own-property only', () => { + // required: ['toString'] must NOT be satisfied by Object.prototype.toString. + expect(validateStructuredValue( + asserted({ type: 'object', properties: { toString: { type: 'string' } }, required: ['toString'] }), + {}, + )).toEqual(['missing required property "value.toString"']) + // additionalProperties: false must flag an OWN `toString` key even though + // `'toString' in properties` is true via the prototype. + expect(validateStructuredValue( + asserted({ type: 'object', additionalProperties: false }), + { toString: 1 }, + )).toEqual(['"value.toString" is not a declared property (additionalProperties: false)']) + // A declared property the value does NOT carry must not be validated + // against the value's INHERITED member (constructor is a function on + // every plain object's prototype, not a carried property). + expect(validateStructuredValue( + asserted({ type: 'object', properties: { constructor: { type: 'string' } } }), + {}, + )).toEqual([]) + }) + + it('a non-plain object value is not an object in the JSON sense', () => { + expect(validateStructuredValue(asserted({ type: 'object' }), new Date(0))) + .toEqual(['"value" must be an object']) + }) + it('collects multiple violations across branches in one pass', () => { expect(validateStructuredValue(schema, { line: 'x', severity: 'mid' })).toEqual([ 'missing required property "value.file"', diff --git a/packages/subagent/subagent-inprocess/src/index.ts b/packages/subagent/subagent-inprocess/src/index.ts index 72906a78fc..08d240d248 100644 --- a/packages/subagent/subagent-inprocess/src/index.ts +++ b/packages/subagent/subagent-inprocess/src/index.ts @@ -25,11 +25,12 @@ import { type StructuredAcquisition, } from './structured.ts' +// The runtime itself (acquire/attach/release) is package-internal: runs +// acquire it inside startInProcessRun, and no other package drives it. Only +// the model-facing vocabulary is public. export { - acquireStructuredRuntime, STRUCTURED_OUTPUT_TOOL, STRUCTURED_OUTPUT_INSTRUCTION, - type StructuredAcquisition, } from './structured.ts' declare module '@deepseek-ai/dsh-agent' { @@ -110,15 +111,18 @@ export function startInProcessRun( if (request.maxDepth !== undefined && childDepth > request.maxDepth) { throw new SubagentDepthError(childDepth, request.maxDepth) } - // Snapshot, then assert, the schema subset BEFORE any child exists (the + // Assert, then snapshot, the schema subset BEFORE any child exists (the // service has already capability-gated; this rejects a schema outside the - // enforced subset loud). The snapshot is load-bearing: the caller keeps its - // reference, so validating and attaching the ORIGINAL would let a - // post-start() mutation drift the enforced schema away from the asserted - // one — the clone pins assertion, the model-visible parameters, and - // validateStructuredValue to the same isolation-immutable value. + // enforced subset loud). Assertion comes FIRST so a hostile value fails as + // OutputSchemaError, never as structuredClone's raw DataCloneError — the + // asserted subset is plain JSON data, which always clones. The snapshot is + // load-bearing: the caller keeps its reference, so attaching the ORIGINAL + // would let a post-start() mutation drift the enforced schema away from the + // asserted one — the clone (taken synchronously with the assertion, no + // interleaving possible) pins assertion, the model-visible parameters, and + // validateStructuredValue to one isolation-immutable value. + if (request.outputSchema !== undefined) assertSupportedOutputSchema(request.outputSchema) const schema = request.outputSchema === undefined ? undefined : structuredClone(request.outputSchema) - if (schema !== undefined) assertSupportedOutputSchema(schema) const childId = AgentId(randomUUID()) // The child's OWN events begin after the seed (fork seeds the parent's diff --git a/scripts/type-equiv.manifest.json b/scripts/type-equiv.manifest.json index b5c648527e..e414cff1f4 100644 --- a/scripts/type-equiv.manifest.json +++ b/scripts/type-equiv.manifest.json @@ -1,84 +1,375 @@ { "comment": "Maps each ` ```ts type-equiv ` block (by doc + declared symbol) to the source symbol it must match verbatim. verify-type-equiv.ts enforces a 1:1 correspondence: every type-equiv block has exactly one entry here, and every entry resolves to exactly one block. Add an entry when you add a type-equiv block; remove it when you remove the block.", "entries": [ - { "doc": "docs/core-data-structures/core.md", "symbol": "Branded", "source": "packages/util/brand/src/index.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "ContentBlockMap", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "Message", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "MessageSourceMap", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "FinishReasonMap", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "GenerateOptions", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "ToolSchema", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "LlmCallConfig", "source": "packages/llm/llm/src/call-config.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "SessionEvent", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "Agent", "source": "packages/core/agent/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "HookContext", "source": "packages/core/agent/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "PromptDecision", "source": "packages/core/agent/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "ContinuationDecision", "source": "packages/core/agent/src/types.ts" }, - { "doc": "docs/core-data-structures/core.md", "symbol": "SessionStartSource", "source": "packages/core/agent/src/types.ts" }, - - { "doc": "docs/core-data-structures/llm-streaming.md", "symbol": "StreamChunk", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/llm-streaming.md", "symbol": "TokenUsage", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/llm-streaming.md", "symbol": "ContentBlockMap", "source": "packages/llm/llm/src/types.ts" }, - { "doc": "docs/core-data-structures/llm-streaming.md", "symbol": "AppIdentity", "source": "packages/llm/llm/src/attribution.ts" }, - - { "doc": "docs/core-data-structures/session.md", "symbol": "SessionEventMap", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "EpochHeader", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "TodoItem", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "SessionEvent", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "TurnTriggerMap", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "TurnEndReasonMap", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "SurfaceEventType", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "SurfaceOp", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "SurfaceIntent", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/session.md", "symbol": "SurfaceNode", "source": "packages/core/session/src/surface.ts" }, - - { "doc": "docs/core-data-structures/persistence.md", "symbol": "SessionHeader", "source": "packages/core/session/src/types.ts" }, - { "doc": "docs/core-data-structures/persistence.md", "symbol": "CreateSessionOptions", "source": "packages/core/session/src/types.ts" }, - - { "doc": "docs/core-data-structures/tools.md", "symbol": "ToolDefinition", "source": "packages/core/tools/src/index.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "SchemaProp", "source": "packages/core/tools/src/schema.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "SchemaSpec", "source": "packages/core/tools/src/schema.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "InferArgs", "source": "packages/core/tools/src/schema.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "ToolExecution", "source": "packages/core/tools/src/index.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "ToolExecutionResult", "source": "packages/core/tools/src/index.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "PreToolDecision", "source": "packages/core/tools/src/index.ts" }, - { "doc": "docs/core-data-structures/tools.md", "symbol": "PostToolDecision", "source": "packages/core/tools/src/index.ts" }, - - { "doc": "docs/core-data-structures/bash.md", "symbol": "BashExecRequest", "source": "packages/bash/bash/src/types.ts" }, - { "doc": "docs/core-data-structures/bash.md", "symbol": "BashExecSpec", "source": "packages/bash/bash/src/types.ts" }, - { "doc": "docs/core-data-structures/bash.md", "symbol": "BashRunResult", "source": "packages/bash/bash/src/types.ts" }, - { "doc": "docs/core-data-structures/bash.md", "symbol": "CollectedOutput", "source": "packages/bash/bash/src/types.ts" }, - { "doc": "docs/core-data-structures/bash.md", "symbol": "BashTask", "source": "packages/bash/bash/src/types.ts" }, - { "doc": "docs/core-data-structures/bash.md", "symbol": "BashTaskRead", "source": "packages/bash/bash/src/types.ts" }, - - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsTarget", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsTargetKey", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsVersion", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsInfo", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsDirEntry", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsWriteIntent", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsWriteOutcome", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsEditRequest", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsEditOutcome", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsErrorCode", "source": "packages/fs/fs/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FsPolicyExec", "source": "packages/fs/fs-policy/src/types.ts" }, - { "doc": "docs/core-data-structures/filesystem.md", "symbol": "FileReadOutcome", "source": "packages/fs/tool-fs/src/read-render.ts" }, - - { "doc": "docs/core-data-structures/compaction.md", "symbol": "CompactionResult", "source": "packages/compact/compact/src/types.ts" }, - - { "doc": "docs/core-data-structures/subagent.md", "symbol": "SubagentCapabilities", "source": "packages/subagent/subagent/src/types.ts" }, - { "doc": "docs/core-data-structures/subagent.md", "symbol": "SubagentStartRequest", "source": "packages/subagent/subagent/src/types.ts" }, - { "doc": "docs/core-data-structures/subagent.md", "symbol": "SubagentResult", "source": "packages/subagent/subagent/src/types.ts" }, - { "doc": "docs/core-data-structures/subagent.md", "symbol": "SubagentStopReasonMap", "source": "packages/subagent/subagent/src/types.ts" }, - { "doc": "docs/core-data-structures/subagent.md", "symbol": "SubagentRun", "source": "packages/subagent/subagent/src/types.ts" }, - { "doc": "docs/core-data-structures/subagent.md", "symbol": "SubagentProvider", "source": "packages/subagent/subagent/src/types.ts" }, - - { "doc": "docs/core-data-structures/web.md", "symbol": "WebSearchRequest", "source": "packages/web/web/src/types.ts" }, - { "doc": "docs/core-data-structures/web.md", "symbol": "WebSearchResult", "source": "packages/web/web/src/types.ts" }, - { "doc": "docs/core-data-structures/web.md", "symbol": "WebSearchSource", "source": "packages/web/web/src/types.ts" }, - { "doc": "docs/core-data-structures/web.md", "symbol": "WebFetchRequest", "source": "packages/web/web/src/types.ts" }, - { "doc": "docs/core-data-structures/web.md", "symbol": "WebFetchResult", "source": "packages/web/web/src/types.ts" }, - { "doc": "docs/core-data-structures/web.md", "symbol": "WebFetchBody", "source": "packages/web/web/src/types.ts" }, - { "doc": "docs/core-data-structures/web.md", "symbol": "WebProviderStatus", "source": "packages/web/web/src/types.ts" } + { + "doc": "docs/core-data-structures/core.md", + "symbol": "Branded", + "source": "packages/util/brand/src/index.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "ContentBlockMap", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "Message", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "MessageSourceMap", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "FinishReasonMap", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "GenerateOptions", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "ToolSchema", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "LlmCallConfig", + "source": "packages/llm/llm/src/call-config.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "SessionEvent", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "Agent", + "source": "packages/core/agent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "HookContext", + "source": "packages/core/agent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "PromptDecision", + "source": "packages/core/agent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "ContinuationDecision", + "source": "packages/core/agent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/core.md", + "symbol": "SessionStartSource", + "source": "packages/core/agent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/llm-streaming.md", + "symbol": "StreamChunk", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/llm-streaming.md", + "symbol": "TokenUsage", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/llm-streaming.md", + "symbol": "ContentBlockMap", + "source": "packages/llm/llm/src/types.ts" + }, + { + "doc": "docs/core-data-structures/llm-streaming.md", + "symbol": "AppIdentity", + "source": "packages/llm/llm/src/attribution.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "SessionEventMap", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "EpochHeader", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "TodoItem", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "SessionEvent", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "TurnTriggerMap", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "TurnEndReasonMap", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "SurfaceEventType", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "SurfaceOp", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "SurfaceIntent", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/session.md", + "symbol": "SurfaceNode", + "source": "packages/core/session/src/surface.ts" + }, + { + "doc": "docs/core-data-structures/persistence.md", + "symbol": "SessionHeader", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/persistence.md", + "symbol": "CreateSessionOptions", + "source": "packages/core/session/src/types.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "ToolDefinition", + "source": "packages/core/tools/src/index.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "SchemaProp", + "source": "packages/core/tools/src/schema.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "SchemaSpec", + "source": "packages/core/tools/src/schema.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "InferArgs", + "source": "packages/core/tools/src/schema.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "ToolExecution", + "source": "packages/core/tools/src/index.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "ToolExecutionResult", + "source": "packages/core/tools/src/index.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "PreToolDecision", + "source": "packages/core/tools/src/index.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "PostToolDecision", + "source": "packages/core/tools/src/index.ts" + }, + { + "doc": "docs/core-data-structures/bash.md", + "symbol": "BashExecRequest", + "source": "packages/bash/bash/src/types.ts" + }, + { + "doc": "docs/core-data-structures/bash.md", + "symbol": "BashExecSpec", + "source": "packages/bash/bash/src/types.ts" + }, + { + "doc": "docs/core-data-structures/bash.md", + "symbol": "BashRunResult", + "source": "packages/bash/bash/src/types.ts" + }, + { + "doc": "docs/core-data-structures/bash.md", + "symbol": "CollectedOutput", + "source": "packages/bash/bash/src/types.ts" + }, + { + "doc": "docs/core-data-structures/bash.md", + "symbol": "BashTask", + "source": "packages/bash/bash/src/types.ts" + }, + { + "doc": "docs/core-data-structures/bash.md", + "symbol": "BashTaskRead", + "source": "packages/bash/bash/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsTarget", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsTargetKey", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsVersion", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsInfo", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsDirEntry", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsWriteIntent", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsWriteOutcome", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsEditRequest", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsEditOutcome", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsErrorCode", + "source": "packages/fs/fs/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FsPolicyExec", + "source": "packages/fs/fs-policy/src/types.ts" + }, + { + "doc": "docs/core-data-structures/filesystem.md", + "symbol": "FileReadOutcome", + "source": "packages/fs/tool-fs/src/read-render.ts" + }, + { + "doc": "docs/core-data-structures/compaction.md", + "symbol": "CompactionResult", + "source": "packages/compact/compact/src/types.ts" + }, + { + "doc": "docs/core-data-structures/subagent.md", + "symbol": "SubagentCapabilities", + "source": "packages/subagent/subagent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/subagent.md", + "symbol": "SubagentStartRequest", + "source": "packages/subagent/subagent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/subagent.md", + "symbol": "SubagentResult", + "source": "packages/subagent/subagent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/subagent.md", + "symbol": "SubagentStopReasonMap", + "source": "packages/subagent/subagent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/subagent.md", + "symbol": "SubagentRun", + "source": "packages/subagent/subagent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/subagent.md", + "symbol": "SubagentProvider", + "source": "packages/subagent/subagent/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebSearchRequest", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebSearchResult", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebSearchSource", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebFetchRequest", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebFetchResult", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebFetchBody", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/web.md", + "symbol": "WebProviderStatus", + "source": "packages/web/web/src/types.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "StructuredScalar", + "source": "packages/core/tools/src/json-schema.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "StructuredSchemaType", + "source": "packages/core/tools/src/json-schema.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "StructuredSchemaNode", + "source": "packages/core/tools/src/json-schema.ts" + }, + { + "doc": "docs/core-data-structures/tools.md", + "symbol": "StructuredOutputSchema", + "source": "packages/core/tools/src/json-schema.ts" + } ] }