From 9163f6129947b4f908d785968fe3c9dbf963144c Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Sun, 19 Jul 2026 14:14:02 +0800 Subject: [PATCH] docs: include JSDoc in website API markers --- scripts/gen-website-api.ts | 58 ++- website/zh-CN/api/cordis/context.md | 100 +++++ website/zh-CN/api/cordis/events.md | 62 ++++ website/zh-CN/api/cordis/fiber.md | 86 +++++ website/zh-CN/api/cordis/registry.md | 28 ++ website/zh-CN/api/cordis/service.md | 8 + website/zh-CN/api/harness/agent-loop.md | 21 ++ website/zh-CN/api/harness/agents.md | 91 +++++ website/zh-CN/api/harness/approval.md | 18 + website/zh-CN/api/harness/bash-env.md | 15 + website/zh-CN/api/harness/bash.md | 22 ++ website/zh-CN/api/harness/code-runtime.md | 22 ++ website/zh-CN/api/harness/compact.md | 32 ++ website/zh-CN/api/harness/events.md | 350 ++++++++++++++++++ website/zh-CN/api/harness/fs.md | 70 ++++ website/zh-CN/api/harness/llm.md | 27 ++ website/zh-CN/api/harness/permission.md | 30 ++ website/zh-CN/api/harness/sandbox.md | 11 + .../zh-CN/api/harness/session-persistence.md | 35 ++ website/zh-CN/api/harness/session-query.md | 26 ++ website/zh-CN/api/harness/sessions.md | 99 +++++ website/zh-CN/api/harness/skills.md | 30 ++ website/zh-CN/api/harness/spill-store.md | 5 + website/zh-CN/api/harness/subagents.md | 25 ++ website/zh-CN/api/harness/system-prompt.md | 30 ++ website/zh-CN/api/harness/tasks.md | 63 ++++ website/zh-CN/api/harness/token-meter.md | 22 ++ website/zh-CN/api/harness/tools.md | 54 +++ website/zh-CN/api/harness/user-interaction.md | 12 + website/zh-CN/api/harness/web.md | 31 ++ website/zh-CN/api/harness/workflows.md | 6 + website/zh-CN/api/index.md | 2 +- 32 files changed, 1479 insertions(+), 12 deletions(-) diff --git a/scripts/gen-website-api.ts b/scripts/gen-website-api.ts index 0420ad2ff3..480c19779f 100644 --- a/scripts/gen-website-api.ts +++ b/scripts/gen-website-api.ts @@ -20,11 +20,12 @@ * cannot land undocumented without CI going red. Pages are English (the * planned zh translation flow arrives separately; see docs/i18n/README.md). * - * Signature fences use the ` ```ts website-api ` info string: doc-typecheck - * only processes its known info strings, so these bare (non-compilable) - * signature fragments are skipped there, while VitePress still highlights the - * `ts` token. The sidebar fragment `website/.vitepress/config/api-sidebar.json` - * is generated alongside so navigation can never drift from the page set. + * Signature fences use the ` ```ts website-api ` info string and retain the + * declaration's original source JSDoc. doc-typecheck only processes its known + * info strings, so these bare (non-compilable) fragments are skipped there, + * while VitePress still highlights the `ts` token. The sidebar fragment + * `website/.vitepress/config/api-sidebar.json` is generated alongside so + * navigation can never drift from the page set. * * `tsx scripts/gen-website-api.ts` → write pages + sidebar * `tsx scripts/gen-website-api.ts --check` → exit 1 if committed copies are @@ -64,6 +65,8 @@ interface MemberDoc { heading: string /** All overload signature lines (bodies stripped). */ signatures: string[] + /** Original source JSDoc, dedented only from its containing declaration. */ + jsDoc: string /** Description prose, one paragraph per line. */ doc: string /** Parameter name → `@param` text, in declaration order. */ @@ -166,6 +169,20 @@ function load(rel: string): { sf: ts.SourceFile; text: string } { // The module-merge walk (cordisModuleBody / eventMembers / serviceClasses) is // shared with gen-cordis-catalog.ts via cordis-walk.ts. +/** Original JSDoc with only the source container's indentation removed. */ +function sourceJSDoc(text: string, sf: ts.SourceFile, node: ts.Node): string { + const raw = rawJsDoc(text, node) + if (raw === '') return '' + const { line } = sf.getLineAndCharacterOfPosition(node.getStart(sf)) + const lineStart = sf.getPositionOfLineAndCharacter(line, 0) + const indent = text.slice(lineStart, node.getStart(sf)) + return raw.split('\n') + .map((sourceLine, index) => index > 0 && sourceLine.startsWith(indent) + ? sourceLine.slice(indent.length) + : sourceLine) + .join('\n') +} + /** Signature text of a member: full text minus body/initializer, whitespace * collapsed, trailing semicolon stripped. */ function signatureOf(member: ts.Node, sf: ts.SourceFile): string { @@ -219,7 +236,7 @@ function memberDoc( const first = group[0] if (!first) throw new Error(`gen-website-api: empty member group for ${name}`) // Doc from the first overload that carries JSDoc prose. - const rawDocs = group.map(m => rawJsDoc(text, m)) + const rawDocs = group.map(m => sourceJSDoc(text, sf, m)) const docIndex = rawDocs.findIndex(r => parseJsDoc(r).doc !== '') const raw = docIndex === -1 ? '' : (rawDocs[docIndex] ?? '') const doc = parseJsDoc(raw).doc @@ -255,6 +272,7 @@ function memberDoc( signatures: (ts.isMethodDeclaration(first) && funcLike.length > 1 ? funcLike.filter(m => ts.isMethodDeclaration(m) && !m.body) : group).map(m => signatureOf(m, sf)), + jsDoc: raw, doc, params, returns: returnsText, @@ -424,8 +442,13 @@ function declPaste(rel: string, symbol: string): { doc: string; code: string; so if (matches.length === 0) throw new Error(`gen-website-api: declaration ${symbol} not found in ${rel}`) const first = matches[0] if (!first) throw new Error(`gen-website-api: declaration ${symbol} not found in ${rel}`) - const doc = parseJsDoc(rawJsDoc(text, first)).doc - const code = matches.map(s => stripBodies(s, sf).replace(/^export\s+(default\s+)?/, '')).join('\n\n') + const firstJSDoc = sourceJSDoc(text, sf, first) + const doc = parseJsDoc(firstJSDoc).doc + const code = matches.map((statement) => { + const jsDoc = sourceJSDoc(text, sf, statement) + const declaration = stripBodies(statement, sf).replace(/^export\s+(default\s+)?/, '') + return jsDoc === '' ? declaration : `${jsDoc}\n${declaration}` + }).join('\n\n') return { doc, code, source: pointer(rel, sf, first) } } @@ -480,6 +503,8 @@ interface HarnessEvent { scope: string mode: Mode | null signature: string + /** Original source event JSDoc, dedented from its module/interface. */ + jsDoc: string doc: string params: { name: string; text: string }[] source: string @@ -494,7 +519,7 @@ function collectHarnessEvents(violations: string[]): HarnessEvent[] { const body = cordisModuleBody(sf) if (!body) continue for (const { name, member } of eventMembers(body, sf)) { - const raw = rawJsDoc(text, member) + const raw = sourceJSDoc(text, sf, member) const { doc, mode } = parseJsDoc(raw) if (!mode) violations.push(`event '${name}' (${pointer(rel, sf, member)}) is missing @mode.`) if (!doc) violations.push(`event '${name}' (${pointer(rel, sf, member)}) has no JSDoc prose.`) @@ -509,7 +534,7 @@ function collectHarnessEvents(violations: string[]): HarnessEvent[] { const tag = tags.get(pname) if (tag) params.push({ name: pname, text: tag }) } - events.push({ name, scope: name.split('/')[0] ?? name, mode, signature: signatureOf(member, sf), doc, params, source: pointer(rel, sf, member) }) + events.push({ name, scope: name.split('/')[0] ?? name, mode, signature: signatureOf(member, sf), jsDoc: raw, doc, params, source: pointer(rel, sf, member) }) } } return events.sort((a, b) => a.name.localeCompare(b.name)) @@ -548,6 +573,7 @@ function renderMember(prefix: string, m: MemberDoc): string[] { const call = m.heading === '' ? '' : m.heading lines.push(`### ${prefix}${m.name}${call}`, '') lines.push('```' + FENCE) + lines.push(m.jsDoc) for (const sig of m.signatures) lines.push(sig) lines.push('```', '') lines.push(...prose(m.doc), '') @@ -620,7 +646,7 @@ function renderEventsPage(events: HarnessEvent[]): string { for (const e of events.filter(ev => ev.scope === scope)) { lines.push(`### ${e.name}`, '') lines.push(`**Mode:** \`${e.mode ?? 'unknown'}\``, '') - lines.push('```' + FENCE, e.signature, '```', '') + lines.push('```' + FENCE, e.jsDoc, e.signature, '```', '') lines.push(...prose(e.doc), '') if (e.params.length > 0) { for (const p of e.params) lines.push(`- \`${p.name}\` — ${unlink(p.text)}`) @@ -653,6 +679,16 @@ export function generate(): Map { const events = collectHarnessEvents(violations) files.set(`${PAGES_DIR}/harness/events.md`, renderEventsPage(events)) + for (const [rel, content] of files) { + if (!rel.endsWith('.md')) continue + for (const match of content.matchAll(/^```ts website-api\n([\s\S]*?)\n```$/gm)) { + const body = match[1] ?? '' + if (!body.startsWith('/**')) { + violations.push(`${rel}: a ts website-api fence does not begin with original source JSDoc.`) + } + } + } + reportViolations('gen-website-api', violations) const sidebar = { diff --git a/website/zh-CN/api/cordis/context.md b/website/zh-CN/api/cordis/context.md index cc08f4e28a..0fbb2fcc70 100644 --- a/website/zh-CN/api/cordis/context.md +++ b/website/zh-CN/api/cordis/context.md @@ -12,6 +12,15 @@ A context is a proxy: normal property reads go through the service resolver, whi ### ctx.extend(meta?) ```ts website-api +/** + * Create a child context with extra metadata on top of the current scope. + * + * The child prototypally inherits every property of this context; own + * properties of `meta` shadow the inherited ones. The parent is not mutated. + * + * @param meta — own properties (including symbol keys) to define on the child. + * @returns a child context inheriting from this one. + */ extend(meta = {}): this ``` @@ -27,6 +36,18 @@ The child prototypally inherits every property of this context; own properties o ### ctx.isolate(name, label?) ```ts website-api +/** + * Create a child context with an independent service scope for `name`. + * + * Below the returned context, reads and writes of the service `name` + * resolve against the new label instead of the parent's, so a different + * implementation can be provided without affecting the parent scope. + * Passing the same `label` to two `isolate()` calls joins their scopes. + * + * @param name — the service name to isolate. + * @param label — scope label to join; defaults to a fresh unique symbol. + * @returns a child context whose `name` service resolves in the new scope. + */ isolate(name: string, label?: symbol) ``` @@ -43,6 +64,18 @@ Below the returned context, reads and writes of the service `name` resolve again ### ctx.intercept(name, config) ```ts website-api +/** + * Add service-specific intercept config for plugins started below this + * context. + * + * Plugins loaded under the returned context see `config` merged into the + * service's resolved config (ancestor entries first; see + * `Service[symbols.resolveConfig]`). The parent context is not affected. + * + * @param name — the service name whose config to intercept. + * @param config — the intercept config to merge for that service. + * @returns a child context carrying the additional intercept entry. + */ intercept(name: K, config: Context[K] extends { [symbols.config]: infer T } ? T : never): this intercept(name: string, config: any): this ``` @@ -60,6 +93,7 @@ Plugins loaded under the returned context see `config` merged into the service's ### ctx.root ```ts website-api +/** The root context of the application (every child context shares it). @experimental */ root: this ``` @@ -70,6 +104,7 @@ The root context of the application (every child context shares it). @experiment ### ctx.baseUrl ```ts website-api +/** Base URL used to resolve relative plugin/module specifiers, if the runtime sets one. */ baseUrl?: string ``` @@ -80,6 +115,7 @@ Base URL used to resolve relative plugin/module specifiers, if the runtime sets ### ctx.events ```ts website-api +/** The event bus. Its methods are also mixed onto `ctx` (`ctx.on`, `ctx.emit`, ...). */ events: EventsService ``` @@ -90,6 +126,7 @@ The event bus. Its methods are also mixed onto `ctx` (`ctx.on`, `ctx.emit`, ...) ### ctx.logger ```ts website-api +/** The logging service. Call `ctx.logger(name)` for a named logger. */ logger: LoggerService ``` @@ -100,6 +137,7 @@ The logging service. Call `ctx.logger(name)` for a named logger. ### ctx.reflect ```ts website-api +/** The reflection layer backing the context proxy (`ctx.get`, `ctx.provide`, ...). */ reflect: ReflectService ``` @@ -110,6 +148,7 @@ The reflection layer backing the context proxy (`ctx.get`, `ctx.provide`, ...). ### ctx.registry ```ts website-api +/** The plugin registry. Its methods are mixed onto `ctx` (`ctx.plugin`, `ctx.inject`). */ registry: RegistryService ``` @@ -122,6 +161,7 @@ The plugin registry. Its methods are mixed onto `ctx` (`ctx.plugin`, `ctx.inject ### Context.effect ```ts website-api +/** Symbol key under which a disposer exposes its {@link EffectMeta} diagnostics tree. */ static readonly effect: unique symbol ``` @@ -132,6 +172,7 @@ Symbol key under which a disposer exposes its EffectMeta diagnostics tree. ### Context.filter ```ts website-api +/** Symbol key for a context's listener filter, consulted on every event dispatch. */ static readonly filter: unique symbol ``` @@ -142,6 +183,7 @@ Symbol key for a context's listener filter, consulted on every event dispatch. ### Context.isolate ```ts website-api +/** Symbol key of the isolation map (see the `Context[symbols.isolate]` property). */ static readonly isolate: unique symbol ``` @@ -152,6 +194,7 @@ Symbol key of the isolation map (see the `Context[symbols.isolate]` property). ### Context.intercept ```ts website-api +/** Symbol key of the intercept map (see the `Context[symbols.intercept]` property). */ static readonly intercept: unique symbol ``` @@ -162,6 +205,15 @@ Symbol key of the intercept map (see the `Context[symbols.intercept]` property). ### Context.is(value) ```ts website-api +/** + * Returns true for Cordis context proxies and context prototypes. + * + * Works across realms and across multiple copies of cordis, because the + * brand is keyed by a global symbol rather than by `instanceof`. + * + * @param value — the value to test. + * @returns `true` if `value` is a Cordis context, narrowing its type. + */ static is(value: any): value is Context ``` @@ -179,6 +231,14 @@ Works across realms and across multiple copies of cordis, because the brand is k ### ctx.get(name, strict?) ```ts website-api +/** + * Read a service from the store without the inject requirement. + * + * @param name — the service name. + * @param strict — when `true` (default), only return implementations + * whose providing fiber is currently active. + * @returns the service value, or `undefined` when not (yet) provided. + */ get(name: K, strict?: boolean): undefined | this[K] get(name: string, strict?: boolean): any ``` @@ -195,6 +255,15 @@ Read a service from the store without the inject requirement. ### ctx.set(name, value) ```ts website-api +/** + * Overwrite a provided service's value. + * + * Only the fiber that provided the service may set it; setting an + * unprovided name throws. + * + * @param name — the service name. + * @param value — the new service value. + */ set(name: K, value: undefined | this[K]): void set(name: string, value: any): void ``` @@ -210,6 +279,18 @@ Only the fiber that provided the service may set it; setting an unprovided name ### ctx.provide(name, value) ```ts website-api +/** + * Register a service implementation owned by the current fiber. + * + * The service becomes visible to dependents in the same isolation scope + * once the fiber is active; it is unregistered (waking dependents) when + * the returned disposer runs or the fiber unloads. Throws if the name is + * already provided in this scope or declared as an accessor. + * + * @param name — the service name. + * @param value — the service value. + * @returns a disposer that unregisters the service. + */ provide(name: K, value: undefined | this[K]): () => void provide(name: string, value?: any): () => void ``` @@ -227,6 +308,15 @@ The service becomes visible to dependents in the same isolation scope once the f ### ctx.accessor(name, options) ```ts website-api +/** + * Define a computed context property backed by get/set hooks. + * + * The accessor is removed when the current fiber unloads. Throws if the + * name is already declared. + * + * @param name — the context property name. + * @param options — the `get` hook and optional `set` hook. + */ accessor(name: string, options: Omit): void ``` @@ -241,6 +331,16 @@ The accessor is removed when the current fiber unloads. Throws if the name is al ### ctx.mixin(name, mixins) ```ts website-api +/** + * Expose selected members of a service directly on `ctx`. + * + * Each mixed-in key becomes an accessor that forwards to the service + * (binding methods to it), so e.g. `ctx.on` forwards to `ctx.events.on`. + * Mixins are removed when the current fiber unloads. + * + * @param name — the context property holding the source service. + * @param mixins — keys to forward, or a source-key → ctx-key map. + */ mixin(name: K, mixins: (keyof this & keyof this[K])[] | Dict): void mixin(source: T, mixins: (keyof this & keyof T)[] | Dict): void ``` diff --git a/website/zh-CN/api/cordis/events.md b/website/zh-CN/api/cordis/events.md index b56f8096fe..77488b5d24 100644 --- a/website/zh-CN/api/cordis/events.md +++ b/website/zh-CN/api/cordis/events.md @@ -7,6 +7,13 @@ The event system mixed into every context. Harness-defined events are cataloged ### ctx.parallel(name, ...args) ```ts website-api +/** + * Dispatch an event, running all listeners concurrently. + * + * @param name — the event name. + * @param args — arguments passed to every listener. + * @returns a promise resolving once every listener has settled. + */ parallel(name: K, ...args: Parameters): Promise parallel(thisArg: NoInfer>, name: K, ...args: Parameters): Promise ``` @@ -23,6 +30,12 @@ Dispatch an event, running all listeners concurrently. ### ctx.emit(name, ...args) ```ts website-api +/** + * Dispatch an event synchronously, ignoring listener return values. + * + * @param name — the event name. + * @param args — arguments passed to every listener. + */ emit(name: K, ...args: Parameters): void emit(thisArg: NoInfer>, name: K, ...args: Parameters): void ``` @@ -37,6 +50,13 @@ Dispatch an event synchronously, ignoring listener return values. ### ctx.serial(name, ...args) ```ts website-api +/** + * Dispatch an event, awaiting listeners in order until one bails. + * + * @param name — the event name. + * @param args — arguments passed to each listener. + * @returns the first bail value (non-null, non-false, non-undefined), if any. + */ serial(name: K, ...args: Parameters): Promisify> serial(thisArg: NoInfer>, name: K, ...args: Parameters): Promisify> ``` @@ -53,6 +73,13 @@ Dispatch an event, awaiting listeners in order until one bails. ### ctx.bail(name, ...args) ```ts website-api +/** + * Dispatch an event, calling listeners in order until one bails. + * + * @param name — the event name. + * @param args — arguments passed to each listener. + * @returns the first bail value (non-null, non-false, non-undefined), if any. + */ bail(name: K, ...args: Parameters): ReturnType bail(thisArg: NoInfer>, name: K, ...args: Parameters): ReturnType ``` @@ -69,6 +96,16 @@ Dispatch an event, calling listeners in order until one bails. ### ctx.waterfall(name, ...args) ```ts website-api +/** + * Dispatch an event whose last argument is a `next` continuation. + * + * Each listener wraps the rest of the chain: calling `next()` invokes the + * next listener (finally the built-in behavior); not calling it vetoes. + * + * @param name — the event name. + * @param args — listener arguments; the final one is the innermost `next`. + * @returns the outermost listener's return value. + */ waterfall(name: K, ...args: Parameters): ReturnType waterfall(thisArg: NoInfer>, name: K, ...args: Parameters): ReturnType ``` @@ -86,6 +123,14 @@ Each listener wraps the rest of the chain: calling `next()` invokes the next lis ### ctx.on(name, listener, options?) ```ts website-api +/** + * Register an event listener owned by the current fiber. + * + * @param name — the event name to listen for. + * @param listener — called with the dispatch arguments. + * @param options — listener options; a boolean is shorthand for `prepend`. + * @returns a disposer removing the listener; `true` if it was still registered. + */ on(name: K, listener: Events[K], options?: boolean | EventOptions): () => boolean ``` @@ -102,6 +147,14 @@ Register an event listener owned by the current fiber. ### ctx.once(name, listener, options?) ```ts website-api +/** + * Same as `on()`, but the listener disposes itself after its first call. + * + * @param name — the event name to listen for. + * @param listener — called at most once with the dispatch arguments. + * @param options — listener options; a boolean is shorthand for `prepend`. + * @returns a disposer removing the listener; `true` if it was still registered. + */ once(name: K, listener: Events[K], options?: boolean | EventOptions): () => boolean ``` @@ -120,6 +173,7 @@ Same as `on()`, but the listener disposes itself after its first call. Options accepted by `ctx.on()` and `ctx.once()`. ```ts website-api +/** Options accepted by `ctx.on()` and `ctx.once()`. */ interface EventOptions { /** Add the listener before existing listeners for the same event. */ prepend?: boolean @@ -136,6 +190,14 @@ Event dispatch strategy used by the event service. `emit` runs synchronous listeners without awaiting them, `parallel` awaits all listeners together, `serial` awaits them in order until one bails, `bail` stops on the first synchronous bail value, and `waterfall` composes listeners around a final `next` callback. ```ts website-api +/** + * Event dispatch strategy used by the event service. + * + * `emit` runs synchronous listeners without awaiting them, `parallel` awaits + * all listeners together, `serial` awaits them in order until one bails, + * `bail` stops on the first synchronous bail value, and `waterfall` composes + * listeners around a final `next` callback. + */ type DispatchMode = 'emit' | 'parallel' | 'serial' | 'bail' | 'waterfall' ``` diff --git a/website/zh-CN/api/cordis/fiber.md b/website/zh-CN/api/cordis/fiber.md index db93a6d273..f79adbaf20 100644 --- a/website/zh-CN/api/cordis/fiber.md +++ b/website/zh-CN/api/cordis/fiber.md @@ -7,6 +7,19 @@ A fiber is one loaded plugin instance: its lifecycle state, validated config, an ### ctx.effect(execute, label?) ```ts website-api +/** + * Register a cleanup-aware effect on this fiber. + * + * `execute` runs immediately; the disposers it produces are collected and + * run (in reverse order) either when the returned disposer is called or + * when the fiber unloads, whichever comes first. Calling the disposer twice + * is a no-op. Throws `CordisError('INACTIVE_EFFECT')` if the fiber is + * already disposed, and `TypeError` if `execute` returns an invalid shape. + * + * @param execute — the effect body; see {@link Effect} for accepted shapes. + * @param label — effect label shown in `getEffects()` diagnostics. + * @returns a disposer that tears the effect down and settles once done. + */ effect(execute: () => SyncEffect, label?: string): Disposable> effect(execute: () => Effect, label?: string): AsyncDisposable> ``` @@ -24,6 +37,7 @@ Register a cleanup-aware effect on this fiber. ### ctx.fiber ```ts website-api +/** The fiber (plugin runtime instance) that owns this context. */ fiber: Fiber ``` @@ -41,6 +55,7 @@ A fiber tracks dependency state, validated config, lifecycle effects, and cleanu ### fiber.uid ```ts website-api +/** Unique id within the registry; 0 for the root fiber, `null` once disposed. */ public uid: number | null ``` @@ -51,6 +66,7 @@ Unique id within the registry; 0 for the root fiber, `null` once disposed. ### fiber.ctx ```ts website-api +/** The context this fiber's plugin runs in (extends the parent context). */ public readonly ctx: Context ``` @@ -61,6 +77,7 @@ The context this fiber's plugin runs in (extends the parent context). ### fiber.config ```ts website-api +/** The validated plugin config (updated by `update()`). */ public config: any ``` @@ -71,6 +88,7 @@ The validated plugin config (updated by `update()`). ### fiber.state ```ts website-api +/** Current lifecycle state; transitions emit `internal/status`. */ public state ``` @@ -81,6 +99,7 @@ Current lifecycle state; transitions emit `internal/status`. ### fiber.dispose ```ts website-api +/** Dispose this fiber: unload the plugin, then settle once cleanup finished. */ public readonly dispose: () => Promise ``` @@ -91,6 +110,7 @@ Dispose this fiber: unload the plugin, then settle once cleanup finished. ### fiber.store ```ts website-api +/** Snapshot of required service implementations while loaded; `undefined` otherwise. */ public store: Dict | undefined ``` @@ -101,6 +121,7 @@ Snapshot of required service implementations while loaded; `undefined` otherwise ### fiber.inertia ```ts website-api +/** The in-flight load/unload transition, if one is currently running. */ public inertia: Promise | undefined ``` @@ -111,6 +132,7 @@ The in-flight load/unload transition, if one is currently running. ### fiber.name ```ts website-api +/** The plugin's display name, inherited from the nearest named ancestor, else `'root'`. */ get name() ``` @@ -121,6 +143,12 @@ The plugin's display name, inherited from the nearest named ancestor, else `'roo ### fiber.assertActive() ```ts website-api +/** + * Throw if the fiber has already been disposed. + * + * @returns nothing when the fiber is still active. + * @throws {CordisError} `INACTIVE_EFFECT` when the fiber's uid has been cleared. + */ assertActive() ``` @@ -133,6 +161,19 @@ Throw if the fiber has already been disposed. ### fiber.effect(execute, label?) ```ts website-api +/** + * Register a cleanup-aware effect on this fiber. + * + * `execute` runs immediately; the disposers it produces are collected and + * run (in reverse order) either when the returned disposer is called or + * when the fiber unloads, whichever comes first. Calling the disposer twice + * is a no-op. Throws `CordisError('INACTIVE_EFFECT')` if the fiber is + * already disposed, and `TypeError` if `execute` returns an invalid shape. + * + * @param execute — the effect body; see {@link Effect} for accepted shapes. + * @param label — effect label shown in `getEffects()` diagnostics. + * @returns a disposer that tears the effect down and settles once done. + */ effect(execute: () => SyncEffect, label?: string): Disposable> effect(execute: () => Effect, label?: string): AsyncDisposable> ``` @@ -150,6 +191,11 @@ Register a cleanup-aware effect on this fiber. ### fiber.getEffects() ```ts website-api +/** + * Return metadata for currently registered effects. + * + * @returns one {@link EffectMeta} tree per labeled live effect. + */ getEffects() ``` @@ -162,6 +208,12 @@ Return metadata for currently registered effects. ### fiber.await() ```ts website-api +/** + * Wait for current lifecycle work and rethrow startup errors. + * + * @returns this fiber, once it has settled into a stable state. + * @throws the config-validation or plugin-startup error, if any. + */ async await() ``` @@ -174,6 +226,12 @@ Wait for current lifecycle work and rethrow startup errors. ### fiber.restart() ```ts website-api +/** + * Dispose and immediately reload this plugin with its current config. + * + * @returns a promise resolving once the reload settled. + * @throws {CordisError} `INACTIVE_EFFECT` when the fiber is already disposed. + */ async restart() ``` @@ -186,6 +244,17 @@ Dispose and immediately reload this plugin with its current config. ### fiber.update(config, noSave?) ```ts website-api +/** + * Validate and apply new config, then restart the plugin. + * + * Runs the `internal/update` waterfall first, so update hooks (and HMR) + * can veto or replace the restart. + * + * @param config — the new raw config; validated before anything restarts. + * @param noSave — hint for persistence hooks not to write the change back. + * @returns nothing; the restart runs behind the `internal/update` waterfall. + * @throws {ValidationError} when the new config fails validation. + */ update(config: any, noSave = false) ``` @@ -205,6 +274,13 @@ Effect body result accepted by `ctx.effect()` and plugin startup. Either a single disposer, a promise of one, or a (possibly async) iterable yielding several — generator effects register each yielded disposer as it is produced. ```ts website-api +/** + * Effect body result accepted by `ctx.effect()` and plugin startup. + * + * Either a single disposer, a promise of one, or a (possibly async) iterable + * yielding several — generator effects register each yielded disposer as it + * is produced. + */ type Effect = | SyncEffect | AsyncEffect @@ -218,6 +294,12 @@ Function returned by an effect to release resources during disposal. Disposers run in reverse registration order when the owning fiber unloads; they may be async, in which case unloading awaits them. ```ts website-api +/** + * Function returned by an effect to release resources during disposal. + * + * Disposers run in reverse registration order when the owning fiber unloads; + * they may be async, in which case unloading awaits them. + */ type Disposable = () => T ``` @@ -228,6 +310,7 @@ type Disposable = () => T Tree node used to expose nested effect labels for diagnostics. ```ts website-api +/** Tree node used to expose nested effect labels for diagnostics. */ interface EffectMeta { /** Human-readable effect label, e.g. `ctx.on("event")` or `ctx.provide("name")`. */ label: string @@ -243,6 +326,7 @@ interface EffectMeta { Framework error with a stable machine-readable code. ```ts website-api +/** Framework error with a stable machine-readable code. */ class CordisError extends Error { /** * @param code — the stable error code; also the default message. @@ -251,6 +335,7 @@ class CordisError extends Error { constructor(public code: CordisError.Code, message?: string) } +/** Cordis error code definitions. */ namespace CordisError { export type Code = keyof typeof Code @@ -267,6 +352,7 @@ namespace CordisError { Error raised when plugin configuration fails standard-schema validation. ```ts website-api +/** Error raised when plugin configuration fails standard-schema validation. */ class ValidationError extends TypeError { name = 'ValidationError' diff --git a/website/zh-CN/api/cordis/registry.md b/website/zh-CN/api/cordis/registry.md index 55f6d666e5..f91f5a72af 100644 --- a/website/zh-CN/api/cordis/registry.md +++ b/website/zh-CN/api/cordis/registry.md @@ -7,6 +7,16 @@ Plugin loading and dependency injection. ### ctx.inject(deps, callback) ```ts website-api +/** + * Run a callback once the requested services are available. + * + * Shorthand for `ctx.plugin({ inject, apply: callback })`: the callback + * is unloaded and re-run whenever a required service changes. + * + * @param deps — required services, as an array or a name → config map. + * @param callback — plugin body called with `(ctx, config)`. + * @returns the fiber; awaiting it settles once loading finished. + */ inject(deps: Inject, callback: Plugin.Function): Fiber & PromiseLike ``` @@ -23,6 +33,14 @@ Shorthand for `ctx.plugin({ inject, apply: callback })`: the callback is unloade ### ctx.plugin(plugin, ...args) ```ts website-api +/** + * Load a plugin in the current context. + * + * @param plugin — a function, class, or `{ apply }` object plugin. + * @param args — the plugin config, validated against its `Config` schema. + * @returns the fiber; awaiting it settles once loading finished + * (rejecting on config or startup errors). + */ plugin

(plugin: P, ...args: Spread>): Fiber & PromiseLike ``` @@ -40,11 +58,13 @@ Load a plugin in the current context. Supported plugin entrypoint shapes. ```ts website-api +/** Supported plugin entrypoint shapes. */ type Plugin = | Plugin.Function | Plugin.Constructor | Plugin.Object +/** Types associated with plugin entrypoints and runtime records. */ namespace Plugin { /** Shared metadata understood by the plugin registry and related tooling. */ export interface Base { @@ -104,8 +124,16 @@ Service dependency declaration accepted by plugins and the `@Inject` decorator. Array form requests services without intercept config. Object form maps each service name to optional intercept config for the plugin context. ```ts website-api +/** + * Service dependency declaration accepted by plugins and the `@Inject` + * decorator. + * + * Array form requests services without intercept config. Object form maps each + * service name to optional intercept config for the plugin context. + */ type Inject = (keyof M)[] | { [K in keyof M]?: M[K] } +/** Utilities for normalizing plugin dependency declarations. */ namespace Inject { /** * Convert array/object/class-inherited inject metadata into a plain map. diff --git a/website/zh-CN/api/cordis/service.md b/website/zh-CN/api/cordis/service.md index acd43163d6..13aa82a2ca 100644 --- a/website/zh-CN/api/cordis/service.md +++ b/website/zh-CN/api/cordis/service.md @@ -12,6 +12,7 @@ Subclasses call `super(ctx, name)` from their constructor. The service is regist ### service.name ```ts website-api +/** The service name this instance is registered under. */ public name!: string ``` @@ -24,6 +25,7 @@ The service name this instance is registered under. ### Service.init ```ts website-api +/** Symbol key of an instance method run after construction (class plugins). */ static readonly init: unique symbol ``` @@ -34,6 +36,7 @@ Symbol key of an instance method run after construction (class plugins). ### Service.check ```ts website-api +/** Symbol key of the availability predicate passed to `ctx.provide()`. */ static readonly check: unique symbol ``` @@ -44,6 +47,7 @@ Symbol key of the availability predicate passed to `ctx.provide()`. ### Service.config ```ts website-api +/** Symbol key of the phantom intercept-config type parameter. */ static readonly config: unique symbol ``` @@ -54,6 +58,7 @@ Symbol key of the phantom intercept-config type parameter. ### Service.invoke ```ts website-api +/** Symbol key of the call body making a service callable (e.g. `ctx.logger()`). */ static readonly invoke: unique symbol ``` @@ -64,6 +69,7 @@ Symbol key of the call body making a service callable (e.g. `ctx.logger()`). ### Service.extend ```ts website-api +/** Symbol key of the helper deriving an extended service instance. */ static readonly extend: unique symbol ``` @@ -74,6 +80,7 @@ Symbol key of the helper deriving an extended service instance. ### Service.tracker ```ts website-api +/** Symbol key of the tracker metadata used for context tracing. */ static readonly tracker: unique symbol ``` @@ -84,6 +91,7 @@ Symbol key of the tracker metadata used for context tracing. ### Service.resolveConfig ```ts website-api +/** Symbol key of the intercept-config resolution helper below. */ static readonly resolveConfig: unique symbol ``` diff --git a/website/zh-CN/api/harness/agent-loop.md b/website/zh-CN/api/harness/agent-loop.md index 6401898e24..9a43a1ba14 100644 --- a/website/zh-CN/api/harness/agent-loop.md +++ b/website/zh-CN/api/harness/agent-loop.md @@ -11,6 +11,15 @@ Concrete agent factory and driver service. ### ctx.agentLoop.create(id, options?, meta?) ```ts website-api +/** + * Create an agent and session under one caller-supplied identity, owned by + * the accessing fiber. Constructor-driven config calls mint a fresh combined + * id before entering this boundary. + * @param id - shared agent/session identity. + * @param options - concrete loop options. + * @param meta - optional fresh-session workspace metadata. + * @returns the published running agent. + */ create(id: SessionId, options: AgentOptions = {}, meta: Pick = {}): Agent ``` @@ -27,6 +36,12 @@ Create an agent and session under one caller-supplied identity, owned by the acc ### ctx.agentLoop.createAgent(ownerCtx, options) ```ts website-api +/** + * Create an owned agent on a caller-supplied session id. + * @param ownerCtx - caller context that structurally owns the transaction. + * @param options - identities, session seed/metadata, loop options, setup, and cancellation. + * @returns the published handle. + */ async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise ``` @@ -42,6 +57,12 @@ Create an owned agent on a caller-supplied session id. ### ctx.agentLoop.resume(ownerCtx, options) ```ts website-api +/** + * Resume an owned agent from the configured persistence service. + * @param ownerCtx - caller context that owns load, setup, and the live lifecycle. + * @param options - persisted identity, loop options, setup, and cancellation. + * @returns the published handle. + */ async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise ``` diff --git a/website/zh-CN/api/harness/agents.md b/website/zh-CN/api/harness/agents.md index 8d6c84cc7a..f92f69bbeb 100644 --- a/website/zh-CN/api/harness/agents.md +++ b/website/zh-CN/api/harness/agents.md @@ -11,6 +11,18 @@ Agent registry (`ctx.agents`): tracks live agents so UI, hook, and orchestrator ### ctx.agents.setFactory(factory) ```ts website-api +/** + * Register the agent-creation factory (the loop calls this on construction, + * effect-scoped). A traced Cordis service is canonicalized to its concrete + * target; each create/resume call is then traced through that caller's + * context so ownership follows the caller without stacking proxy layers. + * Throws if a factory is already registered. Returns the disposer; on + * dispose the factory slot is cleared. + * @param factory - the loop-owned factory {@link create}/{@link resume} delegate to. + * @returns the disposer that clears the factory slot. The exact + * Cordis effect disposer (single-shot): composite (generator) effects may + * yield it directly — exact identity nests the teardown in order. + */ setFactory(factory: AgentFactory): () => void ``` @@ -25,6 +37,15 @@ Register the agent-creation factory (the loop calls this on construction, effect ### ctx.agents.create(options) ```ts website-api +/** + * Create and publish a new agent through the registered factory. + * Distinct from {@link register} (which records an already-constructed + * agent): this constructs the agent and its session. Rejects if no factory is + * registered or creation/setup fails. The resolved {@link AgentHandle} lets + * the owner tear down exactly this agent. + * @param options - shared identity, session seed/metadata, and agent options. + * @returns the handle after setup, rollback-covered publication, and loop start complete. + */ async create(options: CreateAgentOptions): Promise ``` @@ -39,6 +60,13 @@ Create and publish a new agent through the registered factory. Distinct from reg ### ctx.agents.resume(options) ```ts website-api +/** + * Load a persisted session and resume an agent on it through the registered + * factory. Rejects if no factory is registered; the factory rejects if + * session persistence is not configured or persistence/setup fails. + * @param options - persisted identity, configuration, and optional setup. + * @returns the handle after setup, rollback-covered publication, and loop start complete. + */ async resume(options: ResumeAgentOptions): Promise ``` @@ -53,6 +81,24 @@ Load a persisted session and resume an agent on it through the registered factor ### ctx.agents.register(agent) ```ts website-api +/** + * Register a live agent. Throws if an agent with the same id is already + * registered. Emits `agent/created` on registration and `agent/disposed` + * when the calling fiber is disposed — both with the agent's scope carrier + * (`scopeTarget(agent, agent)`): the subject is the agent in hand, so the + * emits are scope-filtered regardless of which context invoked `register` + * (calling through `agent.ctx` scopes EFFECTS; dispatch scoping always + * requires passing the carrier). Returns the disposer. + * @param agent - the already-constructed agent to record in the store. + * @returns the EXACT Cordis effect disposer (single-shot; a repeat call + * returns undefined without awaiting an in-flight teardown). Exact + * identity is load-bearing: a composite (generator) effect that owns a + * teardown ORDER — the agent factory's lifecycle chain — must yield THIS + * function so Cordis nests the unregistration at that yield position; + * yielding a wrapper would leave it disposing as a concurrent sibling on + * owner unload, unregistering the agent (and emitting `agent/disposed`) + * while its final turn is still draining. + */ register(agent: Agent): () => void ``` @@ -67,6 +113,21 @@ Register a live agent. Throws if an agent with the same id is already registered ### ctx.agents.enter(agent, owner) ```ts website-api +/** + * Insert an already-constructed agent without announcing it. This is the + * advanced ordered-lifecycle primitive used by the async agent factory: it + * first completes setup while the agent is unpublished, then assigns the + * returned detach closure into its pre-installed composite teardown before + * calling {@link announce}. Ordinary callers use {@link register}. + * @param agent - the prepared, unpublished agent. + * @param owner - live agent whose scoped context created this agent, or + * undefined for a top-level runtime root. This is runtime ownership, not + * the resumed session's durable parent lineage. + * @returns an idempotent closure that removes this exact entry and emits + * `agent/disposed` with listener failures contained. When called from a + * synchronous `agent/created` listener, removal and disposal wait until + * that creation dispatch unwinds. + */ enter(agent: Agent, owner: Agent | undefined): () => void ``` @@ -82,6 +143,13 @@ Insert an already-constructed agent without announcing it. This is the advanced ### ctx.agents.announce(agent) ```ts website-api +/** + * Announce an agent previously inserted with {@link enter}. + * @param agent - the live inserted agent to announce. + * @throws if `agent` is not the exact live registry entry for its id, or its + * creation announcement already began (including a reentrant call from a + * creation listener). + */ announce(agent: Agent): void ``` @@ -94,6 +162,11 @@ Announce an agent previously inserted with enter. ### ctx.agents.get(id) ```ts website-api +/** + * Look up a live agent. + * @param id - the shared agent/session id to look up. + * @returns the agent, or undefined when no live agent has that id. + */ get(id: SessionId): Agent | undefined ``` @@ -108,6 +181,14 @@ Look up a live agent. ### ctx.agents.isOwnedBy(id, owner) ```ts website-api +/** + * Test whether a live agent was created through one exact parent agent's + * scoped context. Runtime ownership is independent of durable session + * lineage and remains unambiguous when unrelated providers reuse an id. + * @param id - the candidate child agent's shared agent/session id. + * @param owner - the expected runtime creator agent. + * @returns true only while the exact child entry is live under that owner. + */ isOwnedBy(id: SessionId, owner: Agent): boolean ``` @@ -123,6 +204,10 @@ Test whether a live agent was created through one exact parent agent's scoped co ### ctx.agents.list() ```ts website-api +/** + * All live agents, in registration order. + * @returns a fresh array; mutating it does not affect the registry. + */ list(): Agent[] ``` @@ -135,6 +220,12 @@ All live agents, in registration order. ### ctx.agents.roots() ```ts website-api +/** + * All live top-level agents in registration order. A top-level agent was + * created without an owning agent context; durable session lineage does not + * affect this runtime relation, so a resumed fork may still be a root. + * @returns a fresh array; mutating it does not affect the registry. + */ roots(): Agent[] ``` diff --git a/website/zh-CN/api/harness/approval.md b/website/zh-CN/api/harness/approval.md index fe3b090016..4aa2b8ad2d 100644 --- a/website/zh-CN/api/harness/approval.md +++ b/website/zh-CN/api/harness/approval.md @@ -11,6 +11,24 @@ Approval service that applies session policy before answerers and logs every ask ### ctx.approval.request(req) ```ts website-api +/** + * Ask the composed answerers to decide one readonly same-process request. + * The service borrows the request, agent, session, and live signal directly. + * The request requires an open turn because the audit pair must be enclosed + * by the durable log's commit/replay boundary; an idle ask rejects before + * appending anything. The answerer phase always produces an outcome: an + * aborted signal yields `'cancelled'`, a missing or throwing answerer yields + * `'unavailable'` (fail closed), and a rogue non-vocabulary return value is + * normalized to `'unavailable'`. A failure that prevents either audit append + * from committing still rejects because returning an unlogged decision would + * violate the pair. Session contains post-commit observer failures, so an + * authoritative append cannot reject the request or suppress its matching + * audit event. + * @param req - the pending decision (agent, tool identity, reason, signal). + * @returns the closed outcome; `'allowed-once'` is the only grant. + * @throws when no turn is open or either audit event fails before the session + * append commit point. + */ async request(req: ApprovalRequest): Promise ``` diff --git a/website/zh-CN/api/harness/bash-env.md b/website/zh-CN/api/harness/bash-env.md index f8baf32bac..906464080e 100644 --- a/website/zh-CN/api/harness/bash-env.md +++ b/website/zh-CN/api/harness/bash-env.md @@ -11,6 +11,12 @@ Registry (`ctx.bashEnv`) for trusted, per-execution `DSH_*` variables. The names ### ctx.bashEnv.register(contributor) ```ts website-api +/** + * Register one environment contributor. Names and keys are unique; built-in + * keys are reserved. Registration is disposed with the calling plugin fiber. + * @param contributor - declared key ownership and per-execution resolver. + * @returns the disposer that unregisters the contribution. + */ register(contributor: BashEnvContributor): () => void ``` @@ -25,6 +31,11 @@ Register one environment contributor. Names and keys are unique; built-in keys a ### ctx.bashEnv.collect(execution) ```ts website-api +/** + * Build the trusted `DSH_*` snapshot for one bash tool execution. + * @param execution - the current tool execution. + * @returns an immutable environment overlay containing built-ins and current contributions. + */ collect(execution: ToolExecution): DshEnvironment ``` @@ -39,6 +50,10 @@ Build the trusted `DSH_*` snapshot for one bash tool execution. ### ctx.bashEnv.list() ```ts website-api +/** + * Enumerate plugin-contributed variables without executing their resolvers. + * @returns declarations sorted by environment variable name. + */ list(): BashEnvVariableInfo[] ``` diff --git a/website/zh-CN/api/harness/bash.md b/website/zh-CN/api/harness/bash.md index c3e4173763..f340697063 100644 --- a/website/zh-CN/api/harness/bash.md +++ b/website/zh-CN/api/harness/bash.md @@ -16,6 +16,11 @@ Implementations must honor these semantics: ### ctx.bash.sandboxMode ```ts website-api +/** + * The sandbox mode this executor applies by default, or `undefined` when it + * does not sandbox commands. + * @returns the configured default sandbox mode, when supported. + */ get sandboxMode(): SandboxMode | undefined ``` @@ -26,6 +31,12 @@ The sandbox mode this executor applies by default, or `undefined` when it does n ### ctx.bash.resolve(request) ```ts website-api +/** + * Apply implementation-owned defaults and caps to a request before execution. + * @param request - the caller's request; omitted fields get this + * implementation's defaults, capped fields are clamped. + * @returns the fully-specified spec to hand to {@link run}/{@link start}. + */ abstract resolve(request: BashExecRequest): BashExecSpec ``` @@ -40,6 +51,12 @@ Apply implementation-owned defaults and caps to a request before execution. ### ctx.bash.run(spec) ```ts website-api +/** + * Run a command in the foreground; resolves when it finishes. + * @param spec - a resolved spec from {@link resolve}, never a raw request. + * @returns the outcome; nonzero exits, timeout kills, and abort kills + * resolve with a descriptive result rather than reject. + */ abstract run(spec: BashExecSpec): Promise ``` @@ -54,6 +71,11 @@ Run a command in the foreground; resolves when it finishes. ### ctx.bash.start(spec) ```ts website-api +/** + * Start a background process and return its handle immediately. + * @param spec - a resolved spec from {@link resolve}, never a raw request. + * @returns the live process handle (reads, kill, quiescence promise). + */ abstract start(spec: BashExecSpec): BashProcess ``` diff --git a/website/zh-CN/api/harness/code-runtime.md b/website/zh-CN/api/harness/code-runtime.md index ee8300a9f0..fef72ce525 100644 --- a/website/zh-CN/api/harness/code-runtime.md +++ b/website/zh-CN/api/harness/code-runtime.md @@ -11,6 +11,13 @@ Registers one `ctx.codeRuntime` implementation. Program, budget, abort, and subs ### ctx.codeRuntime.language ```ts website-api +/** + * The source language {@link run} expects `program` to be written in, as a + * lowercase identifier. Informational, not gating — a consumer that + * generates language-specific presentation (typed SDK stubs, usage + * instructions) switches on it and fails loud on a language it cannot + * present. Well-known value: `'typescript'`. + */ abstract readonly language: string ``` @@ -21,6 +28,12 @@ The source language run expects `program` to be written in, as a lowercase ident ### ctx.codeRuntime.isolation ```ts website-api +/** + * The execution substrate, as a lowercase identifier. Informational, not + * gating — a descriptor so deployments and diagnostics can tell backends + * apart, not a security claim. Well-known values: `'worker-thread'`, + * `'process'`, `'container'`. + */ abstract readonly isolation: string ``` @@ -31,6 +44,15 @@ The execution substrate, as a lowercase identifier. Informational, not gating ### ctx.codeRuntime.run(request) ```ts website-api +/** + * Execute one program against the request's bindings and capture what it + * emitted. See the class doc for the resolution contract (error is a result + * field; rejection means seam misuse only). + * @param request - the program, its bindings, and the abort signal; the + * request carries everything the runtime acts on, with no hidden defaults. + * @returns the run's outcome: completion value (when transferable), the + * ordered log capture, and the failure (if any). + */ abstract run(request: CodeRunRequest): Promise ``` diff --git a/website/zh-CN/api/harness/compact.md b/website/zh-CN/api/harness/compact.md index 67f17cc941..e06188ee27 100644 --- a/website/zh-CN/api/harness/compact.md +++ b/website/zh-CN/api/harness/compact.md @@ -11,6 +11,21 @@ Abstract compaction service. Implementations own trigger policy, retention, and ### ctx.compact.compactIfNeeded(agent, fullSystemPrompt, sessionPrefix, signal) ```ts website-api +/** + * Check token pressure and compact if the conversation is too large. + * Estimate the next request, including its session prefix, derived history, + * and system prompt. Above threshold, compact a head-anchored range ending at + * a balanced tool boundary and reconsolidate any prior automatic checkpoint. + * Return `null` when no compaction is needed or an open tail leaves no safe + * cutoff. A single oversized retained unit or prefix cannot be repaired here. + * + * @param agent - agent context owning the session surface and model options. + * @param fullSystemPrompt - assembled system prompt, counted toward the estimate. + * @param sessionPrefix - the instance's composed session prefix, counted toward the + * estimate. + * @param signal - cancellation signal; model-backed implementations must forward it. + * @returns the compaction result, or `null` if no compaction was needed. + */ abstract compactIfNeeded( agent: CompactAgentContext, fullSystemPrompt: string, sessionPrefix: readonly Message[], signal: AbortSignal, ): Promise ``` @@ -28,6 +43,23 @@ Check token pressure and compact if the conversation is too large. Estimate the ### ctx.compact.compactRegion(start, end, agent, signal?) ```ts website-api +/** + * Forcibly compact a range of surface nodes into a single summary node. + * `start` and `end` name an inclusive span by surface position, not numeric seq + * order; replacements can make visible seqs non-monotonic. Both edges must be + * balanced so assistant tool calls remain paired with their results. A model- + * backed implementation forwards cancellation and rejects active, missing, + * reversed, or unbalanced ranges. The target session is `agent.session`. + * Use {@link toolPairingBalancedBefore} and {@link toolPairingBalancedAfter} + * for the edge checks. + * + * @param start - first surface seq, inclusive. + * @param end - last surface seq, inclusive. + * @param agent - context whose session is mutated and whose routing options guide summarization. + * @param signal - optional cancellation; model-backed implementations must forward it. + * @throws when compaction is active or the range is missing, reversed, or unbalanced. + * @returns the appended event seqs, summary, replaced range, and token accounting. + */ abstract compactRegion( start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise ``` diff --git a/website/zh-CN/api/harness/events.md b/website/zh-CN/api/harness/events.md index 8d494739ba..fcfa426a81 100644 --- a/website/zh-CN/api/harness/events.md +++ b/website/zh-CN/api/harness/events.md @@ -11,6 +11,16 @@ Every event the harness packages declare on the cordis event bus (40 total), gro **Mode:** `emit` ```ts website-api +/** + * A fully configured agent and live session were published. Setup is + * composition-only; `agent/session-start` is the first startup-driving seam. + * Synchronous listener failure vetoes publication, while returned-promise + * rejection is reported. Detach requested during dispatch waits until every + * creation listener has observed the stable entry. + * @param agent - the newly registered agent with its live session and completed setup. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode emit + */ 'agent/created'(this: Scoped, agent: Agent): void ``` @@ -25,6 +35,14 @@ A fully configured agent and live session were published. Setup is composition-o **Mode:** `emit` ```ts website-api +/** + * An agent left the registry; AgentLoop emits this after driver quiescence + * but before session detachment and scoped-registration unwind. Custom + * registry users own their driver-ordering contract. + * @param agent - the exact agent removed from the registry. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode emit + */ 'agent/disposed'(this: Scoped, agent: Agent): void ``` @@ -39,6 +57,16 @@ An agent left the registry; AgentLoop emits this after driver quiescence but bef **Mode:** `emit` ```ts website-api +/** + * A step or turn errored. The loop reports a failure here (plus the logger) + * even when the error has no in-turn position for a session `error` event. + * @param agent - the agent whose turn errored. + * @param turn - the turn in which the failure surfaced. + * @param step - the step at which the failure surfaced. + * @param error - the failure, verbatim. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode emit + */ 'agent/error'(this: Scoped, agent: Agent, turn: number, step: number, error: Error): void ``` @@ -56,6 +84,22 @@ A step or turn errored. The loop reports a failure here (plus the logger) even w **Mode:** `serial` ```ts website-api +/** + * Awaited serial checkpoint for session-surface mutation after prompt + * assembly and before `step/start`; appends land outside the pending step. + * The loop derives history once afterward, so compaction records and + * replacements are included without rewriting an assembled request. The + * prompt and prefix are the exact pressure inputs for that request, and + * `signal` cancels listener work. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @param agent - the agent opening the step. + * @param turn - the open turn number. + * @param step - the pending step number. + * @param fullSystemPrompt - the assembled prompt. + * @param sessionPrefix - the frozen request prefix. + * @param signal - the turn abort signal. + * @mode serial + */ 'agent/pre-step'(this: Scoped, agent: Agent, turn: number, step: number, fullSystemPrompt: string, sessionPrefix: readonly Message[], signal: AbortSignal): Promise | void ``` @@ -75,6 +119,15 @@ Awaited serial checkpoint for session-surface mutation after prompt assembly and **Mode:** `waterfall` ```ts website-api +/** + * Allow, rewrite, or block one drained prompt before it becomes a user + * message. Call `next()` for the unchanged default. + * @param agent - the agent draining its inbox. + * @param content - the drained message's blocks, as queued. + * @param source - the message's resolved source. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode waterfall + */ 'agent/prompt-submit'(this: Scoped, agent: Agent, content: ContentBlock[], source: MessageSource, next: () => Promise): Promise ``` @@ -91,6 +144,15 @@ Allow, rewrite, or block one drained prompt before it becomes a user message. Ca **Mode:** `emit` ```ts website-api +/** + * Detached, frozen content entered the agent's inbox. Source defaults have + * already been applied, so these are the exact values retained for the log. + * @param agent - the agent whose inbox received the message. + * @param content - the accepted content blocks retained by the inbox. + * @param info - the accepted source plus whether it entered as steering. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode emit + */ 'agent/queued'(this: Scoped, agent: Agent, content: ContentBlock[], info: { source: MessageSource; steering: boolean }): void ``` @@ -107,6 +169,17 @@ Detached, frozen content entered the agent's inbox. Source defaults have already **Mode:** `waterfall` ```ts website-api +/** + * Replace the frozen call configuration. Model-visible content must use + * logged channels; this seam cannot mutate messages. Injection here joins + * the next request because the current step boundary is already fixed. + * @param agent - the agent making the model call. + * @param turn - the open turn number. + * @param step - the step whose request this is. + * @param config - the config the loop would use (frozen); return a replacement to switch. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode waterfall + */ 'agent/request'(this: Scoped, agent: Agent, turn: number, step: number, config: LlmCallConfig, next: () => Promise): Promise ``` @@ -124,6 +197,20 @@ Replace the frozen call configuration. Model-visible content must use logged cha **Mode:** `waterfall` ```ts website-api +/** + * Compose request-only messages placed before derived history. The frozen + * result is computed once per loop instance, logged on its anchoring request + * header, and reused so the provider prefix remains stable. Interrupted + * composition is discarded. Composition precedes the first `agent/pre-step` + * and request boundary, so listener appends join the current request and + * pressure accounting sees the composed prefix. Changing context belongs in + * history; contributors should prepend to `await next()` to preserve registration order. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @param agent - the agent whose session prefix is being composed. + * @param prefix - the frozen seed; return an extended replacement. + * @param signal - aborts composition when the step is torn down. + * @mode waterfall + */ 'agent/session-prefix'(this: Scoped, agent: Agent, prefix: Message[], signal: AbortSignal, next: () => Promise): Promise ``` @@ -140,6 +227,16 @@ Compose request-only messages placed before derived history. The frozen result i **Mode:** `emit` ```ts website-api +/** + * The session lifecycle began, once before the first turn. Use + * `agent.inject()` to seed model-facing context. This is a notification, not + * a veto; disposal requested by a lifecycle owner is rechecked before the + * driver starts. + * @param agent - the agent whose session lifecycle began. + * @param source - why the session started (fresh startup, resume, …). + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode emit + */ 'agent/session-start'(this: Scoped, agent: Agent, source: SessionStartSource): void ``` @@ -155,6 +252,14 @@ The session lifecycle began, once before the first turn. Use `agent.inject()` to **Mode:** `emit` ```ts website-api +/** + * Agent status changed (`idle` ⇄ `running`, or → `disposed`). `send()` does + * not enter `running` synchronously; drive lifecycle from this event. + * @param agent - the agent whose status flipped. + * @param status - the status just entered (the transition's destination). + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode emit + */ 'agent/status'(this: Scoped, agent: Agent, status: AgentStatus): void ``` @@ -170,6 +275,16 @@ Agent status changed (`idle` ⇄ `running`, or → `disposed`). `send()` does no **Mode:** `waterfall` ```ts website-api +/** + * Waterfall: post-process the assembled assistant {@link Message} before + * tool dispatch (validation, content rewriting, …). + * @param agent - the agent that received the step's response. + * @param turn - the open turn number. + * @param step - the step that produced the message. + * @param message - the assistant message as assembled from the stream. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode waterfall + */ 'agent/step-result'(this: Scoped, agent: Agent, turn: number, step: number, message: Message, next: () => Promise): Promise ``` @@ -187,6 +302,15 @@ Waterfall: post-process the assembled assistant Message before tool dispatch (va **Mode:** `waterfall` ```ts website-api +/** + * Override whether the turn continues. The default continues after tool + * calls or steering and stops otherwise; a continue reason becomes steering. + * @param agent - the agent deciding whether to run another step. + * @param turn - the turn being continued or stopped. + * @param defaultDecision - what the loop would do absent an override. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode waterfall + */ 'agent/turn-continuation'(this: Scoped, agent: Agent, turn: number, defaultDecision: ContinuationDecision, next: () => Promise): Promise ``` @@ -203,6 +327,15 @@ Override whether the turn continues. The default continues after tool calls or s **Mode:** `serial` ```ts website-api +/** + * Monotonic terminal-stop checkpoint after continuation and steering are + * folded; a stop remains authoritative through turn close and flush: + * steering queued in that window is discarded, while ordinary sends survive. + * @param agent - the agent whose composed continuation outcome may be stopped. + * @param turn - the turn at its terminal-stop checkpoint. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @mode serial + */ 'agent/turn-stop'(this: Scoped, agent: Agent, turn: number): ContinuationStop | undefined ``` @@ -220,6 +353,15 @@ Monotonic terminal-stop checkpoint after continuation and steering are folded; a **Mode:** `emit` ```ts website-api +/** + * A declarative agent entry failed before it could publish a live agent. + * Consumers that buffer work for the configured identity use this + * transient signal to reject that work instead of waiting forever. Normal + * factory teardown suppresses failures from the cancelled startup attempt. + * @param sessionId - exact shared agent/session identity that failed startup. + * @param error - persistence, setup, or publication failure. + * @mode emit + */ 'agent-loop/config-start-failed'(sessionId: SessionId, error: unknown): void ``` @@ -237,6 +379,13 @@ A declarative agent entry failed before it could publish a live agent. Consumers **Mode:** `waterfall` ```ts website-api +/** + * Ask composed answerers for one decision. Return an outcome to claim the + * request or call `next()`; failure yields the fail-closed default. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent. + * @param req - the pending decision (agent, tool identity, reason, signal). + * @mode waterfall + */ 'approval/request'(this: Scoped, req: ApprovalRequest, next: () => Promise): Promise ``` @@ -253,6 +402,13 @@ Ask composed answerers for one decision. Return an outcome to claim the request **Mode:** `waterfall` ```ts website-api +/** + * Single-slot decision for the next {@link FileSystem.editText}. Calling + * `next()` yields an unconditional edit; the first returned guard wins. + * @param target - the resolved target about to be edited. + * @param actor - the opaque tool-execution context the decider keys off. + * @mode waterfall + */ 'fs/edit-intent'(target: FsTarget, actor: object | undefined, next: () => { version: FsVersion } | undefined | Promise<{ version: FsVersion } | undefined>): Promise<{ version: FsVersion } | undefined> ``` @@ -268,6 +424,14 @@ Single-slot decision for the next FileSystem.editText. Calling `next()` yields a **Mode:** `emit` ```ts website-api +/** + * Record a successful observation. Listeners must be synchronous recorders: + * throws fail the tool call and returned promises are not awaited. + * @param target - the target that was read/written/edited. + * @param version - the version the actor now holds as its observation. + * @param actor - the observing tool-execution context; undefined records nothing useful. + * @mode emit + */ 'fs/observed'(target: FsTarget, version: FsVersion, actor: object | undefined): void ``` @@ -284,6 +448,14 @@ Record a successful observation. Listeners must be synchronous recorders: throws **Mode:** `waterfall` ```ts website-api +/** + * Single-slot decision for the next {@link FileSystem.writeText}. Calling + * `next()` yields the bare provider's unconditional write; the first listener + * that returns an intent owns the decision rather than composing with peers. + * @param target - the resolved target about to be written. + * @param actor - the opaque tool-execution context the decider keys off. + * @mode waterfall + */ 'fs/write-intent'(target: FsTarget, actor: object | undefined, next: () => FsWriteIntent | undefined | Promise): Promise ``` @@ -301,6 +473,17 @@ Single-slot decision for the next FileSystem.writeText. Calling `next()` yields **Mode:** `waterfall` ```ts website-api +/** + * Waterfall around every streaming model call (retry, replay, routing). + * Bound to the {@link LlmService}; call `next()` to reach the resolved + * adapter's stream, or yield your own chunks to short-circuit. + * @param options - the full request. A LOOP-built request arrives + * deep-frozen (mutation throws): its content is a pure function of the + * session log (the reconstructability RFC), so listeners read it, never + * rewrite it. A hand-built one-shot (compaction summarize) is the + * caller's own object and stays mutable here. + * @mode waterfall + */ 'llm/stream'(this: LlmService, options: GenerateOptions, next: () => AsyncIterable): AsyncIterable ``` @@ -317,6 +500,17 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t **Mode:** `emit` ```ts website-api +/** + * Creation announcement during session publication. A synchronous throw vetoes and rolls + * back with a paired disposal; detach requested during dispatch is deferred. + * A returned-promise rejection is logged but cannot retroactively veto this + * synchronous boundary. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners + * receive only sessions entered through that agent's context. + * @param session - the session just entered and announced. + * @dshScopeScan unsupported + * @mode emit + */ 'session/created'(this: Scoped, session: Session): void ``` @@ -331,6 +525,15 @@ Creation announcement during session publication. A synchronous throw vetoes and **Mode:** `emit` ```ts website-api +/** + * Emitted once when an announced session leaves the store, including + * publication rollback, but never for an entry whose creation announcement + * did not begin. Listener failures are logged and contained. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`) reuses the owner scope. + * @param session - the session that is no longer live in the store. + * @dshScopeScan unsupported + * @mode emit + */ 'session/disposed'(this: Scoped, session: Session): void ``` @@ -345,6 +548,17 @@ Emitted once when an announced session leaves the store, including publication r **Mode:** `emit` ```ts website-api +/** + * Post-commit, fire-and-forget append feed. The listener snapshot resolves + * before the log push, but callbacks run after it; observer failures are + * logged and contained without making the committed append fail. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners + * receive only events from sessions entered through that agent's context. + * @param session - the session whose log grew. + * @param event - the appended event, exactly as recorded. + * @dshScopeScan unsupported + * @mode emit + */ 'session/event'(this: Scoped, session: Session, event: SessionEvent): void ``` @@ -360,6 +574,15 @@ Post-commit, fire-and-forget append feed. The listener snapshot resolves before **Mode:** `parallel` ```ts website-api +/** + * Awaited parallel durability checkpoint: every listener runs and the + * caller awaits all of them, with no waterfall veto. Dispatch through + * {@link SessionStore.flush}. Scope-filtered dispatch + * (`@deepseek-ai/dsh-scope`) reuses the session's owner scope. + * @param session - the session whose buffered events must reach durable storage. + * @dshScopeScan unsupported + * @mode parallel + */ 'session/flush'(this: Scoped, session: Session): Promise | void ``` @@ -376,6 +599,14 @@ Awaited parallel durability checkpoint: every listener runs and the caller await **Mode:** `emit` ```ts website-api +/** + * A ready child settled. Scope-filtered dispatch uses the same delegating + * parent carrier as `subagent/start`, so the lifecycle pair reaches the + * same scoped audience. + * @param info - the run identity and terminal outcome. + * @dshScopeScan unsupported + * @mode emit + */ 'subagent/end'(this: Scoped, info: SubagentRunEndInfo): void ``` @@ -390,6 +621,11 @@ A ready child settled. Scope-filtered dispatch uses the same delegating parent c **Mode:** `emit` ```ts website-api +/** + * A provider became resolvable in the registry. + * @param provider - the registered provider. + * @mode emit + */ 'subagent/provider-added'(provider: SubagentProvider): void ``` @@ -404,6 +640,11 @@ A provider became resolvable in the registry. **Mode:** `emit` ```ts website-api +/** + * A provider left the registry. Accepted runs remain holder-owned. + * @param name - the provider name that no longer resolves. + * @mode emit + */ 'subagent/provider-removed'(name: string): void ``` @@ -418,6 +659,16 @@ A provider left the registry. Accepted runs remain holder-owned. **Mode:** `emit` ```ts website-api +/** + * A provider established a ready child. For in-process providers, + * `ctx.agents.get(info.id)` resolves during this notification. + * Scope-filtered dispatch keys the carrier by the delegating parent, so a + * parent-scoped listener observes only its own delegations. Paired with + * `subagent/end`. + * @param info - the provider and ready child identity. + * @dshScopeScan unsupported + * @mode emit + */ 'subagent/start'(this: Scoped, info: SubagentRunInfo): void ``` @@ -434,6 +685,14 @@ A provider established a ready child. For in-process providers, `ctx.agents.get( **Mode:** `waterfall` ```ts website-api +/** + * Expert waterfall over the assembled sections, tools, and variables. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners + * receive only that scope's assemblies. The returned value is authoritative. + * @param assembly - the mutable assembly built from registered providers. + * @param context - the caller's per-assembly context. + * @mode waterfall + */ 'system-prompt/assemble'(this: Scoped, assembly: PromptAssembly, context: AssembleContext, next: () => Promise): Promise ``` @@ -449,6 +708,11 @@ Expert waterfall over the assembled sections, tools, and variables. Scope-filter **Mode:** `emit` ```ts website-api +/** + * Emitted when any prompt provider changes. This registry notification is + * unfiltered because a global change affects every scope. + * @mode emit + */ 'system-prompt/change'(): void ``` @@ -463,6 +727,15 @@ Emitted when any prompt provider changes. This registry notification is unfilter **Mode:** `emit` ```ts website-api +/** + * A tool was registered or unregistered, or a scoped restriction changed + * (the available tool set changed — possibly for one scope only). An + * UNFILTERED registry-subject notification, deliberately not scope-filtered + * dispatch: a global change concerns every agent's next assembly, so a + * scoped listener subscribing here sees every change, not just its own + * scope's. + * @mode emit + */ 'tools/change'(): void ``` @@ -475,6 +748,14 @@ A tool was registered or unregistered, or a scoped restriction changed (the avai **Mode:** `waterfall` ```ts website-api +/** + * Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns + * a normalized result; wrappers may change only `exec.signal`, while call + * identity remains immutable. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls. + * @param exec - the allowed call about to dispatch (name, parsed arguments, caller agent, signal). + * @mode waterfall + */ 'tools/execute'(this: Scoped, exec: ToolExecution, next: () => Promise): Promise ``` @@ -489,6 +770,14 @@ Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a nor **Mode:** `waterfall` ```ts website-api +/** + * Accept, replace, enrich, or block a normalized dispatch result. `next()` + * accepts it unchanged; thrown tools still reach this seam as errors. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls. + * @param exec - the call that just ran (name, parsed arguments, caller agent). + * @param result - the dispatch outcome a listener may accept, replace, or block. + * @mode waterfall + */ 'tools/post-execute'(this: Scoped, exec: ToolExecution, result: Readonly, next: () => Promise): Promise ``` @@ -504,6 +793,13 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts **Mode:** `waterfall` ```ts website-api +/** + * Allow, deny, or ask before dispatch. `next()` delegates to allow; missing + * approval support turns `ask` into denial. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls. + * @param exec - the pending call (name, parsed arguments, caller agent). + * @mode waterfall + */ 'tools/pre-execute'(this: Scoped, exec: ToolExecution, next: () => Promise): Promise ``` @@ -518,6 +814,13 @@ Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approv **Mode:** `emit` ```ts website-api +/** + * Observe the frozen, lossless-JSON final outcome. Listener failures are contained. + * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): keyed by `exec.agent`. + * @param exec - the execution object that traversed the pipeline. + * @param result - a deep-frozen snapshot of the final returned result. + * @mode emit + */ 'tools/result'(this: Scoped, exec: Readonly, result: Readonly): undefined ``` @@ -535,6 +838,16 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained **Mode:** `emit` ```ts website-api +/** + * One `agent()` call settled (clean result, child failure, or run + * cancellation). Paired with {@link Events['workflow/agent-start']} by + * `agent.seq`, exactly once per started call on every stop path — on an + * engine termination path (a worker killed past its grace) the end is + * engine-synthesized with outcome `'cancelled'`. + * @param info - the run's identity snapshot. + * @param agent - the call identity plus its outcome. + * @mode emit + */ 'workflow/agent-end'(info: WorkflowRunInfo, agent: WorkflowAgentEndInfo): void ``` @@ -550,6 +863,15 @@ One `agent()` call settled (clean result, child failure, or run cancellation). P **Mode:** `emit` ```ts website-api +/** + * One `agent()` call established a ready child run. Paired with + * {@link Events['workflow/agent-end']} by `agent.seq`. A call that never + * receives a ready run from the provider emits neither + * event in this pair. + * @param info - the run's identity snapshot. + * @param agent - the call's sequence number, label, phase, and child id. + * @mode emit + */ 'workflow/agent-start'(info: WorkflowRunInfo, agent: WorkflowAgentInfo): void ``` @@ -565,6 +887,15 @@ One `agent()` call established a ready child run. Paired with Events['workflow/a **Mode:** `emit` ```ts website-api +/** + * A workflow run settled (any stop reason). Fired when + * {@link WorkflowRun.result} resolves. Paired with + * {@link Events['workflow/start']}. + * @param info - the run's identity snapshot. + * @param result - the outcome data (stop reason, error, agent count) — + * deliberately WITHOUT the result value (see {@link WorkflowResultInfo}). + * @mode emit + */ 'workflow/end'(info: WorkflowRunInfo, result: WorkflowResultInfo): void ``` @@ -580,6 +911,12 @@ A workflow run settled (any stop reason). Fired when WorkflowRun.result resolves **Mode:** `emit` ```ts website-api +/** + * The script emitted a narration line (a `log(message)` call). + * @param info - the run's identity snapshot. + * @param message - the logged message, verbatim. + * @mode emit + */ 'workflow/log'(info: WorkflowRunInfo, message: string): void ``` @@ -595,6 +932,13 @@ The script emitted a narration line (a `log(message)` call). **Mode:** `emit` ```ts website-api +/** + * The script entered a phase (a `phase(title)` call) — progress grouping + * for observers; no execution semantics. + * @param info - the run's identity snapshot. + * @param title - the phase title, verbatim. + * @mode emit + */ 'workflow/phase'(info: WorkflowRunInfo, title: string): void ``` @@ -610,6 +954,12 @@ The script entered a phase (a `phase(title)` call) — progress grouping for obs **Mode:** `emit` ```ts website-api +/** + * A workflow run started — the script's meta block validated, the body + * about to execute. Paired with {@link Events['workflow/end']}. + * @param info - the run's identity snapshot (id + meta). + * @mode emit + */ 'workflow/start'(info: WorkflowRunInfo): void ``` diff --git a/website/zh-CN/api/harness/fs.md b/website/zh-CN/api/harness/fs.md index 1246bbd27f..aed69681f6 100644 --- a/website/zh-CN/api/harness/fs.md +++ b/website/zh-CN/api/harness/fs.md @@ -11,6 +11,15 @@ Abstract filesystem provider. Targets must preserve identity across aliases; rea ### ctx.fs.resolve(path, opts?) ```ts website-api +/** + * Resolve a model/plugin-supplied path into a stable {@link FsTarget}. May perform I/O (a + * remote/sandboxed backend may need a round-trip to map a path to a stable identity), hence + * async even though the local backend only normalizes + realpaths. + * + * @param path - the path to resolve; relative paths resolve against `opts.cwd`. + * @param opts - optional cwd override and cancellation signal. + * @returns the stable target; the same file yields the same `targetKey`. + */ abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise ``` @@ -26,6 +35,12 @@ Resolve a model/plugin-supplied path into a stable FsTarget. May perform I/O (a ### ctx.fs.stat(target, signal?) ```ts website-api +/** + * Return target metadata, or `undefined` when the target does not exist. + * @param target - the resolved target to stat. + * @param signal - aborts the metadata round-trip. + * @returns metadata only, never content; undefined for an absent target. + */ abstract stat(target: FsTarget, signal?: AbortSignal): Promise ``` @@ -41,6 +56,20 @@ Return target metadata, or `undefined` when the target does not exist. ### ctx.fs.lstat(path, opts?, signal?) ```ts website-api +/** + * Return path metadata without following the final path component when it is a + * symbolic link. This is intentionally path-shaped, not target-shaped: + * {@link resolve} follows symlinks to produce the stable identity used by + * normal reads/writes, while `lstat` lets a consumer reject the path itself + * before that follow happens. + * + * `opts.cwd` follows {@link resolve}'s cwd rules. `undefined` means the path is + * absent. + * @param path - the path to inspect; relative paths resolve against `opts.cwd`. + * @param opts - `cwd` overrides the backend's default base for relative paths. + * @param signal - aborts the metadata round-trip. + * @returns metadata only, never content; undefined for an absent path. + */ abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise ``` @@ -58,6 +87,12 @@ Return path metadata without following the final path component when it is a sym ### ctx.fs.readText(target, signal?) ```ts website-api +/** + * Read the whole regular text file as a single decoded string. + * @param target - the resolved target to read. + * @param signal - aborts the read. + * @returns the full decoded UTF-8 content. + */ abstract readText(target: FsTarget, signal?: AbortSignal): Promise ``` @@ -73,6 +108,15 @@ Read the whole regular text file as a single decoded string. ### ctx.fs.streamText(target, signal?) ```ts website-api +/** + * Stream the whole regular text file as decoded text chunks (same text + * semantics as {@link readText}, for large files). The backend owns + * cross-chunk UTF-8 decoding and binary rejection so the policy layer never + * touches raw bytes. + * @param target - the resolved target to read. + * @param signal - aborts the stream, including between chunks. + * @returns the chunk iterable, decoded and validated like {@link readText}. + */ abstract streamText(target: FsTarget, signal?: AbortSignal): Promise> ``` @@ -88,6 +132,13 @@ Stream the whole regular text file as decoded text chunks (same text semantics a ### ctx.fs.listDir(target, signal?) ```ts website-api +/** + * List direct children of a directory in stable name order. Returns resolved + * child targets plus cheap metadata only; never reads file contents. + * @param target - the resolved directory target. + * @param signal - aborts the listing. + * @returns one entry per direct child, in stable name order. + */ abstract listDir(target: FsTarget, signal?: AbortSignal): Promise ``` @@ -103,6 +154,15 @@ List direct children of a directory in stable name order. Returns resolved child ### ctx.fs.writeText(target, content, expected?, signal?) ```ts website-api +/** + * Atomically create or replace UTF-8 text. `expected` guards intent and + * staleness; omission allows unconditional overwrite. + * @param target - the resolved target to write. + * @param content - the full new file content. + * @param expected - the write intent guarding the write; omit for unconditional. + * @param signal - aborts before the atomic rename takes effect. + * @returns the outcome, including the version the write produced. + */ abstract writeText(target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal): Promise ``` @@ -120,6 +180,16 @@ Atomically create or replace UTF-8 text. `expected` guards intent and staleness; ### ctx.fs.editText(target, edit, expected?, signal?) ```ts website-api +/** + * Atomically edit literal text. When supplied, the version guard is checked + * before matching so stale content reports `FS_STALE_VERSION`; omission edits + * the current content without a freshness precondition. + * @param target - the resolved target to edit. + * @param edit - the literal search/replace request. + * @param expected - the version guard; omit for an unconditional edit. + * @param signal - aborts before the atomic rename takes effect. + * @returns the outcome, including the version the edit produced. + */ abstract editText(target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal): Promise ``` diff --git a/website/zh-CN/api/harness/llm.md b/website/zh-CN/api/harness/llm.md index a70d5bd478..f762857881 100644 --- a/website/zh-CN/api/harness/llm.md +++ b/website/zh-CN/api/harness/llm.md @@ -11,6 +11,14 @@ The abstract `llm` service: an adapter registry plus a streaming model-call surf ### ctx.llm.registerAdapter(providers, adapter) ```ts website-api +/** + * Register an adapter for the given provider routes. Throws `LlmError` with code + * `DUPLICATE_ADAPTER` if any provider already has an adapter (all-or-nothing). + * Disposed with the fiber. + * @param providers - every provider route this adapter should serve. + * @param adapter - the adapter that streams calls for those providers. + * @returns the disposer that unregisters all of them. + */ registerAdapter(providers: string[], adapter: LlmAdapter): () => void ``` @@ -26,6 +34,10 @@ Register an adapter for the given provider routes. Throws `LlmError` with code ` ### ctx.llm.listProviders() ```ts website-api +/** + * Describe provider routes with a registered adapter. + * @returns detached provider metadata in registration order. + */ listProviders(): LlmProviderInfo[] ``` @@ -38,6 +50,12 @@ Describe provider routes with a registered adapter. ### ctx.llm.listModels(provider) ```ts website-api +/** + * Discover models advertised by one registered provider. Catalog membership + * is advisory and never changes routing or request validation. + * @param provider - registered provider route to inspect. + * @returns detached model metadata in adapter-preferred order. + */ async listModels(provider: string): Promise ``` @@ -52,6 +70,15 @@ Discover models advertised by one registered provider. Catalog membership is adv ### ctx.llm.stream(options) ```ts website-api +/** + * Stream one model call as raw chunks (token-level deltas). Throws + * `LlmError` with code `NO_ADAPTER` if no adapter is registered for + * `options.provider`. Replay state is retained only when the same adapter + * instance owns its historical provider and the target provider. Dispatches + * through the `llm/stream` waterfall. + * @param options - the full request; `options.provider` selects the adapter. + * @returns the chunk stream, possibly wrapped by `llm/stream` listeners. + */ stream(options: GenerateOptions): AsyncIterable ``` diff --git a/website/zh-CN/api/harness/permission.md b/website/zh-CN/api/harness/permission.md index fe05ef3a61..c9f99adbf1 100644 --- a/website/zh-CN/api/harness/permission.md +++ b/website/zh-CN/api/harness/permission.md @@ -11,6 +11,10 @@ Owns the deployment's permission presets and their write path. Requires a confin ### ctx.permission.names ```ts website-api +/** + * The advertised preset names, in the preset table's declaration order. + * @returns every switchable preset name. + */ get names(): readonly string[] ``` @@ -21,6 +25,13 @@ The advertised preset names, in the preset table's declaration order. ### ctx.permission.current(events) ```ts website-api +/** + * Resolve the preset matching the effective knob values. A still-matching + * last selection wins shared-bundle ties; otherwise the first table match + * wins, or {@link CUSTOM_PRESET} when no entry matches. + * @param events - the session's events in log order. + * @returns the effective preset name, or `custom` when nothing matches. + */ current(events: readonly SessionEvent[]): string ``` @@ -35,6 +46,12 @@ Resolve the preset matching the effective knob values. A still-matching last sel ### ctx.permission.resolve(name) ```ts website-api +/** + * Resolve a preset's knob bundle. + * @param name - the preset name to resolve. + * @returns the configured bundle. + * @throws when `name` is not in the table. + */ resolve(name: string): PresetSpec ``` @@ -49,6 +66,13 @@ Resolve a preset's knob bundle. ### ctx.permission.optionOf(name) ```ts website-api +/** + * Build the client option for a table entry or {@link CUSTOM_PRESET}. A + * missing label falls back to the table key. + * @param name - a table key, or `custom`. + * @returns the option a client renders. + * @throws when `name` is neither a table key nor `custom`. + */ optionOf(name: string): PresetOption ``` @@ -63,6 +87,12 @@ Build the client option for a table entry or CUSTOM_PRESET. A missing label fall ### ctx.permission.set(session, name) ```ts website-api +/** + * Record a changed preset, then update each changed knob through its own + * setter. Selecting the effective preset again appends nothing. + * @param session - the session the switch belongs to. + * @param name - the preset to switch to; unknown names throw. + */ set(session: Session, name: string): void ``` diff --git a/website/zh-CN/api/harness/sandbox.md b/website/zh-CN/api/harness/sandbox.md index bc5b1d38a5..45187e9d31 100644 --- a/website/zh-CN/api/harness/sandbox.md +++ b/website/zh-CN/api/harness/sandbox.md @@ -11,6 +11,17 @@ Abstract process-sandbox service. confine must return enforcing argv or fail clo ### ctx.sandbox.confine(argv, policy) ```ts website-api +/** + * Wrap `argv` so it executes confined under `policy` on this host; the + * caller spawns the returned argv in place of its own. + * @param argv - the exact argv the caller is about to spawn (program plus + * arguments), NOT a shell string — a shell-shaped consumer passes + * `['bash', '-c', command]`. + * @param policy - the file-effect policy this execution runs under, + * carried per call (see {@link SandboxPolicy}). + * @returns the argv to spawn instead, plus the enforcement completeness + * the selected backend achieves for it. + */ abstract confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv ``` diff --git a/website/zh-CN/api/harness/session-persistence.md b/website/zh-CN/api/harness/session-persistence.md index e382a2f4a4..f200cb1801 100644 --- a/website/zh-CN/api/harness/session-persistence.md +++ b/website/zh-CN/api/harness/session-persistence.md @@ -11,6 +11,13 @@ Durable append-only session storage. Implementations preserve contiguous, lossle ### ctx.sessionPersistence.locate(meta) ```ts website-api +/** + * Resolve this backend's independent local artifact for a session without + * reading, creating, flushing, or otherwise materializing it. Backends such + * as SQLite that do not own one artifact per session return `undefined`. + * @param meta - the immutable session header whose artifact is requested. + * @returns the backend-specific absolute location, when one exists. + */ abstract locate(meta: SessionHeader): SessionLocation | undefined ``` @@ -25,6 +32,13 @@ Resolve this backend's independent local artifact for a session without reading, ### ctx.sessionPersistence.create(meta) ```ts website-api +/** + * Register a new session's metadata. A backend MAY defer the physical write + * until the first {@link append} (lazy materialization), in which case a + * created-but-never-appended session is absent from {@link list} + * — abandoned sessions leave nothing behind. + * @param meta - the immutable header (id, version, cwd, lineage) to record. + */ abstract create(meta: SessionHeader): Promise ``` @@ -37,6 +51,15 @@ Register a new session's metadata. A backend MAY defer the physical write until ### ctx.sessionPersistence.append(id, events) ```ts website-api +/** + * Durably persist a batch of events (called from the write-behind drain at + * the `session/flush` checkpoint). Honors the append-only and contiguous-seq + * contracts: the first event's `seq` MUST equal the stored next-seq (after + * `load` has durably closed any interrupted turn). Rejects non-JSON- + * serializable `event.data` with an error naming the offending event type. + * @param id - the session the batch belongs to. + * @param events - the contiguous batch to persist, in seq order. + */ abstract append(id: SessionId, events: readonly SessionEvent[]): Promise ``` @@ -50,6 +73,14 @@ Durably persist a batch of events (called from the write-behind drain at the `se ### ctx.sessionPersistence.load(id) ```ts website-api +/** + * Load a header and balanced contiguous log. A complete interrupted final + * turn is preserved and durably closed with missing tool errors plus any open + * step and turn boundaries; only a torn final record is discarded. Unknown + * versions and corruption in the committed prefix reject. + * @param id - the persisted session to reload. + * @returns the header and a log ending on a balanced `turn/end`. + */ abstract load(id: SessionId): Promise<{ meta: SessionHeader; events: SessionEvent[] }> ``` @@ -64,6 +95,10 @@ Load a header and balanced contiguous log. A complete interrupted final turn is ### ctx.sessionPersistence.list() ```ts website-api +/** + * Lightweight listing from metadata, without a full-log parse. + * @returns one header per materialized session. + */ abstract list(): Promise ``` diff --git a/website/zh-CN/api/harness/session-query.md b/website/zh-CN/api/harness/session-query.md index f081950aa7..cc826c7af4 100644 --- a/website/zh-CN/api/harness/session-query.md +++ b/website/zh-CN/api/harness/session-query.md @@ -11,6 +11,10 @@ Live-preferred logical-corpus exact-read and relationship-tracing service. ### ctx.sessionQuery.listSessions() ```ts website-api +/** + * List the complete logical corpus using live-preferred records. + * @returns deterministic newest-first cloned session records. + */ listSessions(): Promise ``` @@ -23,6 +27,11 @@ List the complete logical corpus using live-preferred records. ### ctx.sessionQuery.listEvents(sessionId) ```ts website-api +/** + * List lightweight raw-log event records for one logical session. + * @param sessionId - live-preferred session id to read. + * @returns event records in ascending seq order. + */ async listEvents(sessionId: SessionId): Promise ``` @@ -37,6 +46,12 @@ List lightweight raw-log event records for one logical session. ### ctx.sessionQuery.traceSession(sessionId) ```ts website-api +/** + * Trace known ancestry and descendants from one corpus observation. + * @param sessionId - logical session id to trace. + * @returns a complete lineage or an explicit unresolved parent boundary. + * @throws when corpus resolution fails, the target is absent, or its known ancestry cycles. + */ async traceSession(sessionId: SessionId): Promise ``` @@ -51,6 +66,12 @@ Trace known ancestry and descendants from one corpus observation. ### ctx.sessionQuery.traceEvent(request) ```ts website-api +/** + * Trace one event's direct positional and provenance relationships. + * @param request - target session id and event seq. + * @returns direct links plus the target's positional replacement chain. + * @throws when source resolution fails, the target is absent, or surface/provenance validation fails. + */ async traceEvent(request: SessionEventTraceRequest): Promise ``` @@ -65,6 +86,11 @@ Trace one event's direct positional and provenance relationships. ### ctx.sessionQuery.readEvent(request) ```ts website-api +/** + * Read one full event plus a bounded raw-log context window. + * @param request - target session/seq and context sizes. + * @returns cloned target and neighboring events. + */ async readEvent(request: SessionEventReadRequest): Promise ``` diff --git a/website/zh-CN/api/harness/sessions.md b/website/zh-CN/api/harness/sessions.md index 712852fc49..f59001009d 100644 --- a/website/zh-CN/api/harness/sessions.md +++ b/website/zh-CN/api/harness/sessions.md @@ -12,6 +12,27 @@ Persistence is intentionally not implemented here — persistence plugins subscr ### ctx.sessions.create(id?, options?) ```ts website-api +/** + * Create a session owned by the calling fiber: disposing that fiber stops + * event notification and removes the session from the store. `options.seed` + * populates the session with a copy of those events (replay/fork); + * `options.meta` attaches creation metadata (validated absolute `cwd`, + * `parentSession` lineage) as the immutable {@link SessionHeader} (the store + * fills `version`/`id`/`createdAt`). + * + * For an agent whose session must be torn down IN ORDER with its loop (so the + * loop's final flush is captured before the store attachment ends), do NOT use this + * — fold the session lifecycle into the agent's own effect via + * {@link prepare} + {@link enter} + {@link announce} (see + * `dsh-agent-loop`'s creation transaction). + * + * @param id - the session id; omitted, the store mints `session-`. + * @param options - seed events and/or creation metadata for the header. + * @returns the live session, already entered and announced. + * @throws if a session with `id` already exists, metadata is not a plain + * lossless-JSON record with valid scalar fields, or `meta.cwd` is a + * non-absolute path (storage backends key directories off it). + */ create(id?: SessionId, options?: CreateSessionOptions): Session ``` @@ -28,6 +49,22 @@ For an agent whose session must be torn down IN ORDER with its loop (so the loop ### ctx.sessions.prepare(id?, options?) ```ts website-api +/** + * Build a session WITHOUT entering it into the store — validate the id/cwd and + * construct the {@link Session} (with its immutable {@link SessionHeader}). + * Pairs with {@link enter} + {@link announce}: a caller that owns a composite + * `ctx.effect` (the agent factory) folds the session lifecycle into that ONE + * effect so a fiber unload tears the session + agent down as a single ORDERED + * chain rather than as racing sibling effects — which would remove the publication hooks + * before the loop's closing `session/flush`, dropping the closing events. + * + * @param id - the session id; omitted, the store mints `session-`. + * @param options - seed events and/or creation metadata for the header. + * @returns the constructed session, NOT yet in the store. + * @throws if a session with `id` already exists, metadata is not a plain + * lossless-JSON record with valid scalar fields, or `meta.cwd` is a + * non-absolute path. + */ prepare(id?: SessionId, options?: CreateSessionOptions): Session ``` @@ -43,6 +80,28 @@ Build a session WITHOUT entering it into the store — validate the id/cwd and c ### ctx.sessions.enter(session) ```ts website-api +/** + * Enter a {@link prepare}d session into the store: install the module-private + * append publication hooks and add it to the store. Returns the DETACH + * disposer (hooks + store removal). Does NOT emit `session/created` — + * the caller yields this disposer inside its effect and THEN calls + * {@link announce}, so a throwing `session/created` listener rolls the attach + * back instead of leaking it. + * + * Re-checks the id for a duplicate: `prepare` and `enter` are public + * cross-package primitives and a caller may interleave arbitrary work (or + * another create) between them, so a stale prepared session must NOT overwrite + * a live store entry of the same id — its detach disposer would later delete + * the REAL session. The {@link create} convenience and the agent factory call + * the two back-to-back so they never trip this, but the public seam cannot + * assume that. + * + * @param session - a {@link prepare}d session not yet in the store. + * @returns the detach disposer (publication hooks + store removal). When called from + * a synchronous `session/created` listener, removal and disposal wait until + * that creation dispatch unwinds. + * @throws if a session with this id is already in the store. + */ enter(session: Session): () => void ``` @@ -58,6 +117,13 @@ Re-checks the id for a duplicate: `prepare` and `enter` are public cross-package ### ctx.sessions.announce(session) ```ts website-api +/** Emit `session/created` exactly once for an {@link enter}ed session (with + * the carrier {@link enter} captured). Separate from {@link enter} so the + * caller can yield the detach disposer first (rollback safety — see + * {@link enter}). + * @param session - the entered session to announce to listeners. + * @throws if the session is not live or its announcement already began, + * including a reentrant call from a creation listener. */ announce(session: Session): void ``` @@ -70,6 +136,17 @@ Emit `session/created` exactly once for an entered session (with the carrier ent ### ctx.sessions.flush(session) ```ts website-api +/** + * Dispatch the awaited `session/flush` durability checkpoint for `session`, + * with the carrier captured at {@link enter}. THE flush entry point: the + * store owns the carrier, so callers (the loop's turn-end checkpoint, idle + * injection, teardown drains) must come through here rather than dispatch a + * raw `ctx.parallel('session/flush', …)` — one owner, one spelling, and the + * scoped-dispatch invariant can pin it. + * @param session - the session whose buffered events must reach durable storage. + * @returns resolves when every flush listener has settled; after all settle, + * rejects with the first registered listener failure if any listener failed. + */ async flush(session: Session): Promise ``` @@ -84,6 +161,11 @@ Dispatch the awaited `session/flush` durability checkpoint for `session`, with t ### ctx.sessions.get(id) ```ts website-api +/** + * Look up a live session. + * @param id - the session id to look up. + * @returns the session, or undefined when no live session has that id. + */ get(id: SessionId): Session | undefined ``` @@ -98,6 +180,10 @@ Look up a live session. ### ctx.sessions.list() ```ts website-api +/** + * All live sessions, in creation order. + * @returns a fresh array; mutating it does not affect the store. + */ list(): Session[] ``` @@ -110,6 +196,19 @@ All live sessions, in creation order. ### ctx.sessions.fork(source, boundary?, childSessionId?) ```ts website-api +/** + * Create a live child session from a turn-enclosed prefix of a live source. + * `boundary` is an inclusive source event seq; omitted means the source's + * current last event. A non-empty selected slice must end at `turn/end`. + * + * @param source - Live source session object or id. + * @param boundary - Inclusive source event seq to fork through; omitted means + * the source's current last event, and omitted on an empty source forks an + * empty child. + * @param childSessionId - Optional child session id; omitted delegates to + * `SessionStore`'s id policy. + * @returns The created live child session. + */ fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId): Session ``` diff --git a/website/zh-CN/api/harness/skills.md b/website/zh-CN/api/harness/skills.md index 32c4d1b825..31ab6cd1d9 100644 --- a/website/zh-CN/api/harness/skills.md +++ b/website/zh-CN/api/harness/skills.md @@ -11,6 +11,14 @@ Registry of skill providers. It merges provider catalogs with stable first-wins ### ctx.skills.registerProvider(provider) ```ts website-api +/** + * Register a borrowed same-process provider synchronously during plugin apply. Duplicate and + * reserved names throw; remote initialization belongs in `list()`. Fiber disposal unregisters + * the provider and invalidates catalog caches. + * @param provider - the provider to register by `provider.name`. + * @returns the exact Cordis effect disposer that unregisters this provider; + * composite effects may yield it directly to preserve teardown ordering. + */ registerProvider(provider: SkillProvider): () => void ``` @@ -25,6 +33,13 @@ Register a borrowed same-process provider synchronously during plugin apply. Dup ### ctx.skills.register(skill) ```ts website-api +/** + * Register a borrowed readonly runtime skill. Project entries outrank runtime entries, which + * outrank user entries. Same-name runtime entries are first-wins; a duplicate logs a warning and + * receives a no-op disposer so it cannot remove the winner. + * @param skill - the complete skill definition to expose for discovery. + * @returns the exact Cordis effect disposer, preserving composite teardown order and invalidating caches. + */ register(skill: SkillRegistration): () => void ``` @@ -39,6 +54,13 @@ Register a borrowed readonly runtime skill. Project entries outrank runtime entr ### ctx.skills.list(options?) ```ts website-api +/** + * List model-invocable skill summaries for a workspace. Lookup options and + * provider candidates are readonly same-process values borrowed throughout + * discovery. + * @param options - lookup options; `cwd` selects project roots and `signal` cancels discovery. + * @returns sorted summaries, excluding skills disabled for model invocation. + */ async list(options: SkillLookupOptions = {}): Promise ``` @@ -53,6 +75,14 @@ List model-invocable skill summaries for a workspace. Lookup options and provide ### ctx.skills.get(name, options?) ```ts website-api +/** + * Load and validate the winning candidate, passing its opaque discovery locator back to the + * provider. Cancellation is rechecked after selection, including cache hits, and raced against + * loading so an uncooperative provider cannot hang the caller. + * @param name - kebab-case skill name. + * @param options - lookup options; `cwd` selects workspace-sensitive skills and `signal` cancels work. + * @returns the full skill, including body content, or `undefined`. + */ async get(name: string, options: SkillLookupOptions = {}): Promise ``` diff --git a/website/zh-CN/api/harness/spill-store.md b/website/zh-CN/api/harness/spill-store.md index b7fd81c934..942e811c6b 100644 --- a/website/zh-CN/api/harness/spill-store.md +++ b/website/zh-CN/api/harness/spill-store.md @@ -15,6 +15,11 @@ Semantics every implementation must honor: ### ctx.spillStore.saveText(input) ```ts website-api +/** + * Persist `input.content` to a session-scoped spill artifact. + * @param input - the owner, provenance, suggested name, and full text to save. + * @returns the saved artifact's {@link SpillRef}; rejects on a storage failure. + */ abstract saveText(input: SaveTextSpill): Promise ``` diff --git a/website/zh-CN/api/harness/subagents.md b/website/zh-CN/api/harness/subagents.md index 52632e820d..de71a5effe 100644 --- a/website/zh-CN/api/harness/subagents.md +++ b/website/zh-CN/api/harness/subagents.md @@ -11,6 +11,13 @@ Named provider registry and capability-checked start surface. ### ctx.subagents.registerProvider(provider) ```ts website-api +/** + * Register a provider under its name. Registration is effect-scoped and HMR + * safe; removing a provider blocks new starts but does not revoke runs that + * were already returned to their holders. + * @param provider - the trusted provider implementation. + * @returns the exact Cordis effect disposer. + */ registerProvider(provider: SubagentProvider): () => void ``` @@ -25,6 +32,11 @@ Register a provider under its name. Registration is effect-scoped and HMR safe; ### ctx.subagents.getProvider(name) ```ts website-api +/** + * Look up a provider by name. + * @param name - the provider name. + * @returns the provider, or undefined when absent. + */ getProvider(name: string): SubagentProvider | undefined ``` @@ -39,6 +51,10 @@ Look up a provider by name. ### ctx.subagents.list() ```ts website-api +/** + * List registered provider names in insertion order. + * @returns the registered names. + */ list(): string[] ``` @@ -51,6 +67,15 @@ List registered provider names in insertion order. ### ctx.subagents.start(name, request) ```ts website-api +/** + * Establish a ready child on the named provider. Capability and semantic + * checks run before delegation. Provider ownership lasts until its promise + * fulfills; a rejection therefore has no run for the caller to dispose and + * emits no run lifecycle events. + * @param name - the provider to use. + * @param request - child prompt, parent, signal, and optional capabilities. + * @returns the ready holder-owned run. + */ async start(name: string, request: SubagentStartRequest): Promise ``` diff --git a/website/zh-CN/api/harness/system-prompt.md b/website/zh-CN/api/harness/system-prompt.md index 56537ac407..ac22619752 100644 --- a/website/zh-CN/api/harness/system-prompt.md +++ b/website/zh-CN/api/harness/system-prompt.md @@ -11,6 +11,14 @@ Registry service for the prompt inputs assembled before each model step. ### ctx.systemPrompt.section(section) ```ts website-api +/** + * Register an ordered prompt section in the calling context's scope. A scoped + * section shadows a global section with the same name; duplicates within one + * layer and non-finite orders throw. Registration and disposal emit + * `system-prompt/change`. + * @param section - the section to register. + * @returns the exact Cordis effect disposer. + */ section(section: PromptSection): () => void ``` @@ -25,6 +33,13 @@ Register an ordered prompt section in the calling context's scope. A scoped sect ### ctx.systemPrompt.tools(provider) ```ts website-api +/** + * Register a tool-schema provider in the calling context's scope. Global and + * matching scoped providers both contribute; returning the reserved + * {@link TOOL_ORDER_REST} name makes assembly fail. + * @param provider - evaluated for each assembly with its context. + * @returns the exact Cordis effect disposer. + */ tools(provider: (context: AssembleContext) => ToolProviderResult): () => void ``` @@ -39,6 +54,14 @@ Register a tool-schema provider in the calling context's scope. Global and match ### ctx.systemPrompt.variable(name, provider) ```ts website-api +/** + * Register a prompt variable in the calling context's scope. Scoped values + * shadow globals; invalid or duplicate names throw. A provider may return + * `undefined`, but rendering a section that references that value then fails. + * @param name - the `[a-z][a-z0-9_]*` reference name. + * @param provider - evaluated for each assembly. + * @returns the exact Cordis effect disposer. + */ variable(name: string, provider: (context: AssembleContext) => string | undefined): () => void ``` @@ -54,6 +77,13 @@ Register a prompt variable in the calling context's scope. Scoped values shadow ### ctx.systemPrompt.assemble(context?) ```ts website-api +/** + * Assemble global and scoped providers, detach tool parameters, apply + * canonical ordering, then run the assembly waterfall. Scoped sections and + * variables shadow globals; the returned waterfall value is authoritative. + * @param context - the optional scope and plugin-defined assembly fields. + * @returns the authoritative post-waterfall assembly. + */ async assemble(context: AssembleContext = {}): Promise ``` diff --git a/website/zh-CN/api/harness/tasks.md b/website/zh-CN/api/harness/tasks.md index 5ec3061471..1a43639871 100644 --- a/website/zh-CN/api/harness/tasks.md +++ b/website/zh-CN/api/harness/tasks.md @@ -11,6 +11,14 @@ The `tasks` service: the runtime-global background task registry. See the module ### ctx.tasks.start(spec) ```ts website-api +/** + * Preflight access, validation, and owner cleanup before starting and + * atomically registering work. A throwing starter leaves nothing registered; + * after it returns, registration cannot fail. Settlement records the outcome, + * notifies listeners, and releases waiters. + * @param spec - task identity, owner, and synchronous starter. + * @returns the registry-issued `-N` id. + */ start(spec: TaskStart): TaskId ``` @@ -25,6 +33,12 @@ Preflight access, validation, and owner cleanup before starting and atomically r ### ctx.tasks.list(caller?) ```ts website-api +/** + * List caller-owned and unowned tasks in registration order without exposing + * another session's labels. + * @param caller - reading agent; a non-agent caller sees only unowned tasks. + * @returns fresh snapshots. + */ list(caller?: Agent): TaskSnapshot[] ``` @@ -39,6 +53,13 @@ List caller-owned and unowned tasks in registration order without exposing anoth ### ctx.tasks.get(id, caller?) ```ts website-api +/** + * Return a non-consuming snapshot without changing its read cursor or notice + * state. Throws for an unknown or foreign task. + * @param id - task to look up. + * @param caller - reading agent checked against the owner. + * @returns a fresh snapshot. + */ get(id: TaskId, caller?: Agent): TaskSnapshot ``` @@ -54,6 +75,14 @@ Return a non-consuming snapshot without changing its read cursor or notice state ### ctx.tasks.read(id, caller?) ```ts website-api +/** + * Read the next stream delta, or the idempotent final output after settlement. + * A terminal read marks the task reported. Throws for an unknown or foreign + * task. + * @param id - task to read. + * @param caller - reading agent checked against the owner. + * @returns output text and the post-read snapshot. + */ read(id: TaskId, caller?: Agent): TaskRead ``` @@ -69,6 +98,15 @@ Read the next stream delta, or the idempotent final output after settlement. A t ### ctx.tasks.kill(id, caller?, reason?) ```ts website-api +/** + * Request cancellation, then mark the task stopping and reported. A producer + * throw propagates without changing task state. Throws for an unknown or + * foreign task. + * @param id - task to cancel. + * @param caller - killing agent checked against the owner. + * @param reason - logged reason forwarded to the producer. + * @returns `requested` for live work, otherwise `already-finished`. + */ kill(id: TaskId, caller?: Agent, reason?: string): 'requested' | 'already-finished' ``` @@ -85,6 +123,18 @@ Request cancellation, then mark the task stopping and reported. A producer throw ### ctx.tasks.wait(id, timeoutMs, caller?, signal?) ```ts website-api +/** + * Wait for settlement or timeout without cancelling the task. Caller abort + * rejects only while the task is live; after settlement it returns the + * terminal snapshot so a notice suppressed for this waiter is still delivered. + * Timed-out and aborted waits detach their resolvers. Throws for invalid, + * unknown, or foreign input. + * @param id - task to wait for. + * @param timeoutMs - positive finite wait bound in milliseconds. + * @param caller - waiting agent checked against the owner. + * @param signal - optional cancellation of the wait itself. + * @returns snapshot at settlement or timeout. + */ async wait(id: TaskId, timeoutMs: number, caller?: Agent, signal?: AbortSignal): Promise ``` @@ -102,6 +152,13 @@ Wait for settlement or timeout without cancelling the task. Caller abort rejects ### ctx.tasks.onTaskDone(listener) ```ts website-api +/** + * Register an effect-scoped completion listener. Each listener is contained; + * returned promises are observed but not awaited. No listener runs after + * service disposal. + * @param listener - receives each terminal snapshot and its exact owner. + * @returns disposer that unregisters the listener. + */ onTaskDone(listener: TaskDoneListener): () => void ``` @@ -116,6 +173,12 @@ Register an effect-scoped completion listener. Each listener is contained; retur ### ctx.tasks.attachSurface(name) ```ts website-api +/** + * Attach an effect-scoped surface that can read and stop tasks. {@link start} + * refuses work while none is attached. + * @param name - diagnostic label; duplicate names remain independent. + * @returns disposer that detaches this surface. + */ attachSurface(name: string): () => void ``` diff --git a/website/zh-CN/api/harness/token-meter.md b/website/zh-CN/api/harness/token-meter.md index ab4dd8f684..30b83f79d4 100644 --- a/website/zh-CN/api/harness/token-meter.md +++ b/website/zh-CN/api/harness/token-meter.md @@ -11,6 +11,7 @@ Replay owner for one service-wide estimator and isolated per-session folds. ### ctx.tokenMeter.contextWindow ```ts website-api +/** Provider context-window capacity used by pressure consumers. */ readonly contextWindow: number ``` @@ -21,6 +22,22 @@ Provider context-window capacity used by pressure consumers. ### ctx.tokenMeter.measure(session, requestHeader?) ```ts website-api +/** + * Measure current request pressure and surface through the durable tail. + * + * Provider usage is reused only when the latest successful call's canonical + * request envelope matches `requestHeader` and its total is no lower than + * that call's full heuristic anchor; otherwise the complete envelope and + * surface are heuristically repriced. + * + * `requestHeader` affects request pressure only; surface fields always + * describe the current session surface. Every call clones those positional + * nodes, so measurement is O(surface). + * + * @param session - session to replay through its current durable tail. + * @param requestHeader - optional effective request envelope replacing the latest logged header. + * @returns a detached deeply immutable pressure and surface measurement. + */ measure(session: Session, requestHeader?: EpochHeader): TokenMeasurement ``` @@ -38,6 +55,11 @@ Provider usage is reused only when the latest successful call's canonical reques ### ctx.tokenMeter.estimateMessage(message) ```ts website-api +/** + * Heuristically price one model-visible message. + * @param message - message to price without mutation. + * @returns content and role-framing tokens under the fixed service heuristic. + */ estimateMessage(message: Message): number ``` diff --git a/website/zh-CN/api/harness/tools.md b/website/zh-CN/api/harness/tools.md index 6ed4ce024d..eb416e8b75 100644 --- a/website/zh-CN/api/harness/tools.md +++ b/website/zh-CN/api/harness/tools.md @@ -11,6 +11,12 @@ Tool registry and execution pipeline. Scoped registrations shadow globals; one v ### ctx.tools.register(definition) ```ts website-api +/** + * Register globally or in the calling agent scope. Scoped tools shadow + * globals; duplicates within one layer and the reserved `run_code` name fail. + * @param definition - the tool schema, execution, and optional presentation functions. + * @returns the exact disposer that unregisters the tool. + */ register(definition: ToolDefinition): () => void ``` @@ -25,6 +31,13 @@ Register globally or in the calling agent scope. Scoped tools shadow globals; du ### ctx.tools.restrict(filter) ```ts website-api +/** + * Restrict global tools for the calling agent scope. Empty filters, unknown + * names, scope-local names, and reserved transport names fail. Restrictions + * intersect; scoped registrations remain visible. + * @param filter - global-surface mask: `allow` (keep only) and/or `deny` (remove). + * @returns the exact disposer that lifts this restriction. + */ restrict(filter: ToolRestriction): () => void ``` @@ -39,6 +52,16 @@ Restrict global tools for the calling agent scope. Empty filters, unknown names, ### ctx.tools.guard(guard) ```ts website-api +/** + * Register a monotonic guard after the extensible `tools/pre-execute` + * waterfall. A plain-context guard applies globally; one registered through + * `agent.ctx` applies only to that agent. Any matching guard may deny by + * returning a reason, while no guard can force-allow a call another guard + * denied. The exact effect disposer is returned for ordered ownership and + * HMR cleanup. + * @param guard - synchronous check; a returned string denies the execution. + * @returns the exact disposer that unregisters the guard. + */ guard(guard: ToolGuard): () => void ``` @@ -53,6 +76,15 @@ Register a monotonic guard after the extensible `tools/pre-execute` waterfall. A ### ctx.tools.get(name, scope?) ```ts website-api +/** + * Look up a tool as one scope sees it (scoped + * shadows global; a restricted-away global reads as absent). Presenters pass + * the calling agent so the rendered card matches the definition that + * actually executed. + * @param name - the tool name as registered. + * @param scope - the viewing scope (the agent); omitted = the global view. + * @returns the definition the scope resolves, or undefined when none is visible. + */ get(name: string, scope?: ScopeKey): ToolDefinition | undefined ``` @@ -68,6 +100,12 @@ Look up a tool as one scope sees it (scoped shadows global; a restricted-away gl ### ctx.tools.schemas(scope?) ```ts website-api +/** + * Project visible definitions onto the allowlisted model-facing schema fields, + * excluding execution and presentation callbacks. + * @param scope - the viewing scope (the agent); omitted = the global view. + * @returns one deep-cloned schema per visible tool. + */ schemas(scope?: ScopeKey): ToolSchema[] ``` @@ -82,6 +120,13 @@ Project visible definitions onto the allowlisted model-facing schema fields, exc ### ctx.tools.executionMode(exec) ```ts website-api +/** + * Classify a pending call through the caller's visible tool definition. Only + * an exact `true` is parallel; unknown, hidden, undeclared, invalid, or + * throwing classifiers are exclusive. + * @param exec - call name, parsed arguments, and optional agent scope. + * @returns the fail-closed scheduling mode. + */ executionMode(exec: ToolExecutionInput): ToolExecutionMode ``` @@ -96,6 +141,15 @@ Classify a pending call through the caller's visible tool definition. Only an ex ### ctx.tools.execute(exec) ```ts website-api +/** + * Execute through pre-policy, guards, around-dispatch, post-policy, and final + * notification. Tool and listener failures resolve as materialized error + * results; an invisible tool reports `UNKNOWN_TOOL`. The returned outcome is + * the same lossless, frozen snapshot final observers receive. + * @param exec - the typed same-process call input. The registry assigns its + * correlation token before policy begins. + * @returns the materialized final result. + */ async execute(exec: ToolExecutionInput): Promise ``` diff --git a/website/zh-CN/api/harness/user-interaction.md b/website/zh-CN/api/harness/user-interaction.md index 09db0f6107..072087f8ca 100644 --- a/website/zh-CN/api/harness/user-interaction.md +++ b/website/zh-CN/api/harness/user-interaction.md @@ -11,6 +11,12 @@ ### ctx.userInteraction.registerProvider(provider) ```ts website-api +/** + * Register the UI provider. Only one provider may be active in a context. + * + * @param provider UI-side implementation that collects answers. + * @returns Disposer that unregisters this provider. + */ registerProvider(provider: UserInteractionProvider): () => void ``` @@ -25,6 +31,12 @@ Register the UI provider. Only one provider may be active in a context. ### ctx.userInteraction.ask(request) ```ts website-api +/** + * Ask the active UI provider and wait for the user's answer. + * + * @param request Questions, owner agent, and abort signal. + * @returns The answer chosen or typed by the human. + */ async ask(request: AskUserQuestionRequest): Promise ``` diff --git a/website/zh-CN/api/harness/web.md b/website/zh-CN/api/harness/web.md index ca23406caf..5827430261 100644 --- a/website/zh-CN/api/harness/web.md +++ b/website/zh-CN/api/harness/web.md @@ -18,6 +18,13 @@ Selection semantics (resolved at execution time, never order-dependent): ### ctx.web.registerSearchProvider(provider) ```ts website-api +/** + * Register a search provider. Throws {@link WebError} `WEB_DUPLICATE_PROVIDER` + * if its id is already registered for search. Returns a disposer; disposed + * with the calling fiber. + * @param provider - the provider; its `id` is the registry key. + * @returns the disposer that unregisters the provider. + */ registerSearchProvider(provider: WebSearchProvider): () => void ``` @@ -32,6 +39,13 @@ Register a search provider. Throws WebError `WEB_DUPLICATE_PROVIDER` if its id i ### ctx.web.registerFetchProvider(provider) ```ts website-api +/** + * Register a fetch provider. Throws {@link WebError} `WEB_DUPLICATE_PROVIDER` + * if its id is already registered for fetch. Returns a disposer; disposed + * with the calling fiber. + * @param provider - the provider; its `id` is the registry key. + * @returns the disposer that unregisters the provider. + */ registerFetchProvider(provider: WebFetchProvider): () => void ``` @@ -46,6 +60,15 @@ Register a fetch provider. Throws WebError `WEB_DUPLICATE_PROVIDER` if its id is ### ctx.web.search(request, signal?) ```ts website-api +/** + * Run one search through the selected provider. Resolves the provider at call + * time with the selection rules above; throws {@link WebError} when the + * capability cannot run. The seam enforces `request.maxResults` on the result: + * if the provider over-returns, `sources[]` is truncated and `truncated` set. + * @param request - the query plus result-shaping options. + * @param signal - optional cancellation signal forwarded to the provider. + * @returns the provider's results, capped to `request.maxResults`. + */ async search(request: WebSearchRequest, signal?: AbortSignal): Promise ``` @@ -61,6 +84,14 @@ Run one search through the selected provider. Resolves the provider at call time ### ctx.web.fetch(request, signal?) ```ts website-api +/** + * Retrieve one URL through the selected provider. Resolves the provider at + * call time with the selection rules above; throws {@link WebError} when the + * capability cannot run. A non-2xx response is a result, not a throw. + * @param request - the URL plus retrieval options. + * @param signal - optional cancellation signal forwarded to the provider. + * @returns the retrieval outcome; non-2xx responses resolve descriptively. + */ async fetch(request: WebFetchRequest, signal?: AbortSignal): Promise ``` diff --git a/website/zh-CN/api/harness/workflows.md b/website/zh-CN/api/harness/workflows.md index 5518f3e564..f34c3d8a6c 100644 --- a/website/zh-CN/api/harness/workflows.md +++ b/website/zh-CN/api/harness/workflows.md @@ -11,6 +11,12 @@ Workflow execution seam. Invalid requests throw before publication; a live run i ### ctx.workflows.start(request) ```ts website-api +/** + * Parse and execute a workflow script. + * @param request - the script, its `args`, the parent agent, and an + * optional cancel signal. + * @returns the live run; its `result` resolves when the script settles. + */ abstract start(request: WorkflowStartRequest): WorkflowRun ``` diff --git a/website/zh-CN/api/index.md b/website/zh-CN/api/index.md index 7e1812bd5f..4357fcbfe3 100644 --- a/website/zh-CN/api/index.md +++ b/website/zh-CN/api/index.md @@ -1,6 +1,6 @@ # API 参考 -本节是 DeepSeek Harness 的 API 参考。除本页外,`cordis/` 与 `harness/` 下的所有页面**由脚本从源码生成**(`pnpm run gen-website-api`,CI 校验新鲜度),签名与说明永远与代码一致;生成页目前为英文,中文版将随统一翻译流程提供。 +本节是 DeepSeek Harness 的 API 参考。除本页外,`cordis/` 与 `harness/` 下的所有页面**由脚本从源码生成**(`pnpm run gen-website-api`,CI 校验新鲜度);签名代码块保留源码的原始 JSDoc,签名与说明永远与代码一致。生成页目前为英文,中文版将随统一翻译流程提供。 ## 框架 API