From 3fcab700fd03b3e4d24563a7e97d22628cab834c Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 11:41:03 -0300 Subject: [PATCH 01/30] fix(docs): resolve JSDoc re-export coverage --- scripts/check-jsdoc-coverage.test.mjs | 49 +++++++++++++++++++++++++-- scripts/lib/public-api-snapshot.mjs | 47 +++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/scripts/check-jsdoc-coverage.test.mjs b/scripts/check-jsdoc-coverage.test.mjs index 9366f2832..455a2ea6b 100644 --- a/scripts/check-jsdoc-coverage.test.mjs +++ b/scripts/check-jsdoc-coverage.test.mjs @@ -27,10 +27,10 @@ function tempDir() { } describe('public API JSDoc coverage', () => { - test('counts JSDoc on declarations reached through renamed re-exports', () => { + test('resolves extensionless re-exports to documented declarations', () => { const dir = tempDir() const entry = path.join(dir, 'index.d.ts') - writeFileSync(entry, "export { documented as publicName, undocumented } from './impl.js'\n") + writeFileSync(entry, "export { documented as publicName, undocumented } from './impl'\n") writeFileSync(path.join(dir, 'impl.d.ts'), [ '/** Public operation. */', 'export declare function documented(): void', @@ -39,13 +39,56 @@ describe('public API JSDoc coverage', () => { ].join('\n')) const ts = loadTypeScript() - const program = createDeclarationProgram(ts, [entry]) + const program = createDeclarationProgram(ts, [entry], { + module: ts.ModuleKind.ESNext, + moduleResolution: ts.ModuleResolutionKind.Bundler, + allowArbitraryExtensions: true, + }) const checker = program.getTypeChecker() const sourceFile = program.getSourceFile(entry) assert.ok(sourceFile) assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['publicName', 'undocumented']) }) + test('resolves Svelte component declarations for documented re-exports', () => { + const dir = tempDir() + const entry = path.join(dir, 'index.d.ts') + writeFileSync(entry, "export { default as ChatContainer } from './ChatContainer.svelte'\n") + writeFileSync(path.join(dir, 'ChatContainer.svelte.d.ts'), [ + '/** A scrollable chat region. */', + 'declare const ChatContainer: unknown', + 'export default ChatContainer', + ].join('\n')) + + const ts = loadTypeScript() + const program = createDeclarationProgram(ts, [entry], { + module: ts.ModuleKind.ESNext, + moduleResolution: ts.ModuleResolutionKind.Bundler, + allowArbitraryExtensions: true, + }) + const checker = program.getTypeChecker() + const sourceFile = program.getSourceFile(entry) + assert.ok(sourceFile) + assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['ChatContainer']) + }) + + test('counts JSDoc attached directly to a named export statement', () => { + const dir = tempDir() + const entry = path.join(dir, 'index.d.ts') + writeFileSync(entry, [ + '/** Public operation documented at the package entrypoint. */', + "export { documented as publicName } from './impl.js'", + ].join('\n')) + writeFileSync(path.join(dir, 'impl.d.ts'), 'export declare function documented(): void\n') + + const ts = loadTypeScript() + const program = createDeclarationProgram(ts, [entry]) + const checker = program.getTypeChecker() + const sourceFile = program.getSourceFile(entry) + assert.ok(sourceFile) + assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['publicName']) + }) + test('uses public snapshot symbols and reports per-package totals', () => { const snapshot = { schemaVersion: 1, diff --git a/scripts/lib/public-api-snapshot.mjs b/scripts/lib/public-api-snapshot.mjs index 30bd6c70a..9112431ce 100644 --- a/scripts/lib/public-api-snapshot.mjs +++ b/scripts/lib/public-api-snapshot.mjs @@ -578,7 +578,7 @@ export function getDocumentedExportsFromSourceFile(ts, checker, sourceFile) { if (!moduleSymbol) { throw new Error(`unable to resolve module symbol for ${sourceFile.fileName}`) } - return sortCopy(checker.getExportsOfModule(moduleSymbol) + const documented = new Set(checker.getExportsOfModule(moduleSymbol) .filter((symbol) => { let target = symbol if (symbol.flags & ts.SymbolFlags.Alias) { @@ -594,6 +594,21 @@ export function getDocumentedExportsFromSourceFile(ts, checker, sourceFile) { return hasDocs(symbol) || hasDocs(target) }) .map((symbol) => symbol.getName())) + + for (const statement of sourceFile.statements) { + if (!ts.isExportDeclaration(statement) || !statement.exportClause) continue + if ((statement.jsDoc?.length ?? 0) === 0) continue + + if (ts.isNamedExports(statement.exportClause)) { + for (const specifier of statement.exportClause.elements) { + documented.add(specifier.name.text) + } + } else if (ts.isNamespaceExport(statement.exportClause)) { + documented.add(statement.exportClause.name.text) + } + } + + return sortCopy([...documented]) } /** @@ -723,6 +738,15 @@ export function buildPublicApiSnapshot(packages, io) { ? createDeclarationProgram(ts, allRoots) : null const checker = program ? program.getTypeChecker() : null + const documentationProgram = + allRoots.length > 0 + ? createDeclarationProgram(ts, allRoots, { + module: ts.ModuleKind.ESNext, + moduleResolution: ts.ModuleResolutionKind.Bundler, + allowArbitraryExtensions: true, + }) + : null + const documentationChecker = documentationProgram?.getTypeChecker() ?? null /** @type {Record} */ const packagesOut = {} @@ -754,20 +778,37 @@ export function buildPublicApiSnapshot(packages, io) { /** @type {Set} */ const documented = new Set() - if (item.absTargets.length > 0 && program && checker) { + if ( + item.absTargets.length > 0 && + program && + checker && + documentationProgram && + documentationChecker + ) { /** @type {SnapshotSymbol[][]} */ const lists = [] for (const abs of item.absTargets) { const sourceFile = program.getSourceFile(abs) + const documentationSourceFile = documentationProgram.getSourceFile(abs) if (!sourceFile) { errors.push( `${item.packageName} ${item.subpath}: unreadable module source file ${abs}`, ) continue } + if (!documentationSourceFile) { + errors.push( + `${item.packageName} ${item.subpath}: unreadable documentation declaration file ${abs}`, + ) + continue + } try { lists.push(getExportsFromSourceFile(ts, checker, sourceFile)) - for (const name of getDocumentedExportsFromSourceFile(ts, checker, sourceFile)) { + for (const name of getDocumentedExportsFromSourceFile( + ts, + documentationChecker, + documentationSourceFile, + )) { documented.add(name) } } catch (error) { From 5454ab9263edb2e890f696207d54344ae42cb938 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 12:57:23 -0300 Subject: [PATCH 02/30] fix(docs): follow JSDoc through re-exports --- scripts/check-jsdoc-coverage.test.mjs | 30 ++++++++++++++--- scripts/lib/public-api-snapshot.mjs | 46 +++++++++++---------------- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/scripts/check-jsdoc-coverage.test.mjs b/scripts/check-jsdoc-coverage.test.mjs index 455a2ea6b..00178d3f7 100644 --- a/scripts/check-jsdoc-coverage.test.mjs +++ b/scripts/check-jsdoc-coverage.test.mjs @@ -27,14 +27,13 @@ function tempDir() { } describe('public API JSDoc coverage', () => { - test('resolves extensionless re-exports to documented declarations', () => { + test('follows direct and renamed re-exports to the original JSDoc', () => { const dir = tempDir() const entry = path.join(dir, 'index.d.ts') writeFileSync(entry, "export { documented as publicName, undocumented } from './impl'\n") writeFileSync(path.join(dir, 'impl.d.ts'), [ '/** Public operation. */', 'export declare function documented(): void', - '/** @deprecated Use another operation. */', 'export declare function undocumented(): void', ].join('\n')) @@ -47,7 +46,28 @@ describe('public API JSDoc coverage', () => { const checker = program.getTypeChecker() const sourceFile = program.getSourceFile(entry) assert.ok(sourceFile) - assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['publicName', 'undocumented']) + assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['publicName']) + }) + + test('follows export-star re-exports and keeps undocumented names missing', () => { + const dir = tempDir() + const entry = path.join(dir, 'index.d.ts') + writeFileSync(entry, "export * from './impl'\n") + writeFileSync(path.join(dir, 'impl.d.ts'), [ + '/** Documented operation. */', + 'export declare function documented(): void', + 'export declare function undocumented(): void', + ].join('\n')) + + const ts = loadTypeScript() + const program = createDeclarationProgram(ts, [entry], { + module: ts.ModuleKind.ESNext, + moduleResolution: ts.ModuleResolutionKind.Bundler, + }) + const checker = program.getTypeChecker() + const sourceFile = program.getSourceFile(entry) + assert.ok(sourceFile) + assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['documented']) }) test('resolves Svelte component declarations for documented re-exports', () => { @@ -72,7 +92,7 @@ describe('public API JSDoc coverage', () => { assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['ChatContainer']) }) - test('counts JSDoc attached directly to a named export statement', () => { + test('does not let a re-export comment document an undocumented declaration', () => { const dir = tempDir() const entry = path.join(dir, 'index.d.ts') writeFileSync(entry, [ @@ -86,7 +106,7 @@ describe('public API JSDoc coverage', () => { const checker = program.getTypeChecker() const sourceFile = program.getSourceFile(entry) assert.ok(sourceFile) - assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), ['publicName']) + assert.deepEqual(getDocumentedExportsFromSourceFile(ts, checker, sourceFile), []) }) test('uses public snapshot symbols and reports per-package totals', () => { diff --git a/scripts/lib/public-api-snapshot.mjs b/scripts/lib/public-api-snapshot.mjs index 9112431ce..6344391dd 100644 --- a/scripts/lib/public-api-snapshot.mjs +++ b/scripts/lib/public-api-snapshot.mjs @@ -578,37 +578,29 @@ export function getDocumentedExportsFromSourceFile(ts, checker, sourceFile) { if (!moduleSymbol) { throw new Error(`unable to resolve module symbol for ${sourceFile.fileName}`) } - const documented = new Set(checker.getExportsOfModule(moduleSymbol) - .filter((symbol) => { - let target = symbol - if (symbol.flags & ts.SymbolFlags.Alias) { - try { - target = checker.getAliasedSymbol(symbol) - } catch { - target = symbol - } + const hasDocs = (symbol) => + symbol.getDocumentationComment(checker).length > 0 || + symbol.getJsDocTags(checker).length > 0 + const resolveOriginal = (symbol) => { + let current = symbol + const seen = new Set() + while (current.flags & ts.SymbolFlags.Alias) { + if (seen.has(current)) break + seen.add(current) + try { + const target = checker.getAliasedSymbol(current) + if (!target || target === current) break + current = target + } catch { + break } - const hasDocs = (candidate) => - candidate.getDocumentationComment(checker).length > 0 || - candidate.getJsDocTags(checker).length > 0 - return hasDocs(symbol) || hasDocs(target) - }) - .map((symbol) => symbol.getName())) - - for (const statement of sourceFile.statements) { - if (!ts.isExportDeclaration(statement) || !statement.exportClause) continue - if ((statement.jsDoc?.length ?? 0) === 0) continue - - if (ts.isNamedExports(statement.exportClause)) { - for (const specifier of statement.exportClause.elements) { - documented.add(specifier.name.text) - } - } else if (ts.isNamespaceExport(statement.exportClause)) { - documented.add(statement.exportClause.name.text) } + return current } - return sortCopy([...documented]) + return sortCopy(checker.getExportsOfModule(moduleSymbol) + .filter((symbol) => hasDocs(resolveOriginal(symbol))) + .map((symbol) => symbol.getName())) } /** From daad8ec7e8de52a8a447c86d0f310521e5fb80d9 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 13:06:51 -0300 Subject: [PATCH 03/30] docs(svelte): document public API --- .changeset/doc03-svelte.md | 5 +++++ docs/stability/jsdoc-coverage-v1.json | 13 +---------- .../src/components/ChatContainer.svelte.d.ts | 1 + .../src/components/CodeBlock.svelte.d.ts | 1 + .../src/components/InputBar.svelte.d.ts | 1 + .../src/components/Markdown.svelte.d.ts | 1 + .../svelte/src/components/Message.svelte.d.ts | 1 + .../components/ThinkingIndicator.svelte.d.ts | 1 + .../src/components/ToolCallView.svelte.d.ts | 1 + .../components/ToolConfirmation.svelte.d.ts | 1 + packages/svelte/src/index.ts | 22 +++++++++++++++++++ packages/svelte/src/useChat.ts | 16 ++++++++++++-- 12 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 .changeset/doc03-svelte.md diff --git a/.changeset/doc03-svelte.md b/.changeset/doc03-svelte.md new file mode 100644 index 000000000..f6407bea7 --- /dev/null +++ b/.changeset/doc03-svelte.md @@ -0,0 +1,5 @@ +--- +'@agentskit/svelte': patch +--- + +Document the public Svelte API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 264d2e0cd..c80b931e7 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -1197,18 +1197,7 @@ ".::StatechartTransitionResult", ".::transitionStatechart" ], - "@agentskit/svelte": [ - ".::ChatContainer", - ".::CodeBlock", - ".::createChatStore", - ".::InputBar", - ".::Markdown", - ".::Message", - ".::SvelteChatStore", - ".::ThinkingIndicator", - ".::ToolCallView", - ".::ToolConfirmation" - ], + "@agentskit/svelte": [], "@agentskit/templates": [ ".::AdapterTemplateConfig", ".::createAdapterTemplate", diff --git a/packages/svelte/src/components/ChatContainer.svelte.d.ts b/packages/svelte/src/components/ChatContainer.svelte.d.ts index 8980e234e..943647215 100644 --- a/packages/svelte/src/components/ChatContainer.svelte.d.ts +++ b/packages/svelte/src/components/ChatContainer.svelte.d.ts @@ -1,4 +1,5 @@ import type { Component, Snippet } from 'svelte' +/** A scrollable chat region that follows changes to its rendered content. */ declare const ChatContainer: Component<{ children?: Snippet }> export default ChatContainer diff --git a/packages/svelte/src/components/CodeBlock.svelte.d.ts b/packages/svelte/src/components/CodeBlock.svelte.d.ts index 1ed091184..473d7297f 100644 --- a/packages/svelte/src/components/CodeBlock.svelte.d.ts +++ b/packages/svelte/src/components/CodeBlock.svelte.d.ts @@ -1,4 +1,5 @@ import type { Component } from 'svelte' +/** Render a code block and optionally expose a clipboard copy button. */ declare const CodeBlock: Component<{ code: string; language?: string; copyable?: boolean }> export default CodeBlock diff --git a/packages/svelte/src/components/InputBar.svelte.d.ts b/packages/svelte/src/components/InputBar.svelte.d.ts index 9cd5e6afe..ceef56ec6 100644 --- a/packages/svelte/src/components/InputBar.svelte.d.ts +++ b/packages/svelte/src/components/InputBar.svelte.d.ts @@ -1,6 +1,7 @@ import type { Component } from 'svelte' import type { ChatReturn } from '@agentskit/core' +/** Render a chat textarea and submit control bound to a Svelte chat store. */ declare const InputBar: Component<{ chat: ChatReturn placeholder?: string diff --git a/packages/svelte/src/components/Markdown.svelte.d.ts b/packages/svelte/src/components/Markdown.svelte.d.ts index 2fc33c96e..bbf2ad713 100644 --- a/packages/svelte/src/components/Markdown.svelte.d.ts +++ b/packages/svelte/src/components/Markdown.svelte.d.ts @@ -1,4 +1,5 @@ import type { Component } from 'svelte' +/** Display chat content with an optional streaming marker. */ declare const Markdown: Component<{ content: string; streaming?: boolean }> export default Markdown diff --git a/packages/svelte/src/components/Message.svelte.d.ts b/packages/svelte/src/components/Message.svelte.d.ts index 78f199c7e..6e0d6fb1e 100644 --- a/packages/svelte/src/components/Message.svelte.d.ts +++ b/packages/svelte/src/components/Message.svelte.d.ts @@ -1,6 +1,7 @@ import type { Component, Snippet } from 'svelte' import type { Message as MessageType } from '@agentskit/core' +/** Render a chat message with optional avatar and action snippets. */ declare const Message: Component<{ message: MessageType avatar?: Snippet diff --git a/packages/svelte/src/components/ThinkingIndicator.svelte.d.ts b/packages/svelte/src/components/ThinkingIndicator.svelte.d.ts index f2b7a9f22..2919d8b04 100644 --- a/packages/svelte/src/components/ThinkingIndicator.svelte.d.ts +++ b/packages/svelte/src/components/ThinkingIndicator.svelte.d.ts @@ -1,4 +1,5 @@ import type { Component } from 'svelte' +/** Show a labeled thinking indicator when `visible` is true. */ declare const ThinkingIndicator: Component<{ visible: boolean; label?: string }> export default ThinkingIndicator diff --git a/packages/svelte/src/components/ToolCallView.svelte.d.ts b/packages/svelte/src/components/ToolCallView.svelte.d.ts index 7cc9deb75..107e5d5ed 100644 --- a/packages/svelte/src/components/ToolCallView.svelte.d.ts +++ b/packages/svelte/src/components/ToolCallView.svelte.d.ts @@ -1,5 +1,6 @@ import type { Component } from 'svelte' import type { ToolCall } from '@agentskit/core' +/** Show a tool call summary with expandable arguments and result details. */ declare const ToolCallView: Component<{ toolCall: ToolCall }> export default ToolCallView diff --git a/packages/svelte/src/components/ToolConfirmation.svelte.d.ts b/packages/svelte/src/components/ToolConfirmation.svelte.d.ts index ac4377c86..c160ac031 100644 --- a/packages/svelte/src/components/ToolConfirmation.svelte.d.ts +++ b/packages/svelte/src/components/ToolConfirmation.svelte.d.ts @@ -1,6 +1,7 @@ import type { Component } from 'svelte' import type { ToolCall } from '@agentskit/core' +/** Show approval controls while a tool call requires confirmation. */ declare const ToolConfirmation: Component<{ toolCall: ToolCall onApprove: (toolCallId: string) => void diff --git a/packages/svelte/src/index.ts b/packages/svelte/src/index.ts index b1a8c599d..7d5df340c 100644 --- a/packages/svelte/src/index.ts +++ b/packages/svelte/src/index.ts @@ -1,11 +1,33 @@ +/** + * Create a readable Svelte chat store with the core controller's actions. + * @param config The chat controller configuration. + * @returns A state store with chat actions and a `destroy()` cleanup method. + * @example + * ```ts + * import { onDestroy } from 'svelte' + * import { createChatStore } from '@agentskit/svelte' + * const chat = createChatStore(config) + * onDestroy(chat.destroy) + * ``` + */ export { createChatStore } from './useChat' + +/** A readable chat state store with controller actions and cleanup. */ export type { SvelteChatStore } from './useChat' +/** A scrollable chat region that follows changes to its rendered content. */ export { default as ChatContainer } from './components/ChatContainer.svelte' +/** Render a chat message with optional avatar and action snippets. */ export { default as Message } from './components/Message.svelte' +/** Render a chat textarea and submit control bound to a Svelte chat store. */ export { default as InputBar } from './components/InputBar.svelte' +/** Display chat content with an optional streaming marker. */ export { default as Markdown } from './components/Markdown.svelte' +/** Render a code block and optionally expose a clipboard copy button. */ export { default as CodeBlock } from './components/CodeBlock.svelte' +/** Show a tool call summary with expandable arguments and result details. */ export { default as ToolCallView } from './components/ToolCallView.svelte' +/** Show a labeled thinking indicator when `visible` is true. */ export { default as ThinkingIndicator } from './components/ThinkingIndicator.svelte' +/** Show approval controls while a tool call requires confirmation. */ export { default as ToolConfirmation } from './components/ToolConfirmation.svelte' diff --git a/packages/svelte/src/useChat.ts b/packages/svelte/src/useChat.ts index 190811687..4a7573326 100644 --- a/packages/svelte/src/useChat.ts +++ b/packages/svelte/src/useChat.ts @@ -2,6 +2,7 @@ import { writable, type Readable } from 'svelte/store' import { ConfigError, ErrorCodes, createChatController } from '@agentskit/core' import type { ChatConfig, ChatController, ChatReturn, ChatState } from '@agentskit/core' +/** A Svelte-readable chat state store with controller actions and cleanup. */ export interface SvelteChatStore extends Readable { send: ChatController['send'] stop: ChatController['stop'] @@ -13,12 +14,23 @@ export interface SvelteChatStore extends Readable { proposeToolCall: ChatReturn['proposeToolCall'] approve: ChatController['approve'] deny: ChatController['deny'] + /** Unsubscribe from controller updates and stop the active response. */ destroy: () => void } /** - * Svelte 5 store. Same shape as `@agentskit/react`'s hook return, - * exposed as a `Readable` + action methods. + * Create a Svelte-readable chat store with the shared chat actions. + * + * @param config The chat configuration passed to the core controller. + * @returns A readable state store with send, control, and cleanup methods. + * @example + * ```ts + * import { onDestroy } from 'svelte' + * import { createChatStore } from '@agentskit/svelte' + * + * const chat = createChatStore(config) + * onDestroy(chat.destroy) + * ``` */ export function createChatStore(config: ChatConfig): SvelteChatStore { const controller = createChatController(config) From cad3952679861a2103fa0f8c2c54bf32e64eeaa7 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 13:21:07 -0300 Subject: [PATCH 04/30] docs(core): document root public API --- .changeset/doc03-core-root.md | 5 + docs/stability/jsdoc-coverage-v1.json | 168 +----------------------- packages/core/src/agent-loop.ts | 16 +++ packages/core/src/budget.ts | 8 ++ packages/core/src/controller.ts | 9 ++ packages/core/src/errors.ts | 9 ++ packages/core/src/memory.ts | 17 +++ packages/core/src/primitives.ts | 37 ++++++ packages/core/src/progressive.ts | 4 + packages/core/src/rag.ts | 8 ++ packages/core/src/types/adapter.ts | 6 + packages/core/src/types/agent.ts | 3 + packages/core/src/types/chat.ts | 11 ++ packages/core/src/types/common.ts | 2 + packages/core/src/types/content.ts | 22 ++++ packages/core/src/types/eval.ts | 3 + packages/core/src/types/memory.ts | 12 ++ packages/core/src/types/message.ts | 4 + packages/core/src/types/retrieval.ts | 3 + packages/core/src/types/skill.ts | 1 + packages/core/src/types/stream.ts | 7 + packages/core/src/types/tool.ts | 17 +++ packages/core/src/virtualized-memory.ts | 1 + 23 files changed, 207 insertions(+), 166 deletions(-) create mode 100644 .changeset/doc03-core-root.md diff --git a/.changeset/doc03-core-root.md b/.changeset/doc03-core-root.md new file mode 100644 index 000000000..4af08b5f0 --- /dev/null +++ b/.changeset/doc03-core-root.md @@ -0,0 +1,5 @@ +--- +'@agentskit/core': patch +--- + +Document the public API of the root entry and shared chat types. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 264d2e0cd..b0f64f087 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -21,7 +21,6 @@ ".::createOpenAICompatibleEmbedder", ".::createRotatingCredentials", ".::CredentialRefreshable", - ".::DataRegion", ".::deepseek", ".::DeepSeekConfig", ".::deepseekEmbedder", @@ -201,103 +200,6 @@ ".::writeStarterProject" ], "@agentskit/core": [ - ".::activateSkills", - ".::ActivateSkillsResult", - ".::AdapterContext", - ".::AdapterError", - ".::AdapterFactory", - ".::AdapterRequest", - ".::AgentEvent", - ".::AgentsKitError", - ".::ArgsValidationError", - ".::ArgsValidationResult", - ".::audioPart", - ".::AudioPart", - ".::BudgetStrategy", - ".::buildMessage", - ".::buildToolMap", - ".::ChatConfig", - ".::ChatController", - ".::ChatMemory", - ".::ChatReturn", - ".::ChatState", - ".::CompileBudgetInput", - ".::CompileBudgetResult", - ".::ConfigError", - ".::consumeStream", - ".::ConsumeStreamHandlers", - ".::ContentPart", - ".::createChatController", - ".::createEventEmitter", - ".::createInMemoryMemory", - ".::createLocalStorageMemory", - ".::createStaticRetriever", - ".::createToolLifecycle", - ".::DataRegion", - ".::deserializeMessages", - ".::EditOptions", - ".::EmbedFn", - ".::ErrorCodes", - ".::EvalResult", - ".::EvalSuite", - ".::EvalTestCase", - ".::executeSafeTool", - ".::ExecuteSafeToolOptions", - ".::executeToolCall", - ".::filePart", - ".::FilePart", - ".::formatRetrievedDocuments", - ".::ImagePart", - ".::MaybePromise", - ".::MemoryError", - ".::MemoryRecord", - ".::Message", - ".::MessageRole", - ".::MessageStatus", - ".::Observer", - ".::ParsedToolArgs", - ".::parseToolArgs", - ".::PartKind", - ".::ProgressiveArgParser", - ".::ProgressiveExecOptions", - ".::ProgressiveExecResult", - ".::ProgressiveFieldEvent", - ".::RetrievedDocument", - ".::Retriever", - ".::RetrieverRequest", - ".::RuntimeError", - ".::SandboxError", - ".::serializeMessages", - ".::SkillDefinition", - ".::SkillError", - ".::StreamChunk", - ".::StreamSource", - ".::StreamStatus", - ".::StreamToolCallPayload", - ".::TokenUsage", - ".::ToolAuthorizationContext", - ".::ToolAuthorizationDecision", - ".::ToolAuthorizationPhase", - ".::ToolAuthorizer", - ".::ToolCall", - ".::ToolCallHandlerContext", - ".::ToolCallStatus", - ".::ToolDefinition", - ".::ToolError", - ".::ToolExecResult", - ".::ToolExecutionContext", - ".::UseStreamOptions", - ".::UseStreamReturn", - ".::VectorDocument", - ".::VectorFilter", - ".::VectorFilterCompound", - ".::VectorFilterOperator", - ".::VectorFilterPredicate", - ".::VectorMemory", - ".::VectorSearchOptions", - ".::videoPart", - ".::VideoPart", - ".::VirtualizedMemoryOptions", "./a2a::A2AAgentCard", "./a2a::A2AApproveParams", "./a2a::A2ACancelParams", @@ -433,8 +335,6 @@ "@agentskit/eval": [ ".::AgentFn", ".::AgentResponse", - ".::EvalResult", - ".::EvalSuite", ".::runEval", ".::RunEvalConfig", "./braintrust::ALL_SCORERS", @@ -517,56 +417,26 @@ "./snapshot::tokenize" ], "@agentskit/ink": [ - ".::AdapterContext", - ".::AdapterFactory", - ".::AdapterRequest", - ".::ChatConfig", ".::ChatContainer", ".::ChatContainerProps", - ".::ChatController", - ".::ChatMemory", - ".::ChatReturn", - ".::ChatState", - ".::createChatController", - ".::createInMemoryMemory", - ".::createLocalStorageMemory", ".::createProgressObserver", - ".::createStaticRetriever", ".::defaultInkTheme", - ".::formatRetrievedDocuments", ".::InkTheme", ".::InkThemeProvider", ".::InputBar", ".::InputBarProps", ".::MarkdownTextProps", - ".::MaybePromise", - ".::MemoryRecord", ".::Message", ".::MessageProps", - ".::MessageRole", - ".::MessageStatus", - ".::MessageType", ".::ProgressObserverOptions", - ".::RetrievedDocument", - ".::Retriever", - ".::RetrieverRequest", ".::StatusHeader", ".::StatusHeaderProps", - ".::StreamChunk", - ".::StreamSource", - ".::StreamStatus", - ".::StreamToolCallPayload", ".::ThinkingIndicator", ".::ThinkingIndicatorProps", - ".::ToolCall", - ".::ToolCallHandlerContext", - ".::ToolCallStatus", ".::ToolCallView", ".::ToolCallViewProps", ".::ToolConfirmation", ".::ToolConfirmationProps", - ".::ToolDefinition", - ".::ToolExecutionContext", ".::TopologyGraphSource", ".::TopologyGraphView", ".::TopologyGraphViewEdge", @@ -574,9 +444,7 @@ ".::TopologyGraphViewProps", ".::TopologyGraphViewSnapshot", ".::useChat", - ".::useInkTheme", - ".::UseStreamOptions", - ".::UseStreamReturn" + ".::useInkTheme" ], "@agentskit/integrations": [ ".::acuityIntegration", @@ -903,52 +771,22 @@ "./chunker::chunkText" ], "@agentskit/react": [ - ".::AdapterContext", - ".::AdapterFactory", - ".::AdapterRequest", - ".::ChatConfig", ".::ChatContainer", ".::ChatContainerProps", - ".::ChatController", - ".::ChatMemory", - ".::ChatReturn", - ".::ChatState", ".::CodeBlock", ".::CodeBlockProps", - ".::createChatController", - ".::createInMemoryMemory", - ".::createLocalStorageMemory", - ".::createStaticRetriever", - ".::formatRetrievedDocuments", ".::InputBar", ".::InputBarProps", ".::Markdown", ".::MarkdownProps", - ".::MaybePromise", - ".::MemoryRecord", ".::Message", ".::MessageProps", - ".::MessageRole", - ".::MessageStatus", - ".::MessageType", - ".::RetrievedDocument", - ".::Retriever", - ".::RetrieverRequest", - ".::StreamChunk", - ".::StreamSource", - ".::StreamStatus", - ".::StreamToolCallPayload", ".::ThinkingIndicator", ".::ThinkingIndicatorProps", - ".::ToolCall", - ".::ToolCallHandlerContext", - ".::ToolCallStatus", ".::ToolCallView", ".::ToolCallViewProps", ".::ToolConfirmation", ".::ToolConfirmationProps", - ".::ToolDefinition", - ".::ToolExecutionContext", ".::TopologyGraphSource", ".::TopologyGraphView", ".::TopologyGraphViewEdge", @@ -956,9 +794,7 @@ ".::TopologyGraphViewSnapshot", ".::useChat", ".::useReactive", - ".::useStream", - ".::UseStreamOptions", - ".::UseStreamReturn" + ".::useStream" ], "@agentskit/react-native": [ ".::ChatContainer", diff --git a/packages/core/src/agent-loop.ts b/packages/core/src/agent-loop.ts index 7111a5677..040b46ae5 100644 --- a/packages/core/src/agent-loop.ts +++ b/packages/core/src/agent-loop.ts @@ -14,6 +14,10 @@ import type { // --- buildToolMap --- +/** Combine tool lists into a name-keyed map; later definitions replace earlier ones. + * @param sources Tool lists in replacement precedence order. + * @returns A map containing the last definition for each name. + */ export function buildToolMap( ...sources: Array ): Map { @@ -27,11 +31,17 @@ export function buildToolMap( // --- activateSkills --- +/** System prompt and tools produced while activating chat skills. */ export interface ActivateSkillsResult { systemPrompt: string | undefined skillTools: ToolDefinition[] } +/** Add skill prompts and activation-provided tools to a chat configuration. + * @param skills Skills whose prompts and activation hooks should be applied. + * @param prompt Optional base system prompt. + * @returns The combined system prompt and tools returned by activation hooks. + */ export async function activateSkills( skills: SkillDefinition[], prompt?: string, @@ -57,6 +67,7 @@ export async function activateSkills( // --- executeSafeTool --- +/** Outcome and duration of one safe tool execution attempt. */ export interface ToolExecResult { status: 'complete' | 'error' | 'skipped' result?: string @@ -64,6 +75,7 @@ export interface ToolExecResult { durationMs: number } +/** Dependencies and callbacks used to execute and report a tool call. */ export interface ExecuteSafeToolOptions { tool: ToolDefinition | undefined toolCall: ToolCall @@ -84,6 +96,10 @@ export async function auth(fn: ToolAuthorizer | undefined, call: ToolCall, conte } +/** Validate, authorize, and execute a tool while reporting its lifecycle. + * @param options Tool call and lifecycle dependencies, validators, and callbacks. + * @returns The execution status, result or error text, and elapsed time. + */ export async function executeSafeTool( options: ExecuteSafeToolOptions, ): Promise { diff --git a/packages/core/src/budget.ts b/packages/core/src/budget.ts index 79867ade8..dab26217f 100644 --- a/packages/core/src/budget.ts +++ b/packages/core/src/budget.ts @@ -2,8 +2,10 @@ import type { Message } from './types/message' import type { TokenCounter } from './types/token-counter' import type { ToolDefinition } from './types/tool' +/** Strategy used to reduce a request when it exceeds its token budget. */ export type BudgetStrategy = 'drop-oldest' | 'sliding-window' | 'summarize' +/** Inputs for estimating and trimming a model request to a token budget. */ export interface CompileBudgetInput { /** Hard upper bound (model context limit - reserveForOutput). */ budget: number @@ -25,6 +27,7 @@ export interface CompileBudgetInput { keepRecent?: number } +/** Trimmed request, token breakdown, and messages removed to fit the budget. */ export interface CompileBudgetResult { messages: Message[] systemPrompt?: string @@ -79,6 +82,11 @@ async function toNumber(v: number | Promise): Promise { * - 'sliding-window': backwards-compatible alias of 'drop-oldest' * - 'summarize': fold dropped messages into a single summary message */ +/** Count and trim request content according to the selected budget strategy. + * @param input Messages, prompt, tools, budget, and trimming strategy. + * @returns The retained request content with token counts and dropped messages. + * @throws Error when the system prompt and tools exceed the effective budget or summarization is requested without a summarizer. + */ export async function compileBudget(input: CompileBudgetInput): Promise { const counter = input.counter ?? approximateCounter const strategy = input.strategy ?? 'drop-oldest' diff --git a/packages/core/src/controller.ts b/packages/core/src/controller.ts index f0aa15d4b..a9a6e5fec 100644 --- a/packages/core/src/controller.ts +++ b/packages/core/src/controller.ts @@ -23,6 +23,15 @@ import type { AgentEvent, AgentEventContext, } from './types' +/** Create a chat controller from adapter, conversation, and optional integration settings. + * @param initial Adapter, prompt, tool, memory, and observer settings for the chat. + * @returns Controller methods for managing the session and reading its state. + * @example + * ```ts + * const chat = createChatController({ adapter }) + * await chat.send('Hello') + * ``` + */ export function createChatController(initial: ChatConfig): ChatController { let config = initial const controllerCorrelation: AgentEventContext = initial.correlation ?? { operationId: generateId('operation') } diff --git a/packages/core/src/errors.ts b/packages/core/src/errors.ts index 1ac1dd98b..5d8773127 100644 --- a/packages/core/src/errors.ts +++ b/packages/core/src/errors.ts @@ -26,6 +26,7 @@ function formatError(code: string, message: string, hint?: string, docsUrl?: str // Base class // --------------------------------------------------------------------------- +/** Base error with a stable code, optional hint, docs link, and cause. */ export class AgentsKitError extends Error { readonly code: string readonly hint: string | undefined @@ -56,6 +57,7 @@ export class AgentsKitError extends Error { // Subclasses // --------------------------------------------------------------------------- +/** Error raised when an adapter is missing or cannot provide its stream. */ export class AdapterError extends AgentsKitError { constructor(options: { code: string @@ -69,6 +71,7 @@ export class AdapterError extends AgentsKitError { } } +/** Error raised when a tool is missing, invalid, forbidden, or fails. */ export class ToolError extends AgentsKitError { constructor(options: { code: string @@ -82,6 +85,7 @@ export class ToolError extends AgentsKitError { } } +/** Error raised when chat memory cannot load, save, or clear data. */ export class MemoryError extends AgentsKitError { constructor(options: { code: string @@ -95,6 +99,7 @@ export class MemoryError extends AgentsKitError { } } +/** Error raised for invalid or incomplete AgentsKit configuration. */ export class ConfigError extends AgentsKitError { constructor(options: { code: string @@ -108,6 +113,7 @@ export class ConfigError extends AgentsKitError { } } +/** Error raised when a runtime input or execution step fails. */ export class RuntimeError extends AgentsKitError { constructor(options: { code: string @@ -121,6 +127,7 @@ export class RuntimeError extends AgentsKitError { } } +/** Error raised when sandbox policy or execution fails. */ export class SandboxError extends AgentsKitError { constructor(options: { code: string @@ -134,6 +141,7 @@ export class SandboxError extends AgentsKitError { } } +/** Error raised when a skill definition or activation is invalid. */ export class SkillError extends AgentsKitError { constructor(options: { code: string @@ -151,6 +159,7 @@ export class SkillError extends AgentsKitError { // Error code constants // --------------------------------------------------------------------------- +/** Stable error-code strings used by AgentsKit error classes. */ export const ErrorCodes = { // Adapter errors AK_ADAPTER_MISSING: 'AK_ADAPTER_MISSING', diff --git a/packages/core/src/memory.ts b/packages/core/src/memory.ts index 53cb13858..a9f525745 100644 --- a/packages/core/src/memory.ts +++ b/packages/core/src/memory.ts @@ -1,6 +1,10 @@ import { ErrorCodes, MemoryError } from './errors' import type { ChatMemory, MemoryRecord, Message } from './types' +/** Convert messages into the versioned JSON-safe memory record format. + * @param messages Messages to serialize. + * @returns A version 1 record with ISO timestamp strings. + */ export function serializeMessages(messages: Message[]): MemoryRecord { return JSON.parse(JSON.stringify({ version: 1, @@ -8,6 +12,10 @@ export function serializeMessages(messages: Message[]): MemoryRecord { })) as MemoryRecord } +/** Restore messages from a memory record, including `createdAt` dates. + * @param record Serialized record, or `null` / `undefined` for no messages. + * @returns Restored messages; an absent record produces an empty array. + */ export function deserializeMessages(record: MemoryRecord | null | undefined): Message[] { if (!record?.messages) return [] return record.messages.map(message => ({ @@ -16,6 +24,10 @@ export function deserializeMessages(record: MemoryRecord | null | undefined): Me })) } +/** Create a message-memory backend that stores data in the current process. + * @param initialMessages Optional messages to seed the store. + * @returns A `ChatMemory` implementation backed by an in-memory array. + */ export function createInMemoryMemory(initialMessages: Message[] = []): ChatMemory { let messages = [...initialMessages] @@ -32,6 +44,11 @@ export function createInMemoryMemory(initialMessages: Message[] = []): ChatMemor } } +/** Create a browser-local-storage backend using the supplied storage key. + * @param key Local storage key for the serialized message record. + * @returns A `ChatMemory` implementation backed by browser local storage. + * @throws MemoryError from load, save, or clear when storage access fails. + */ export function createLocalStorageMemory(key: string): ChatMemory { return { async load() { diff --git a/packages/core/src/primitives.ts b/packages/core/src/primitives.ts index 01b4abea0..9d6cc900a 100644 --- a/packages/core/src/primitives.ts +++ b/packages/core/src/primitives.ts @@ -47,10 +47,17 @@ export function createId(prefix: string): string { * @param prefix - Namespace or kind to include at the start of the ID. * @returns The prefix followed by a UUID. */ +/** Generate a prefixed UUID for an entity such as a message or run. + * @param prefix Namespace or entity kind included before the UUID. + * @returns The prefix and a cryptographically random UUID separated by `-`. + */ export function generateId(prefix: string): string { return createId(prefix) } +/** Create an observer emitter that isolates observer failures from callers. + * @returns Methods to register observers and emit events to them. + */ export function createEventEmitter() { const observers = new Set() @@ -74,6 +81,10 @@ export function createEventEmitter() { } } +/** Create a message with a generated ID and creation timestamp. + * @param params Role, content, and optional message status and metadata. + * @returns A message with a generated ID and current creation date. + */ export function buildMessage(params: { role: MessageRole content: string @@ -107,6 +118,13 @@ function serializeToolResult(result: unknown): string { } } +/** Execute a tool and return its result as text, reporting streamed partial output. + * @param tool Tool whose `execute` function is called. + * @param args Parsed arguments passed to the tool. + * @param context Conversation and tool-call context. + * @param onPartialResult Called with accumulated text after each streamed item. + * @returns The tool result serialized as text. + */ export async function executeToolCall( tool: ToolDefinition, args: Record, @@ -128,6 +146,7 @@ export async function executeToolCall( return serializeToolResult(result) } +/** Parsed tool arguments and whether the input passed bounded JSON checks. */ export interface ParsedToolArgs { args: Record valid: boolean @@ -152,6 +171,10 @@ function isBoundedJsonObject(value: Record): boolean { return true } +/** Parse a bounded JSON object of tool arguments; invalid input returns an empty object. + * @param args JSON text emitted for a tool call. + * @returns Parsed arguments and a validity flag. + */ export function parseToolArgs(args: string): ParsedToolArgs { if (new TextEncoder().encode(args).byteLength > MAX_TOOL_ARGS_BYTES) return { args: {}, valid: false } try { @@ -167,6 +190,10 @@ export function parseToolArgs(args: string): ParsedToolArgs { } /** Backwards-compatible parser for callers that only need the safe value. */ +/** Return parsed tool arguments, or an empty object when parsing fails. + * @param args JSON text emitted for a tool call. + * @returns Parsed arguments or an empty object when invalid. + */ export function safeParseArgs(args: string): Record { return parseToolArgs(args).args } @@ -218,6 +245,10 @@ function scheduleLifecycleDisposal(state: ToolLifecycleState): void { }) } +/** Track tool initialization and defer disposal until active calls finish. + * @param tools Name-keyed tool definitions used by this lifecycle. + * @returns Idempotent initialization and disposal methods for a tool set. + */ export function createToolLifecycle(tools: Map) { const state: ToolLifecycleState = { initialized: new Set(), @@ -285,6 +316,7 @@ export function acquireToolLifecycle( } } +/** Callbacks for each event emitted by a model response stream. */ export interface ConsumeStreamHandlers { onText?: (accumulated: string) => void onReasoning?: (accumulated: string) => void @@ -295,6 +327,11 @@ export interface ConsumeStreamHandlers { onDone: (accumulatedText: string) => void } +/** Dispatch stream events to handlers and report accumulated text on completion. + * @param source Abortable source of response chunks. + * @param handlers Callbacks for text, reasoning, tools, usage, errors, and completion. + * @returns A promise fulfilled when the stream ends or reports an error. + */ export async function consumeStream( source: StreamSource, handlers: ConsumeStreamHandlers, diff --git a/packages/core/src/progressive.ts b/packages/core/src/progressive.ts index 653cc8aed..2d1f89456 100644 --- a/packages/core/src/progressive.ts +++ b/packages/core/src/progressive.ts @@ -1,6 +1,7 @@ import type { ToolCall, ToolDefinition, ToolExecutionContext } from './types/tool' import type { Message } from './types/message' +/** Parsed top-level JSON field emitted as soon as its value is complete. */ export interface ProgressiveFieldEvent { /** Top-level field name whose value just finished being streamed. */ field: string @@ -12,6 +13,7 @@ export interface ProgressiveFieldEvent { offset: number } +/** Incremental parser state and methods for streamed tool-argument JSON. */ export interface ProgressiveArgParser { /** Append a new chunk of JSON text. Emits `onField` for each top-level field that completes. */ push: (chunk: string) => ProgressiveFieldEvent[] @@ -201,6 +203,7 @@ export function createProgressiveArgParser(): ProgressiveArgParser { } } +/** Callbacks and field requirements for progressive tool execution. */ export interface ProgressiveExecOptions { /** Start executing after these fields have been received. Default: first field. */ triggerFields?: string[] @@ -208,6 +211,7 @@ export interface ProgressiveExecOptions { onField?: (event: ProgressiveFieldEvent) => void } +/** Parsed fields and execution promise returned by progressive execution. */ export interface ProgressiveExecResult { fields: ProgressiveFieldEvent[] finalArgs: Record diff --git a/packages/core/src/rag.ts b/packages/core/src/rag.ts index d4c62f841..0a365369b 100644 --- a/packages/core/src/rag.ts +++ b/packages/core/src/rag.ts @@ -15,6 +15,10 @@ function scoreDocument(document: RetrievedDocument, query: string): number { ), 0) } +/** Create a retriever that returns configured documents for each query. + * @param config Documents to expose through the retriever. + * @returns A retriever that returns the configured documents. + */ export function createStaticRetriever(config: StaticRetrieverConfig): Retriever { const { documents, limit = 4 } = config @@ -32,6 +36,10 @@ export function createStaticRetriever(config: StaticRetrieverConfig): Retriever } } +/** Format retrieved documents into text suitable for a model prompt. + * @param documents Retrieved content and metadata to format. + * @returns A labeled text block containing the document contents. + */ export function formatRetrievedDocuments(documents: RetrievedDocument[]): string { if (documents.length === 0) return '' diff --git a/packages/core/src/types/adapter.ts b/packages/core/src/types/adapter.ts index 219dfdc46..199c3e7c8 100644 --- a/packages/core/src/types/adapter.ts +++ b/packages/core/src/types/adapter.ts @@ -3,6 +3,7 @@ import type { StreamSource } from './stream' import type { ToolDefinition } from './tool' import type { AgentEventContext } from './agent' +/** Optional model settings and metadata supplied with an adapter request. */ export interface AdapterContext { systemPrompt?: string temperature?: number @@ -11,6 +12,7 @@ export interface AdapterContext { metadata?: Record } +/** Messages and context passed to an adapter when creating a stream. */ export interface AdapterRequest { messages: Message[] context?: AdapterContext @@ -46,6 +48,10 @@ export interface AdapterCapabilities { extensions?: Record } +/** Factory that turns a request into a stream of model output. + * @param request Messages and model context for the response. + * @returns The response stream and its abort method. + */ export type AdapterFactory = { createSource: (request: AdapterRequest) => StreamSource /** Optional capabilities hint. See AdapterCapabilities. */ diff --git a/packages/core/src/types/agent.ts b/packages/core/src/types/agent.ts index 72675d72b..dd3e49d93 100644 --- a/packages/core/src/types/agent.ts +++ b/packages/core/src/types/agent.ts @@ -3,6 +3,7 @@ * boundaries. `operationId` is the stable cross-system identity; the other * fields preserve local lifecycle identities without collapsing their meaning. */ +/** IDs that correlate events across an operation, run, session, or turn. */ export interface AgentEventContext { readonly operationId: string readonly runId?: string @@ -33,8 +34,10 @@ type AgentEventPayload = | { type: 'run-aborted' } | { type: 'error'; error: Error } +/** Typed lifecycle event emitted by an agent or runtime observer source. */ export type AgentEvent = AgentEventPayload & { readonly correlation?: AgentEventContext } +/** Observer callback registered to receive agent lifecycle events. */ export interface Observer { name: string on: (event: AgentEvent) => void | Promise diff --git a/packages/core/src/types/chat.ts b/packages/core/src/types/chat.ts index 0e93f5040..ebad1db03 100644 --- a/packages/core/src/types/chat.ts +++ b/packages/core/src/types/chat.ts @@ -8,6 +8,13 @@ import type { Retriever } from './retrieval' import type { SkillDefinition } from './skill' import type { AgentEventContext, Observer } from './agent' +/** Configuration for a headless chat controller and its integrations. + * @example + * ```ts + * const chat = createChatController({ adapter: openai({ apiKey, model: 'gpt-4o' }) }) + * await chat.send('Hello') + * ``` + */ export interface ChatConfig { adapter: AdapterFactory /** Optional identity propagated to adapter requests and runtime events. */ @@ -42,6 +49,7 @@ export interface ChatConfig { validateArgs?: ArgsValidator } +/** Current messages, input, stream status, error, and accumulated usage. */ export interface ChatState { messages: Message[] status: StreamStatus @@ -55,6 +63,7 @@ export interface ChatState { usage: TokenUsage } +/** Options controlling how a user-message edit affects later turns. */ export interface EditOptions { /** * When editing a user message, also regenerate the assistant response @@ -63,6 +72,7 @@ export interface EditOptions { regenerate?: boolean } +/** Imperative API for reading and controlling a chat session. */ export interface ChatController { getState: () => ChatState subscribe: (listener: () => void) => () => void @@ -90,6 +100,7 @@ export interface ChatController { deny: (toolCallId: string, reason?: string) => Promise } +/** Chat state combined with the actions exposed by framework bindings. */ export interface ChatReturn extends ChatState { send: (text: string) => Promise stop: () => void diff --git a/packages/core/src/types/common.ts b/packages/core/src/types/common.ts index 14f44e526..c037302d7 100644 --- a/packages/core/src/types/common.ts +++ b/packages/core/src/types/common.ts @@ -1,3 +1,5 @@ +/** Accept a value returned synchronously or through a promise. */ export type MaybePromise = T | Promise +/** Cloud region used to describe where a service stores or processes data. */ export type DataRegion = 'eu' | 'us' | 'apac' diff --git a/packages/core/src/types/content.ts b/packages/core/src/types/content.ts index 4e982b595..120b1ce5a 100644 --- a/packages/core/src/types/content.ts +++ b/packages/core/src/types/content.ts @@ -6,11 +6,13 @@ * `partsToText`). */ +/** Plain text content in a multi-modal message. */ export interface TextPart { type: 'text' text: string } +/** Image content referenced by a URL, data URL, or provider identifier. */ export interface ImagePart { type: 'image' /** Data URL, http(s) URL, or provider-hosted reference id. */ @@ -20,6 +22,7 @@ export interface ImagePart { detail?: 'low' | 'high' | 'auto' } +/** Audio content referenced by a URL, data URL, or provider identifier. */ export interface AudioPart { type: 'audio' source: string @@ -28,6 +31,7 @@ export interface AudioPart { durationSec?: number } +/** Video content referenced by a URL, data URL, or provider identifier. */ export interface VideoPart { type: 'video' source: string @@ -35,6 +39,7 @@ export interface VideoPart { durationSec?: number } +/** File content referenced by a URL, data URL, or provider identifier. */ export interface FilePart { type: 'file' source: string @@ -43,8 +48,10 @@ export interface FilePart { filename?: string } +/** Supported provider-neutral parts of a multi-modal message. */ export type ContentPart = TextPart | ImagePart | AudioPart | VideoPart | FilePart +/** Discriminator values used by the supported content-part variants. */ export type PartKind = ContentPart['type'] /** Build a text part. */ @@ -57,14 +64,29 @@ export function imagePart(source: string, opts: Omit = {}): AudioPart { return { type: 'audio', source, ...opts } } +/** Build a video part from a URL, data URI, or hosted reference. + * @param source Video source reference. + * @param opts Optional MIME type and duration metadata. + * @returns A video content part. + */ export function videoPart(source: string, opts: Omit = {}): VideoPart { return { type: 'video', source, ...opts } } +/** Build a file part from a URL, data URI, or hosted reference. + * @param source File source reference. + * @param opts Optional MIME type and original filename. + * @returns A file content part. + */ export function filePart(source: string, opts: Omit = {}): FilePart { return { type: 'file', source, ...opts } } diff --git a/packages/core/src/types/eval.ts b/packages/core/src/types/eval.ts index 6de7e8811..08ad136c6 100644 --- a/packages/core/src/types/eval.ts +++ b/packages/core/src/types/eval.ts @@ -1,9 +1,11 @@ +/** Input and expected-output check used by an evaluation suite. */ export interface EvalTestCase { input: string expected: string | ((result: string) => boolean) metadata?: Record } +/** Aggregate score and per-case outcomes from an evaluation run. */ export interface EvalResult { totalCases: number passed: number @@ -19,6 +21,7 @@ export interface EvalResult { }> } +/** Named collection of evaluation cases. */ export interface EvalSuite { name: string cases: EvalTestCase[] diff --git a/packages/core/src/types/memory.ts b/packages/core/src/types/memory.ts index 4499506ed..112e10e00 100644 --- a/packages/core/src/types/memory.ts +++ b/packages/core/src/types/memory.ts @@ -2,6 +2,7 @@ import type { DataRegion, MaybePromise } from './common' import type { Message } from './message' import type { RetrievedDocument } from './retrieval' +/** Persistence contract for loading, saving, and clearing chat messages. */ export interface ChatMemory { /** Data-residency region for this memory backend, when known. */ region?: DataRegion @@ -14,6 +15,7 @@ export interface MemoryOperationOptions { signal?: AbortSignal } +/** Embedded content record stored by a vector-memory backend. */ export interface VectorDocument { id: string content: string @@ -36,6 +38,7 @@ export interface VectorDocument { */ export type VectorFilterPrimitive = string | number | boolean | null +/** Comparison operators supported by portable vector metadata filters. */ export type VectorFilterOperator = | { $eq: VectorFilterPrimitive } | { $ne: VectorFilterPrimitive } @@ -47,17 +50,21 @@ export type VectorFilterOperator = | { $lte: number | string } | { $exists: boolean } +/** Primitive equality shorthand or an explicit metadata filter operator. */ export type VectorFilterPredicate = VectorFilterPrimitive | VectorFilterOperator +/** Boolean combination of nested vector metadata filters. */ export interface VectorFilterCompound { $and?: VectorFilter[] $or?: VectorFilter[] } +/** Portable metadata filter accepted by vector-memory search. */ export type VectorFilter = | VectorFilterCompound | { [field: string]: VectorFilterPredicate } +/** Result limit, similarity threshold, and metadata filter for vector search. */ export interface VectorSearchOptions { topK?: number threshold?: number @@ -65,6 +72,7 @@ export interface VectorSearchOptions { filter?: VectorFilter } +/** Contract for storing, searching, and optionally deleting embedded documents. */ export interface VectorMemory { /** Data-residency region for this vector backend, when known. */ region?: DataRegion @@ -76,4 +84,8 @@ export interface VectorMemory { delete?: (ids: string[]) => MaybePromise } +/** Convert text into its numeric embedding vector. + * @param text Content to embed. + * @returns The text embedding as an array of numbers. + */ export type EmbedFn = (text: string) => Promise diff --git a/packages/core/src/types/message.ts b/packages/core/src/types/message.ts index df24d5f8c..025083f55 100644 --- a/packages/core/src/types/message.ts +++ b/packages/core/src/types/message.ts @@ -1,9 +1,12 @@ import type { ContentPart } from './content' import type { ToolCall } from './tool' +/** Role assigned to a message in a conversation. */ export type MessageRole = 'user' | 'assistant' | 'system' | 'tool' +/** Lifecycle state of a message while it is created or processed. */ export type MessageStatus = 'pending' | 'streaming' | 'complete' | 'error' +/** Conversation message with optional tool calls and multi-modal parts. */ export interface Message { id: string role: MessageRole @@ -22,6 +25,7 @@ export interface Message { createdAt: Date } +/** Versioned JSON-safe representation of messages stored by a memory backend. */ export interface MemoryRecord { version: 1 messages: Array & { createdAt: string }> diff --git a/packages/core/src/types/retrieval.ts b/packages/core/src/types/retrieval.ts index 4de6e0d62..0f8b8bfbc 100644 --- a/packages/core/src/types/retrieval.ts +++ b/packages/core/src/types/retrieval.ts @@ -1,6 +1,7 @@ import type { MaybePromise } from './common' import type { Message } from './message' +/** Document returned by a retriever for a query. */ export interface RetrievedDocument { id: string content: string @@ -9,11 +10,13 @@ export interface RetrievedDocument { metadata?: Record } +/** Query and conversation context supplied to a retriever. */ export interface RetrieverRequest { query: string messages: Message[] } +/** Retrieval contract used to add relevant documents to a chat request. */ export interface Retriever { retrieve: (request: RetrieverRequest) => MaybePromise } diff --git a/packages/core/src/types/skill.ts b/packages/core/src/types/skill.ts index cb9b6f1af..eb133e711 100644 --- a/packages/core/src/types/skill.ts +++ b/packages/core/src/types/skill.ts @@ -1,6 +1,7 @@ import type { MaybePromise } from './common' import type { ToolDefinition } from './tool' +/** Prompt, metadata, and optional activation hook contributed by a skill. */ export interface SkillDefinition { name: string description: string diff --git a/packages/core/src/types/stream.ts b/packages/core/src/types/stream.ts index bf0c72e14..66d80886e 100644 --- a/packages/core/src/types/stream.ts +++ b/packages/core/src/types/stream.ts @@ -1,5 +1,7 @@ +/** State of a response stream. */ export type StreamStatus = 'idle' | 'streaming' | 'complete' | 'error' +/** Tool call data carried by a streamed response chunk. */ export interface StreamToolCallPayload { id: string name: string @@ -7,12 +9,14 @@ export interface StreamToolCallPayload { result?: string } +/** Token counts reported for a model response. */ export interface TokenUsage { promptTokens: number completionTokens: number totalTokens: number } +/** One text, tool, reasoning, usage, error, or completion event from a stream. */ export interface StreamChunk { type: 'text' | 'tool_call' | 'tool_result' | 'reasoning' | 'usage' | 'error' | 'done' content?: string @@ -21,17 +25,20 @@ export interface StreamChunk { metadata?: Record } +/** Abortable asynchronous source of model response chunks. */ export interface StreamSource { stream: () => AsyncIterableIterator abort: () => void } +/** Callbacks for observing chunks and completion from a stream hook. */ export interface UseStreamOptions { onChunk?: (chunk: StreamChunk) => void onComplete?: (text: string) => void onError?: (error: Error) => void } +/** Latest chunk and accumulated text exposed by a stream hook. */ export interface UseStreamReturn { data: StreamChunk | null text: string diff --git a/packages/core/src/types/tool.ts b/packages/core/src/types/tool.ts index 027a3ef48..642515370 100644 --- a/packages/core/src/types/tool.ts +++ b/packages/core/src/types/tool.ts @@ -2,8 +2,10 @@ import type { JSONSchema7 } from 'json-schema' import type { MaybePromise } from './common' import type { Message } from './message' +/** Runtime state of a model-requested tool call. */ export type ToolCallStatus = 'pending' | 'running' | 'complete' | 'error' | 'requires_confirmation' +/** Tool call requested by a model, including parsed arguments and outcome. */ export interface ToolCall { id: string name: string @@ -13,6 +15,7 @@ export interface ToolCall { status: ToolCallStatus } +/** Conversation context passed to a tool's execute function. */ export interface ToolExecutionContext { messages: Message[] call: ToolCall @@ -29,12 +32,14 @@ export interface ToolExecutionContext { // model produced. Default behaviour (no validator) is passthrough. // --------------------------------------------------------------------------- +/** One tool-argument validation issue and its field path. */ export interface ArgsValidationError { /** JSON pointer / dotted path to the offending field, or '' for root. */ path: string message: string } +/** Result returned by an injected tool-argument validator. */ export interface ArgsValidationResult { valid: boolean errors?: ArgsValidationError[] @@ -47,6 +52,7 @@ export interface ArgsValidationResult { * Returns `{ valid: true }` to allow execution, or `{ valid: false, errors }` * to reject it with `AK_TOOL_INVALID_INPUT`. */ +/** Validate tool arguments against a JSON Schema before execution. */ export type ArgsValidator = ( schema: JSONSchema7, args: Record, @@ -91,6 +97,7 @@ type InferJSONSchemaObject = : Record /** Top-level inference: extract args type from a JSON Schema definition. */ +/** Infer a TypeScript argument object from a JSON Schema literal. */ export type InferSchemaType = T extends { type: 'object'; properties: infer _P } ? InferJSONSchemaObject @@ -100,6 +107,7 @@ export type InferSchemaType = // ToolDefinition — generic with backward-compatible default // --------------------------------------------------------------------------- +/** Executable tool contract, including optional schema and lifecycle hooks. */ export interface ToolDefinition> { name: string description?: string @@ -142,12 +150,21 @@ export function defineTool( return config as ToolDefinition> } +/** Messages and resolved tool supplied to call and authorization handlers. */ export interface ToolCallHandlerContext { messages: Message[] tool?: ToolDefinition } +/** Stage at which a tool authorization decision is requested. */ export type ToolAuthorizationPhase = 'propose' | 'execute' +/** Tool-call context annotated with the authorization stage. */ export interface ToolAuthorizationContext extends ToolCallHandlerContext { phase: ToolAuthorizationPhase } +/** Allow or reject a tool call, with an optional explanation. */ export interface ToolAuthorizationDecision { allowed: boolean; reason?: string } +/** Callback that decides whether a proposed or executing tool call is allowed. + * @param toolCall Proposed or executing tool call. + * @param context Conversation, tool, and authorization phase. + * @returns A sync or async allow/deny decision. + */ export type ToolAuthorizer = (toolCall: ToolCall, context: ToolAuthorizationContext) => MaybePromise diff --git a/packages/core/src/virtualized-memory.ts b/packages/core/src/virtualized-memory.ts index 2c9efdb8c..5058ae509 100644 --- a/packages/core/src/virtualized-memory.ts +++ b/packages/core/src/virtualized-memory.ts @@ -1,6 +1,7 @@ import type { ChatMemory } from './types/memory' import type { Message } from './types/message' +/** Active-window and retrieval settings for virtualized chat memory. */ export interface VirtualizedMemoryOptions { /** Maximum number of recent messages to keep "hot" (always loaded). Default 50. */ maxActive?: number From a92963b835ffe4d630d5180efa2d8bdeead67f27 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 13:36:49 -0300 Subject: [PATCH 05/30] docs(core): fit entry docs within file budget --- packages/core/src/controller.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/core/src/controller.ts b/packages/core/src/controller.ts index a9a6e5fec..d8eddad65 100644 --- a/packages/core/src/controller.ts +++ b/packages/core/src/controller.ts @@ -23,16 +23,7 @@ import type { AgentEvent, AgentEventContext, } from './types' -/** Create a chat controller from adapter, conversation, and optional integration settings. - * @param initial Adapter, prompt, tool, memory, and observer settings for the chat. - * @returns Controller methods for managing the session and reading its state. - * @example - * ```ts - * const chat = createChatController({ adapter }) - * await chat.send('Hello') - * ``` - */ -export function createChatController(initial: ChatConfig): ChatController { +/** Create a chat controller from adapter, conversation, and optional integrations. @param initial Adapter, prompt, tool, memory, and observer settings. @returns Controller methods for managing the session and reading its state. @example `const chat = createChatController({ adapter }); await chat.send('Hello')`. */ export function createChatController(initial: ChatConfig): ChatController { let config = initial const controllerCorrelation: AgentEventContext = initial.correlation ?? { operationId: generateId('operation') } let activeCorrelation: AgentEventContext = controllerCorrelation From cb0d3ee9f2c647be37e5da061e9c73aa3ef7a744 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 13:39:12 -0300 Subject: [PATCH 06/30] docs(angular): document public API --- .changeset/doc03-angular.md | 5 +++++ docs/stability/jsdoc-coverage-v1.json | 10 +--------- packages/angular/src/components.ts | 7 +++++++ 3 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 .changeset/doc03-angular.md diff --git a/.changeset/doc03-angular.md b/.changeset/doc03-angular.md new file mode 100644 index 000000000..9aa64ec40 --- /dev/null +++ b/.changeset/doc03-angular.md @@ -0,0 +1,5 @@ +--- +'@agentskit/angular': patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 264d2e0cd..f8176e5e1 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -127,15 +127,7 @@ "./createAdapter::createAdapter", "./langchain-bridge::AdapterToLangChainModelOptions" ], - "@agentskit/angular": [ - ".::CodeBlockComponent", - ".::InputBarComponent", - ".::MarkdownComponent", - ".::MessageComponent", - ".::ThinkingIndicatorComponent", - ".::ToolCallViewComponent", - ".::ToolConfirmationComponent" - ], + "@agentskit/angular": [], "@agentskit/cli": [ ".::AgentsKitConfig", ".::BuildRagOptions", diff --git a/packages/angular/src/components.ts b/packages/angular/src/components.ts index b1c2e2375..cb69cd625 100644 --- a/packages/angular/src/components.ts +++ b/packages/angular/src/components.ts @@ -41,6 +41,7 @@ export class ChatContainerComponent implements AfterViewInit, OnDestroy { } } +/** Displays a chat message with role and status data attributes. */ @Component({ selector: 'ak-message', standalone: true, @@ -58,6 +59,7 @@ export class MessageComponent { @Input({ required: true }) message!: MessageType } +/** Renders a chat input and sends its contents when the form is submitted. */ @Component({ selector: 'ak-input-bar', standalone: true, @@ -104,6 +106,7 @@ export class InputBarComponent { } } +/** Displays markdown content and exposes whether it is still streaming. */ @Component({ selector: 'ak-markdown', standalone: true, @@ -114,6 +117,7 @@ export class MarkdownComponent { @Input() streaming = false } +/** Displays a code block with an optional clipboard copy button. */ @Component({ selector: 'ak-code-block', standalone: true, @@ -134,6 +138,7 @@ export class CodeBlockComponent { } } +/** Toggles a tool call's formatted arguments and result details. */ @Component({ selector: 'ak-tool-call-view', standalone: true, @@ -165,6 +170,7 @@ export class ToolCallViewComponent { } } +/** Shows a status message while the chat is waiting for a response. */ @Component({ selector: 'ak-thinking-indicator', standalone: true, @@ -180,6 +186,7 @@ export class ThinkingIndicatorComponent { @Input() label = 'Thinking...' } +/** Displays approval controls for a tool call awaiting confirmation. */ @Component({ selector: 'ak-tool-confirmation', standalone: true, From 43beed40f64933ea0f1944e57498a9c138040786 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 13:53:09 -0300 Subject: [PATCH 07/30] docs(solid): document public API --- .changeset/doc03-solid.md | 5 +++++ docs/stability/jsdoc-coverage-v1.json | 19 +------------------ .../solid/src/components/ChatContainer.tsx | 5 +++++ packages/solid/src/components/CodeBlock.tsx | 5 +++++ packages/solid/src/components/InputBar.tsx | 5 +++++ packages/solid/src/components/Markdown.tsx | 5 +++++ packages/solid/src/components/Message.tsx | 5 +++++ .../src/components/ThinkingIndicator.tsx | 5 +++++ .../solid/src/components/ToolCallView.tsx | 5 +++++ .../solid/src/components/ToolConfirmation.tsx | 5 +++++ 10 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 .changeset/doc03-solid.md diff --git a/.changeset/doc03-solid.md b/.changeset/doc03-solid.md new file mode 100644 index 000000000..59e6fa289 --- /dev/null +++ b/.changeset/doc03-solid.md @@ -0,0 +1,5 @@ +--- +'@agentskit/solid': patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index c61d3f1b4..072238ea6 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -1100,24 +1100,7 @@ ".::technicalWriter", ".::transactionTriage" ], - "@agentskit/solid": [ - ".::ChatContainer", - ".::ChatContainerProps", - ".::CodeBlock", - ".::CodeBlockProps", - ".::InputBar", - ".::InputBarProps", - ".::Markdown", - ".::MarkdownProps", - ".::Message", - ".::MessageProps", - ".::ThinkingIndicator", - ".::ThinkingIndicatorProps", - ".::ToolCallView", - ".::ToolCallViewProps", - ".::ToolConfirmation", - ".::ToolConfirmationProps" - ], + "@agentskit/solid": [], "@agentskit/statechart": [], "@agentskit/svelte": [ ".::ChatContainer", diff --git a/packages/solid/src/components/ChatContainer.tsx b/packages/solid/src/components/ChatContainer.tsx index a50960741..3be4448d0 100644 --- a/packages/solid/src/components/ChatContainer.tsx +++ b/packages/solid/src/components/ChatContainer.tsx @@ -1,10 +1,15 @@ import { onMount, onCleanup, type JSX } from 'solid-js' +/** Props accepted by the reactive chat scroll container. */ export interface ChatContainerProps { children?: JSX.Element class?: string } +/** Render a scroll container that follows newly added chat content. + * @param props Container children and optional CSS class. + * @returns The headless chat container element. + */ export function ChatContainer(props: ChatContainerProps): JSX.Element { let containerRef: HTMLDivElement | undefined diff --git a/packages/solid/src/components/CodeBlock.tsx b/packages/solid/src/components/CodeBlock.tsx index 278260242..c4c39c279 100644 --- a/packages/solid/src/components/CodeBlock.tsx +++ b/packages/solid/src/components/CodeBlock.tsx @@ -1,11 +1,16 @@ import { Show, type JSX } from 'solid-js' +/** Props accepted by the code block and optional copy control. */ export interface CodeBlockProps { code: string language?: string copyable?: boolean } +/** Render code with its optional language label and clipboard control. + * @param props The code and optional presentation settings. + * @returns The headless code block element. + */ export function CodeBlock(props: CodeBlockProps): JSX.Element { const handleCopy = () => { navigator.clipboard.writeText(props.code) diff --git a/packages/solid/src/components/InputBar.tsx b/packages/solid/src/components/InputBar.tsx index 0fa334b69..ec8e899fd 100644 --- a/packages/solid/src/components/InputBar.tsx +++ b/packages/solid/src/components/InputBar.tsx @@ -1,12 +1,17 @@ import { type JSX } from 'solid-js' import type { ChatReturn } from '@agentskit/core' +/** Props accepted by the chat input and submit control. */ export interface InputBarProps { chat: ChatReturn placeholder?: string disabled?: boolean } +/** Render an input that sends non-empty chat text on submit. + * @param props The chat controller and optional input settings. + * @returns The headless chat input form. + */ export function InputBar(props: InputBarProps): JSX.Element { const placeholder = () => props.placeholder ?? 'Type a message...' const blocked = () => (props.disabled ?? false) || props.chat.status === 'streaming' diff --git a/packages/solid/src/components/Markdown.tsx b/packages/solid/src/components/Markdown.tsx index 2f5bf04fd..07be81bbd 100644 --- a/packages/solid/src/components/Markdown.tsx +++ b/packages/solid/src/components/Markdown.tsx @@ -1,10 +1,15 @@ import { type JSX } from 'solid-js' +/** Props accepted by the markdown content surface. */ export interface MarkdownProps { content: string streaming?: boolean } +/** Render text content with an optional streaming data attribute. + * @param props The content and optional streaming state. + * @returns The headless markdown element. + */ export function Markdown(props: MarkdownProps): JSX.Element { return (
diff --git a/packages/solid/src/components/Message.tsx b/packages/solid/src/components/Message.tsx index 1e926114e..d7873ec2d 100644 --- a/packages/solid/src/components/Message.tsx +++ b/packages/solid/src/components/Message.tsx @@ -1,12 +1,17 @@ import { Show, type JSX } from 'solid-js' import type { Message as MessageType } from '@agentskit/core' +/** Props accepted by the headless chat message component. */ export interface MessageProps { message: MessageType avatar?: JSX.Element actions?: JSX.Element } +/** Render a message with optional avatar and action content. + * @param props The message and optional content slots. + * @returns The headless chat message element. + */ export function Message(props: MessageProps): JSX.Element { return (
props.label ?? 'Thinking...' diff --git a/packages/solid/src/components/ToolCallView.tsx b/packages/solid/src/components/ToolCallView.tsx index 62eaa1ffd..1e06423ec 100644 --- a/packages/solid/src/components/ToolCallView.tsx +++ b/packages/solid/src/components/ToolCallView.tsx @@ -1,10 +1,15 @@ import { createSignal, Show, type JSX } from 'solid-js' import type { ToolCall } from '@agentskit/core' +/** Props accepted by the collapsible tool call display. */ export interface ToolCallViewProps { toolCall: ToolCall } +/** Render a tool call with a toggle for its arguments and result. + * @param props The tool call to display. + * @returns The headless tool call element. + */ export function ToolCallView(props: ToolCallViewProps): JSX.Element { const [expanded, setExpanded] = createSignal(false) diff --git a/packages/solid/src/components/ToolConfirmation.tsx b/packages/solid/src/components/ToolConfirmation.tsx index 69695fb0d..9c645d4e3 100644 --- a/packages/solid/src/components/ToolConfirmation.tsx +++ b/packages/solid/src/components/ToolConfirmation.tsx @@ -1,12 +1,17 @@ import { Show, type JSX } from 'solid-js' import type { ToolCall } from '@agentskit/core' +/** Props accepted by the tool confirmation controls. */ export interface ToolConfirmationProps { toolCall: ToolCall onApprove: (toolCallId: string) => void onDeny: (toolCallId: string, reason?: string) => void } +/** Render approve and deny controls for a tool awaiting confirmation. + * @param props The tool call and its approval callbacks. + * @returns The confirmation element or an empty value. + */ export function ToolConfirmation(props: ToolConfirmationProps): JSX.Element { return ( From 5bcb9fa4fa56c7191dc999282dd38a089a87c56b Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 13:58:52 -0300 Subject: [PATCH 08/30] docs(core): document named subpath APIs --- .changeset/doc03-core-subpaths.md | 5 ++ docs/stability/jsdoc-coverage-v1.json | 95 +----------------------- packages/core/src/a2a.ts | 14 ++++ packages/core/src/agent-schema.ts | 5 ++ packages/core/src/auto-summarize.ts | 1 + packages/core/src/compose-tool.ts | 1 + packages/core/src/eval-format.ts | 16 ++++ packages/core/src/fuzzy-match.ts | 1 + packages/core/src/generative-ui.ts | 34 +++++++++ packages/core/src/hitl.ts | 4 + packages/core/src/manifest.ts | 9 +++ packages/core/src/memory-validation.ts | 6 ++ packages/core/src/prompt-experiments.ts | 5 ++ packages/core/src/security/fence.ts | 1 + packages/core/src/security/injection.ts | 4 + packages/core/src/security/pii.ts | 5 ++ packages/core/src/security/rate-limit.ts | 4 + packages/core/src/security/saml.ts | 9 +++ packages/core/src/security/sso.ts | 10 +++ packages/core/src/security/taxonomy.ts | 4 + packages/core/src/security/vault.ts | 7 ++ packages/core/src/self-debug.ts | 4 + packages/core/src/tool-proposal.ts | 6 ++ packages/core/src/types/finding.ts | 1 + 24 files changed, 157 insertions(+), 94 deletions(-) create mode 100644 .changeset/doc03-core-subpaths.md diff --git a/.changeset/doc03-core-subpaths.md b/.changeset/doc03-core-subpaths.md new file mode 100644 index 000000000..73c6f4062 --- /dev/null +++ b/.changeset/doc03-core-subpaths.md @@ -0,0 +1,5 @@ +--- +'@agentskit/core': patch +--- + +Document the public API of the named core export subpaths. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index c61d3f1b4..4c951bb63 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -297,99 +297,7 @@ ".::VectorSearchOptions", ".::videoPart", ".::VideoPart", - ".::VirtualizedMemoryOptions", - "./a2a::A2AAgentCard", - "./a2a::A2AApproveParams", - "./a2a::A2ACancelParams", - "./a2a::A2AInvokeParams", - "./a2a::A2AInvokeResult", - "./a2a::A2AMethod", - "./a2a::A2ASkillDescriptor", - "./a2a::A2ATaskStatusNotification", - "./a2a::validateAgentCard", - "./agent-schema::AgentSchema", - "./agent-schema::AgentSchemaMemory", - "./agent-schema::AgentSchemaModel", - "./agent-schema::AgentSchemaTool", - "./agent-schema::ParseAgentSchemaOptions", - "./auto-summarize::AutoSummarizeOptions", - "./compose-tool::ComposeToolOptions", - "./eval-format::EvalCase", - "./eval-format::EvalCaseExpectation", - "./eval-format::EvalRunResult", - "./eval-format::EvalSuiteDoc", - "./eval-format::validateEvalRunResult", - "./eval-format::validateEvalSuite", - "./finding::Finding", - "./fuzzy-match::FuzzyMatch", - "./generative-ui::Artifact", - "./generative-ui::ArtifactChart", - "./generative-ui::ArtifactCode", - "./generative-ui::ArtifactHtml", - "./generative-ui::ArtifactMarkdown", - "./generative-ui::DetectedArtifact", - "./generative-ui::UIElement", - "./generative-ui::UIElementArtifact", - "./generative-ui::UIElementButton", - "./generative-ui::UIElementCard", - "./generative-ui::UIElementHeading", - "./generative-ui::UIElementImage", - "./generative-ui::UIElementList", - "./generative-ui::UIElementStack", - "./generative-ui::UIMessage", - "./generative-ui::validateArtifact", - "./generative-ui::validateElement", - "./generative-ui::validateUIMessage", - "./hitl::Approval", - "./hitl::ApprovalGate", - "./hitl::ApprovalStore", - "./hitl::RequestApprovalInput", - "./manifest::Manifest", - "./manifest::ManifestSkill", - "./manifest::ManifestTool", - "./manifest::validateManifest", - "./memory-validation::validateMemoryRecord", - "./prompt-experiments::PromptDecision", - "./prompt-experiments::PromptExperiment", - "./prompt-experiments::PromptExperimentContext", - "./prompt-experiments::PromptResolver", - "./prompt-experiments::PromptVariant", - "./security::createOidcVerifier", - "./security::createSamlVerifier", - "./security::FenceOptions", - "./security::InjectionDetector", - "./security::InjectionDetectorOptions", - "./security::InjectionHeuristic", - "./security::InjectionVerdict", - "./security::OidcClaims", - "./security::OidcVerifier", - "./security::PIIRedactionHit", - "./security::PIIRedactionMatch", - "./security::PIIRedactionResult", - "./security::PIIRedactor", - "./security::PIIRule", - "./security::PIITaxonomy", - "./security::RateLimitBucket", - "./security::RateLimitDecision", - "./security::RateLimiter", - "./security::RateLimiterOptions", - "./security::RedactionAuditEvent", - "./security::RedactionAuditSink", - "./security::RedactionVault", - "./security::RevealOptions", - "./security::SamlAssertion", - "./security::SamlAttribute", - "./security::SamlVerifier", - "./security::SamlVerifierOptions", - "./security::TaxonomyValidationIssue", - "./security::TaxonomyValidationResult", - "./security::TokenizeOptions", - "./security::VaultEntry", - "./self-debug::SelfDebugger", - "./self-debug::SelfDebugInput", - "./self-debug::SelfDebugOptions", - "./self-debug::SelfDebugResult", - "./tool-proposal::proposeToolCall" + ".::VirtualizedMemoryOptions" ], "@agentskit/cross-platform": [ ".::basename", @@ -1122,7 +1030,6 @@ "@agentskit/svelte": [ ".::ChatContainer", ".::CodeBlock", - ".::createChatStore", ".::InputBar", ".::Markdown", ".::Message", diff --git a/packages/core/src/a2a.ts b/packages/core/src/a2a.ts index 488864db5..35e1cab6f 100644 --- a/packages/core/src/a2a.ts +++ b/packages/core/src/a2a.ts @@ -11,6 +11,7 @@ import { isRecord } from './primitives' export const A2A_PROTOCOL_VERSION = '2026-04' +/** Public identity, version, skills, and optional metadata advertised by an agent. */ export interface A2AAgentCard { /** Stable identifier (reverse-DNS or npm scope recommended). */ id: string @@ -27,6 +28,7 @@ export interface A2AAgentCard { icon?: string } +/** A skill an agent advertises for remote invocation. */ export interface A2ASkillDescriptor { name: string description?: string @@ -44,6 +46,7 @@ export interface A2ASkillDescriptor { // Wire protocol — JSON-RPC 2.0 methods // --------------------------------------------------------------------------- +/** JSON-RPC parameters for invoking one advertised agent skill. */ export interface A2AInvokeParams { skill: string input: Record @@ -53,6 +56,7 @@ export interface A2AInvokeParams { stream?: boolean } +/** Result envelope returned for an agent task invocation. */ export interface A2AInvokeResult { taskId: string /** Terminal state for non-streaming invocations; 'running' for stream. */ @@ -61,6 +65,7 @@ export interface A2AInvokeResult { error?: { code: number; message: string; data?: unknown } } +/** Progress or terminal status payload for a running agent task. */ export interface A2ATaskStatusNotification { taskId: string status: 'running' | 'completed' | 'failed' | 'requires-approval' @@ -70,11 +75,13 @@ export interface A2ATaskStatusNotification { error?: { code: number; message: string } } +/** Parameters for cancelling an existing agent task. */ export interface A2ACancelParams { taskId: string reason?: string } +/** Parameters for recording an approval decision on an agent task. */ export interface A2AApproveParams { taskId: string decision: 'approved' | 'rejected' @@ -82,6 +89,7 @@ export interface A2AApproveParams { metadata?: Record } +/** JSON-RPC method names supported by the A2A protocol helpers. */ export type A2AMethod = | 'agent/card' | 'task/invoke' @@ -93,6 +101,12 @@ export type A2AMethod = // Minimal validator // --------------------------------------------------------------------------- +/** + * Validate the required agent-card fields and return the typed card. + * @param raw Untrusted value to validate. + * @returns The agent card with validated skill names. + * @throws {Error} If the card or any skill has an invalid required field. + */ export function validateAgentCard(raw: unknown): A2AAgentCard { if (!isRecord(raw)) throw new Error('A2A: agent card must be an object') if (typeof raw.id !== 'string') throw new Error('A2A: card.id required') diff --git a/packages/core/src/agent-schema.ts b/packages/core/src/agent-schema.ts index dd2971bdc..31116b67e 100644 --- a/packages/core/src/agent-schema.ts +++ b/packages/core/src/agent-schema.ts @@ -1,6 +1,7 @@ import type { JSONSchema7 } from 'json-schema' import { isRecord } from './primitives' +/** Provider and optional generation settings for an agent model. */ export interface AgentSchemaModel { provider: string model?: string @@ -9,6 +10,7 @@ export interface AgentSchemaModel { baseUrl?: string } +/** Tool declaration included in an agent configuration schema. */ export interface AgentSchemaTool { name: string description?: string @@ -19,12 +21,14 @@ export interface AgentSchemaTool { tags?: string[] } +/** Memory adapter selection and configuration for an agent. */ export interface AgentSchemaMemory { kind: 'inMemory' | 'localStorage' | 'custom' key?: string options?: Record } +/** Portable declarative configuration for an AgentsKit agent. */ export interface AgentSchema { name: string description?: string @@ -36,6 +40,7 @@ export interface AgentSchema { metadata?: Record } +/** Options for parsing an agent schema with a caller-supplied format parser. */ export interface ParseAgentSchemaOptions { /** * Parser for non-JSON input (e.g. YAML). Defaults to `JSON.parse`. diff --git a/packages/core/src/auto-summarize.ts b/packages/core/src/auto-summarize.ts index 0984f026e..0658cfdc4 100644 --- a/packages/core/src/auto-summarize.ts +++ b/packages/core/src/auto-summarize.ts @@ -3,6 +3,7 @@ import type { Message } from './types/message' import type { TokenCounter } from './types/token-counter' import { approximateCounter } from './budget' +/** Token budget, summarizer, and callbacks for automatic memory compaction. */ export interface AutoSummarizeOptions { /** Hard cap on stored tokens. Once exceeded, the oldest messages are summarized. */ maxTokens: number diff --git a/packages/core/src/compose-tool.ts b/packages/core/src/compose-tool.ts index 56169891d..b329a1199 100644 --- a/packages/core/src/compose-tool.ts +++ b/packages/core/src/compose-tool.ts @@ -28,6 +28,7 @@ export interface ComposeStep = Record boolean } +/** Tool metadata, ordered steps, and hooks used to build a composed tool. */ export interface ComposeToolOptions = Record> { name: string description?: string diff --git a/packages/core/src/eval-format.ts b/packages/core/src/eval-format.ts index f4dcbdae9..adbbcfc83 100644 --- a/packages/core/src/eval-format.ts +++ b/packages/core/src/eval-format.ts @@ -11,6 +11,7 @@ import { isRecord } from './primitives' export const EVAL_FORMAT_VERSION = '2026-04' +/** Matching rules used to decide whether an evaluation output passes. */ export interface EvalCaseExpectation { /** Literal substring match. */ contains?: string @@ -22,6 +23,7 @@ export interface EvalCaseExpectation { semanticSimilarity?: number } +/** One input and its optional expected-output checks in an eval suite. */ export interface EvalCase { id: string input: string @@ -29,6 +31,7 @@ export interface EvalCase { metadata?: Record } +/** Versioned, portable collection of evaluation cases and suite metadata. */ export interface EvalSuiteDoc { evalFormatVersion: typeof EVAL_FORMAT_VERSION name: string @@ -37,6 +40,7 @@ export interface EvalSuiteDoc { cases: EvalCase[] } +/** Versioned result summary and per-case outcomes from an eval run. */ export interface EvalRunResult { evalFormatVersion: typeof EVAL_FORMAT_VERSION suite: string @@ -71,6 +75,12 @@ function assertIsoTimestamp(value: unknown, field: string): asserts value is str assert(typeof value === 'string' && !Number.isNaN(Date.parse(value)), `${field} must be a valid timestamp`) } +/** + * Validate and normalize an untrusted evaluation-suite document. + * @param raw Value to validate. + * @returns A suite document using the current format version. + * @throws {Error} If required fields, versions, or case identifiers are invalid. + */ export function validateEvalSuite(raw: unknown): EvalSuiteDoc { assert(isRecord(raw), 'root must be an object') assert(raw.evalFormatVersion === EVAL_FORMAT_VERSION, `evalFormatVersion must be "${EVAL_FORMAT_VERSION}"`) @@ -96,6 +106,12 @@ export function validateEvalSuite(raw: unknown): EvalSuiteDoc { } } +/** + * Validate an untrusted evaluation-run result and its totals. + * @param raw Value to validate. + * @returns The validated run result. + * @throws {Error} If timestamps, case records, or aggregate totals are inconsistent. + */ export function validateEvalRunResult(raw: unknown): EvalRunResult { assert(isRecord(raw), 'root must be an object') assert(raw.evalFormatVersion === EVAL_FORMAT_VERSION, `evalFormatVersion must be "${EVAL_FORMAT_VERSION}"`) diff --git a/packages/core/src/fuzzy-match.ts b/packages/core/src/fuzzy-match.ts index b2ceab319..811d21c5c 100644 --- a/packages/core/src/fuzzy-match.ts +++ b/packages/core/src/fuzzy-match.ts @@ -62,6 +62,7 @@ export function jaroWinkler(a: string, b: string, opts: { caseSensitive?: boolea return j + prefix * 0.1 * (1 - j) } +/** Candidate value and similarity score returned by fuzzy matching. */ export interface FuzzyMatch { candidate: string score: number diff --git a/packages/core/src/generative-ui.ts b/packages/core/src/generative-ui.ts index 85e981a4b..0b13bb129 100644 --- a/packages/core/src/generative-ui.ts +++ b/packages/core/src/generative-ui.ts @@ -11,24 +11,28 @@ import { isRecord } from './primitives' +/** Plain text node in a structured UI message. */ export interface UIElementText { kind: 'text' text: string weight?: 'normal' | 'bold' } +/** Heading node in a structured UI message. */ export interface UIElementHeading { kind: 'heading' level: 1 | 2 | 3 text: string } +/** Ordered or unordered list node in a structured UI message. */ export interface UIElementList { kind: 'list' ordered?: boolean items: string[] } +/** Button node with a label and optional action payload. */ export interface UIElementButton { kind: 'button' label: string @@ -37,29 +41,34 @@ export interface UIElementButton { variant?: 'primary' | 'secondary' | 'danger' } +/** Image node with a source URL and optional alternative text. */ export interface UIElementImage { kind: 'image' src: string alt?: string } +/** Card node containing child UI elements. */ export interface UIElementCard { kind: 'card' title?: string children: UIElement[] } +/** Layout node that groups child UI elements in a stack. */ export interface UIElementStack { kind: 'stack' direction?: 'row' | 'column' children: UIElement[] } +/** UI node that embeds a typed artifact. */ export interface UIElementArtifact { kind: 'artifact' artifact: Artifact } +/** Discriminated union of the supported structured UI nodes. */ export type UIElement = | UIElementText | UIElementHeading @@ -74,6 +83,7 @@ export type UIElement = // Artifacts — rich content blocks // --------------------------------------------------------------------------- +/** Source-code artifact with a language identifier. */ export interface ArtifactCode { type: 'code' language: string @@ -81,11 +91,13 @@ export interface ArtifactCode { filename?: string } +/** Markdown document artifact. */ export interface ArtifactMarkdown { type: 'markdown' source: string } +/** HTML artifact marked as untrusted for safe renderer handling. */ export interface ArtifactHtml { type: 'html' source: string @@ -95,6 +107,7 @@ export interface ArtifactHtml { sandbox?: string } +/** Data and display settings for a chart artifact. */ export interface ArtifactChart { type: 'chart' chartType: 'line' | 'bar' | 'pie' | 'scatter' | 'area' @@ -104,12 +117,14 @@ export interface ArtifactChart { title?: string } +/** Discriminated union of supported code, text, HTML, and chart artifacts. */ export type Artifact = ArtifactCode | ArtifactMarkdown | ArtifactHtml | ArtifactChart // --------------------------------------------------------------------------- // UI message wrapper + validators // --------------------------------------------------------------------------- +/** Versioned message containing structured UI elements. */ export interface UIMessage { version: 1 root: UIElement @@ -119,6 +134,12 @@ function assert(condition: unknown, message: string): asserts condition { if (!condition) throw new Error(`Invalid UIMessage: ${message}`) } +/** + * Validate an untrusted artifact object. + * @param raw Value to validate. + * @returns The artifact when its kind and fields are supported. + * @throws {Error} If the value does not match a supported artifact shape. + */ export function validateArtifact(raw: unknown): Artifact { assert(isRecord(raw), 'artifact must be an object') const type = raw.type @@ -145,6 +166,12 @@ function validateChildren(raw: unknown): UIElement[] { return raw.map(c => validateElement(c)) } +/** + * Validate an untrusted structured UI element, including nested children. + * @param raw Value to validate. + * @returns The validated UI element. + * @throws {Error} If its kind or nested fields are invalid. + */ export function validateElement(raw: unknown): UIElement { assert(isRecord(raw), 'element must be an object') switch (raw.kind) { @@ -176,6 +203,12 @@ export function validateElement(raw: unknown): UIElement { } } +/** + * Validate an untrusted versioned UI message and its elements. + * @param raw Value to validate. + * @returns The validated UI message. + * @throws {Error} If the version or any element is invalid. + */ export function validateUIMessage(raw: unknown): UIMessage { assert(isRecord(raw), 'root must be an object') assert(raw.version === 1, `unsupported version: ${String(raw.version)}`) @@ -200,6 +233,7 @@ export function parseUIMessage(input: string): UIMessage { // Artifact detection — pull artifacts out of a plain text stream // --------------------------------------------------------------------------- +/** Code artifact found in text, with source offsets for its fenced block. */ export interface DetectedArtifact { artifact: Artifact /** Offsets in the source where the fence started / ended. */ diff --git a/packages/core/src/hitl.ts b/packages/core/src/hitl.ts index 0ba1bc63d..fe3fd2280 100644 --- a/packages/core/src/hitl.ts +++ b/packages/core/src/hitl.ts @@ -13,6 +13,7 @@ import { AgentsKitError, ConfigError, ErrorCodes } from './errors' export type ApprovalDecision = 'approved' | 'rejected' +/** Persisted approval request and its pending or resolved decision state. */ export interface Approval { id: string /** Logical gate name (e.g. 'delete-user', 'send-email'). */ @@ -26,6 +27,7 @@ export interface Approval { decisionMetadata?: Record } +/** Async persistence contract used by approval gates. */ export interface ApprovalStore { /** Persist a new pending approval. */ put: (approval: Approval) => Promise @@ -38,6 +40,7 @@ export interface ApprovalStore { patch: (id: string, update: Partial>, options?: { expectedStatus?: Approval['status'] }) => Promise | null> } +/** Request details submitted to an approval gate. */ export interface RequestApprovalInput { /** Gate name (reuse across invocations — how approvers identify it). */ name: string @@ -47,6 +50,7 @@ export interface RequestApprovalInput { id: string } +/** API for requesting approval and recording decisions for a payload type. */ export interface ApprovalGate { /** * Reserve or reuse an approval by id. First caller creates a diff --git a/packages/core/src/manifest.ts b/packages/core/src/manifest.ts index f690c13e8..cec774baa 100644 --- a/packages/core/src/manifest.ts +++ b/packages/core/src/manifest.ts @@ -10,6 +10,7 @@ import { isRecord } from './primitives' export const MANIFEST_VERSION = '2026-04' +/** Tool metadata and optional input schema in a distributable manifest. */ export interface ManifestTool { name: string description?: string @@ -20,6 +21,7 @@ export interface ManifestTool { requiresConfirmation?: boolean } +/** Skill prompt, tool requirements, delegation targets, and examples. */ export interface ManifestSkill { name: string description?: string @@ -32,6 +34,7 @@ export interface ManifestSkill { examples?: Array<{ input: string; output: string }> } +/** Versioned package document for distributing AgentsKit tools and skills. */ export interface Manifest { manifestVersion: typeof MANIFEST_VERSION name: string @@ -109,6 +112,12 @@ function assertSchema(raw: unknown, path: string, active = new Set(), de active.delete(raw) } +/** + * Validate an untrusted manifest and its nested tool schemas. + * @param raw Value to validate. + * @returns The validated manifest. + * @throws {Error} If required fields or nested schema constraints are invalid. + */ export function validateManifest(raw: unknown): Manifest { assert(isRecord(raw), 'root must be an object') assert(raw.manifestVersion === MANIFEST_VERSION, `manifestVersion must be "${MANIFEST_VERSION}"`) diff --git a/packages/core/src/memory-validation.ts b/packages/core/src/memory-validation.ts index e049b4cca..ceea113e7 100644 --- a/packages/core/src/memory-validation.ts +++ b/packages/core/src/memory-validation.ts @@ -125,6 +125,12 @@ function projectMessage(message: SerializedMessage): SerializedMessage { } } +/** + * Validate an untrusted versioned memory record and return its known fields. + * @param input Value to validate. + * @returns A JSON-safe memory record. + * @throws {Error} If the version or record fields are invalid. + */ export function validateMemoryRecord(input: unknown): MemoryRecord { const snapshot = cloneJsonRecord(input, invalidRecord, Infinity, false) if (snapshot.version !== 1 || !Array.isArray(snapshot.messages)) invalidRecord() diff --git a/packages/core/src/prompt-experiments.ts b/packages/core/src/prompt-experiments.ts index 842e61eda..af55c4db2 100644 --- a/packages/core/src/prompt-experiments.ts +++ b/packages/core/src/prompt-experiments.ts @@ -1,3 +1,4 @@ +/** Prompt value and relative allocation weight for one experiment choice. */ export interface PromptVariant { /** Variant id — matches a feature-flag payload / flag value. */ id: string @@ -7,6 +8,7 @@ export interface PromptVariant { weight?: number } +/** Optional subject identifier and metadata passed into variant resolution. */ export interface PromptExperimentContext { /** * Opaque stable identifier used for sticky assignment — user id, @@ -18,11 +20,13 @@ export interface PromptExperimentContext { metadata?: Record } +/** Function that selects a configured variant or returns a known variant id. */ export type PromptResolver = ( variants: PromptVariant[], context: PromptExperimentContext, ) => PromptVariant | Promise> | string | Promise +/** Named experiment configuration with variant resolution and exposure hook. */ export interface PromptExperiment { /** Experiment name — used by analytics / flag providers as the key. */ name: string @@ -43,6 +47,7 @@ export interface PromptExperiment { }) => void } +/** Selected prompt variant and whether the resolver used its fallback. */ export interface PromptDecision { name: string variantId: string diff --git a/packages/core/src/security/fence.ts b/packages/core/src/security/fence.ts index 565439d04..257a52d28 100644 --- a/packages/core/src/security/fence.ts +++ b/packages/core/src/security/fence.ts @@ -30,6 +30,7 @@ function markerId(): string { return s.toUpperCase() // 10 hex chars } +/** Label and optional deterministic marker id for an untrusted-content fence. */ export interface FenceOptions { /** Human label shown in the marker, e.g. 'WEB PAGE', 'DOCUMENT'. Default 'INPUT'. */ label?: string diff --git a/packages/core/src/security/injection.ts b/packages/core/src/security/injection.ts index 8f69a5eba..466389e02 100644 --- a/packages/core/src/security/injection.ts +++ b/packages/core/src/security/injection.ts @@ -1,3 +1,4 @@ +/** Named pattern and score contribution used by an injection detector. */ export interface InjectionHeuristic { name: string pattern: RegExp @@ -5,6 +6,7 @@ export interface InjectionHeuristic { weight: number } +/** Score, decision, and matched signals returned by an injection detector. */ export interface InjectionVerdict { score: number blocked: boolean @@ -12,6 +14,7 @@ export interface InjectionVerdict { source: 'heuristic' | 'classifier' | 'hybrid' } +/** Threshold, heuristic set, and optional classifier for injection checks. */ export interface InjectionDetectorOptions { /** Threshold above which `blocked = true`. Default 0.7. */ threshold?: number @@ -25,6 +28,7 @@ export interface InjectionDetectorOptions { classifier?: (input: string) => Promise | number } +/** Async prompt-injection check using configured heuristics and classifier. */ export interface InjectionDetector { check: (input: string) => Promise } diff --git a/packages/core/src/security/pii.ts b/packages/core/src/security/pii.ts index a434e1fd2..df902b554 100644 --- a/packages/core/src/security/pii.ts +++ b/packages/core/src/security/pii.ts @@ -1,5 +1,6 @@ import type { Message } from '../types/message' +/** Named regular-expression rule and replacement used by a PII redactor. */ export interface PIIRule { name: string /** Pattern to match. Use global flag for full replacement. */ @@ -11,22 +12,26 @@ export interface PIIRule { replacer?: string | ((match: string) => string) } +/** Source offset and length of one redacted match. */ export interface PIIRedactionMatch { offset: number length: number } +/** Match count and offsets reported for one redaction rule. */ export interface PIIRedactionHit { rule: string count: number matches: PIIRedactionMatch[] } +/** Redacted payload together with the rules and matches that changed it. */ export interface PIIRedactionResult { value: TPayload hits: PIIRedactionHit[] } +/** String and message redaction operations built from a set of PII rules. */ export interface PIIRedactor { redact: (input: string) => PIIRedactionResult redactMessages: (messages: Message[]) => PIIRedactionResult diff --git a/packages/core/src/security/rate-limit.ts b/packages/core/src/security/rate-limit.ts index 7d7579d3c..5839eb512 100644 --- a/packages/core/src/security/rate-limit.ts +++ b/packages/core/src/security/rate-limit.ts @@ -1,3 +1,4 @@ +/** Capacity, refill amount, and interval for a token-bucket policy. */ export interface RateLimitBucket { /** Tokens available per window. */ capacity: number @@ -7,6 +8,7 @@ export interface RateLimitBucket { windowMs: number } +/** Allow/deny result and remaining capacity for one rate-limit check. */ export interface RateLimitDecision { allowed: boolean remaining: number @@ -16,6 +18,7 @@ export interface RateLimitDecision { bucket: string } +/** Key extraction, bucket selection, clock, and memory bounds for a limiter. */ export interface RateLimiterOptions { /** Extract the key to bucket against — user id, IP, API key, etc. */ keyOf: (context: TContext) => string @@ -39,6 +42,7 @@ export interface RateLimiterOptions { ttlMs?: number } +/** In-memory token-bucket operations for checking and inspecting limits. */ export interface RateLimiter { check: (context: TContext) => RateLimitDecision /** Drop bucket state for a specific key (e.g. on logout). */ diff --git a/packages/core/src/security/saml.ts b/packages/core/src/security/saml.ts index 25bb6f549..3ccec827a 100644 --- a/packages/core/src/security/saml.ts +++ b/packages/core/src/security/saml.ts @@ -1,10 +1,12 @@ import { ConfigError, ErrorCodes } from '../errors' +/** Named attribute and values extracted from a parsed SAML assertion. */ export interface SamlAttribute { name: string values: string[] } +/** Parsed SAML subject, issuer, audience, validity, and attributes. */ export interface SamlAssertion { /** SAML NameID — usually the user's stable identifier. */ subject: string @@ -18,6 +20,7 @@ export interface SamlAssertion { attributes: SamlAttribute[] } +/** Expected issuer and audience after the XML signature is checked externally. */ export interface SamlVerifierOptions { /** Expected `Issuer` (IdP entity id). */ issuer: string @@ -29,6 +32,7 @@ export interface SamlVerifierOptions { clockSkewSeconds?: number } +/** Claim checks and tenant extraction for parsed SAML assertions. */ export interface SamlVerifier { /** Verify a parsed SAML assertion after external signature validation. */ verifyClaims: (assertion: SamlAssertion) => void @@ -36,6 +40,11 @@ export interface SamlVerifier { extractTenant: (assertion: SamlAssertion, attributeName: string) => string | undefined } +/** Create claim checks for assertions whose XML signature was validated externally. + * @param options Expected issuer, audience, and signature-validation declaration. + * @returns Claim verification and tenant extraction methods. + * @throws {ConfigError} If external signature validation is not declared. + */ export function createSamlVerifier(options: SamlVerifierOptions): SamlVerifier { if (options.signatureValidation !== 'external') { throw new ConfigError({ diff --git a/packages/core/src/security/sso.ts b/packages/core/src/security/sso.ts index 1c9fd3dda..44509d186 100644 --- a/packages/core/src/security/sso.ts +++ b/packages/core/src/security/sso.ts @@ -24,6 +24,7 @@ export type { SamlAssertion, SamlAttribute, SamlVerifier, SamlVerifierOptions } // OIDC ID-token verifier (RS256 / ES256) // --------------------------------------------------------------------------- +/** Issuer, audience, JWKS, and clock settings for an OIDC ID-token verifier. */ export interface OidcVerifierOptions { /** Expected `iss` claim. Required. */ issuer: string @@ -51,6 +52,7 @@ export interface OidcVerifierOptions { jwksTimeoutMs?: number } +/** Standard validated OIDC claims plus provider-specific claims. */ export interface OidcClaims { iss: string sub: string @@ -62,6 +64,7 @@ export interface OidcClaims { [claim: string]: unknown } +/** Operations for verifying ID tokens and refreshing cached JWKS keys. */ export interface OidcVerifier { /** Verify a JWT. Throws on invalid signature, claims, or expiry. */ verify: (token: string) => Promise @@ -257,6 +260,13 @@ async function verifySignature( }) } +/** Create a verifier for OIDC tokens signed with RS256 or ES256. + * @param options Issuer, audience, and optional JWKS fetch settings. + * @returns A verifier that checks token signatures and standard claims. + * @example + * const verifier = createOidcVerifier({ issuer, audience: 'my-app' }) + * const claims = await verifier.verify(idToken) + */ export function createOidcVerifier(options: OidcVerifierOptions): OidcVerifier { const jwksUrl = options.jwksUrl ?? `${options.issuer.replace(/\/$/, '')}/.well-known/jwks.json` const jwksTtlMs = options.jwksTtlMs ?? 60 * 60 * 1000 diff --git a/packages/core/src/security/taxonomy.ts b/packages/core/src/security/taxonomy.ts index 3b5c2f8c5..2aea5e97c 100644 --- a/packages/core/src/security/taxonomy.ts +++ b/packages/core/src/security/taxonomy.ts @@ -6,6 +6,7 @@ import type { PIIRule } from './pii' * the taxonomy can be loaded from a manifest file (or fetched from a * remote source) without `eval`. */ +/** JSON-serializable rule definition used in a PII taxonomy. */ export interface PIITaxonomyEntry { name: string /** Regex source (the body, no slashes). */ @@ -18,6 +19,7 @@ export interface PIITaxonomyEntry { description?: string } +/** Versioned collection of JSON-friendly PII redaction rules. */ export interface PIITaxonomy { /** Schema version. Must be `'1'`. */ version: '1' @@ -26,6 +28,7 @@ export interface PIITaxonomy { rules: PIITaxonomyEntry[] } +/** Path and message describing one invalid taxonomy field. */ export interface TaxonomyValidationIssue { /** Rule index in the input array (-1 for top-level / shape errors). */ index: number @@ -34,6 +37,7 @@ export interface TaxonomyValidationIssue { message: string } +/** Validation status and all issues found in a PII taxonomy. */ export interface TaxonomyValidationResult { ok: boolean issues: TaxonomyValidationIssue[] diff --git a/packages/core/src/security/vault.ts b/packages/core/src/security/vault.ts index 84863d802..3328cf338 100644 --- a/packages/core/src/security/vault.ts +++ b/packages/core/src/security/vault.ts @@ -16,6 +16,7 @@ import type { PIIRule } from './pii' * Closes the reveal-by-role half of issue #791. */ +/** Identity and roles checked when revealing tokenized PII. */ export interface RevealActor { /** Stable identity (email, OIDC subject, service-account name). */ id: string @@ -23,6 +24,7 @@ export interface RevealActor { roles: string[] } +/** Stored original value, permitted roles, timestamp, and audit metadata. */ export interface VaultEntry { /** ISO 8601 timestamp the value was tokenized. */ storedAt: string @@ -34,6 +36,7 @@ export interface VaultEntry { metadata?: Record } +/** Async storage contract for originals hidden behind redaction tokens. */ export interface RedactionVault { put: (token: string, entry: VaultEntry) => Promise /** Returns the entry with no role-check; reveal() does the check. */ @@ -41,6 +44,7 @@ export interface RedactionVault { delete?: (token: string) => Promise } +/** Audit record emitted when values are tokenized or revealed. */ export interface RedactionAuditEvent { type: 'pii:redact' | 'pii:reveal' | 'pii:reveal-denied' /** ISO 8601 timestamp. */ @@ -55,8 +59,10 @@ export interface RedactionAuditEvent { context?: Record } +/** Callback that records a PII tokenization or reveal audit event. */ export type RedactionAuditSink = (event: RedactionAuditEvent) => void | Promise +/** PII rules, vault, reveal roles, and audit settings for tokenization. */ export interface TokenizeOptions { /** * Rules driving the match. Same shape as `PIIRedactor`'s rules; pass @@ -79,6 +85,7 @@ export interface TokenizeOptions { context?: Record } +/** Vault, actor, and audit settings for restoring tokenized values. */ export interface RevealOptions { vault: RedactionVault actor: RevealActor diff --git a/packages/core/src/self-debug.ts b/packages/core/src/self-debug.ts index c786f9a2e..aafeeb196 100644 --- a/packages/core/src/self-debug.ts +++ b/packages/core/src/self-debug.ts @@ -1,5 +1,6 @@ import type { ToolDefinition } from './types/tool' +/** Failed tool call details supplied to a self-debugger. */ export interface SelfDebugInput { tool: ToolDefinition args: Record @@ -7,6 +8,7 @@ export interface SelfDebugInput { attempt: number } +/** Corrected arguments to retry with, or `null` to stop retrying. */ export interface SelfDebugResult { /** Either corrected arguments (retry) or `null` to give up. */ args: Record | null @@ -14,8 +16,10 @@ export interface SelfDebugResult { reasoning?: string } +/** Callback that proposes corrected arguments after a tool execution error. */ export type SelfDebugger = (input: SelfDebugInput) => Promise | SelfDebugResult +/** Retry limit and event callback for a self-debugging tool wrapper. */ export interface SelfDebugOptions { /** Max retry attempts after the original call. Default 2. */ maxAttempts?: number diff --git a/packages/core/src/tool-proposal.ts b/packages/core/src/tool-proposal.ts index 4ac7d138f..521258da0 100644 --- a/packages/core/src/tool-proposal.ts +++ b/packages/core/src/tool-proposal.ts @@ -1,5 +1,11 @@ import type { ChatController, ToolCall } from './types' type Proposal = Pick +/** + * Submit a tool-call proposal to a chat controller. + * @param controller Controller that owns the proposal flow. + * @param proposal Proposed tool call and associated context. + * @returns The controller's resolved tool call. + */ export const proposeToolCall = (controller: ChatController, proposal: Proposal): Promise => controller.proposeToolCall(proposal) diff --git a/packages/core/src/types/finding.ts b/packages/core/src/types/finding.ts index 1dd51062b..b014e76ea 100644 --- a/packages/core/src/types/finding.ts +++ b/packages/core/src/types/finding.ts @@ -11,6 +11,7 @@ export const SEVERITY_ORDER = ['critical', 'high', 'medium', 'low', 'info'] as c /** Derived from SEVERITY_ORDER so the union and the order can never drift apart. */ export type Severity = (typeof SEVERITY_ORDER)[number] +/** Structured issue with severity, evidence, confidence, and a suggested fix. */ export interface Finding { /** Stable id within a run (for dedup / referencing). */ id: string From 3507eb0fc5f2ea37a4fc8a47c2381368249c5344 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:05:05 -0300 Subject: [PATCH 09/30] docs(vue): document public API --- .changeset/doc03-vue.md | 5 +++++ docs/stability/jsdoc-coverage-v1.json | 10 +--------- packages/vue/src/ChatContainer.ts | 4 ++++ packages/vue/src/components.ts | 7 +++++++ packages/vue/src/useChat.ts | 6 ++++++ 5 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 .changeset/doc03-vue.md diff --git a/.changeset/doc03-vue.md b/.changeset/doc03-vue.md new file mode 100644 index 000000000..d8f6d1297 --- /dev/null +++ b/.changeset/doc03-vue.md @@ -0,0 +1,5 @@ +--- +'@agentskit/vue': patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index c61d3f1b4..bda1f1bfd 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -1241,14 +1241,6 @@ "./mcp::McpToolDescriptor", "./mcp::McpToolsListResult" ], - "@agentskit/vue": [ - ".::CodeBlock", - ".::InputBar", - ".::Markdown", - ".::Message", - ".::ThinkingIndicator", - ".::ToolCallView", - ".::ToolConfirmation" - ] + "@agentskit/vue": [] } } diff --git a/packages/vue/src/ChatContainer.ts b/packages/vue/src/ChatContainer.ts index dd1ec1247..b75d1075f 100644 --- a/packages/vue/src/ChatContainer.ts +++ b/packages/vue/src/ChatContainer.ts @@ -5,6 +5,10 @@ import { useChat } from './useChat' /** * Headless chat container. Renders messages + input using * `data-ak-*` attributes; style it with your own CSS. + * @example + * ```vue + * + * ``` */ export const ChatContainer = defineComponent({ name: 'AkChatContainer', diff --git a/packages/vue/src/components.ts b/packages/vue/src/components.ts index 35e422ad0..0798050a0 100644 --- a/packages/vue/src/components.ts +++ b/packages/vue/src/components.ts @@ -14,6 +14,7 @@ export const ChatRoot = defineComponent({ }, }) +/** Displays a message with optional avatar and action slots. */ export const Message = defineComponent({ name: 'AkMessage', props: { message: { type: Object as PropType, required: true } }, @@ -35,6 +36,7 @@ export const Message = defineComponent({ }, }) +/** Renders a chat input that submits non-empty text. */ export const InputBar = defineComponent({ name: 'AkInputBar', props: { @@ -84,6 +86,7 @@ export const InputBar = defineComponent({ }, }) +/** Displays text content with an optional streaming state. */ export const Markdown = defineComponent({ name: 'AkMarkdown', props: { @@ -100,6 +103,7 @@ export const Markdown = defineComponent({ }, }) +/** Displays code with an optional language label and copy button. */ export const CodeBlock = defineComponent({ name: 'AkCodeBlock', props: { @@ -119,6 +123,7 @@ export const CodeBlock = defineComponent({ }, }) +/** Displays a tool call with expandable arguments and result. */ export const ToolCallView = defineComponent({ name: 'AkToolCallView', props: { toolCall: { type: Object as PropType, required: true } }, @@ -148,6 +153,7 @@ export const ToolCallView = defineComponent({ }, }) +/** Displays a labeled status indicator when visible. */ export const ThinkingIndicator = defineComponent({ name: 'AkThinkingIndicator', props: { @@ -169,6 +175,7 @@ export const ThinkingIndicator = defineComponent({ }, }) +/** Displays approval controls while a tool call requires confirmation. */ export const ToolConfirmation = defineComponent({ name: 'AkToolConfirmation', props: { diff --git a/packages/vue/src/useChat.ts b/packages/vue/src/useChat.ts index d3376d675..1ba5896ab 100644 --- a/packages/vue/src/useChat.ts +++ b/packages/vue/src/useChat.ts @@ -5,6 +5,12 @@ import type { ChatConfig, ChatReturn, ChatState } from '@agentskit/core' /** * Vue 3 composable — same shape as `@agentskit/react`'s `useChat`, * wired through Vue's reactivity. + * @param config Chat controller configuration. + * @returns Reactive chat state and controller actions. + * @example + * ```ts + * const chat = useChat(chatConfig) + * ``` */ export function useChat(config: ChatConfig): ChatReturn { const controller = createChatController(config) From 7e6381e5e7911ae6df1ced01fe25aae7c149f222 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:06:21 -0300 Subject: [PATCH 10/30] docs(core): fit OIDC docs within file budget --- packages/core/src/security/sso.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/core/src/security/sso.ts b/packages/core/src/security/sso.ts index 44509d186..38cf207f5 100644 --- a/packages/core/src/security/sso.ts +++ b/packages/core/src/security/sso.ts @@ -19,13 +19,11 @@ export type { SamlAssertion, SamlAttribute, SamlVerifier, SamlVerifierOptions } * * Closes part of issue #203 (SSO half). */ - // --------------------------------------------------------------------------- // OIDC ID-token verifier (RS256 / ES256) // --------------------------------------------------------------------------- -/** Issuer, audience, JWKS, and clock settings for an OIDC ID-token verifier. */ -export interface OidcVerifierOptions { +/** Issuer, audience, JWKS, and clock settings for an OIDC ID-token verifier. */ export interface OidcVerifierOptions { /** Expected `iss` claim. Required. */ issuer: string /** Expected `aud` claim — string or one of multiple acceptable audiences. */ @@ -52,8 +50,7 @@ export interface OidcVerifierOptions { jwksTimeoutMs?: number } -/** Standard validated OIDC claims plus provider-specific claims. */ -export interface OidcClaims { +/** Standard validated OIDC claims plus provider-specific claims. */ export interface OidcClaims { iss: string sub: string aud: string | string[] @@ -64,8 +61,7 @@ export interface OidcClaims { [claim: string]: unknown } -/** Operations for verifying ID tokens and refreshing cached JWKS keys. */ -export interface OidcVerifier { +/** Operations for verifying ID tokens and refreshing cached JWKS keys. */ export interface OidcVerifier { /** Verify a JWT. Throws on invalid signature, claims, or expiry. */ verify: (token: string) => Promise /** Force a JWKS refresh (useful after a known IdP key rotation). */ @@ -263,11 +259,8 @@ async function verifySignature( /** Create a verifier for OIDC tokens signed with RS256 or ES256. * @param options Issuer, audience, and optional JWKS fetch settings. * @returns A verifier that checks token signatures and standard claims. - * @example - * const verifier = createOidcVerifier({ issuer, audience: 'my-app' }) - * const claims = await verifier.verify(idToken) - */ -export function createOidcVerifier(options: OidcVerifierOptions): OidcVerifier { + * @example `const verifier = createOidcVerifier({ issuer, audience: 'my-app' }); await verifier.verify(idToken)` + */ export function createOidcVerifier(options: OidcVerifierOptions): OidcVerifier { const jwksUrl = options.jwksUrl ?? `${options.issuer.replace(/\/$/, '')}/.well-known/jwks.json` const jwksTtlMs = options.jwksTtlMs ?? 60 * 60 * 1000 const clockSkew = options.clockSkewSeconds ?? 30 From eb98f3715fe703f02c81959100ef32295626feb5 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:10:04 -0300 Subject: [PATCH 11/30] fix(vue): flatten tool result rendering --- packages/vue/src/components.ts | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/vue/src/components.ts b/packages/vue/src/components.ts index 0798050a0..d217ff363 100644 --- a/packages/vue/src/components.ts +++ b/packages/vue/src/components.ts @@ -129,8 +129,8 @@ export const ToolCallView = defineComponent({ props: { toolCall: { type: Object as PropType, required: true } }, setup(props) { const expanded = ref(false) - return () => - h('div', { 'data-ak-tool-call': '', 'data-ak-tool-status': props.toolCall.status }, [ + return () => { + const children = [ h( 'button', { @@ -143,13 +143,20 @@ export const ToolCallView = defineComponent({ }, props.toolCall.name, ), - expanded.value - ? h('div', { 'data-ak-tool-details': '' }, [ - h('pre', { 'data-ak-tool-args': '' }, JSON.stringify(props.toolCall.args, null, 2)), - props.toolCall.result ? h('div', { 'data-ak-tool-result': '' }, props.toolCall.result) : null, - ]) - : null, - ]) + ] + + if (expanded.value) { + const details = [ + h('pre', { 'data-ak-tool-args': '' }, JSON.stringify(props.toolCall.args, null, 2)), + ] + if (props.toolCall.result) { + details.push(h('div', { 'data-ak-tool-result': '' }, props.toolCall.result)) + } + children.push(h('div', { 'data-ak-tool-details': '' }, details)) + } + + return h('div', { 'data-ak-tool-call': '', 'data-ak-tool-status': props.toolCall.status }, children) + } }, }) From fe9de7c8599d7d7bf1da2ecc04792d833c18f541 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:18:52 -0300 Subject: [PATCH 12/30] docs(templates): document public API --- .changeset/doc03-templates.md | 5 +++ docs/stability/jsdoc-coverage-v1.json | 13 +------ packages/templates/src/factories.ts | 45 +++++++++++++++++++++++ packages/templates/src/scaffold-config.ts | 1 + packages/templates/src/scaffold.ts | 7 ++++ packages/templates/src/validate.ts | 15 ++++++++ 6 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 .changeset/doc03-templates.md diff --git a/.changeset/doc03-templates.md b/.changeset/doc03-templates.md new file mode 100644 index 000000000..e903c5df7 --- /dev/null +++ b/.changeset/doc03-templates.md @@ -0,0 +1,5 @@ +--- +'@agentskit/templates': patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index c61d3f1b4..9c4621309 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -1131,18 +1131,7 @@ ".::ToolCallView", ".::ToolConfirmation" ], - "@agentskit/templates": [ - ".::AdapterTemplateConfig", - ".::createAdapterTemplate", - ".::createSkillTemplate", - ".::createToolTemplate", - ".::ScaffoldType", - ".::SkillTemplateConfig", - ".::ToolTemplateConfig", - ".::validateAdapterTemplate", - ".::validateSkillTemplate", - ".::validateToolTemplate" - ], + "@agentskit/templates": [], "@agentskit/tools": [ ".::DefineZodToolConfig", ".::FetchUrlConfig", diff --git a/packages/templates/src/factories.ts b/packages/templates/src/factories.ts index bbbd26007..e839e2925 100644 --- a/packages/templates/src/factories.ts +++ b/packages/templates/src/factories.ts @@ -6,6 +6,7 @@ import type { } from '@agentskit/core' import { validateToolTemplate, validateSkillTemplate, validateAdapterTemplate } from './validate' +/** Options merged into a tool definition before validation. */ export interface ToolTemplateConfig { base?: ToolDefinition name: string @@ -19,6 +20,20 @@ export interface ToolTemplateConfig { dispose?: ToolDefinition['dispose'] } +/** Create and validate a tool definition from configuration. + * @param config The tool name, implementation, and optional fields. + * @returns A validated tool definition. + * @throws `ConfigError` when the resulting tool is invalid. + * @example + * ```ts + * const searchTool = createToolTemplate({ + * name: 'search', + * description: 'Search the catalog.', + * schema: { type: 'object' }, + * execute: async () => 'results', + * }) + * ``` + */ export function createToolTemplate(config: ToolTemplateConfig): ToolDefinition { const tool: ToolDefinition = { ...(config.base ?? {}), @@ -39,6 +54,7 @@ export function createToolTemplate(config: ToolTemplateConfig): ToolDefinition { return tool } +/** Options merged into a skill definition before validation. */ export interface SkillTemplateConfig { base?: SkillDefinition name: string @@ -53,6 +69,19 @@ export interface SkillTemplateConfig { onActivate?: SkillDefinition['onActivate'] } +/** Create and validate a skill definition from configuration. + * @param config The skill name, prompt, and optional fields. + * @returns A validated skill definition. + * @throws `ConfigError` when the resulting skill is invalid. + * @example + * ```ts + * const writingSkill = createSkillTemplate({ + * name: 'writer', + * description: 'Writes concise summaries.', + * systemPrompt: 'Summarize the supplied material.', + * }) + * ``` + */ export function createSkillTemplate(config: SkillTemplateConfig): SkillDefinition { const skill: SkillDefinition = { ...(config.base ?? { name: '', description: '', systemPrompt: '' }), @@ -71,6 +100,7 @@ export function createSkillTemplate(config: SkillTemplateConfig): SkillDefinitio return skill } +/** Options for constructing a named adapter factory. */ export interface AdapterTemplateConfig { name: string createSource: AdapterFactory['createSource'] @@ -78,6 +108,21 @@ export interface AdapterTemplateConfig { capabilities?: AdapterCapabilities } +/** Create and validate a named adapter factory. + * @param config The adapter name, source factory, and optional capabilities. + * @returns A validated adapter factory with its name. + * @throws `ConfigError` when the resulting adapter is invalid. + * @example + * ```ts + * const adapter = createAdapterTemplate({ + * name: 'my-adapter', + * createSource: () => ({ + * stream: async function* () { yield { type: 'done' as const } }, + * abort: () => {}, + * }), + * }) + * ``` + */ export function createAdapterTemplate( config: AdapterTemplateConfig, ): AdapterFactory & { name: string } { diff --git a/packages/templates/src/scaffold-config.ts b/packages/templates/src/scaffold-config.ts index 4ca927f06..19ea8830b 100644 --- a/packages/templates/src/scaffold-config.ts +++ b/packages/templates/src/scaffold-config.ts @@ -12,6 +12,7 @@ export const SCAFFOLD_TYPES = [ 'browser-adapter', ] as const +/** One of the extension shapes supported by {@link scaffold}. */ export type ScaffoldType = (typeof SCAFFOLD_TYPES)[number] /** diff --git a/packages/templates/src/scaffold.ts b/packages/templates/src/scaffold.ts index fc0dc66a0..6773427e9 100644 --- a/packages/templates/src/scaffold.ts +++ b/packages/templates/src/scaffold.ts @@ -88,6 +88,13 @@ export function planScaffoldFiles(config: ScaffoldConfig): PlannedFile[] { * renames atomically into `join(dir, name)`. Existing destinations fail * unless `overwrite: true`. Symlink destinations are always rejected. * Returned paths are the final destinations (never staging paths). + * @param config The scaffold type, package name, destination, and options. + * @returns Absolute paths of the generated package files. + * @throws `ConfigError` for invalid configuration, symlink destinations, or existing destinations without `overwrite`. + * @example + * ```ts + * const files = await scaffold({ type: 'tool', name: 'my-search', dir: './extensions' }) + * ``` */ export async function scaffold(config: ScaffoldConfig): Promise { validateScaffoldConfig(config) diff --git a/packages/templates/src/validate.ts b/packages/templates/src/validate.ts index ae017dffb..3d507e83c 100644 --- a/packages/templates/src/validate.ts +++ b/packages/templates/src/validate.ts @@ -22,6 +22,11 @@ function isPlainObject(value: unknown): value is Record { return prototype === Object.prototype || prototype === null } +/** Validate a tool definition and narrow the value to `ToolDefinition`. + * @param tool The value to validate. + * @returns Nothing; asserts that `tool` is a `ToolDefinition`. + * @throws `ConfigError` when a required tool field is invalid. + */ export function validateToolTemplate(tool: unknown): asserts tool is ToolDefinition { requireObject(tool, 'Tool') requireTrimmedString(tool.name, 'Tool name') @@ -37,6 +42,11 @@ export function validateToolTemplate(tool: unknown): asserts tool is ToolDefinit } } +/** Validate a skill definition and narrow the value to `SkillDefinition`. + * @param skill The value to validate. + * @returns Nothing; asserts that `skill` is a `SkillDefinition`. + * @throws `ConfigError` when a required skill field is invalid. + */ export function validateSkillTemplate(skill: unknown): asserts skill is SkillDefinition { requireObject(skill, 'Skill') requireTrimmedString(skill.name, 'Skill name') @@ -49,6 +59,11 @@ export function validateSkillTemplate(skill: unknown): asserts skill is SkillDef } } +/** Validate an adapter factory and narrow it to its named adapter shape. + * @param adapter The value to validate. + * @returns Nothing; asserts that `adapter` has a name and `createSource` function. + * @throws `ConfigError` when the adapter shape is invalid. + */ export function validateAdapterTemplate( adapter: unknown, ): asserts adapter is AdapterFactory & { name: string } { From b44d0a06565c95fa08040cd4d079f46c07125ff0 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:28:29 -0300 Subject: [PATCH 13/30] docs(adapters): document public API root exports --- .changeset/doc03-adapters-main.md | 5 + docs/stability/jsdoc-coverage-v1.json | 93 +------------------ packages/adapters/src/anthropic.ts | 11 +++ packages/adapters/src/azure-openai.ts | 16 ++++ packages/adapters/src/bail.ts | 8 ++ packages/adapters/src/bedrock.ts | 14 +++ packages/adapters/src/carbon.ts | 6 ++ packages/adapters/src/cerebras.ts | 11 +++ packages/adapters/src/cohere.ts | 3 + packages/adapters/src/createAdapter.ts | 5 + packages/adapters/src/credential-rotation.ts | 12 +++ packages/adapters/src/deepseek.ts | 11 +++ packages/adapters/src/deprecation.ts | 18 ++++ packages/adapters/src/embedders/deepseek.ts | 8 ++ packages/adapters/src/embedders/gemini.ts | 8 ++ packages/adapters/src/embedders/grok.ts | 8 ++ packages/adapters/src/embedders/kimi.ts | 8 ++ packages/adapters/src/embedders/ollama.ts | 8 ++ .../src/embedders/openai-compatible.ts | 9 ++ packages/adapters/src/embedders/openai.ts | 8 ++ packages/adapters/src/ensemble.ts | 12 +++ packages/adapters/src/fallback.ts | 6 ++ packages/adapters/src/fireworks.ts | 3 + packages/adapters/src/gemini.ts | 11 +++ packages/adapters/src/generic.ts | 5 + packages/adapters/src/grok.ts | 11 +++ packages/adapters/src/groq.ts | 3 + packages/adapters/src/huggingface.ts | 3 + packages/adapters/src/kimi.ts | 11 +++ packages/adapters/src/langchain.ts | 16 ++++ packages/adapters/src/llamacpp.ts | 3 + packages/adapters/src/lmstudio.ts | 3 + packages/adapters/src/mistral.ts | 3 + packages/adapters/src/mock.ts | 15 +++ packages/adapters/src/ollama.ts | 11 +++ packages/adapters/src/openai.ts | 11 +++ packages/adapters/src/openrouter.ts | 3 + packages/adapters/src/replicate.ts | 16 ++++ packages/adapters/src/router.ts | 9 ++ packages/adapters/src/together.ts | 3 + packages/adapters/src/types.ts | 3 + packages/adapters/src/vercel-ai.ts | 11 +++ packages/adapters/src/vertex.ts | 16 ++++ packages/adapters/src/vllm.ts | 3 + packages/adapters/src/webllm.ts | 16 ++++ 45 files changed, 385 insertions(+), 92 deletions(-) create mode 100644 .changeset/doc03-adapters-main.md diff --git a/.changeset/doc03-adapters-main.md b/.changeset/doc03-adapters-main.md new file mode 100644 index 000000000..c14ed2f5b --- /dev/null +++ b/.changeset/doc03-adapters-main.md @@ -0,0 +1,5 @@ +--- +"@agentskit/adapters": patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..8f4e1754c 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -2,97 +2,8 @@ "schemaVersion": 1, "packages": { "@agentskit/adapters": [ - ".::anthropic", - ".::AnthropicConfig", - ".::ApplyCarbonOptions", - ".::azureOpenAI", - ".::azureOpenAIAdapter", - ".::AzureOpenAIConfig", - ".::bailAdapter", - ".::BailConfig", - ".::bedrock", - ".::bedrockAdapter", - ".::BedrockConfig", - ".::CarbonTable", - ".::cerebrasAdapter", - ".::CerebrasConfig", - ".::CohereConfig", - ".::createAdapter", - ".::createOpenAICompatibleEmbedder", - ".::createRotatingCredentials", - ".::CredentialRefreshable", ".::DataRegion", - ".::deepseek", - ".::DeepSeekConfig", - ".::deepseekEmbedder", - ".::DeepSeekEmbedderConfig", - ".::DeprecationPolicy", - ".::EnsembleAggregator", - ".::EnsembleBranchResult", - ".::EnsembleCandidate", - ".::EnsembleOptions", - ".::FallbackCandidate", - ".::FallbackOptions", - ".::FireworksConfig", - ".::gemini", - ".::GeminiConfig", - ".::geminiEmbedder", - ".::GeminiEmbedderConfig", - ".::generic", - ".::GenericAdapterConfig", - ".::grok", - ".::GrokConfig", - ".::grokEmbedder", - ".::GrokEmbedderConfig", - ".::GroqConfig", - ".::HuggingFaceConfig", - ".::kimi", - ".::KimiConfig", - ".::kimiEmbedder", - ".::KimiEmbedderConfig", - ".::langchain", - ".::LangChainConfig", - ".::langgraph", - ".::LangGraphConfig", - ".::LlamaCppConfig", - ".::LMStudioConfig", - ".::MistralConfig", - ".::MockAdapterOptions", - ".::MockResponse", - ".::ModelDeprecation", - ".::ollama", - ".::OllamaConfig", - ".::ollamaEmbedder", - ".::OllamaEmbedderConfig", - ".::openai", - ".::OpenAICompatibleEmbedderConfig", - ".::OpenAIConfig", - ".::openaiEmbedder", - ".::OpenAIEmbedderConfig", - ".::OpenRouterConfig", - ".::RecordedTurn", - ".::RecordingFixture", - ".::RecordingSink", - ".::replicate", - ".::replicateAdapter", - ".::ReplicateConfig", - ".::resolveModel", - ".::ResolveModelInput", - ".::ResolveModelResult", - ".::RotatingCredentials", - ".::RouterCandidate", - ".::RouterOptions", - ".::RouterPolicy", - ".::TogetherConfig", - ".::vercelAI", - ".::VercelAIConfig", - ".::vertex", - ".::vertexAdapter", - ".::VertexConfig", - ".::VLLMConfig", - ".::webllm", - ".::webllmAdapter", - ".::WebLlmEngineLike", + ".::DataRegion", "./catalog::CatalogDispatchConfig", "./catalog::CatalogDispatchError", "./catalog::CatalogDriftReport", @@ -124,7 +35,6 @@ "./cli::resolveCliManifest", "./cli::SerializeCliPromptOptions", "./cli::validateCliProviderManifest", - "./createAdapter::createAdapter", "./langchain-bridge::AdapterToLangChainModelOptions" ], "@agentskit/angular": [ @@ -1098,7 +1008,6 @@ "@agentskit/svelte": [ ".::ChatContainer", ".::CodeBlock", - ".::createChatStore", ".::InputBar", ".::Markdown", ".::Message", diff --git a/packages/adapters/src/anthropic.ts b/packages/adapters/src/anthropic.ts index 1f2e0a5c7..32b9b864f 100644 --- a/packages/adapters/src/anthropic.ts +++ b/packages/adapters/src/anthropic.ts @@ -3,6 +3,9 @@ import { parseAnthropicStream, type RetryOptions } from './utils' import { createStreamSource } from './stream-source' import { toAnthropicMessages } from './tool-history' +/** + * Configuration options for the Anthropic chat adapter. + */ export interface AnthropicConfig { apiKey: string model: string @@ -11,6 +14,14 @@ export interface AnthropicConfig { retry?: RetryOptions } +/** + * Creates an adapter for Anthropic Messages API. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = anthropic({ apiKey: '…', model: 'model-name' }) + */ export function anthropic(config: AnthropicConfig): AdapterFactory { const { apiKey, model, baseUrl = 'https://api.anthropic.com', maxTokens = 4096, retry } = config diff --git a/packages/adapters/src/azure-openai.ts b/packages/adapters/src/azure-openai.ts index 7b09ac4fd..b58a69ea8 100644 --- a/packages/adapters/src/azure-openai.ts +++ b/packages/adapters/src/azure-openai.ts @@ -2,6 +2,9 @@ import type { AdapterFactory, AdapterRequest, StreamSource } from '@agentskit/co import { parseOpenAIStream, toProviderMessages, type RetryOptions } from './utils' import { createStreamSource } from './stream-source' +/** + * Configuration options for the Azure OpenAI chat adapter. + */ export interface AzureOpenAIConfig { apiKey: string /** Resource endpoint, e.g. `https://my-resource.openai.azure.com`. */ @@ -17,6 +20,14 @@ export interface AzureOpenAIConfig { const DEFAULT_API_VERSION = '2024-10-21' +/** + * Creates an adapter for Azure OpenAI chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = azureOpenAI({ apiKey: '…', endpoint: 'https://example.openai.azure.com', deployment: 'chat' }) + */ export function azureOpenAI(config: AzureOpenAIConfig): AdapterFactory { const { apiKey, endpoint, deployment, apiVersion = DEFAULT_API_VERSION, retry } = config const includeUsage = config.includeUsage ?? true @@ -63,4 +74,9 @@ export function azureOpenAI(config: AzureOpenAIConfig): AdapterFactory { } } +/** + * Creates an adapter for Azure OpenAI chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export const azureOpenAIAdapter = azureOpenAI diff --git a/packages/adapters/src/bail.ts b/packages/adapters/src/bail.ts index 0cc6922e4..a6f8b94fd 100644 --- a/packages/adapters/src/bail.ts +++ b/packages/adapters/src/bail.ts @@ -1,6 +1,9 @@ import type { AdapterFactory } from '@agentskit/core' import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the bail adapter. + */ export interface BailConfig extends OpenAICompatibleConfig {} const BAIL_BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1' @@ -32,6 +35,11 @@ export function bail(config: Partial & { apiKey: string }): AdapterF } } +/** + * Creates an adapter that fails with a configured error. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export const bailAdapter = bail /** Alias matching Alibaba's product naming. */ export const qwen = bail diff --git a/packages/adapters/src/bedrock.ts b/packages/adapters/src/bedrock.ts index 151061c6d..8e62ca514 100644 --- a/packages/adapters/src/bedrock.ts +++ b/packages/adapters/src/bedrock.ts @@ -3,6 +3,9 @@ import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from ' import { adapterErrorChunk, isAbortError, parseCompleteToolArgs } from './stream-errors' import { toAnthropicMessages } from './tool-history' +/** + * Configuration options for the Amazon Bedrock chat adapter. + */ export interface BedrockConfig { /** Bedrock model id, e.g. `anthropic.claude-3-5-sonnet-20241022-v2:0`. */ model: string @@ -187,6 +190,14 @@ async function* parseAnthropicBedrockEvents( yield adapterErrorChunk('Bedrock stream ended before message_stop') } +/** + * Creates an adapter for Amazon Bedrock Converse streaming. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = bedrock({ model: 'anthropic.claude-3-5-sonnet-20241022-v2:0' }) + */ export function bedrock(config: BedrockConfig): AdapterFactory { const { model, region, maxTokens = 4096 } = config @@ -262,4 +273,7 @@ export function bedrock(config: BedrockConfig): AdapterFactory { } } +/** + * Creates an adapter for Amazon Bedrock Converse streaming. + */ export const bedrockAdapter = bedrock diff --git a/packages/adapters/src/carbon.ts b/packages/adapters/src/carbon.ts index 1c03108fc..bc6efac18 100644 --- a/packages/adapters/src/carbon.ts +++ b/packages/adapters/src/carbon.ts @@ -21,6 +21,9 @@ import type { RouterCandidate } from './router' export type ProviderRegionKey = `${string}:${string}` +/** + * Carbon intensity values used to estimate emissions for provider regions. + */ export type CarbonTable = Record /** @@ -64,6 +67,9 @@ export const DEFAULT_CARBON_TABLE: CarbonTable = { 'cerebras:us-west-2': 0.18, } +/** + * Configuration options for the carbon estimation utilities. + */ export interface ApplyCarbonOptions { /** Override the default table. */ table?: CarbonTable diff --git a/packages/adapters/src/cerebras.ts b/packages/adapters/src/cerebras.ts index b00dc8344..7b022dd3e 100644 --- a/packages/adapters/src/cerebras.ts +++ b/packages/adapters/src/cerebras.ts @@ -1,6 +1,9 @@ import type { AdapterFactory } from '@agentskit/core' import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Cerebras chat adapter. + */ export interface CerebrasConfig extends OpenAICompatibleConfig {} const CEREBRAS_BASE_URL = 'https://api.cerebras.ai/v1' @@ -29,4 +32,12 @@ export function cerebras(config: Partial & { apiKey: string }): } } +/** + * Creates an adapter for Cerebras chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = cerebrasAdapter({ apiKey: '…', model: 'model-name' }) + */ export const cerebrasAdapter = cerebras diff --git a/packages/adapters/src/cohere.ts b/packages/adapters/src/cohere.ts index a7d7c2e5b..6761d5aa0 100644 --- a/packages/adapters/src/cohere.ts +++ b/packages/adapters/src/cohere.ts @@ -1,6 +1,9 @@ import type { AdapterFactory } from '@agentskit/core' import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the adapter support. + */ export interface CohereConfig extends OpenAICompatibleConfig {} const COHERE_BASE_URL = 'https://api.cohere.com/compatibility/v1' diff --git a/packages/adapters/src/createAdapter.ts b/packages/adapters/src/createAdapter.ts index 68f59ee6e..e553b4bc6 100644 --- a/packages/adapters/src/createAdapter.ts +++ b/packages/adapters/src/createAdapter.ts @@ -2,6 +2,11 @@ import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from ' import type { CreateAdapterConfig } from './types' import { adapterErrorChunk, isAbortError, raceAbort } from './stream-errors' +/** + * Creates an adapter from send and stream parsing functions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export function createAdapter(config: CreateAdapterConfig): AdapterFactory { return { createSource: (request: AdapterRequest): StreamSource => { diff --git a/packages/adapters/src/credential-rotation.ts b/packages/adapters/src/credential-rotation.ts index 08bab72d0..1372ffa05 100644 --- a/packages/adapters/src/credential-rotation.ts +++ b/packages/adapters/src/credential-rotation.ts @@ -18,6 +18,9 @@ export type CredentialResolver = () => string | Promise +/** + * Credential provider that returns the current credential. + */ export interface RotatingCredentials { /** Resolve the current secret. Opt-in adapters call this on every request. */ current: CredentialResolver @@ -36,6 +39,9 @@ export interface CredentialRotationEvent { fingerprint: string } +/** + * Credential provider that can refresh expiring credentials. + */ export interface CredentialRefreshable { /** * Opt-in adapters that support credential rotation expose this method. @@ -46,6 +52,12 @@ export interface CredentialRefreshable { refreshCredentials: (next: string) => Promise } +/** + * Creates a credential provider that refreshes expiring credentials. + * @param initial Value passed to the function. + * @param options Adapter configuration. + * @returns The RotatingCredentials result. + */ export function createRotatingCredentials( initial: string, options: { id: string }, diff --git a/packages/adapters/src/deepseek.ts b/packages/adapters/src/deepseek.ts index a17dc8ca5..86f04c5e7 100644 --- a/packages/adapters/src/deepseek.ts +++ b/packages/adapters/src/deepseek.ts @@ -1,5 +1,16 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the DeepSeek chat adapter. + */ export interface DeepSeekConfig extends OpenAICompatibleConfig {} +/** + * Creates an adapter for DeepSeek chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = deepseek({ apiKey: '…', model: 'model-name' }) + */ export const deepseek = createOpenAICompatibleAdapter('https://api.deepseek.com') diff --git a/packages/adapters/src/deprecation.ts b/packages/adapters/src/deprecation.ts index 33812fcb3..083f457b3 100644 --- a/packages/adapters/src/deprecation.ts +++ b/packages/adapters/src/deprecation.ts @@ -18,6 +18,9 @@ import { ConfigError, ErrorCodes, type AdapterFactory } from '@agentskit/core' export type DeprecationAction = 'warn' | 'remap' | 'fail' +/** + * Deprecation metadata for a model identifier. + */ export interface ModelDeprecation { provider: string model: string @@ -29,6 +32,9 @@ export interface ModelDeprecation { note?: string } +/** + * Policy for handling deprecated model identifiers. + */ export interface DeprecationPolicy { onDeprecation: DeprecationAction table?: ModelDeprecation[] @@ -58,11 +64,17 @@ export const DEFAULT_DEPRECATION_TABLE: ModelDeprecation[] = [ { provider: 'google', model: 'gemini-pro-vision', successor: 'gemini-1.5-pro', sunsetOn: '2024-07-12' }, ] +/** + * Input used to resolve a model against a deprecation table. + */ export interface ResolveModelInput { provider: string model: string } +/** + * A result returned by model deprecation handling. + */ export interface ResolveModelResult { /** Final model id to use (may differ from input if remapped). */ model: string @@ -70,6 +82,12 @@ export interface ResolveModelResult { deprecation?: ModelDeprecation } +/** + * Resolves a model against the deprecation table and policy. + * @param input Input to resolve. + * @param policy Policy used during resolution. + * @returns The resolved model and any deprecation information. + */ export function resolveModel( input: ResolveModelInput, policy: DeprecationPolicy, diff --git a/packages/adapters/src/embedders/deepseek.ts b/packages/adapters/src/embedders/deepseek.ts index 27fed7241..91520612d 100644 --- a/packages/adapters/src/embedders/deepseek.ts +++ b/packages/adapters/src/embedders/deepseek.ts @@ -1,5 +1,13 @@ import { createOpenAICompatibleEmbedder, type OpenAICompatibleEmbedderConfig } from './openai-compatible' +/** + * Configuration options for the DeepSeek embedder. + */ export interface DeepSeekEmbedderConfig extends OpenAICompatibleEmbedderConfig {} +/** + * Creates an embedder for DeepSeek embeddings. + * @param config Embedder configuration. + * @returns An embedding function. + */ export const deepseekEmbedder = createOpenAICompatibleEmbedder('DeepSeek', 'https://api.deepseek.com') diff --git a/packages/adapters/src/embedders/gemini.ts b/packages/adapters/src/embedders/gemini.ts index 9a787ce82..75ddf9c6d 100644 --- a/packages/adapters/src/embedders/gemini.ts +++ b/packages/adapters/src/embedders/gemini.ts @@ -4,6 +4,9 @@ import { embeddingError, readEmbeddingJson, requireEmbeddingVector, throwIfNotOk const MAX_MODEL_LIST_BYTES = 2 * 1024 * 1024 const MAX_EMBEDDING_RESPONSE_BYTES = 16 * 1024 * 1024 +/** + * Configuration options for the Gemini embedder. + */ export interface GeminiEmbedderConfig { apiKey: string model?: string @@ -43,6 +46,11 @@ async function buildModelError( } } +/** + * Creates an embedder for Gemini embeddings. + * @param config Adapter configuration. + * @returns The EmbedFn result. + */ export function geminiEmbedder(config: GeminiEmbedderConfig): EmbedFn { const { apiKey, diff --git a/packages/adapters/src/embedders/grok.ts b/packages/adapters/src/embedders/grok.ts index 2c2d3cbf0..3cc8d456a 100644 --- a/packages/adapters/src/embedders/grok.ts +++ b/packages/adapters/src/embedders/grok.ts @@ -1,5 +1,13 @@ import { createOpenAICompatibleEmbedder, type OpenAICompatibleEmbedderConfig } from './openai-compatible' +/** + * Configuration options for the xAI Grok embedder. + */ export interface GrokEmbedderConfig extends OpenAICompatibleEmbedderConfig {} +/** + * Creates an embedder for xAI embeddings. + * @param config Embedder configuration. + * @returns An embedding function. + */ export const grokEmbedder = createOpenAICompatibleEmbedder('Grok', 'https://api.x.ai') diff --git a/packages/adapters/src/embedders/kimi.ts b/packages/adapters/src/embedders/kimi.ts index bf465a709..71e05f9f3 100644 --- a/packages/adapters/src/embedders/kimi.ts +++ b/packages/adapters/src/embedders/kimi.ts @@ -1,5 +1,13 @@ import { createOpenAICompatibleEmbedder, type OpenAICompatibleEmbedderConfig } from './openai-compatible' +/** + * Configuration options for the Moonshot Kimi embedder. + */ export interface KimiEmbedderConfig extends OpenAICompatibleEmbedderConfig {} +/** + * Creates an embedder for Moonshot Kimi embeddings. + * @param config Embedder configuration. + * @returns An embedding function. + */ export const kimiEmbedder = createOpenAICompatibleEmbedder('Kimi', 'https://api.moonshot.ai') diff --git a/packages/adapters/src/embedders/ollama.ts b/packages/adapters/src/embedders/ollama.ts index f30f330a5..a6e30a55a 100644 --- a/packages/adapters/src/embedders/ollama.ts +++ b/packages/adapters/src/embedders/ollama.ts @@ -4,6 +4,9 @@ import { embeddingError, readEmbeddingJson, requireEmbeddingVector, throwIfNotOk const MAX_MODEL_LIST_BYTES = 2 * 1024 * 1024 const MAX_EMBEDDING_RESPONSE_BYTES = 16 * 1024 * 1024 +/** + * Configuration options for the Ollama embedder. + */ export interface OllamaEmbedderConfig { model?: string baseUrl?: string @@ -37,6 +40,11 @@ async function buildModelError( } } +/** + * Creates an embedder for the Ollama embeddings API. + * @param config Adapter configuration. + * @returns The EmbedFn result. + */ export function ollamaEmbedder(config: OllamaEmbedderConfig): EmbedFn { const { model = 'nomic-embed-text', baseUrl = 'http://localhost:11434' } = config diff --git a/packages/adapters/src/embedders/openai-compatible.ts b/packages/adapters/src/embedders/openai-compatible.ts index e40cbca03..34b33d181 100644 --- a/packages/adapters/src/embedders/openai-compatible.ts +++ b/packages/adapters/src/embedders/openai-compatible.ts @@ -5,6 +5,9 @@ import { embeddingError, readEmbeddingJson, requireEmbeddingVector, throwIfNotOk const MAX_MODEL_LIST_BYTES = 2 * 1024 * 1024 const MAX_EMBEDDING_RESPONSE_BYTES = 16 * 1024 * 1024 +/** + * Configuration options for the OpenAI-compatible embedder. + */ export interface OpenAICompatibleEmbedderConfig { apiKey: string model: string @@ -43,6 +46,12 @@ async function buildModelError( } } +/** + * Creates an embedder for an OpenAI-compatible embeddings API. + * @param provider Value passed to the function. + * @param defaultBaseUrl Value passed to the function. + * @returns The the function result result. + */ export function createOpenAICompatibleEmbedder(provider: string, defaultBaseUrl: string) { return function embedder(config: OpenAICompatibleEmbedderConfig): EmbedFn { if (!config.model) { diff --git a/packages/adapters/src/embedders/openai.ts b/packages/adapters/src/embedders/openai.ts index e16382771..3a470924c 100644 --- a/packages/adapters/src/embedders/openai.ts +++ b/packages/adapters/src/embedders/openai.ts @@ -4,6 +4,9 @@ import { embeddingError, readEmbeddingJson, requireEmbeddingVector, throwIfNotOk const MAX_MODEL_LIST_BYTES = 2 * 1024 * 1024 const MAX_EMBEDDING_RESPONSE_BYTES = 16 * 1024 * 1024 +/** + * Configuration options for the OpenAI embedder. + */ export interface OpenAIEmbedderConfig { apiKey: string model?: string @@ -41,6 +44,11 @@ async function buildModelError( } } +/** + * Creates an embedder for the OpenAI embeddings API. + * @param config Adapter configuration. + * @returns The EmbedFn result. + */ export function openaiEmbedder(config: OpenAIEmbedderConfig): EmbedFn { const { apiKey, model = 'text-embedding-3-small', baseUrl = 'https://api.openai.com' } = config diff --git a/packages/adapters/src/ensemble.ts b/packages/adapters/src/ensemble.ts index bf07d8958..36de040aa 100644 --- a/packages/adapters/src/ensemble.ts +++ b/packages/adapters/src/ensemble.ts @@ -2,6 +2,9 @@ import { AdapterError, ConfigError, ErrorCodes } from '@agentskit/core' import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from '@agentskit/core' import { isAbortError } from './stream-errors' +/** + * A candidate used by ensemble adapter. + */ export interface EnsembleCandidate { id: string adapter: AdapterFactory @@ -9,6 +12,9 @@ export interface EnsembleCandidate { weight?: number } +/** + * A result returned by ensemble adapter. + */ export interface EnsembleBranchResult { id: string text: string @@ -16,12 +22,18 @@ export interface EnsembleBranchResult { error?: Error } +/** + * Function that selects an output from ensemble branch results. + */ export type EnsembleAggregator = | 'majority-vote' | 'concat' | 'longest' | ((branches: EnsembleBranchResult[]) => string | Promise) +/** + * Configuration options for the ensemble adapter. + */ export interface EnsembleOptions { candidates: EnsembleCandidate[] /** How to combine branches into the single output text. Default 'majority-vote'. */ diff --git a/packages/adapters/src/fallback.ts b/packages/adapters/src/fallback.ts index 0956b0570..341dba764 100644 --- a/packages/adapters/src/fallback.ts +++ b/packages/adapters/src/fallback.ts @@ -2,6 +2,9 @@ import { AdapterError, ConfigError, ErrorCodes } from '@agentskit/core' import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from '@agentskit/core' import { isAbortError } from './stream-errors' +/** + * Configuration options for the fallback adapter. + */ export interface FallbackOptions { /** * Predicate deciding whether an error from a given adapter should @@ -12,6 +15,9 @@ export interface FallbackOptions { onFallback?: (from: { id: string; index: number; error: Error }) => void } +/** + * A candidate used by fallback adapter. + */ export interface FallbackCandidate { id: string adapter: AdapterFactory diff --git a/packages/adapters/src/fireworks.ts b/packages/adapters/src/fireworks.ts index 3b99158bb..082833c07 100644 --- a/packages/adapters/src/fireworks.ts +++ b/packages/adapters/src/fireworks.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Fireworks chat adapter. + */ export interface FireworksConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/gemini.ts b/packages/adapters/src/gemini.ts index 1e0530144..04ddbc88e 100644 --- a/packages/adapters/src/gemini.ts +++ b/packages/adapters/src/gemini.ts @@ -3,6 +3,9 @@ import { parseGeminiStream, type RetryOptions } from './utils' import { createStreamSource } from './stream-source' import { toGeminiContents } from './tool-history' +/** + * Configuration options for the Gemini chat adapter. + */ export interface GeminiConfig { apiKey: string model: string @@ -10,6 +13,14 @@ export interface GeminiConfig { retry?: RetryOptions } +/** + * Creates an adapter for Gemini streaming chat. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = gemini({ apiKey: '…', model: 'model-name' }) + */ export function gemini(config: GeminiConfig): AdapterFactory { const { apiKey, model, baseUrl = 'https://generativelanguage.googleapis.com', retry } = config diff --git a/packages/adapters/src/generic.ts b/packages/adapters/src/generic.ts index 10ae4f1ec..5524f1995 100644 --- a/packages/adapters/src/generic.ts +++ b/packages/adapters/src/generic.ts @@ -2,6 +2,11 @@ import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from ' import type { GenericAdapterConfig } from './types' import { isAbortError, raceAbort } from './stream-errors' +/** + * Creates an adapter from a generic request sender. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export function generic(config: GenericAdapterConfig): AdapterFactory { return { createSource: (request: AdapterRequest): StreamSource => { diff --git a/packages/adapters/src/grok.ts b/packages/adapters/src/grok.ts index ec52a1b20..0a814c661 100644 --- a/packages/adapters/src/grok.ts +++ b/packages/adapters/src/grok.ts @@ -1,5 +1,16 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the xAI Grok chat adapter. + */ export interface GrokConfig extends OpenAICompatibleConfig {} +/** + * Creates an adapter for xAI Grok chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = grok({ apiKey: '…', model: 'model-name' }) + */ export const grok = createOpenAICompatibleAdapter('https://api.x.ai') diff --git a/packages/adapters/src/groq.ts b/packages/adapters/src/groq.ts index eb7e139ff..4bae04601 100644 --- a/packages/adapters/src/groq.ts +++ b/packages/adapters/src/groq.ts @@ -1,6 +1,9 @@ import type { AdapterFactory } from '@agentskit/core' import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Groq chat adapter. + */ export interface GroqConfig extends OpenAICompatibleConfig {} const GROQ_BASE_URL = 'https://api.groq.com/openai/v1' diff --git a/packages/adapters/src/huggingface.ts b/packages/adapters/src/huggingface.ts index 5876e5c41..4ec659c8b 100644 --- a/packages/adapters/src/huggingface.ts +++ b/packages/adapters/src/huggingface.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Hugging Face chat adapter. + */ export interface HuggingFaceConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/kimi.ts b/packages/adapters/src/kimi.ts index 53d300b2f..60ba17ddc 100644 --- a/packages/adapters/src/kimi.ts +++ b/packages/adapters/src/kimi.ts @@ -1,5 +1,16 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Moonshot Kimi chat adapter. + */ export interface KimiConfig extends OpenAICompatibleConfig {} +/** + * Creates an adapter for Moonshot Kimi chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = kimi({ apiKey: '…', model: 'model-name' }) + */ export const kimi = createOpenAICompatibleAdapter('https://api.moonshot.ai') diff --git a/packages/adapters/src/langchain.ts b/packages/adapters/src/langchain.ts index 507e4ce1b..10ccd7232 100644 --- a/packages/adapters/src/langchain.ts +++ b/packages/adapters/src/langchain.ts @@ -6,6 +6,9 @@ type LangChainRunnable = { streamEvents?: (input: unknown, config?: Record) => AsyncIterable> | Promise>> } +/** + * Configuration options for the LangChain and LangGraph adapters. + */ export interface LangChainConfig { runnable: LangChainRunnable mode?: 'stream' | 'events' @@ -24,6 +27,11 @@ function isToolStartEvent(eventName: string): boolean { return eventName === 'on_tool_start' || eventName.endsWith('_tool_start') } +/** + * Wraps a LangChain chat model as an AgentsKit adapter. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export function langchain(config: LangChainConfig): AdapterFactory { const { runnable, mode = 'stream' } = config @@ -96,10 +104,18 @@ export function langchain(config: LangChainConfig): AdapterFactory { } } +/** + * Configuration options for the LangChain and LangGraph adapters. + */ export interface LangGraphConfig { graph: LangChainRunnable } +/** + * Wraps a LangGraph-compatible model as an AgentsKit adapter. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export function langgraph(config: LangGraphConfig): AdapterFactory { return langchain({ runnable: config.graph, diff --git a/packages/adapters/src/llamacpp.ts b/packages/adapters/src/llamacpp.ts index a38f90b96..4cf3f6302 100644 --- a/packages/adapters/src/llamacpp.ts +++ b/packages/adapters/src/llamacpp.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the llama.cpp chat adapter. + */ export interface LlamaCppConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/lmstudio.ts b/packages/adapters/src/lmstudio.ts index 346121bac..4737fa817 100644 --- a/packages/adapters/src/lmstudio.ts +++ b/packages/adapters/src/lmstudio.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the LM Studio chat adapter. + */ export interface LMStudioConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/mistral.ts b/packages/adapters/src/mistral.ts index e680056ad..c395015a9 100644 --- a/packages/adapters/src/mistral.ts +++ b/packages/adapters/src/mistral.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Mistral chat adapter. + */ export interface MistralConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/mock.ts b/packages/adapters/src/mock.ts index c4f50390b..563d453e9 100644 --- a/packages/adapters/src/mock.ts +++ b/packages/adapters/src/mock.ts @@ -7,8 +7,14 @@ import type { } from '@agentskit/core' import { abortableSleep, adapterErrorChunk, isAbortError } from './stream-errors' +/** + * A mock response emitted by a mock adapter. + */ export type MockResponse = StreamChunk[] | ((request: AdapterRequest) => StreamChunk[]) +/** + * Configuration options for the mock and recording adapters. + */ export interface MockAdapterOptions { /** * Static chunks, a request-aware function, or a sequence of responses @@ -149,6 +155,9 @@ function resolve( // Recording / replay // ============================================================================ +/** + * One recorded request and response turn. + */ export interface RecordedTurn { /** ISO timestamp when this turn was recorded. */ recordedAt: string @@ -158,8 +167,14 @@ export interface RecordedTurn { chunks: StreamChunk[] } +/** + * Recorded turns used to replay adapter responses. + */ export type RecordingFixture = RecordedTurn[] +/** + * Sink that stores recorded adapter turns. + */ export interface RecordingSink { push(turn: RecordedTurn): void | Promise } diff --git a/packages/adapters/src/ollama.ts b/packages/adapters/src/ollama.ts index 5ec3e4ceb..5d2d2af2e 100644 --- a/packages/adapters/src/ollama.ts +++ b/packages/adapters/src/ollama.ts @@ -2,12 +2,23 @@ import type { AdapterFactory, AdapterRequest, StreamSource } from '@agentskit/co import { parseOllamaStream, type RetryOptions } from './utils' import { createStreamSource } from './stream-source' +/** + * Configuration options for the Ollama chat adapter. + */ export interface OllamaConfig { model: string baseUrl?: string retry?: RetryOptions } +/** + * Creates an adapter for Ollama chat. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = ollama({ model: 'llama3.1' }) + */ export function ollama(config: OllamaConfig): AdapterFactory { const { model, baseUrl = 'http://localhost:11434', retry } = config diff --git a/packages/adapters/src/openai.ts b/packages/adapters/src/openai.ts index 56c297077..92103ec0f 100644 --- a/packages/adapters/src/openai.ts +++ b/packages/adapters/src/openai.ts @@ -2,6 +2,9 @@ import type { AdapterCapabilities, AdapterFactory, AdapterRequest, StreamSource import { parseOpenAIStream, toProviderMessages, type RetryOptions } from './utils' import { createStreamSource } from './stream-source' +/** + * Configuration options for the OpenAI chat adapter. + */ export interface OpenAIConfig { apiKey: string model: string @@ -19,6 +22,14 @@ export interface OpenAIConfig { capabilities?: Partial } +/** + * Creates an adapter for OpenAI chat completions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = openai({ apiKey: '…', model: 'model-name' }) + */ export function openai(config: OpenAIConfig): AdapterFactory { const { apiKey, model, baseUrl = 'https://api.openai.com', retry } = config // Normalize: many compatible endpoints are declared WITH a trailing `/v1` diff --git a/packages/adapters/src/openrouter.ts b/packages/adapters/src/openrouter.ts index 740ad735b..7664f00f3 100644 --- a/packages/adapters/src/openrouter.ts +++ b/packages/adapters/src/openrouter.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the OpenRouter chat adapter. + */ export interface OpenRouterConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/replicate.ts b/packages/adapters/src/replicate.ts index 2cbc0f369..2a75c3686 100644 --- a/packages/adapters/src/replicate.ts +++ b/packages/adapters/src/replicate.ts @@ -2,6 +2,9 @@ import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from ' import { parseSSE, readJson } from '@agentskit/net' import { adapterErrorChunk, isAbortError } from './stream-errors' +/** + * Configuration options for the Replicate chat adapter. + */ export interface ReplicateConfig { apiKey: string /** Replicate model id, e.g. `meta/meta-llama-3-70b-instruct`. */ @@ -52,6 +55,14 @@ async function* parseReplicateStream( if (!sawDone) yield adapterErrorChunk('Replicate stream ended without done event') } +/** + * Creates an adapter for Replicate streaming predictions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = replicate({ apiKey: '…', model: 'model-name' }) + */ export function replicate(config: ReplicateConfig): AdapterFactory { const { apiKey, model, version, baseUrl = DEFAULT_BASE_URL, toInput = (r) => ({ prompt: defaultPrompt(r) }) } = config @@ -135,4 +146,9 @@ export function replicate(config: ReplicateConfig): AdapterFactory { } } +/** + * Creates an adapter for Replicate streaming predictions. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export const replicateAdapter = replicate diff --git a/packages/adapters/src/router.ts b/packages/adapters/src/router.ts index 7da1f2bea..25037da3e 100644 --- a/packages/adapters/src/router.ts +++ b/packages/adapters/src/router.ts @@ -9,6 +9,9 @@ import type { } from '@agentskit/core' import { isAbortError, raceAbort } from './stream-errors' +/** + * A candidate used by model routing. + */ export interface RouterCandidate { id: string adapter: AdapterFactory @@ -38,6 +41,9 @@ export interface RouterCandidate { gCO2PerKtok?: number } +/** + * Policy used to select an adapter routing candidate. + */ export type RouterPolicy = | 'cheapest' | 'fastest' @@ -46,6 +52,9 @@ export type RouterPolicy = | 'capability-match' | ((input: { request: AdapterRequest; candidates: RouterCandidate[] }) => string | Promise) +/** + * Configuration options for the model routing. + */ export interface RouterOptions { candidates: RouterCandidate[] /** Require all selected adapters to match this data-residency region. */ diff --git a/packages/adapters/src/together.ts b/packages/adapters/src/together.ts index 7b2977a6a..3ac1974f3 100644 --- a/packages/adapters/src/together.ts +++ b/packages/adapters/src/together.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the Together AI chat adapter. + */ export interface TogetherConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/types.ts b/packages/adapters/src/types.ts index 094ab2303..3a596033b 100644 --- a/packages/adapters/src/types.ts +++ b/packages/adapters/src/types.ts @@ -17,6 +17,9 @@ export interface CreateAdapterConfig { abort?: () => void } +/** + * Configuration options for the adapter configuration. + */ export interface GenericAdapterConfig { send: ( request: AdapterRequest, diff --git a/packages/adapters/src/vercel-ai.ts b/packages/adapters/src/vercel-ai.ts index d2ed23026..28db7af1f 100644 --- a/packages/adapters/src/vercel-ai.ts +++ b/packages/adapters/src/vercel-ai.ts @@ -4,6 +4,9 @@ import type { RetryOptions } from './utils' import { createStreamSource } from './stream-source' import { adapterErrorChunk } from './stream-errors' +/** + * Configuration options for the Vercel AI SDK adapter. + */ export interface VercelAIConfig { api: string headers?: Record @@ -105,6 +108,14 @@ export async function* parseVercelStream( yield* parseVercelTextStream(stream) } +/** + * Creates an adapter for the Vercel AI SDK. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = vercelAI({ api: 'https://example.com/chat' }) + */ export function vercelAI(config: VercelAIConfig): AdapterFactory { const { api, headers = {}, retry } = config diff --git a/packages/adapters/src/vertex.ts b/packages/adapters/src/vertex.ts index 5fa32a4b8..e3af2c9f7 100644 --- a/packages/adapters/src/vertex.ts +++ b/packages/adapters/src/vertex.ts @@ -3,6 +3,9 @@ import { parseGeminiStream, type RetryOptions } from './utils' import { createStreamSource } from './stream-source' import { toGeminiContents } from './tool-history' +/** + * Configuration options for the Vertex AI chat adapter. + */ export interface VertexConfig { /** GCP project id. */ project: string @@ -22,6 +25,14 @@ export interface VertexConfig { retry?: RetryOptions } +/** + * Creates an adapter for Vertex AI Gemini streaming. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = vertex({ project: 'my-project', region: 'us-central1', model: 'gemini-2.5-pro' }) + */ export function vertex(config: VertexConfig): AdapterFactory { const { project, region, model, accessToken, publisher = 'google', retry } = config const url = `https://${region}-aiplatform.googleapis.com/v1/projects/${project}/locations/${region}/publishers/${publisher}/models/${model}:streamGenerateContent?alt=sse` @@ -73,4 +84,9 @@ export function vertex(config: VertexConfig): AdapterFactory { } } +/** + * Creates an adapter for Vertex AI Gemini streaming. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export const vertexAdapter = vertex diff --git a/packages/adapters/src/vllm.ts b/packages/adapters/src/vllm.ts index 80f772620..a0ea94345 100644 --- a/packages/adapters/src/vllm.ts +++ b/packages/adapters/src/vllm.ts @@ -1,5 +1,8 @@ import { createOpenAICompatibleAdapter, type OpenAICompatibleConfig } from './openai-compatible' +/** + * Configuration options for the vLLM chat adapter. + */ export interface VLLMConfig extends OpenAICompatibleConfig {} /** diff --git a/packages/adapters/src/webllm.ts b/packages/adapters/src/webllm.ts index f77fab38f..0b0d61f0b 100644 --- a/packages/adapters/src/webllm.ts +++ b/packages/adapters/src/webllm.ts @@ -24,6 +24,9 @@ export interface WebLlmConfig { onProgress?: (info: { progress: number; text: string }) => void } +/** + * Data type used by the WebLLM chat adapter. + */ export interface WebLlmEngineLike { reload(model: string, opts?: { initProgressCallback?: (i: { progress: number; text: string }) => void }): Promise chat: { @@ -59,6 +62,14 @@ async function loadSdk(): Promise { return cachedSdk } +/** + * Creates an adapter for WebLLM chat generation. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + * + * @example + * const adapter = webllm({ model: 'Llama-3.1-8B-Instruct-q4f16_1-MLC' }) + */ export function webllm(config: WebLlmConfig): AdapterFactory { let enginePromise: Promise | null = null const getEngine = (): Promise => { @@ -141,4 +152,9 @@ export function webllm(config: WebLlmConfig): AdapterFactory { } } +/** + * Creates an adapter for WebLLM chat generation. + * @param config Adapter configuration. + * @returns An AgentsKit adapter factory. + */ export const webllmAdapter = webllm From f22c75f7371ac69d8b48f31a13c5b9159fb8e6be Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:38:40 -0300 Subject: [PATCH 14/30] docs(eval): document public API --- .changeset/doc03-eval.md | 5 ++++ docs/stability/jsdoc-coverage-v1.json | 36 +---------------------- packages/eval/src/ci/index.ts | 2 ++ packages/eval/src/diff/diff.ts | 5 ++++ packages/eval/src/replay/against.ts | 24 +++++++++++----- packages/eval/src/replay/cassette.ts | 22 ++++++++++++++ packages/eval/src/replay/io.ts | 6 ++++ packages/eval/src/replay/player.ts | 16 +++++++---- packages/eval/src/replay/recorder.ts | 14 +++++++-- packages/eval/src/replay/time-travel.ts | 14 ++++++--- packages/eval/src/replay/types.ts | 4 +++ packages/eval/src/runner.ts | 10 +++++++ packages/eval/src/snapshot/snapshot.ts | 38 +++++++++++++++++++++++++ packages/eval/src/types.ts | 3 ++ 14 files changed, 144 insertions(+), 55 deletions(-) create mode 100644 .changeset/doc03-eval.md diff --git a/.changeset/doc03-eval.md b/.changeset/doc03-eval.md new file mode 100644 index 000000000..25cb04aa1 --- /dev/null +++ b/.changeset/doc03-eval.md @@ -0,0 +1,5 @@ +--- +"@agentskit/eval": patch +--- + +Document the public evaluation, replay, snapshot, diff, and CI reporting APIs. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..7281197d8 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -431,12 +431,8 @@ "./pure::SplitLinesOptions" ], "@agentskit/eval": [ - ".::AgentFn", - ".::AgentResponse", ".::EvalResult", ".::EvalSuite", - ".::runEval", - ".::RunEvalConfig", "./braintrust::ALL_SCORERS", "./braintrust::BraintrustRunOptions", "./braintrust::citationCorrectness", @@ -484,37 +480,7 @@ "./braintrust/scorers::SchemaValidityMeta", "./braintrust/scorers::taskSuccess", "./braintrust/scorers::toolArgValidity", - "./braintrust/scorers::ToolArgValidityInput", - "./ci::CiReportOptions", - "./ci::CiReportOutput", - "./diff::Attribution", - "./diff::AttributionInput", - "./diff::DiffLine", - "./diff::DiffOp", - "./diff::PromptDiff", - "./replay::Cassette", - "./replay::CassetteEntry", - "./replay::createCassette", - "./replay::fingerprintRequest", - "./replay::loadCassette", - "./replay::parseCassette", - "./replay::RecordingAdapter", - "./replay::RecordOptions", - "./replay::ReplayAgainstOptions", - "./replay::ReplayAgainstResult", - "./replay::ReplayOptions", - "./replay::serializeCassette", - "./replay::TimeTravelSession", - "./replay/io::loadCassette", - "./snapshot::comparePrompt", - "./snapshot::cosine", - "./snapshot::EmbedFn", - "./snapshot::jaccard", - "./snapshot::normalize", - "./snapshot::SnapshotMode", - "./snapshot::SnapshotOptions", - "./snapshot::SnapshotResult", - "./snapshot::tokenize" + "./braintrust/scorers::ToolArgValidityInput" ], "@agentskit/ink": [ ".::AdapterContext", diff --git a/packages/eval/src/ci/index.ts b/packages/eval/src/ci/index.ts index ddd21ac13..111a13c41 100644 --- a/packages/eval/src/ci/index.ts +++ b/packages/eval/src/ci/index.ts @@ -3,6 +3,7 @@ import { renderGitHubAnnotations, renderJUnit, renderMarkdown } from './reporter export { renderJUnit, renderMarkdown, renderGitHubAnnotations } from './reporters' +/** Configuration for writing CI reports from an evaluation result. */ export interface CiReportOptions { suiteName: string result: EvalResult @@ -18,6 +19,7 @@ export interface CiReportOptions { stepSummary?: boolean } +/** Rendered reports and accuracy status returned by {@link reportToCi}. */ export interface CiReportOutput { junit: string markdown: string diff --git a/packages/eval/src/diff/diff.ts b/packages/eval/src/diff/diff.ts index e7946dd2e..7e7c759e1 100644 --- a/packages/eval/src/diff/diff.ts +++ b/packages/eval/src/diff/diff.ts @@ -1,5 +1,7 @@ +/** Whether a prompt line is unchanged, added, or removed. */ export type DiffOp = 'equal' | 'add' | 'remove' +/** One line in a prompt diff, with a one-based line number for its source side. */ export interface DiffLine { op: DiffOp /** 1-based line number in the side that owns this line. */ @@ -7,6 +9,7 @@ export interface DiffLine { content: string } +/** Line changes and aggregate counts produced by {@link promptDiff}. */ export interface PromptDiff { lines: DiffLine[] added: number @@ -77,6 +80,7 @@ export function formatDiff(diff: PromptDiff): string { .join('\n') } +/** Old and new prompt/output pairs used to attribute an output change. */ export interface AttributionInput { oldPrompt: string newPrompt: string @@ -84,6 +88,7 @@ export interface AttributionInput { newOutput: string } +/** Prompt/output change flags and lines sharing tokens with the output delta. */ export interface Attribution { outputChanged: boolean promptChanged: boolean diff --git a/packages/eval/src/replay/against.ts b/packages/eval/src/replay/against.ts index e54c8b369..f8f964af2 100644 --- a/packages/eval/src/replay/against.ts +++ b/packages/eval/src/replay/against.ts @@ -2,6 +2,7 @@ import { ConfigError, ErrorCodes, type AdapterFactory, type StreamChunk } from ' import { defensiveSnapshot } from './clone' import type { Cassette } from './types' +/** Comparison of one recorded turn with the candidate adapter's response. */ export interface ReplayAgainstResult { turn: number input: string @@ -11,6 +12,7 @@ export interface ReplayAgainstResult { similarity: number } +/** Limits and concurrency settings for {@link replayAgainst}. */ export interface ReplayAgainstOptions { /** Max concurrent candidate turns. Default 1 (sequential, safer). */ concurrency?: number @@ -53,11 +55,17 @@ function assertNonNegativeInt(value: unknown, name: string): number { return value } -/** - * Re-run every recorded turn in `cassette` through a different - * `candidate` adapter and return a per-turn comparison. Fast way to - * A/B a production trace against a cheaper or newer model without - * touching real users. +/** Replay recorded turns through another adapter and compare concatenated text output. + * + * @param cassette Recorded turns to replay. + * @param candidate Adapter factory to evaluate against the recorded turns. + * @param options Optional turn limit and maximum candidate concurrency. + * @returns One comparison result for each selected cassette entry. + * @throws ConfigError when `limit` or `concurrency` is not a non-negative integer. + * @example + * ```ts + * const turns = await replayAgainst(cassette, candidate, { limit: 10 }) + * ``` */ export async function replayAgainst( cassette: Cassette, @@ -112,8 +120,10 @@ export async function replayAgainst( return results } -/** - * Summary metric over a list of `replayAgainst` turns. +/** Summarize similarity and candidate errors across replay comparisons. + * + * @param turns Results returned by {@link replayAgainst}. + * @returns Mean and minimum similarity, error count, and turn count. */ export function summarizeReplay(turns: ReplayAgainstResult[]): { avgSimilarity: number diff --git a/packages/eval/src/replay/cassette.ts b/packages/eval/src/replay/cassette.ts index 905dda5dd..6ce30368e 100644 --- a/packages/eval/src/replay/cassette.ts +++ b/packages/eval/src/replay/cassette.ts @@ -2,6 +2,11 @@ import { ConfigError, ErrorCodes, isRecord, type AdapterRequest } from '@agentsk import { defensiveSnapshot } from './clone' import type { Cassette, CassetteEntry } from './types' +/** Create a version 1 cassette with an isolated copy of its initial data. + * + * @param init Optional cassette fields to copy into the new cassette. + * @returns A cassette with version 1 and an empty entries array by default. + */ export function createCassette(init: Partial = {}): Cassette { return { version: 1, @@ -11,6 +16,11 @@ export function createCassette(init: Partial = {}): Cassette { } } +/** Serialize a cassette as indented JSON. + * + * @param cassette Cassette to serialize. + * @returns The cassette JSON string. + */ export function serializeCassette(cassette: Cassette): string { return JSON.stringify(cassette, null, 2) } @@ -116,6 +126,12 @@ function assertCassetteEntry(entry: unknown, index: number): asserts entry is Ca } } +/** Parse and validate a serialized version 1 cassette. + * + * @param input JSON text to parse. + * @returns A validated cassette with message timestamps restored as dates. + * @throws ConfigError when the JSON or cassette shape is invalid or unsupported. + */ export function parseCassette(input: string): Cassette { let parsed: unknown try { @@ -159,6 +175,12 @@ export function parseCassette(input: string): Cassette { return cassette } +/** Create a stable JSON fingerprint for the serializable parts of an adapter request. + * + * @param request Adapter request to fingerprint. + * @returns Canonical JSON used to match recorded requests. + * @throws ConfigError when the request contains values that cannot be fingerprinted. + */ export function fingerprintRequest(request: AdapterRequest): string { const seen = new WeakSet() diff --git a/packages/eval/src/replay/io.ts b/packages/eval/src/replay/io.ts index 908139aa6..382ee37d5 100644 --- a/packages/eval/src/replay/io.ts +++ b/packages/eval/src/replay/io.ts @@ -13,6 +13,12 @@ export async function saveCassette(path: string, cassette: Cassette): Promise { const { readFile } = await import('node:fs/promises') const raw = await readFile(path, 'utf8') diff --git a/packages/eval/src/replay/player.ts b/packages/eval/src/replay/player.ts index dee70cdd1..af1b1ae2e 100644 --- a/packages/eval/src/replay/player.ts +++ b/packages/eval/src/replay/player.ts @@ -23,12 +23,16 @@ function resolveMode(mode: ReplayOptions['mode']): 'strict' | 'sequential' | 'lo return mode } -/** - * Build an AdapterFactory that replays a previously recorded cassette. - * Matching modes: - * - strict: require exact fingerprint match - * - sequential: pop next unused entry - * - loose: match by last user message content +/** Create an adapter factory that replays chunks from a recorded cassette. + * + * @param cassette Recorded requests and stream chunks to replay. + * @param options Request matching mode; strict matching is the default. + * @returns An adapter factory that yields the matched cassette entry's chunks. + * @throws ConfigError when the replay mode is invalid; RuntimeError when no entry matches or sequential replay is exhausted. + * @example + * ```ts + * const replay = createReplayAdapter(cassette, { mode: 'strict' }) + * ``` */ export function createReplayAdapter(cassette: Cassette, options: ReplayOptions = {}): AdapterFactory { const mode = resolveMode(options.mode) diff --git a/packages/eval/src/replay/recorder.ts b/packages/eval/src/replay/recorder.ts index 4485f1cc2..c37d9eeab 100644 --- a/packages/eval/src/replay/recorder.ts +++ b/packages/eval/src/replay/recorder.ts @@ -3,14 +3,22 @@ import { createCassette } from './cassette' import { defensiveSnapshot } from './clone' import type { Cassette, RecordOptions } from './types' +/** Adapter factory and cassette populated by {@link createRecordingAdapter}. */ export interface RecordingAdapter { factory: AdapterFactory cassette: Cassette } -/** - * Wrap an existing AdapterFactory. All streamed chunks are recorded into - * a fresh Cassette so the session can be replayed deterministically. +/** Wrap an adapter factory and record each request's streamed chunks in a cassette. + * + * @param base Adapter factory whose requests should be recorded. + * @param options Optional cassette seed and metadata. + * @returns A recording factory and the cassette it populates. + * @example + * ```ts + * const recording = createRecordingAdapter(adapter) + * // Pass recording.factory to a runtime, then save recording.cassette. + * ``` */ export function createRecordingAdapter( base: AdapterFactory, diff --git a/packages/eval/src/replay/time-travel.ts b/packages/eval/src/replay/time-travel.ts index 3b619fe06..1c870f14d 100644 --- a/packages/eval/src/replay/time-travel.ts +++ b/packages/eval/src/replay/time-travel.ts @@ -2,6 +2,7 @@ import type { StreamChunk } from '@agentskit/core' import { defensiveSnapshot } from './clone' import type { Cassette, CassetteEntry } from './types' +/** Cursor-based view for inspecting, changing, and forking cassette chunks. */ export interface TimeTravelSession { /** Total number of chunks across all entries (flattened). */ readonly length: number @@ -45,10 +46,15 @@ function assertIndexInRange(index: number, min: number, maxInclusive: number, la } } -/** - * Wrap a cassette in a cursor-based API. Lets a debugger step through - * a recorded session, rewrite tool results or text chunks, and fork a - * new cassette at any point to replay alternate histories. +/** Create a cursor-based session for inspecting and editing recorded chunks. + * + * @param cassette Cassette to copy into the editable session. + * @returns A session for seeking, stepping, overriding chunks, and forking cassettes. + * @example + * ```ts + * const session = createTimeTravelSession(cassette) + * const firstChunk = session.step() + * ``` */ export function createTimeTravelSession(cassette: Cassette): TimeTravelSession { const working: Cassette = defensiveSnapshot({ diff --git a/packages/eval/src/replay/types.ts b/packages/eval/src/replay/types.ts index 5af3c6828..fc930d8b0 100644 --- a/packages/eval/src/replay/types.ts +++ b/packages/eval/src/replay/types.ts @@ -1,10 +1,12 @@ import type { AdapterRequest, StreamChunk } from '@agentskit/core' +/** One adapter request and the stream chunks recorded for it. */ export interface CassetteEntry { request: AdapterRequest chunks: StreamChunk[] } +/** Versioned collection of recorded adapter requests and stream chunks. */ export interface Cassette { version: 1 seed?: string | number @@ -12,11 +14,13 @@ export interface Cassette { entries: CassetteEntry[] } +/** Optional seed and metadata attached to a newly recorded cassette. */ export interface RecordOptions { seed?: string | number metadata?: Record } +/** Request matching strategy used by a replay adapter. */ export interface ReplayOptions { /** * Matching strategy when a request does not appear in cassette: diff --git a/packages/eval/src/runner.ts b/packages/eval/src/runner.ts index fb0a4ff88..d2c0f31fc 100644 --- a/packages/eval/src/runner.ts +++ b/packages/eval/src/runner.ts @@ -85,6 +85,16 @@ function validateConfig(config: unknown): asserts config is RunEvalConfig { } } +/** Run each case in an evaluation suite and return its pass, latency, and token usage results. + * + * @param config Agent and suite to evaluate. + * @returns Aggregate results for every case in the suite. + * @throws RuntimeError when the configuration has an invalid shape. + * @example + * ```ts + * const result = await runEval({ agent: async input => `Answer: ${input}`, suite }) + * ``` + */ export async function runEval(config: RunEvalConfig): Promise { validateConfig(config) const { agent, suite } = config diff --git a/packages/eval/src/snapshot/snapshot.ts b/packages/eval/src/snapshot/snapshot.ts index ca865698a..518caae9d 100644 --- a/packages/eval/src/snapshot/snapshot.ts +++ b/packages/eval/src/snapshot/snapshot.ts @@ -1,18 +1,22 @@ import { ConfigError, ErrorCodes, RuntimeError } from '@agentskit/core' +/** Comparison method used to match actual prompt text against a snapshot. */ export type SnapshotMode = | { kind: 'exact' } | { kind: 'normalized' } | { kind: 'similarity'; threshold: number; embed?: EmbedFn } +/** Function that maps text to an embedding vector for similarity comparison. */ export type EmbedFn = (text: string) => Promise | number[] +/** Options for comparing or updating a file-backed prompt snapshot. */ export interface SnapshotOptions { mode?: SnapshotMode /** Override via env var. Defaults to process.env.UPDATE_SNAPSHOTS === '1'. */ update?: boolean } +/** Match status, reason, and text or similarity values from a snapshot comparison. */ export interface SnapshotResult { matched: boolean reason: string @@ -21,6 +25,11 @@ export interface SnapshotResult { actual: string } +/** Lowercase text, replace punctuation and symbols with spaces, and collapse whitespace. + * + * @param s Text to normalize. + * @returns Normalized text with leading and trailing whitespace removed. + */ export function normalize(s: string): string { return s .toLowerCase() @@ -29,10 +38,21 @@ export function normalize(s: string): string { .trim() } +/** Split normalized text into non-empty tokens. + * + * @param s Text to tokenize. + * @returns Normalized tokens in their original order. + */ export function tokenize(s: string): string[] { return normalize(s).split(' ').filter(Boolean) } +/** Measure token overlap between two strings using the Jaccard coefficient. + * + * @param a First text value. + * @param b Second text value. + * @returns Intersection-over-union of their normalized token sets, or 1 when both are empty. + */ export function jaccard(a: string, b: string): number { const setA = new Set(tokenize(a)) const setB = new Set(tokenize(b)) @@ -43,6 +63,12 @@ export function jaccard(a: string, b: string): number { return union === 0 ? 0 : inter / union } +/** Measure the cosine similarity between two vectors. + * + * @param a First vector. + * @param b Second vector. + * @returns Cosine similarity, or 0 when dimensions differ, vectors are empty, or either magnitude is zero. + */ export function cosine(a: number[], b: number[]): number { if (a.length !== b.length || a.length === 0) return 0 let dot = 0 @@ -88,6 +114,18 @@ function assertEmbeddingVector(value: unknown, label: string): number[] { return value as number[] } +/** Compare prompt text exactly, after normalization, or by token or embedding similarity. + * + * @param actual Prompt text produced by the current run. + * @param expected Stored or expected prompt text. + * @param mode Comparison mode; defaults to exact string equality. + * @returns Whether the prompts matched and the comparison reason and values. + * @throws ConfigError for an invalid similarity threshold; RuntimeError for invalid embeddings or non-finite similarity. + * @example + * ```ts + * const result = await comparePrompt(actualPrompt, savedPrompt, { kind: 'normalized' }) + * ``` + */ export async function comparePrompt( actual: string, expected: string, diff --git a/packages/eval/src/types.ts b/packages/eval/src/types.ts index bcaa3a736..83899f1e9 100644 --- a/packages/eval/src/types.ts +++ b/packages/eval/src/types.ts @@ -1,12 +1,15 @@ import type { EvalSuite, EvalResult } from '@agentskit/core' +/** Text returned by an evaluated agent, optionally with token counts. */ export type AgentResponse = string | { content: string tokenUsage?: { prompt: number; completion: number } } +/** Async function that receives a test input and returns the agent response. */ export type AgentFn = (input: string) => Promise +/** Agent and test suite configuration for {@link runEval}. */ export interface RunEvalConfig { agent: AgentFn suite: EvalSuite From bed7118a2ce41c70b930801dbaf75b95c1a3222e Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:42:09 -0300 Subject: [PATCH 15/30] docs(adapters): document public subpaths --- .changeset/doc03-adapters-subpaths.md | 5 +++ docs/stability/jsdoc-coverage-v1.json | 34 +------------------- packages/adapters/src/catalog/dispatch.ts | 6 ++++ packages/adapters/src/catalog/drift.ts | 8 +++++ packages/adapters/src/catalog/pricing.ts | 6 ++++ packages/adapters/src/cli/index.ts | 21 +++++++++++++ packages/adapters/src/cli/json.ts | 6 ++++ packages/adapters/src/cli/manifests.ts | 35 +++++++++++++++++++++ packages/adapters/src/cli/process.ts | 5 +++ packages/adapters/src/cli/prompt.ts | 3 ++ packages/adapters/src/cli/types.ts | 38 +++++++++++++++++++++++ packages/adapters/src/langchain-bridge.ts | 3 ++ 12 files changed, 137 insertions(+), 33 deletions(-) create mode 100644 .changeset/doc03-adapters-subpaths.md diff --git a/.changeset/doc03-adapters-subpaths.md b/.changeset/doc03-adapters-subpaths.md new file mode 100644 index 000000000..c14ed2f5b --- /dev/null +++ b/.changeset/doc03-adapters-subpaths.md @@ -0,0 +1,5 @@ +--- +"@agentskit/adapters": patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..595de6473 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -93,39 +93,7 @@ ".::webllm", ".::webllmAdapter", ".::WebLlmEngineLike", - "./catalog::CatalogDispatchConfig", - "./catalog::CatalogDispatchError", - "./catalog::CatalogDriftReport", - "./catalog::classifyCatalogProvider", - "./catalog::ResolveCostOptions", - "./catalog::ResolvedCost", - "./cli::AcpCliAdapterOptions", - "./cli::AcpClientInfo", - "./cli::BuiltInCliManifestId", - "./cli::CliAdapterOptions", - "./cli::CliCapabilityRequirements", - "./cli::CliDiagnostic", - "./cli::CliJsonAdapterOptions", - "./cli::CliJsonParser", - "./cli::CliJsonResponse", - "./cli::CliManifestOptions", - "./cli::CliProcessOptions", - "./cli::CliSecurityMode", - "./cli::CliTerminationReason", - "./cli::CliToolCall", - "./cli::createAcpCliAdapter", - "./cli::createCliAdapter", - "./cli::createJsonCliAdapter", - "./cli::diagnoseCliProvider", - "./cli::diagnoseCliProviderManifest", - "./cli::listCliProviderManifests", - "./cli::manifestCapabilities", - "./cli::parseCliJsonResponse", - "./cli::resolveCliManifest", - "./cli::SerializeCliPromptOptions", - "./cli::validateCliProviderManifest", - "./createAdapter::createAdapter", - "./langchain-bridge::AdapterToLangChainModelOptions" + "./createAdapter::createAdapter" ], "@agentskit/angular": [ ".::CodeBlockComponent", diff --git a/packages/adapters/src/catalog/dispatch.ts b/packages/adapters/src/catalog/dispatch.ts index 610e762c0..c895d7b57 100644 --- a/packages/adapters/src/catalog/dispatch.ts +++ b/packages/adapters/src/catalog/dispatch.ts @@ -4,6 +4,9 @@ import type { RetryOptions } from '../utils' import { getProvider } from './loader' import type { CatalogProvider } from './types' +/** + * Provider, model, credentials, and optional transport settings for catalog-based dispatch. + */ export interface CatalogDispatchConfig { provider: string model: string @@ -13,6 +16,9 @@ export interface CatalogDispatchConfig { retry?: RetryOptions } +/** + * Error raised when a catalog provider cannot be dispatched through an OpenAI-compatible adapter. + */ export class CatalogDispatchError extends Error { constructor( message: string, diff --git a/packages/adapters/src/catalog/drift.ts b/packages/adapters/src/catalog/drift.ts index 22b74ed26..ca4b6228c 100644 --- a/packages/adapters/src/catalog/drift.ts +++ b/packages/adapters/src/catalog/drift.ts @@ -13,6 +13,11 @@ export const FIRST_CLASS_PROVIDERS = ['anthropic', 'openai', 'google'] as const /** How a catalog provider is expected to reach an AgentsKit adapter. */ export type CatalogProviderSupport = 'native' | 'openai-compatible' | 'unsupported' +/** + * Classifies how a catalog provider can be connected to an AgentsKit adapter. + * @param provider Provider identity and OpenAI-compatibility metadata. + * @returns The provider support category. + */ export function classifyCatalogProvider( provider: Pick, ): CatalogProviderSupport { @@ -21,6 +26,9 @@ export function classifyCatalogProvider( return 'unsupported' } +/** + * Catalog drift findings for provider dispatchability and required native providers. + */ export interface CatalogDriftReport { /** Catalog providers that are neither first-class nor OpenAI-compatible — undispatchable. */ undispatchable: string[] diff --git a/packages/adapters/src/catalog/pricing.ts b/packages/adapters/src/catalog/pricing.ts index 2a1f6870c..d5c9c2d49 100644 --- a/packages/adapters/src/catalog/pricing.ts +++ b/packages/adapters/src/catalog/pricing.ts @@ -9,6 +9,9 @@ import type { CatalogModelCost } from './types' */ const LIVE_URL = 'https://models.dev/api.json' +/** + * Options for resolving model pricing from the local catalog or live source. + */ export interface ResolveCostOptions { /** * Opt in to a live fetch. Default `false` keeps the runtime offline and @@ -22,6 +25,9 @@ export interface ResolveCostOptions { fetchImpl?: typeof fetch } +/** + * Model pricing together with its source and cache freshness. + */ export interface ResolvedCost { cost?: CatalogModelCost /** Where the returned cost came from. */ diff --git a/packages/adapters/src/cli/index.ts b/packages/adapters/src/cli/index.ts index 78e186d6a..567dabdd1 100644 --- a/packages/adapters/src/cli/index.ts +++ b/packages/adapters/src/cli/index.ts @@ -331,6 +331,13 @@ async function* runAcp( } } +/** + * Creates a streaming text adapter that runs an external CLI process. + * @param options Executable and process settings for the CLI. + * @returns An AgentsKit adapter factory. + * @example + * const adapter = createCliAdapter({ command: 'codex', args: ['exec'] }) + */ export function createCliAdapter(options: CliAdapterOptions): AdapterFactory { return createFactory(mergeCapabilities({ streaming: true, @@ -340,6 +347,13 @@ export function createCliAdapter(options: CliAdapterOptions): AdapterFactory { }, options.capabilities), (request, signal) => runText(request, signal, options)) } +/** + * Creates a non-streaming adapter that parses structured output from an external CLI. + * @param options Executable, process, and JSON parsing settings. + * @returns An AgentsKit adapter factory. + * @example + * const adapter = createJsonCliAdapter({ command: 'claude', args: ['-p'] }) + */ export function createJsonCliAdapter(options: CliJsonAdapterOptions): AdapterFactory { return createFactory(mergeCapabilities({ streaming: false, @@ -349,6 +363,13 @@ export function createJsonCliAdapter(options: CliJsonAdapterOptions): AdapterFac }, options.capabilities), (request, signal) => runJson(request, signal, options)) } +/** + * Creates a streaming adapter for an external CLI that speaks Agent Client Protocol. + * @param options Executable, process, and ACP client settings. + * @returns An AgentsKit adapter factory. + * @example + * const adapter = createAcpCliAdapter({ command: 'opencode' }) + */ export function createAcpCliAdapter(options: AcpCliAdapterOptions): AdapterFactory { return createFactory({ streaming: true, diff --git a/packages/adapters/src/cli/json.ts b/packages/adapters/src/cli/json.ts index 102f23179..ae0a2b0af 100644 --- a/packages/adapters/src/cli/json.ts +++ b/packages/adapters/src/cli/json.ts @@ -4,6 +4,12 @@ export { isRecord } from '@agentskit/core' export const cliError = (message: string, cause?: unknown): AdapterError => new AdapterError({ code: ErrorCodes.AK_ADAPTER_STREAM_FAILED, message, cause }) +/** + * Converts a normalized CLI JSON response object to AgentsKit stream chunks. + * @param value Parsed JSON response value. + * @returns Stream chunks for its text, reasoning, tool calls, usage, and metadata. + * @throws {Error} If the value or a nested response field is malformed. + */ export function parseCliJsonResponse(value: unknown): readonly StreamChunk[] { if (!isRecord(value)) throw cliError('CLI JSON response must be an object') const chunks: StreamChunk[] = [] diff --git a/packages/adapters/src/cli/manifests.ts b/packages/adapters/src/cli/manifests.ts index 09e84d5f4..e71d31f81 100644 --- a/packages/adapters/src/cli/manifests.ts +++ b/packages/adapters/src/cli/manifests.ts @@ -63,8 +63,14 @@ export interface BuiltInCliManifestProtocols { grok: 'acp' opencode: 'acp' } +/** + * Identifier of a built-in CLI provider manifest. + */ export type BuiltInCliManifestId = keyof BuiltInCliManifestProtocols +/** + * Overrides for resolving a CLI provider manifest into adapter options. + */ export interface CliManifestOptions

{ args?: readonly string[] mode?: CliSecurityMode @@ -193,6 +199,12 @@ function validateCapabilities(manifest: CliProviderManifest): void { } } +/** + * Validates a CLI provider manifest and narrows its type. + * @param manifest Manifest value to validate. + * @returns Nothing; successful completion asserts the manifest type. + * @throws {Error} If the manifest is invalid or declares capabilities unsupported by its protocol. + */ export function validateCliProviderManifest(manifest: unknown): asserts manifest is CliProviderManifest { if (!isRecord(manifest)) throw manifestError('CLI manifest must be an object') if (typeof manifest.id !== 'string' || typeof manifest.name !== 'string' || typeof manifest.command !== 'string') { @@ -236,6 +248,10 @@ export function validateCliProviderManifest(manifest: unknown): asserts manifest validateCapabilities(candidate) } +/** + * Returns copies of the built-in CLI provider manifests. + * @returns A new array of built-in manifests with copied mutable fields. + */ export function listCliProviderManifests(): CliProviderManifest[] { return manifests.map((manifest): CliProviderManifest => ({ ...manifest, @@ -254,6 +270,13 @@ export function getCliProviderManifest( return listCliProviderManifests().find(manifest => manifest.id === id) as ReturnType> } +/** + * Resolves a CLI provider manifest and its overrides into adapter options. + * @param manifest Provider manifest to resolve. + * @param options Per-invocation overrides for the manifest. + * @returns Adapter options for the manifest protocol. + * @throws {Error} If the manifest is invalid or the selected mode is unsupported. + */ export function resolveCliManifest(manifest: M, options: CliManifestOptions = {}): CliJsonAdapterOptions { validateCliProviderManifest(manifest) const mode = options.mode ?? 'review-safe' @@ -285,6 +308,12 @@ function adapterCapabilities(manifest: CliProviderManifest): AdapterCapabilities return { streaming, structuredOutput, reasoning, tools, extensions: { cli: { provider: manifest.id, protocol: manifest.protocol } } } } +/** + * Checks whether a CLI provider manifest can run and reports its version and status. + * @param manifest Provider manifest to check. + * @param options Process-mode and diagnostic settings. + * @returns Availability and process diagnostics for the provider. + */ export async function diagnoseCliProviderManifest( manifest: M, options: Omit, 'args'> = {}, @@ -300,6 +329,12 @@ export async function diagnoseCliProviderManifest return diagnostic } +/** + * Returns AgentsKit capabilities declared by a CLI provider manifest. + * @param manifest Provider manifest to inspect. + * @returns Adapter capabilities represented by the manifest. + * @throws {Error} If the manifest is invalid. + */ export function manifestCapabilities(manifest: CliProviderManifest): AdapterCapabilities { validateCliProviderManifest(manifest) return adapterCapabilities(manifest) diff --git a/packages/adapters/src/cli/process.ts b/packages/adapters/src/cli/process.ts index 188653d45..0aee23b7e 100644 --- a/packages/adapters/src/cli/process.ts +++ b/packages/adapters/src/cli/process.ts @@ -291,6 +291,11 @@ export async function* readCliStdout( } } +/** + * Runs a CLI version diagnostic and reports whether the executable is available. + * @param options Process and diagnostic command settings. + * @returns Availability and process diagnostics for the CLI. + */ export async function diagnoseCliProvider( options: CliProcessOptions & { diagnosticArgs?: readonly string[] }, ): Promise { diff --git a/packages/adapters/src/cli/prompt.ts b/packages/adapters/src/cli/prompt.ts index 4922ee746..a21ec09fc 100644 --- a/packages/adapters/src/cli/prompt.ts +++ b/packages/adapters/src/cli/prompt.ts @@ -43,6 +43,9 @@ export function serializeCliPrompt(request: AdapterRequest, options: SerializeCl return `${blocks.join('\n\n')}\n` } +/** + * Options controlling whether system instructions and tool descriptions are included in a serialized CLI prompt. + */ export interface SerializeCliPromptOptions { /** Include the `[system]` block and `system` messages. Default `true`. */ system?: boolean diff --git a/packages/adapters/src/cli/types.ts b/packages/adapters/src/cli/types.ts index 57fa6f141..f27abfea1 100644 --- a/packages/adapters/src/cli/types.ts +++ b/packages/adapters/src/cli/types.ts @@ -5,6 +5,9 @@ import type { TokenUsage, } from '@agentskit/core' +/** + * Process environment policy applied when launching a CLI adapter. + */ export type CliSecurityMode = 'review-safe' | 'trusted-local' | 'restricted-environment' /** * Transport protocol of a CLI manifest. The protocol bounds what the adapter @@ -31,8 +34,14 @@ export interface CliProtocolCapabilityKeys { /** The subset of `CliCapabilityRequirements` that protocol `P` supports. */ export type CliCapabilitiesFor

= Pick +/** + * Reason a CLI child process stopped before normal completion. + */ export type CliTerminationReason = 'aborted' | 'timeout' | 'output-limit' +/** + * Capabilities a CLI adapter must support before starting a process. + */ export interface CliCapabilityRequirements { streaming?: boolean structuredOutput?: boolean @@ -44,6 +53,9 @@ export interface CliCapabilityRequirements { nativeAuth?: boolean } +/** + * Availability, version, exit status, and lifecycle details reported for a CLI process. + */ export interface CliDiagnostic { available?: boolean success?: boolean @@ -59,6 +71,9 @@ export interface CliDiagnostic { error?: string } +/** + * Executable, input, environment, limits, and diagnostics for a CLI child process. + */ export interface CliProcessOptions { /** Executable path or an explicit executable name resolved by the OS. */ command: string @@ -88,6 +103,9 @@ export interface CliProcessOptions { requiredCapabilities?: CliCapabilityRequirements } +/** + * Process settings and request/response mapping for a text CLI adapter. + */ export interface CliAdapterOptions extends CliProcessOptions { /** Defaults to a newline-terminated JSON representation of AdapterRequest. */ serializeRequest?: (request: AdapterRequest) => string | Uint8Array @@ -97,12 +115,18 @@ export interface CliAdapterOptions extends CliProcessOptions { capabilities?: AdapterCapabilities } +/** + * Tool call parsed from a CLI structured response. + */ export interface CliToolCall { id: string name: string args: string } +/** + * Normalized text, reasoning, tool calls, usage, or metadata parsed from CLI JSON output. + */ export interface CliJsonResponse { text?: string reasoning?: string @@ -111,8 +135,16 @@ export interface CliJsonResponse { metadata?: Record } +/** + * Maps a decoded CLI JSON value to AgentsKit stream chunks. + * @param value Decoded JSON value from the CLI. + * @returns Normalized stream chunks for the response. + */ export type CliJsonParser = (value: unknown) => readonly StreamChunk[] +/** + * Process settings and JSON decoding hooks for a structured-output CLI adapter. + */ export interface CliJsonAdapterOptions extends CliAdapterOptions { /** Maps one schema-validated JSON response to normalized stream chunks. */ parse?: CliJsonParser @@ -120,11 +152,17 @@ export interface CliJsonAdapterOptions extends CliAdapterOptions { parseOutput?: (stdout: string) => unknown } +/** + * Client identity sent when initializing an Agent Client Protocol session. + */ export interface AcpClientInfo { name: string version: string } +/** + * Process and client settings for an Agent Client Protocol CLI adapter. + */ export interface AcpCliAdapterOptions extends CliProcessOptions { protocolVersion?: 1 clientInfo?: AcpClientInfo diff --git a/packages/adapters/src/langchain-bridge.ts b/packages/adapters/src/langchain-bridge.ts index 148762b04..36eaf6814 100644 --- a/packages/adapters/src/langchain-bridge.ts +++ b/packages/adapters/src/langchain-bridge.ts @@ -29,6 +29,9 @@ export interface AgentsKitChatModelCallOptions extends BaseChatModelCallOptions tools?: BindToolsInput[] } +/** + * Configuration passed to the LangChain chat model created from an AgentsKit adapter. + */ export interface AdapterToLangChainModelOptions extends BaseChatModelParams { /** Reported as the LangSmith model name and `_llmType()` suffix. Default: `agentskit`. */ modelName?: string From 655a60149d0e6219d67879c0df3c8ce2a9c1e43f Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:43:39 -0300 Subject: [PATCH 16/30] fix(eval): flatten diff rendering conditional --- packages/eval/src/diff/diff.ts | 6 +++++- packages/eval/tests/diff.test.ts | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/eval/src/diff/diff.ts b/packages/eval/src/diff/diff.ts index 7e7c759e1..551526419 100644 --- a/packages/eval/src/diff/diff.ts +++ b/packages/eval/src/diff/diff.ts @@ -76,7 +76,11 @@ export function promptDiff(oldPrompt: string, newPrompt: string): PromptDiff { */ export function formatDiff(diff: PromptDiff): string { return diff.lines - .map(l => (l.op === 'equal' ? ` ${l.content}` : l.op === 'add' ? `+ ${l.content}` : `- ${l.content}`)) + .map(l => { + if (l.op === 'equal') return ` ${l.content}` + if (l.op === 'add') return `+ ${l.content}` + return `- ${l.content}` + }) .join('\n') } diff --git a/packages/eval/tests/diff.test.ts b/packages/eval/tests/diff.test.ts index 22e5c4eb3..b737daa01 100644 --- a/packages/eval/tests/diff.test.ts +++ b/packages/eval/tests/diff.test.ts @@ -32,8 +32,8 @@ describe('promptDiff', () => { it('formatDiff renders unified-diff style', () => { const d = promptDiff('a', 'b') const text = formatDiff(d) - expect(text).toContain('- a') - expect(text).toContain('+ b') + expect(text).toBe('- a\n+ b') + expect(formatDiff(promptDiff('a', 'a'))).toBe(' a') }) }) From e5aa31807dfb85a56b1666bae14a58e28d3a6c1b Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:52:15 -0300 Subject: [PATCH 17/30] docs(cli): document public API --- .changeset/doc03-cli.md | 5 ++ docs/stability/jsdoc-coverage-v1.json | 65 +------------------ packages/cli/src/app/ChatApp.tsx | 14 ++++ packages/cli/src/commands/index.ts | 6 ++ packages/cli/src/config.ts | 8 +++ packages/cli/src/dev.ts | 16 +++++ packages/cli/src/doctor.ts | 29 +++++++++ .../cli/src/extensibility/hooks/runner.ts | 4 ++ .../src/extensibility/hooks/shell-hooks.ts | 8 +++ packages/cli/src/extensibility/mcp/bridge.ts | 9 +++ packages/cli/src/extensibility/mcp/client.ts | 4 ++ .../src/extensibility/permissions/policy.ts | 20 ++++++ .../cli/src/extensibility/plugins/loader.ts | 4 ++ .../cli/src/extensibility/plugins/types.ts | 28 ++++++++ .../cli/src/extensibility/rag/embedders.ts | 4 ++ packages/cli/src/extensibility/rag/runner.ts | 12 ++++ .../src/extensibility/telemetry/pricing.ts | 19 ++++++ packages/cli/src/init.ts | 16 +++++ packages/cli/src/providers.ts | 16 +++++ packages/cli/src/run.ts | 13 ++++ packages/cli/src/sessions.ts | 44 +++++++++++++ packages/cli/src/tunnel.ts | 12 ++++ 22 files changed, 292 insertions(+), 64 deletions(-) create mode 100644 .changeset/doc03-cli.md diff --git a/.changeset/doc03-cli.md b/.changeset/doc03-cli.md new file mode 100644 index 000000000..50f1ea1a4 --- /dev/null +++ b/.changeset/doc03-cli.md @@ -0,0 +1,5 @@ +--- +"@agentskit/cli": patch +--- + +Document public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..b13ab584b 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -136,70 +136,7 @@ ".::ToolCallViewComponent", ".::ToolConfirmationComponent" ], - "@agentskit/cli": [ - ".::AgentsKitConfig", - ".::BuildRagOptions", - ".::ChatApp", - ".::ChatCommandOptions", - ".::ChatProviderOptions", - ".::CheckResult", - ".::CheckStatus", - ".::ComputedCost", - ".::ConfigHookEntry", - ".::ConfigHooksMap", - ".::createCli", - ".::defaultPolicy", - ".::DevOptions", - ".::DevWatcher", - ".::disposeMcpClients", - ".::DoctorOptions", - ".::DoctorReport", - ".::findLatestSession", - ".::findSession", - ".::getPricing", - ".::HookDispatchResult", - ".::HookEvent", - ".::HookHandler", - ".::HookPayload", - ".::HookResult", - ".::IndexResult", - ".::InitCommandOptions", - ".::listSessions", - ".::LoadConfigOptions", - ".::LoadPluginsOptions", - ".::McpBridgeResult", - ".::McpServerSpec", - ".::McpTool", - ".::OpenAiEmbedderConfig", - ".::PermissionAction", - ".::PermissionMode", - ".::PermissionPolicy", - ".::PermissionRule", - ".::PluginContext", - ".::ProviderFactory", - ".::RagConfig", - ".::registerPricing", - ".::renderChatHeader", - ".::renderReport", - ".::resolveChatProvider", - ".::ResolvedChatProvider", - ".::ResolvedSession", - ".::ResolveSessionInput", - ".::runAgent", - ".::RunCommandOptions", - ".::runDoctor", - ".::sessionFilePath", - ".::SessionMetadata", - ".::SessionRecord", - ".::startDev", - ".::StarterKind", - ".::TokenUsageLike", - ".::TunnelController", - ".::TunnelLike", - ".::TunnelOptions", - ".::writeSessionMeta", - ".::writeStarterProject" - ], + "@agentskit/cli": [], "@agentskit/core": [ ".::activateSkills", ".::ActivateSkillsResult", diff --git a/packages/cli/src/app/ChatApp.tsx b/packages/cli/src/app/ChatApp.tsx index cf58fc0ba..e0dea5a05 100644 --- a/packages/cli/src/app/ChatApp.tsx +++ b/packages/cli/src/app/ChatApp.tsx @@ -29,6 +29,10 @@ import type { HookHandler } from '../extensibility/plugins' import { applyPolicyToTools } from '../extensibility/permissions' import { useEffect } from 'react' +/** + * Provider, session, tool, memory, plugin, hook, and permission settings for the CLI chat app. + + */ export interface ChatCommandOptions { provider: string model?: string @@ -76,6 +80,10 @@ export function groupIntoTurns(messages: ChatMessage[]): ChatMessage[][] { return turns } +/** + * Interactive Ink chat component configured with provider, session, tools, and plugins. + + */ export function ChatApp(options: ChatCommandOptions) { const { runtime, @@ -298,6 +306,12 @@ function feedbackBorder(kind: FeedbackKind): string { } } +/** + * Renders a compact provider, model, mode, tool, skill, and memory summary for chat. + * @param options Chat provider and feature settings. + * @returns A single-line chat header. + * @throws {Error} If the requested provider or its required configuration is unsupported. + */ export function renderChatHeader(options: ChatCommandOptions): string { const runtime = resolveChatProvider(options) const parts = [`provider=${runtime.provider}`] diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index c767645e0..c12724f24 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -15,6 +15,12 @@ import { registerRulesCommand } from './rules' import { registerAddCommand } from './add' import { registerDiffCommand, registerUpdateCommand } from './registry-maintenance' +/** + * Creates the Commander program and registers the AgentsKit CLI commands. + * @returns A configured Commander program. + * @example + * const program = createCli() + */ export function createCli(): Command { const program = new Command() program diff --git a/packages/cli/src/config.ts b/packages/cli/src/config.ts index 54cc5b982..d6f64bb68 100644 --- a/packages/cli/src/config.ts +++ b/packages/cli/src/config.ts @@ -2,6 +2,10 @@ import { access, readFile } from 'node:fs/promises' import { homedir } from 'node:os' import { resolve, join } from 'node:path' +/** + * Configuration values loaded by the AgentsKit CLI, including defaults and integrations. + + */ export interface AgentsKitConfig { tools?: { filesystem?: { basePath?: string } @@ -110,6 +114,10 @@ async function loadPackageJsonConfig(dir: string): Promise void): this close(): Promise @@ -80,6 +88,14 @@ export interface DevController { restarts: () => number } +/** + * Runs a project entry file and restarts it when watched files change. + * @param options Entry, watch patterns, and process overrides. + * @returns A controller for observing and stopping the development session. + * @throws {Error} If the entry file is missing or the TypeScript runner is unavailable. + * @example + * const dev = startDev({ entry: './src/index.ts' }) + */ export function startDev(options: DevOptions): DevController { const entry = pathResolve(process.cwd(), options.entry) if (!existsSync(entry)) { diff --git a/packages/cli/src/doctor.ts b/packages/cli/src/doctor.ts index b4c9c3d5e..dabe311b9 100644 --- a/packages/cli/src/doctor.ts +++ b/packages/cli/src/doctor.ts @@ -5,8 +5,16 @@ import { loadConfig } from './config' import { DEFAULT_DOCTOR_PROVIDERS, resolveProviderRegistryEntry } from './provider-registry' import type { ProviderRegistryEntry } from './provider-registry' +/** + * Outcome category returned by an AgentsKit doctor check. + + */ export type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip' +/** + * Status, description, and optional remediation for one doctor check. + + */ export interface CheckResult { status: CheckStatus name: string @@ -14,6 +22,10 @@ export interface CheckResult { fix?: string } +/** + * Doctor check results and aggregate pass, warning, failure, and skip counts. + + */ export interface DoctorReport { results: CheckResult[] pass: number @@ -233,6 +245,10 @@ export async function checkConfig(): Promise { // Orchestration // ============================================================================ +/** + * Provider selection and network settings for the environment doctor. + + */ export interface DoctorOptions { /** Provider names to check. Defaults to all known providers. */ providers?: string[] @@ -242,6 +258,13 @@ export interface DoctorOptions { fetchImpl?: typeof fetch } +/** + * Checks the local Node environment, AgentsKit configuration, and selected providers. + * @param options Provider selection and network-check settings. + * @returns A report containing each check and aggregate status counts. + * @example + * const report = await runDoctor({ noNetwork: true }) + */ export async function runDoctor(options: DoctorOptions = {}): Promise { const providers = options.providers ?? DEFAULT_DOCTOR_PROVIDERS const fetchImpl = options.fetchImpl ?? fetch @@ -283,6 +306,12 @@ const ICON: Record = { skip: '○', } +/** + * Formats doctor check results as a terminal-friendly report. + * @param report Doctor results and aggregate counts. + * @param opts Optional rendering settings. + * @returns The formatted report text. + */ export function renderReport(report: DoctorReport, opts: { color?: boolean } = {}): string { const color = opts.color ?? true const c = (code: string, text: string) => (color ? `\x1b[${code}m${text}\x1b[0m` : text) diff --git a/packages/cli/src/extensibility/hooks/runner.ts b/packages/cli/src/extensibility/hooks/runner.ts index 6343b166f..11da3881b 100644 --- a/packages/cli/src/extensibility/hooks/runner.ts +++ b/packages/cli/src/extensibility/hooks/runner.ts @@ -1,5 +1,9 @@ import type { HookEvent, HookHandler, HookPayload, HookResult } from '../plugins/types' +/** + * Final hook payload and whether dispatch was blocked. + + */ export interface HookDispatchResult { /** Final payload after any `modify` handlers. */ payload: HookPayload diff --git a/packages/cli/src/extensibility/hooks/shell-hooks.ts b/packages/cli/src/extensibility/hooks/shell-hooks.ts index bf13d6a5a..c18d71c83 100644 --- a/packages/cli/src/extensibility/hooks/shell-hooks.ts +++ b/packages/cli/src/extensibility/hooks/shell-hooks.ts @@ -3,6 +3,10 @@ import type { HookEvent, HookHandler, HookPayload, HookResult } from '../plugins const MAX_HOOK_STDOUT_BYTES = 64 * 1024 +/** + * Shell command and optional matcher and timeout for a configured lifecycle hook. + + */ export interface ConfigHookEntry { /** * Command to run through the platform shell (`sh -c` on POSIX, `cmd.exe /d /s /c` @@ -15,6 +19,10 @@ export interface ConfigHookEntry { timeout?: number } +/** + * Configured shell hooks keyed by lifecycle event. + + */ export type ConfigHooksMap = Partial> /** diff --git a/packages/cli/src/extensibility/mcp/bridge.ts b/packages/cli/src/extensibility/mcp/bridge.ts index e2d76c1ab..1cbc8f048 100644 --- a/packages/cli/src/extensibility/mcp/bridge.ts +++ b/packages/cli/src/extensibility/mcp/bridge.ts @@ -2,6 +2,10 @@ import type { ToolDefinition } from '@agentskit/core' import type { McpServerSpec } from '../plugins/types' import { McpClient, type McpTool } from './client' +/** + * Started MCP clients and the tool definitions bridged from their servers. + + */ export interface McpBridgeResult { clients: McpClient[] tools: ToolDefinition[] @@ -52,6 +56,11 @@ function mcpToolToDefinition( } } +/** + * Disposes every MCP client opened for a CLI session. + * @param clients MCP clients to stop. + * @returns Nothing. + */ export function disposeMcpClients(clients: McpClient[]): void { for (const client of clients) client.dispose() } diff --git a/packages/cli/src/extensibility/mcp/client.ts b/packages/cli/src/extensibility/mcp/client.ts index a0fcfbbf9..50f313dab 100644 --- a/packages/cli/src/extensibility/mcp/client.ts +++ b/packages/cli/src/extensibility/mcp/client.ts @@ -5,6 +5,10 @@ import type { McpServerSpec } from '../plugins/types' const MAX_FRAME_BYTES = 1024 * 1024 const DISPOSE_GRACE_MS = 1000 +/** + * Tool name and optional description and input schema reported by an MCP server. + + */ export interface McpTool { name: string description?: string diff --git a/packages/cli/src/extensibility/permissions/policy.ts b/packages/cli/src/extensibility/permissions/policy.ts index 01290aedc..99cd808e2 100644 --- a/packages/cli/src/extensibility/permissions/policy.ts +++ b/packages/cli/src/extensibility/permissions/policy.ts @@ -1,9 +1,21 @@ import type { ToolDefinition } from '@agentskit/core' +/** + * Default policy mode used when evaluating tool permissions. + + */ export type PermissionMode = 'default' | 'plan' | 'acceptEdits' | 'bypassPermissions' +/** + * Action the CLI applies to a tool: allow, ask for confirmation, or deny. + + */ export type PermissionAction = 'allow' | 'ask' | 'deny' +/** + * Tool matcher, permission action, and optional rule scope. + + */ export interface PermissionRule { /** Exact name, or a `RegExp` / `"re:pattern"` string matching the tool name. */ tool: string | RegExp @@ -11,11 +23,19 @@ export interface PermissionRule { scope?: 'session' | 'project' | 'global' } +/** + * Default permission mode and explicit tool rules for a CLI session. + + */ export interface PermissionPolicy { mode: PermissionMode rules: PermissionRule[] } +/** + * Default permission policy with ask-on-unmatched behavior. + + */ export const defaultPolicy: PermissionPolicy = { mode: 'default', rules: [], diff --git a/packages/cli/src/extensibility/plugins/loader.ts b/packages/cli/src/extensibility/plugins/loader.ts index 5a99961e1..0d2a9413b 100644 --- a/packages/cli/src/extensibility/plugins/loader.ts +++ b/packages/cli/src/extensibility/plugins/loader.ts @@ -4,6 +4,10 @@ import { isAbsolute, join, resolve } from 'node:path' import { pathToFileURL } from 'node:url' import type { Plugin, PluginBundle, PluginContext, PluginFactory } from './types' +/** + * Plugin specifiers, discovery directories, and callbacks used while loading plugins. + + */ export interface LoadPluginsOptions { /** Plugin specifiers: absolute paths, relative paths, or package names. */ specs?: string[] diff --git a/packages/cli/src/extensibility/plugins/types.ts b/packages/cli/src/extensibility/plugins/types.ts index 8e33a5566..550b22090 100644 --- a/packages/cli/src/extensibility/plugins/types.ts +++ b/packages/cli/src/extensibility/plugins/types.ts @@ -20,6 +20,10 @@ export interface Plugin { dispose?: () => void | Promise } +/** + * CLI services and project context passed to plugin factories. + + */ export interface PluginContext { /** Working directory the CLI was launched from. */ cwd: string @@ -29,6 +33,10 @@ export interface PluginContext { log: (msg: string) => void } +/** + * Factory that creates an adapter from provider credentials and model settings. + + */ export type ProviderFactory = (config: { apiKey?: string model: string @@ -36,6 +44,10 @@ export type ProviderFactory = (config: { extra?: Record }) => unknown +/** + * Lifecycle event names accepted by plugin hooks. + + */ export type HookEvent = | 'SessionStart' | 'SessionEnd' @@ -47,22 +59,38 @@ export type HookEvent = | 'Stop' | 'Error' +/** + * Lifecycle-specific data passed to plugin hooks. + + */ export interface HookPayload { event: HookEvent [key: string]: unknown } +/** + * Continue, modify, or block decision returned by a hook handler. + + */ export type HookResult = | { decision: 'continue' } | { decision: 'block'; reason: string } | { decision: 'modify'; payload: HookPayload } +/** + * Handler that receives a lifecycle payload and returns a hook decision. + + */ export interface HookHandler { event: HookEvent matcher?: RegExp | ((payload: HookPayload) => boolean) run: (payload: HookPayload) => HookResult | Promise } +/** + * Command, arguments, environment, and name for one MCP server process. + + */ export interface McpServerSpec { name: string command: string diff --git a/packages/cli/src/extensibility/rag/embedders.ts b/packages/cli/src/extensibility/rag/embedders.ts index ab5aca9bd..cf57ea641 100644 --- a/packages/cli/src/extensibility/rag/embedders.ts +++ b/packages/cli/src/extensibility/rag/embedders.ts @@ -4,6 +4,10 @@ import { NetError, readJson, readText } from '@agentskit/net' const MAX_EMBEDDER_RESPONSE_BYTES = 16 * 1024 * 1024 const MAX_EMBEDDER_ERROR_BYTES = 1024 * 1024 +/** + * API key and optional model and endpoint for the OpenAI-compatible embedder. + + */ export interface OpenAiEmbedderConfig { apiKey: string model?: string diff --git a/packages/cli/src/extensibility/rag/runner.ts b/packages/cli/src/extensibility/rag/runner.ts index eb997c612..36291aa60 100644 --- a/packages/cli/src/extensibility/rag/runner.ts +++ b/packages/cli/src/extensibility/rag/runner.ts @@ -7,6 +7,10 @@ import type { RAG } from '@agentskit/rag' import type { EmbedFn } from '@agentskit/core' import { createOpenAiEmbedder } from './embedders' +/** + * Sources, embedder, storage, chunking, and retrieval settings for CLI RAG. + + */ export interface RagConfig { enabled?: boolean backend?: 'memory' | 'file' @@ -22,6 +26,10 @@ export interface RagConfig { topK?: number } +/** + * Configuration and optional embedder used to create a file-backed RAG instance. + + */ export interface BuildRagOptions { config: RagConfig cwd?: string @@ -29,6 +37,10 @@ export interface BuildRagOptions { embedder?: EmbedFn } +/** + * Count and absolute paths of the files ingested by a RAG index operation. + + */ export interface IndexResult { /** Number of input documents ingested. */ documentCount: number diff --git a/packages/cli/src/extensibility/telemetry/pricing.ts b/packages/cli/src/extensibility/telemetry/pricing.ts index e1e3f456f..5a4f262f1 100644 --- a/packages/cli/src/extensibility/telemetry/pricing.ts +++ b/packages/cli/src/extensibility/telemetry/pricing.ts @@ -23,10 +23,21 @@ const builtinPricing: Record = { const customPricing: Record = {} +/** + * Registers or replaces per-million-token prices for a model in this process. + * @param model Model identifier to register. + * @param pricing Input and output prices in USD per million tokens. + * @returns Nothing. + */ export function registerPricing(model: string, pricing: ModelPricing): void { customPricing[model] = pricing } +/** + * Looks up registered model pricing by exact id or provider-prefixed model id. + * @param model Model identifier to look up. + * @returns Pricing for the model, or `undefined` when it is unknown. + */ export function getPricing(model: string | undefined): ModelPricing | undefined { if (!model) return undefined if (customPricing[model]) return customPricing[model] @@ -36,11 +47,19 @@ export function getPricing(model: string | undefined): ModelPricing | undefined return customPricing[short] ?? builtinPricing[short] } +/** + * Prompt and completion token counts used for cost calculation. + + */ export interface TokenUsageLike { promptTokens: number completionTokens: number } +/** + * Estimated input, output, and total cost for one model response. + + */ export interface ComputedCost { model: string inputUsd: number diff --git a/packages/cli/src/init.ts b/packages/cli/src/init.ts index f31bafb0e..5e24a9f50 100644 --- a/packages/cli/src/init.ts +++ b/packages/cli/src/init.ts @@ -9,6 +9,10 @@ import { writeStarterProject as writeProject } from './init-writer' export type { Provider } from './init-providers' +/** + * Built-in project template identifier accepted by the init command. + + */ export type StarterKind = | 'react' | 'nextjs' @@ -27,6 +31,10 @@ export type ToolKind = 'web_search' | 'filesystem' | 'shell' export type MemoryKind = 'none' | 'file' | 'sqlite' export type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun' +/** + * Destination, starter template, and optional provider, tools, memory, and package-manager settings. + + */ export interface InitCommandOptions { targetDir: string template: StarterKind @@ -1514,6 +1522,14 @@ const TEMPLATE_FN: Record Record { return writeProject(options, TEMPLATE_FN) } diff --git a/packages/cli/src/providers.ts b/packages/cli/src/providers.ts index 899f33797..86fe891dc 100644 --- a/packages/cli/src/providers.ts +++ b/packages/cli/src/providers.ts @@ -11,6 +11,10 @@ import { } from '@agentskit/adapters' import type { AdapterFactory } from '@agentskit/core' +/** + * Provider identifier and optional model, credentials, or endpoint used to resolve a chat adapter. + + */ export interface ChatProviderOptions { provider: string model?: string @@ -18,6 +22,10 @@ export interface ChatProviderOptions { baseUrl?: string } +/** + * Resolved adapter together with provider, model, mode, and display summary. + + */ export interface ResolvedChatProvider { adapter: AdapterFactory provider: string @@ -122,6 +130,14 @@ function createDemoAdapter(provider: string, model?: string): AdapterFactory { } } +/** + * Resolves a provider name and credentials to an AgentsKit chat adapter. + * @param options Provider, model, credential, and endpoint settings. + * @returns Adapter and resolved provider details. + * @throws {Error} If the provider is unsupported or required credentials or model are missing. + * @example + * const resolved = resolveChatProvider({ provider: 'demo' }) + */ export function resolveChatProvider(options: ChatProviderOptions): ResolvedChatProvider { const name = options.provider.toLowerCase() diff --git a/packages/cli/src/run.ts b/packages/cli/src/run.ts index 3867e35c9..453e01af7 100644 --- a/packages/cli/src/run.ts +++ b/packages/cli/src/run.ts @@ -3,6 +3,10 @@ import type { AgentEvent, Observer } from '@agentskit/core' import { resolveChatProvider } from './providers' import { resolveTools, resolveSkill, resolveSkills, resolveMemory } from './resolve' +/** + * Provider and agent runtime options accepted by the CLI run command. + + */ export interface RunCommandOptions { provider: string model?: string @@ -41,6 +45,15 @@ function formatEvent(event: AgentEvent): string { } } +/** + * Runs one agent task with the selected provider, tools, skills, and memory. + * @param task User task to run. + * @param options Provider and runtime settings. + * @returns A promise that resolves when the run completes. + * @throws {Error} If mutually exclusive skill options are both set or provider configuration is invalid. + * @example + * await runAgent('Say hello', { provider: 'demo' }) + */ export async function runAgent(task: string, options: RunCommandOptions): Promise { if (options.skill && options.skills) { throw new Error('--skill and --skills are mutually exclusive. Use one or the other.') diff --git a/packages/cli/src/sessions.ts b/packages/cli/src/sessions.ts index b452c8d6d..37b4d596a 100644 --- a/packages/cli/src/sessions.ts +++ b/packages/cli/src/sessions.ts @@ -12,6 +12,10 @@ import { import { homedir } from 'node:os' import { join } from 'node:path' +/** + * Session identifiers, timestamps, preview, message count, and optional provider labels. + + */ export interface SessionMetadata { id: string cwd: string @@ -27,6 +31,10 @@ export interface SessionMetadata { forkedFrom?: string } +/** + * Session metadata paired with its message file path. + + */ export interface SessionRecord { metadata: SessionMetadata file: string @@ -55,6 +63,12 @@ export function generateSessionId(): string { return `${ts}-${suffix}` } +/** + * Returns the message file path for a session and ensures its storage directory exists. + * @param id Session identifier. + * @param cwd Working directory used to namespace session storage. + * @returns The absolute path to the session JSON file. + */ export function sessionFilePath(id: string, cwd: string = process.cwd()): string { ensureDir(dirFor(cwd)) return join(dirFor(cwd), `${id}.json`) @@ -74,6 +88,12 @@ function readMeta(id: string, cwd: string = process.cwd()): SessionMetadata | nu } } +/** + * Writes session metadata to the CLI session store with private file permissions. + * @param meta Session metadata to persist. + * @param cwd Working directory used to namespace session storage. + * @returns Nothing. + */ export function writeSessionMeta(meta: SessionMetadata, cwd: string = process.cwd()): void { ensureDir(dirFor(cwd)) const path = metaPath(meta.id, cwd) @@ -89,6 +109,11 @@ export function derivePreview(messages: Array<{ role: string; content: string }> return single.length > 80 ? `${single.slice(0, 80)}…` : single } +/** + * Lists session records for a working directory, newest first. + * @param cwd Working directory used to locate sessions. + * @returns Session records with their metadata and file paths. + */ export function listSessions(cwd: string = process.cwd()): SessionRecord[] { const dir = dirFor(cwd) if (!existsSync(dir)) return [] @@ -125,11 +150,22 @@ export function listSessions(cwd: string = process.cwd()): SessionRecord[] { return records } +/** + * Returns the most recently updated session for a working directory. + * @param cwd Working directory used to locate sessions. + * @returns The newest session record, or `null` when none exists. + */ export function findLatestSession(cwd: string = process.cwd()): SessionRecord | null { const all = listSessions(cwd) return all[0] ?? null } +/** + * Finds a session by id, label, or id prefix. + * @param id Session identifier, label, or unique prefix. + * @param cwd Working directory used to locate sessions. + * @returns The matching session record, or `null` when none matches. + */ export function findSession(id: string, cwd: string = process.cwd()): SessionRecord | null { const all = listSessions(cwd) const exact = all.find(s => s.metadata.id === id || s.metadata.label === id) @@ -186,6 +222,10 @@ export function forkSession( return { id: newId, file: newFile, isNew: true } } +/** + * Explicit file, resume, create-new, and working-directory settings for session resolution. + + */ export interface ResolveSessionInput { explicitPath?: string resumeId?: string | true @@ -193,6 +233,10 @@ export interface ResolveSessionInput { cwd?: string } +/** + * Session identifier, message file path, and whether the session was newly created. + + */ export interface ResolvedSession { id: string file: string diff --git a/packages/cli/src/tunnel.ts b/packages/cli/src/tunnel.ts index 57ee5b29b..39702af75 100644 --- a/packages/cli/src/tunnel.ts +++ b/packages/cli/src/tunnel.ts @@ -1,5 +1,9 @@ import kleur from 'kleur' +/** + * Local port and optional host, subdomain, callbacks, and tunnel provider override. + + */ export interface TunnelOptions { /** Local port to expose. Required. */ port: number @@ -15,12 +19,20 @@ export interface TunnelOptions { onReady?: (url: string) => void } +/** + * Tunnel provider handle with its public URL and lifecycle methods. + + */ export interface TunnelLike { url: string on(event: 'request' | 'error' | 'close', listener: (...args: unknown[]) => void): unknown close(): void } +/** + * Public tunnel URL, completion promise, stop action, and request count. + + */ export interface TunnelController { /** The public URL once ready. */ url: string From cfa6c9278f1e060abaea77cbcecd6b10b947233f Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 14:58:54 -0300 Subject: [PATCH 18/30] docs(eval-braintrust): document public API --- .changeset/doc03-eval-braintrust.md | 5 ++ docs/stability/jsdoc-coverage-v1.json | 48 ------------------- packages/eval-braintrust/src/ci.ts | 19 ++++++++ packages/eval-braintrust/src/runner.ts | 33 +++++++++++++ packages/eval-braintrust/src/scorers/index.ts | 3 ++ .../eval-braintrust/src/scorers/quality.ts | 23 +++++++++ .../eval-braintrust/src/scorers/robustness.ts | 24 ++++++++++ packages/eval-braintrust/src/types.ts | 4 ++ 8 files changed, 111 insertions(+), 48 deletions(-) create mode 100644 .changeset/doc03-eval-braintrust.md diff --git a/.changeset/doc03-eval-braintrust.md b/.changeset/doc03-eval-braintrust.md new file mode 100644 index 000000000..e0681ee9d --- /dev/null +++ b/.changeset/doc03-eval-braintrust.md @@ -0,0 +1,5 @@ +--- +"@agentskit/eval-braintrust": patch +--- + +Document the public Braintrust scoring, runner, and regression APIs. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..bcecd2d11 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -437,54 +437,6 @@ ".::EvalSuite", ".::runEval", ".::RunEvalConfig", - "./braintrust::ALL_SCORERS", - "./braintrust::BraintrustRunOptions", - "./braintrust::citationCorrectness", - "./braintrust::detectRegressions", - "./braintrust::ExperimentResult", - "./braintrust::factualGrounding", - "./braintrust::fallbackResilience", - "./braintrust::formatAlertsMarkdown", - "./braintrust::hitlGateCorrectness", - "./braintrust::noCrashSurvival", - "./braintrust::qualityFamily", - "./braintrust::RegressionAlert", - "./braintrust::RegressionThresholds", - "./braintrust::robustnessFamily", - "./braintrust::runBraintrustEval", - "./braintrust::RunBraintrustEvalArgs", - "./braintrust::schemaSurvival", - "./braintrust::scoreCase", - "./braintrust::ScoredCase", - "./braintrust::Scorer", - "./braintrust::ScorerFamily", - "./braintrust::ScorerInput", - "./braintrust::ScorerResult", - "./braintrust::summarize", - "./braintrust::taskSuccess", - "./braintrust::toolArgValidity", - "./braintrust/ci::detectRegressions", - "./braintrust/ci::formatAlertsMarkdown", - "./braintrust/ci::RegressionAlert", - "./braintrust/ci::RegressionThresholds", - "./braintrust/scorers::ALL_SCORERS", - "./braintrust/scorers::citationCorrectness", - "./braintrust/scorers::CitationMeta", - "./braintrust/scorers::CrashMeta", - "./braintrust/scorers::factualGrounding", - "./braintrust/scorers::FactualGroundingMeta", - "./braintrust/scorers::FallbackMeta", - "./braintrust/scorers::fallbackResilience", - "./braintrust/scorers::hitlGateCorrectness", - "./braintrust/scorers::HitlMeta", - "./braintrust/scorers::noCrashSurvival", - "./braintrust/scorers::qualityFamily", - "./braintrust/scorers::robustnessFamily", - "./braintrust/scorers::schemaSurvival", - "./braintrust/scorers::SchemaValidityMeta", - "./braintrust/scorers::taskSuccess", - "./braintrust/scorers::toolArgValidity", - "./braintrust/scorers::ToolArgValidityInput", "./ci::CiReportOptions", "./ci::CiReportOutput", "./diff::Attribution", diff --git a/packages/eval-braintrust/src/ci.ts b/packages/eval-braintrust/src/ci.ts index 278bfd879..a4b61ce83 100644 --- a/packages/eval-braintrust/src/ci.ts +++ b/packages/eval-braintrust/src/ci.ts @@ -1,11 +1,13 @@ import { ConfigError, ErrorCodes } from '@agentskit/core' import type { ExperimentResult } from './runner' +/** Global and scorer-specific score drop limits used by {@link detectRegressions}. */ export interface RegressionThresholds { default?: number perScorer?: Record } +/** One scorer whose current mean dropped beyond its configured threshold. */ export interface RegressionAlert { scorer: string baseline: number @@ -24,6 +26,18 @@ function assertUnitInterval(value: unknown, name: string): number { return value } +/** Find scorers whose mean score fell by more than their configured threshold. + * + * @param baseline Baseline scorer means and sample counts. + * @param current Current scorer means and sample counts. + * @param thresholds Optional default and per-scorer maximum drops; default is 0.05. + * @returns Regression alerts for scorers present in both summaries. + * @throws ConfigError when a threshold is not a finite number in [0, 1]. + * @example + * ```ts + * const alerts = detectRegressions(previous.summary, latest.summary, { default: 0.05 }) + * ``` + */ export function detectRegressions( baseline: ExperimentResult['summary'], current: ExperimentResult['summary'], @@ -48,6 +62,11 @@ export function detectRegressions( return out } +/** Render regression alerts as a Markdown table, or a no-regressions message. + * + * @param alerts Alerts returned by {@link detectRegressions}. + * @returns A Markdown summary suitable for a pull request or CI report. + */ export function formatAlertsMarkdown(alerts: RegressionAlert[]): string { if (alerts.length === 0) return '✅ No regressions detected.' const rows = alerts diff --git a/packages/eval-braintrust/src/runner.ts b/packages/eval-braintrust/src/runner.ts index b8ccd79e7..05a59045f 100644 --- a/packages/eval-braintrust/src/runner.ts +++ b/packages/eval-braintrust/src/runner.ts @@ -1,6 +1,7 @@ import { ErrorCodes, isRecord, RuntimeError } from '@agentskit/core' import type { Scorer, ScorerInput, ScorerResult } from './types' +/** Project, experiment, and opt-in upload settings for {@link runBraintrustEval}. */ export interface BraintrustRunOptions { apiKey?: string projectName: string @@ -17,6 +18,7 @@ export interface BraintrustRunOptions { } } +/** One input, agent output, metadata, and scorer results from a Braintrust evaluation. */ export interface ScoredCase { input: string output: string @@ -26,6 +28,7 @@ export interface ScoredCase { durationMs?: number } +/** Per-case scores, aggregate means, and optional Braintrust experiment details. */ export interface ExperimentResult { projectName: string experimentName: string @@ -133,6 +136,12 @@ function remoteMetadata( return out } +/** Run each scorer for one case and convert thrown or malformed results to `scorer_error` entries. + * + * @param scorers Scorers to run in order. + * @param args Input, output, expected value, and metadata passed to each scorer. + * @returns One valid scorer result or isolated error result per scorer. + */ export async function scoreCase( scorers: Scorer[], args: ScorerInput, @@ -163,6 +172,12 @@ export async function scoreCase( return out } +/** Aggregate each scorer's mean score and sample count across evaluated cases. + * + * @param cases Cases whose scorer results should be aggregated. + * @returns A map from scorer name to its mean score and result count. + * @throws RuntimeError when a case contains an invalid scorer result. + */ export function summarize(cases: ScoredCase[]): Record { const acc = new Map() for (const c of cases) { @@ -186,6 +201,7 @@ export function summarize(cases: ScoredCase[]): Record { cases: TCase[] agent: (input: string) => Promise<{ output: string; metadata?: Record }> @@ -193,10 +209,27 @@ export interface RunBraintrustEvalArgs options: BraintrustRunOptions } +/** Optional Braintrust SDK injection used by the runner. */ export interface RunBraintrustEvalInternals { bt?: BraintrustModule } +/** Score evaluation cases and optionally log the results to a Braintrust experiment. + * + * @param args Cases, agent, scorers, and run options. + * @param internals Optional SDK injection for the Braintrust integration. + * @returns Local case scores and summary, plus an experiment URL or non-fatal SDK warnings when applicable. + * @throws RuntimeError when the upload field size is outside the supported range. + * @example + * ```ts + * const result = await runBraintrustEval({ + * cases: [{ input: '2 + 2?', output: '', expected: '4' }], + * agent: async input => ({ output: await agent.run(input) }), + * scorers: [taskSuccess], + * options: { projectName: 'my-agent' }, + * }) + * ``` + */ export async function runBraintrustEval( args: RunBraintrustEvalArgs, internals: RunBraintrustEvalInternals = {}, diff --git a/packages/eval-braintrust/src/scorers/index.ts b/packages/eval-braintrust/src/scorers/index.ts index 2f31ca8f8..83fc479e1 100644 --- a/packages/eval-braintrust/src/scorers/index.ts +++ b/packages/eval-braintrust/src/scorers/index.ts @@ -32,6 +32,7 @@ import { } from './robustness' import type { ScorerFamily } from '../types' +/** The four built-in quality scorers grouped as one scorer family. */ export const qualityFamily: ScorerFamily = { family: 'quality', scorers: [ @@ -42,6 +43,7 @@ export const qualityFamily: ScorerFamily = { ], } +/** The four built-in robustness scorers grouped as one scorer family. */ export const robustnessFamily: ScorerFamily = { family: 'robustness', scorers: [ @@ -52,6 +54,7 @@ export const robustnessFamily: ScorerFamily = { ], } +/** Flat list of all built-in quality and robustness scorers. */ export const ALL_SCORERS: ScorerFamily['scorers'] = [ ...qualityFamily.scorers, ...robustnessFamily.scorers, diff --git a/packages/eval-braintrust/src/scorers/quality.ts b/packages/eval-braintrust/src/scorers/quality.ts index eacd6bdd8..4da2c4eac 100644 --- a/packages/eval-braintrust/src/scorers/quality.ts +++ b/packages/eval-braintrust/src/scorers/quality.ts @@ -2,6 +2,11 @@ import type { Scorer } from '../types' const clamp = (n: number): number => Math.min(1, Math.max(0, n)) +/** Score whether output matches an expected string, regular expression, or predicate. + * + * @param args Scorer input with the output and expected value. + * @returns A binary `task_success` score, or zero when no expected value is supplied. + */ export const taskSuccess: Scorer boolean)> = ({ output, expected }) => { if (expected === undefined) { return { name: 'task_success', score: 0, rationale: 'no expected value provided' } @@ -19,10 +24,16 @@ export const taskSuccess: Scorer boolean) return { name: 'task_success', score: pass ? 1 : 0 } } +/** Optional source strings read by {@link factualGrounding}. */ export interface FactualGroundingMeta { sources?: string[] } +/** Score the fraction of provided source strings mentioned in the output. + * + * @param args Scorer input with output text and source metadata. + * @returns The case-insensitive matched-source fraction, or zero when no sources are provided. + */ export const factualGrounding: Scorer = ({ output, metadata }) => { const sources = metadata?.sources ?? [] if (sources.length === 0) { @@ -36,12 +47,18 @@ export const factualGrounding: Scorer = ({ output } } +/** Optional expected citation labels read by {@link citationCorrectness}. */ export interface CitationMeta { expectedCitations?: string[] } const CITATION_RE = /\[(\d+)\]|\(([^()]+\.[a-z]{2,4})\)|([^<]+)<\/source>/gi +/** Score citations found in supported bracket, parenthesis, or source-tag forms. + * + * @param args Scorer input with output text and optional expected citations. + * @returns The fraction of expected citations found, or a binary score when none are specified. + */ export const citationCorrectness: Scorer = ({ output, metadata }) => { const expected = metadata?.expectedCitations ?? [] const found = new Set() @@ -63,10 +80,16 @@ export const citationCorrectness: Scorer = ({ output, met } } +/** Optional tool call metadata read by {@link toolArgValidity}. */ export interface ToolArgValidityInput { toolCalls?: Array<{ name: string; args: unknown; schemaValid?: boolean }> } +/** Score the fraction of recorded tool calls not marked schema-invalid. + * + * @param args Scorer input with optional tool call metadata. + * @returns The valid-call fraction, or one when no tool calls are present. + */ export const toolArgValidity: Scorer = ({ metadata }) => { const calls = metadata?.toolCalls ?? [] if (calls.length === 0) { diff --git a/packages/eval-braintrust/src/scorers/robustness.ts b/packages/eval-braintrust/src/scorers/robustness.ts index 6ac1994e2..9bae2f996 100644 --- a/packages/eval-braintrust/src/scorers/robustness.ts +++ b/packages/eval-braintrust/src/scorers/robustness.ts @@ -1,10 +1,16 @@ import type { Scorer } from '../types' +/** Optional schema validation fields read by {@link schemaSurvival}. */ export interface SchemaValidityMeta { schemaValid?: boolean parseError?: string | null } +/** Score whether metadata reports a valid schema and no parse error. + * + * @param args Scorer input with schema validity metadata. + * @returns One unless metadata reports an invalid schema or parse error. + */ export const schemaSurvival: Scorer = ({ metadata }) => { const valid = metadata?.schemaValid !== false && !metadata?.parseError return { @@ -14,11 +20,17 @@ export const schemaSurvival: Scorer = ({ metadata } } } +/** Optional expected and observed human-in-the-loop gate fields. */ export interface HitlMeta { hitlExpected?: boolean hitlTriggered?: boolean } +/** Score whether the human-in-the-loop gate matched the expected trigger state. + * + * @param args Scorer input with expected and observed HITL metadata. + * @returns One when the states match, otherwise zero. + */ export const hitlGateCorrectness: Scorer = ({ metadata }) => { const expected = metadata?.hitlExpected ?? false const triggered = metadata?.hitlTriggered ?? false @@ -30,11 +42,17 @@ export const hitlGateCorrectness: Scorer = ({ metadata }) => } } +/** Optional primary error and fallback status fields. */ export interface FallbackMeta { primaryError?: string | null fallbackFired?: boolean } +/** Score whether a failed primary attempt was recovered by a fallback. + * + * @param args Scorer input with primary-error and fallback metadata. + * @returns One for a clean run or fired fallback, and zero for an uncovered primary error. + */ export const fallbackResilience: Scorer = ({ metadata }) => { const errored = Boolean(metadata?.primaryError) const fallback = Boolean(metadata?.fallbackFired) @@ -46,11 +64,17 @@ export const fallbackResilience: Scorer = ({ metadata }) return { name: 'fallback_resilience', score: 0, rationale: 'primary errored, no fallback' } } +/** Optional crash signal fields read by {@link noCrashSurvival}. */ export interface CrashMeta { crashed?: boolean uncaughtException?: string | null } +/** Score whether metadata reports a crash or uncaught exception. + * + * @param args Scorer input with crash metadata. + * @returns Zero for a crash signal, otherwise one. + */ export const noCrashSurvival: Scorer = ({ metadata }) => { const crashed = metadata?.crashed === true || Boolean(metadata?.uncaughtException) return { diff --git a/packages/eval-braintrust/src/types.ts b/packages/eval-braintrust/src/types.ts index 6c339cfac..9f1ab8ff9 100644 --- a/packages/eval-braintrust/src/types.ts +++ b/packages/eval-braintrust/src/types.ts @@ -1,3 +1,4 @@ +/** Input fields passed to a scorer, including optional expected output and metadata. */ export interface ScorerInput> { input: string output: string @@ -5,6 +6,7 @@ export interface ScorerInput } +/** Function that scores one input and may return its result asynchronously. */ export type Scorer> = ( args: ScorerInput, ) => ScorerResult | Promise +/** A named group of scorers for one evaluation dimension. */ export interface ScorerFamily { family: 'quality' | 'robustness' scorers: Scorer[] From 5b0e8db1f2d698bb40d8216a1a0ea3e2ec73d6d2 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:01:58 -0300 Subject: [PATCH 19/30] docs(runtime): document public API --- .changeset/doc03-runtime.md | 5 ++ docs/stability/jsdoc-coverage-v1.json | 87 --------------------- packages/runtime/src/background.ts | 35 +++++++++ packages/runtime/src/chat-trigger.ts | 15 ++++ packages/runtime/src/durable.ts | 18 +++++ packages/runtime/src/flow.ts | 42 ++++++++++ packages/runtime/src/multi-agent-auction.ts | 11 +++ packages/runtime/src/multi-agent-compare.ts | 14 ++++ packages/runtime/src/multi-agent-debate.ts | 8 ++ packages/runtime/src/multi-agent-vote.ts | 11 +++ packages/runtime/src/multi-agent.ts | 21 +++++ packages/runtime/src/quota.ts | 20 +++++ packages/runtime/src/runner.ts | 1 + packages/runtime/src/speculate.ts | 15 ++++ packages/runtime/src/topologies.ts | 32 ++++++++ packages/runtime/src/types.ts | 12 +++ packages/runtime/src/validator-guard.ts | 30 +++++++ 17 files changed, 290 insertions(+), 87 deletions(-) create mode 100644 .changeset/doc03-runtime.md diff --git a/.changeset/doc03-runtime.md b/.changeset/doc03-runtime.md new file mode 100644 index 000000000..f65688d70 --- /dev/null +++ b/.changeset/doc03-runtime.md @@ -0,0 +1,5 @@ +--- +'@agentskit/runtime': patch +--- + +Document the public API with JSDoc. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..1c7b86328 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -547,7 +547,6 @@ ".::ToolCallStatus", ".::ToolDefinition", ".::ToolExecutionContext", - ".::useChat", ".::UseStreamOptions", ".::UseStreamReturn" ], @@ -911,94 +910,9 @@ ], "@agentskit/react-native": [], "@agentskit/runtime": [ - ".::AuctionConfig", - ".::AuctionHandlerOptions", - ".::AuctionScorerFn", - ".::blackboard", - ".::BlackboardConfig", - ".::ChatSurfaceEvent", - ".::ChatSurfaceEventType", - ".::ChatTrigger", - ".::ChatTriggerObserverEvent", - ".::ChatTriggerOptions", - ".::CompareConfig", - ".::CompareEvalFn", - ".::CompareHandlerOptions", - ".::CompareJudgeFn", - ".::CompareSelection", - ".::CompiledFlow", - ".::compileFlow", - ".::CompileFlowOptions", - ".::createAuctionHandler", - ".::createCompareHandler", - ".::createCronScheduler", - ".::createDebateHandler", - ".::createDurableRunner", - ".::createQuotaTracker", - ".::createRuntime", ".::createSharedContext", - ".::createValidatorGuard", - ".::createVoteHandler", - ".::cronMatches", - ".::CronScheduler", - ".::CronSchedulerOptions", - ".::DebateConfig", - ".::DebateHandlerOptions", - ".::DelegateConfig", - ".::DurableEvent", - ".::DurableRunner", - ".::DurableRunnerOptions", - ".::FlowDefinition", - ".::FlowHandler", - ".::FlowHandlerContext", - ".::FlowRegistry", - ".::FlowRunEvent", - ".::FlowValidationIssue", - ".::FlowValidationResult", - ".::hierarchical", - ".::HierarchicalConfig", - ".::HierarchicalNode", - ".::InMemoryScratchpadStore", - ".::parseSchedule", - ".::QuotaExceededEvent", - ".::QuotaMap", - ".::QuotaSnapshot", - ".::QuotaTracker", - ".::QuotaTrackerOptions", ".::ReadonlySharedContext", - ".::RunFlowOptions", - ".::RunOptions", - ".::RunResult", - ".::RuntimeConfig", ".::SharedContext", - ".::SpeculateInput", - ".::SpeculateOutput", - ".::SpeculatePicker", - ".::SpeculativeCandidate", - ".::SpeculativeResult", - ".::StepLogStore", - ".::supervisor", - ".::SupervisorConfig", - ".::SwarmConfig", - ".::TopologyLogEvent", - ".::TopologyObserver", - ".::validateFlow", - ".::Validator", - ".::ValidatorAuditEvent", - ".::ValidatorCheckContext", - ".::ValidatorGuard", - ".::ValidatorGuardOptions", - ".::ValidatorGuardRun", - ".::ValidatorGuardRunOptions", - ".::ValidatorResult", - ".::VoteBallot", - ".::VoteConfig", - ".::VoteHandlerOptions", - ".::VoteJudgeFn", - ".::WebhookHandler", - ".::WebhookOptions", - ".::WebhookRequest", - ".::WebhookResponse", "./shared-context::createSharedContext", "./shared-context::ReadonlySharedContext", "./shared-context::SharedContext" @@ -1098,7 +1012,6 @@ "@agentskit/svelte": [ ".::ChatContainer", ".::CodeBlock", - ".::createChatStore", ".::InputBar", ".::Markdown", ".::Message", diff --git a/packages/runtime/src/background.ts b/packages/runtime/src/background.ts index 79933d0a5..575fc25c9 100644 --- a/packages/runtime/src/background.ts +++ b/packages/runtime/src/background.ts @@ -22,6 +22,9 @@ export interface CronJob { runOnStart?: boolean } +/** + * Job, schedule, context, and clock options for a cron scheduler. + */ export interface CronSchedulerOptions { jobs: CronJob[] /** Observability hook. */ @@ -99,6 +102,12 @@ function isAnyField(field: string): boolean { return field.split(',').some(segment => segment === '*' || segment.startsWith('*/')) } +/** + * Parse a five-field cron expression or `every:` schedule. + * @param schedule Schedule string to parse. + * @returns Parsed schedule fields for matching. + * @throws {Error} When the schedule syntax is invalid. + */ export function parseSchedule(schedule: string): ParsedSchedule { const trimmed = schedule.trim() if (trimmed.startsWith('every:')) { @@ -132,6 +141,12 @@ export function parseSchedule(schedule: string): ParsedSchedule { } } +/** + * Check whether a parsed cron schedule matches a date. + * @param schedule Parsed five-field cron schedule. + * @param now Date to check. + * @returns Whether every cron field matches the date. + */ export function cronMatches(schedule: ParsedCron, now: Date): boolean { if (!schedule.minute.has(now.getMinutes()) || !schedule.hour.has(now.getHours()) || !schedule.month.has(now.getMonth() + 1)) return false const domMatch = schedule.dom.has(now.getDate()) @@ -144,6 +159,9 @@ export function cronMatches(schedule: ParsedCron, now: Date): boolean { return dayMatch } +/** + * Controls for starting and stopping scheduled job execution. + */ export interface CronScheduler { start: () => void stop: () => void @@ -151,6 +169,11 @@ export interface CronScheduler { tick: (now?: Date) => Promise } +/** + * Create a scheduler that dispatches a job when its cron or interval schedule is due. + * @param options Schedule, job callback, clock, and error handling options. + * @returns A scheduler with start and stop controls. + */ export function createCronScheduler( options: CronSchedulerOptions, ): CronScheduler { @@ -219,17 +242,26 @@ export function createCronScheduler( // Webhook handler // --------------------------------------------------------------------------- +/** + * Normalized incoming webhook method, headers, and body. + */ export interface WebhookRequest { headers?: Record body?: string | Record } +/** + * HTTP status, headers, and body returned by a webhook handler. + */ export interface WebhookResponse { status: number body: string headers?: Record } +/** + * Configuration for adapting incoming webhook requests to agent execution. + */ export interface WebhookOptions { agent: AgentHandle /** @@ -252,6 +284,9 @@ function defaultExtract(req: WebhookRequest): string { return JSON.stringify(req.body ?? '') } +/** + * Async function that handles one webhook request and returns a response. + */ export type WebhookHandler = (req: WebhookRequest) => Promise /** diff --git a/packages/runtime/src/chat-trigger.ts b/packages/runtime/src/chat-trigger.ts index b6036b52d..6fed5fc94 100644 --- a/packages/runtime/src/chat-trigger.ts +++ b/packages/runtime/src/chat-trigger.ts @@ -115,6 +115,9 @@ export interface ChatInstallationEvent extends ChatSurfaceMeta { tenantId: string } +/** + * Normalized inbound message, mention, reply, reaction, upload, or installation event. + */ export type ChatSurfaceEvent = | ChatMessageEvent | ChatMentionEvent @@ -123,6 +126,9 @@ export type ChatSurfaceEvent = | ChatFileUploadEvent | ChatInstallationEvent +/** + * Discriminant values available on normalized chat-surface events. + */ export type ChatSurfaceEventType = ChatSurfaceEvent['type'] /** @@ -152,6 +158,9 @@ export interface ChatSurfaceAdapter { reply?: (event: ChatSurfaceEvent, text: string) => Promise | void } +/** + * Lifecycle event emitted while a chat trigger handles a surface event. + */ export interface ChatTriggerObserverEvent { /** * - `received` → before any work @@ -169,6 +178,9 @@ export interface ChatTriggerObserverEvent { reason?: string } +/** + * Adapter, agent runner, and optional observer configuration for chat triggers. + */ export interface ChatTriggerOptions { adapter: ChatSurfaceAdapter agent: AgentHandle @@ -225,6 +237,9 @@ function defaultBuildContext(event: ChatSurfaceEvent): TContext { return { event } as unknown as TContext } +/** + * Framework-independent webhook handler and observer wiring for a chat trigger. + */ export interface ChatTrigger { handler: WebhookHandler surface: ChatSurface diff --git a/packages/runtime/src/durable.ts b/packages/runtime/src/durable.ts index eef30eb50..a79d0c008 100644 --- a/packages/runtime/src/durable.ts +++ b/packages/runtime/src/durable.ts @@ -28,6 +28,9 @@ export interface StepRecord { attempt: number } +/** + * Persistence contract for appending, retrieving, listing, and optionally clearing step records. + */ export interface StepLogStore { append: (record: StepRecord) => Promise get: (runId: string, stepId: string) => Promise | null> @@ -35,6 +38,9 @@ export interface StepLogStore { clear?: (runId: string) => Promise } +/** + * Options for durable step execution, including its store and stable run identifier. + */ export interface DurableRunnerOptions { store: StepLogStore runId: string @@ -48,12 +54,18 @@ export interface DurableRunnerOptions { onEvent?: (event: DurableEvent) => void } +/** + * Lifecycle event emitted when a durable step starts, succeeds, fails, or replays. + */ export type DurableEvent = | { type: 'step:replay'; stepId: string; name: string; runId: string } | { type: 'step:start'; stepId: string; name: string; runId: string; attempt: number } | { type: 'step:success'; stepId: string; name: string; runId: string; durationMs: number } | { type: 'step:failure'; stepId: string; name: string; runId: string; error: string; attempt: number } +/** + * Operations for executing, replaying, inspecting, and resetting steps in one run. + */ export interface DurableRunner { /** * Execute `fn` under the name `stepId`. If the step has already @@ -82,6 +94,12 @@ function isStepRecord(input: unknown): input is StepRecord { ) } +/** + * Create a runner that records step results and replays completed steps for a run. + * @param options Store, run identifier, retry policy, abort signal, and event callback. + * @returns A runner with `step`, `history`, and `reset` operations. + * @throws {RuntimeError} When a recorded step failed or an operation is aborted. + */ export function createDurableRunner(options: DurableRunnerOptions): DurableRunner { const maxAttempts = Math.max(1, options.maxAttempts ?? 1) const retryDelayMs = Math.max(0, options.retryDelayMs ?? 0) diff --git a/packages/runtime/src/flow.ts b/packages/runtime/src/flow.ts index 6a58e8990..affe3c3a8 100644 --- a/packages/runtime/src/flow.ts +++ b/packages/runtime/src/flow.ts @@ -28,6 +28,9 @@ export interface FlowNode { needs?: string[] } +/** + * Named directed acyclic flow made of handler-backed nodes and dependencies. + */ export interface FlowDefinition { name: string version?: number | string @@ -35,6 +38,9 @@ export interface FlowDefinition { nodes: FlowNode[] } +/** + * Input, node metadata, dependency outputs, and static values supplied to a flow handler. + */ export interface FlowHandlerContext { node: FlowNode /** Initial input passed to `runFlow`. */ @@ -45,18 +51,30 @@ export interface FlowHandlerContext { with: Record } +/** + * A sync or async function that processes one flow node context. + */ export type FlowHandler = ( ctx: FlowHandlerContext, ) => Promise | TResult +/** + * Map of handler names to functions used by flow nodes. + */ export type FlowRegistry = Record> +/** + * A validation error identifying an invalid node or flow structure. + */ export interface FlowValidationIssue { code: 'duplicate-id' | 'missing-handler' | 'unknown-dependency' | 'self-dependency' | 'cycle' message: string nodeId?: string } +/** + * Flow validity, validation issues, and execution order. + */ export interface FlowValidationResult { ok: boolean issues: FlowValidationIssue[] @@ -64,6 +82,12 @@ export interface FlowValidationResult { order: string[] } +/** + * Validate flow node identifiers, handlers, dependencies, and cycles. + * @param def Flow definition to inspect. + * @param registry Optional handler registry used to check handler names. + * @returns Validation status, issues, and topological node order when valid. + */ export function validateFlow( def: FlowDefinition, registry?: FlowRegistry, @@ -144,11 +168,17 @@ function topoSort( return { ok: false, cycle: stuck } } +/** + * Flow definition and registry used to compile an executable flow. + */ export interface CompileFlowOptions { definition: FlowDefinition registry: FlowRegistry } +/** + * Run identifier, durable store, retry settings, and event callback for a flow run. + */ export interface RunFlowOptions { /** Defaults to a fresh `runId` per call. Reuse to resume after a crash. */ runId?: string @@ -160,6 +190,9 @@ export interface RunFlowOptions { onEvent?: (event: FlowRunEvent) => void } +/** + * Lifecycle event emitted while a flow and its nodes execute. + */ export type FlowRunEvent = | { type: 'flow:start'; flow: string; runId: string } | { type: 'node:start'; flow: string; runId: string; nodeId: string } @@ -167,12 +200,21 @@ export type FlowRunEvent = | { type: 'node:failure'; flow: string; runId: string; nodeId: string; error: string } | { type: 'flow:done'; flow: string; runId: string; outputs: Record } +/** + * Validated flow definition, node order, and durable run function. + */ export interface CompiledFlow { definition: FlowDefinition order: string[] run: (input?: TInput, options?: RunFlowOptions) => Promise> } +/** + * Validate and compile a flow into a durable DAG runner. + * @param options Flow definition and handler registry. + * @returns Compiled flow with its execution order and `run` method. + * @throws {RuntimeError} When the definition has validation issues. + */ export function compileFlow( options: CompileFlowOptions, ): CompiledFlow { diff --git a/packages/runtime/src/multi-agent-auction.ts b/packages/runtime/src/multi-agent-auction.ts index f3ba5f415..10a737c1d 100644 --- a/packages/runtime/src/multi-agent-auction.ts +++ b/packages/runtime/src/multi-agent-auction.ts @@ -11,8 +11,14 @@ import { type TopologyRunAgent, } from './multi-agent' +/** + * Return a numeric score for a bid and its agent identifier. + */ export type AuctionScorerFn = (bid: AgentRunResult, agentId: string) => number +/** + * Dependencies and bid selection settings for an auction handler. + */ export type AuctionHandlerOptions = { runAgent: TopologyRunAgent customScorer?: AuctionScorerFn @@ -56,6 +62,11 @@ const passesReservePrice = ( return true } +/** + * Create a handler that collects bids and selects one according to configured criteria. + * @param opts Agent runner and auction configuration. + * @returns An async handler resolving to an `ok`, `failed`, or `paused` outcome. + */ export const createAuctionHandler = (opts: AuctionHandlerOptions) => { return async (node: AuctionConfig, input: unknown, ctx: Ctx): Promise => { const task = node.task ?? input diff --git a/packages/runtime/src/multi-agent-compare.ts b/packages/runtime/src/multi-agent-compare.ts index 563672a5e..a0efc8f46 100644 --- a/packages/runtime/src/multi-agent-compare.ts +++ b/packages/runtime/src/multi-agent-compare.ts @@ -10,12 +10,18 @@ import { type TopologyRunAgent, } from './multi-agent' +/** + * Score a candidate result for evaluation-based selection. + */ export type CompareEvalFn = ( results: AgentRunResult[], evalRef: string, ctx: Ctx, ) => Promise +/** + * Ask an injected judge agent to select among candidate results. + */ export type CompareJudgeFn = ( results: AgentRunResult[], agentIds: string[], @@ -24,6 +30,9 @@ export type CompareJudgeFn = ( ctx: Ctx, ) => Promise +/** + * Dependencies and selection helpers for a compare topology handler. + */ export type CompareHandlerOptions = { runAgent: TopologyRunAgent evaluator?: CompareEvalFn @@ -90,6 +99,11 @@ const failInvalidWinnerIdx = (mode: 'eval' | 'judge', winnerIdx: number): Topolo }, }) +/** + * Create a fan-out handler that runs agents and selects or combines their results. + * @param opts Agent runner, comparison configuration, and optional selection helpers. + * @returns An async handler resolving to an `ok`, `failed`, or `paused` outcome. + */ export const createCompareHandler = (opts: CompareHandlerOptions) => { return async (node: CompareConfig, input: unknown, ctx: Ctx): Promise => { const nodeInput = node.input ?? (input as Record | undefined) diff --git a/packages/runtime/src/multi-agent-debate.ts b/packages/runtime/src/multi-agent-debate.ts index fbdbd90c2..04fd58dbf 100644 --- a/packages/runtime/src/multi-agent-debate.ts +++ b/packages/runtime/src/multi-agent-debate.ts @@ -3,12 +3,20 @@ import type { DebateConfig, TopologyOutcome, TopologyRunAgent } from './multi-agent' +/** + * Dependencies and debate settings for a debate topology handler. + */ export type DebateHandlerOptions = { runAgent: TopologyRunAgent } type DebateMessage = { role: 'proponent' | 'opponent'; content: unknown } +/** + * Create a handler that alternates proponent and opponent agents before a judge decides. + * @param opts Agent runner and debate configuration. + * @returns An async handler resolving to an `ok`, `failed`, or `paused` outcome. + */ export const createDebateHandler = (opts: DebateHandlerOptions) => { return async (node: DebateConfig, input: unknown, ctx: Ctx): Promise => { const topic = node.topic diff --git a/packages/runtime/src/multi-agent-vote.ts b/packages/runtime/src/multi-agent-vote.ts index 54fb29300..49977c0dc 100644 --- a/packages/runtime/src/multi-agent-vote.ts +++ b/packages/runtime/src/multi-agent-vote.ts @@ -10,6 +10,9 @@ import { type VoteConfig, } from './multi-agent' +/** + * Resolve a tied vote by asking an injected judge agent. + */ export type VoteJudgeFn = ( outputs: unknown[], agentIds: string[], @@ -17,6 +20,9 @@ export type VoteJudgeFn = ( ctx: Ctx, ) => Promise +/** + * Dependencies and ballot settings for a vote topology handler. + */ export type VoteHandlerOptions = { runAgent: TopologyRunAgent judger?: VoteJudgeFn @@ -102,6 +108,11 @@ const plurality = (scores: Map): { winner: string; topScore: num return { winner, topScore, isTie: tiers.length > 1 } } +/** + * Create a fan-out handler that collects ballots and resolves a vote. + * @param opts Agent runner, ballot policy, and optional tie-break judge. + * @returns An async handler resolving to an `ok`, `failed`, or `paused` outcome. + */ export const createVoteHandler = (opts: VoteHandlerOptions) => { return async (node: VoteConfig, input: unknown, ctx: Ctx): Promise => { const nodeInput = node.input ?? (input as Record | undefined) diff --git a/packages/runtime/src/multi-agent.ts b/packages/runtime/src/multi-agent.ts index 29b38c6ce..ebdd680cf 100644 --- a/packages/runtime/src/multi-agent.ts +++ b/packages/runtime/src/multi-agent.ts @@ -65,6 +65,9 @@ export type ScratchpadStore = { entries(): ReadonlyArray<[string, unknown]> } +/** + * Store arbitrary values by key in process memory for topology coordination. + */ export class InMemoryScratchpadStore implements ScratchpadStore { private readonly _data = new Map() @@ -83,6 +86,9 @@ export class InMemoryScratchpadStore implements ScratchpadStore { // --- Config shapes (structurally compatible with a host's node schemas) --- +/** + * Strategy for combining, choosing, evaluating, judging, or manually selecting compare results. + */ export type CompareSelection = | { readonly mode: 'manual' } | { readonly mode: 'all'; readonly combine: 'concat' | 'merge' } @@ -90,18 +96,27 @@ export type CompareSelection = | { readonly mode: 'eval'; readonly evalRef: string } | { readonly mode: 'judge'; readonly criteria: string; readonly judgeAgent: string } +/** + * Agent list, shared input, and result selection strategy for compare. + */ export interface CompareConfig { readonly agents: readonly string[] readonly input?: unknown readonly selection: CompareSelection } +/** + * Ballot policy for majority, weighted, unanimous, or quorum voting. + */ export type VoteBallot = | { readonly mode: 'majority' } | { readonly mode: 'weighted'; readonly weights?: Record } | { readonly mode: 'unanimous' } | { readonly mode: 'quorum'; readonly threshold: number } +/** + * Agent list, input, ballot policy, and tie-breaking behavior for vote. + */ export interface VoteConfig { readonly agents: readonly string[] readonly input?: unknown @@ -110,6 +125,9 @@ export interface VoteConfig { readonly judgeAgent?: string } +/** + * Topic, participants, round limit, and optional early-exit behavior for a debate. + */ export interface DebateConfig { readonly topic: unknown readonly format?: unknown @@ -120,6 +138,9 @@ export interface DebateConfig { readonly earlyExit?: 'on-agreement' | string } +/** + * Bidders, selection criteria, and optional reserve, timeout, and fallback settings. + */ export interface AuctionConfig { readonly bidders: readonly string[] readonly task?: unknown diff --git a/packages/runtime/src/quota.ts b/packages/runtime/src/quota.ts index b3bbe99df..1c05c4aed 100644 --- a/packages/runtime/src/quota.ts +++ b/packages/runtime/src/quota.ts @@ -30,8 +30,14 @@ export interface ToolQuota { dryRunRequiredIn?: string[] } +/** + * Tool names mapped to their per-run, sliding-window, or dry-run limits. + */ export type QuotaMap = Record +/** + * Details of a tool quota that rejected an invocation. + */ export interface QuotaExceededEvent { tool: string /** Which limit fired. */ @@ -44,6 +50,9 @@ export interface QuotaExceededEvent { at: string } +/** + * Quota rules and optional environment, event sink, and clock. + */ export interface QuotaTrackerOptions { quotas: QuotaMap /** Active environment tag (`'production'`, `'staging'`, …). */ @@ -54,6 +63,9 @@ export interface QuotaTrackerOptions { now?: () => number } +/** + * Admission, accounting, reset, and inspection methods for tool quotas. + */ export interface QuotaTracker { /** Throws and reserves one admission when the tool is over budget. */ check: (tool: string, runId: string) => void @@ -67,11 +79,19 @@ export interface QuotaTracker { snapshot: () => QuotaSnapshot } +/** + * Current per-run counters and timestamps in the sliding-window counters. + */ export interface QuotaSnapshot { perRun: Record> perWindow: Record } +/** + * Create per-run and sliding-window quota counters for tools. + * @param options Quota limits, environment, event callback, and optional clock. + * @returns Tracker methods for admission checks, recording, release, reset, and snapshots. + */ export function createQuotaTracker(options: QuotaTrackerOptions): QuotaTracker { const now = options.now ?? (() => Date.now()) const perRun = new Map>() diff --git a/packages/runtime/src/runner.ts b/packages/runtime/src/runner.ts index 3028c2fbe..c214eba0a 100644 --- a/packages/runtime/src/runner.ts +++ b/packages/runtime/src/runner.ts @@ -92,6 +92,7 @@ async function consumeStreamWithAbort( } } +/** Create a headless agent runtime. @param config Runtime defaults, overridden by supported run options. @returns A `run(task, options?)` agent runner. @example `const result = await createRuntime({ adapter }).run('Summarize this report')` */ export function createRuntime(config: RuntimeConfig) { const emitter = createEventEmitter() diff --git a/packages/runtime/src/speculate.ts b/packages/runtime/src/speculate.ts index f4c72559e..ae9e80b1e 100644 --- a/packages/runtime/src/speculate.ts +++ b/packages/runtime/src/speculate.ts @@ -1,6 +1,9 @@ import { ConfigError, ErrorCodes, RuntimeError } from '@agentskit/core' import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from '@agentskit/core' +/** + * Adapter candidate and cancellation policy for a speculative request. + */ export interface SpeculativeCandidate { /** Human label used in results. */ id: string @@ -9,6 +12,9 @@ export interface SpeculativeCandidate { abortOnLoser?: boolean } +/** + * Stream text, chunks, latency, and failure or abort status for one candidate. + */ export interface SpeculativeResult { id: string chunks: StreamChunk[] @@ -18,8 +24,14 @@ export interface SpeculativeResult { aborted?: boolean } +/** + * Select a candidate identifier from completed speculative results. + */ export type SpeculatePicker = (results: SpeculativeResult[]) => string | Promise +/** + * Candidates, adapter request, winner selection policy, and optional timeout. + */ export interface SpeculateInput { candidates: SpeculativeCandidate[] request: AdapterRequest @@ -37,6 +49,9 @@ export interface SpeculateInput { timeoutMs?: number } +/** + * Winning result, losing results, and the full set of speculative results. + */ export interface SpeculateOutput { winner: SpeculativeResult losers: SpeculativeResult[] diff --git a/packages/runtime/src/topologies.ts b/packages/runtime/src/topologies.ts index d484438d2..34ea21581 100644 --- a/packages/runtime/src/topologies.ts +++ b/packages/runtime/src/topologies.ts @@ -25,6 +25,7 @@ export interface AgentHandle { abort?: () => void } +/** Event emitted as a topology starts or agents are assigned work. */ export interface TopologyLogEvent { topology: string phase: 'dispatch' | 'agent:start' | 'agent:end' | 'merge' | 'done' @@ -34,12 +35,16 @@ export interface TopologyLogEvent { iteration?: number } +/** Receives topology lifecycle events for logging or observation. */ export type TopologyObserver = (event: TopologyLogEvent) => void // --------------------------------------------------------------------------- // Supervisor: one planner agent delegates to workers, then synthesizes. // --------------------------------------------------------------------------- +/** + * Configuration for the supervisor topology. + */ export interface SupervisorConfig { supervisor: AgentHandle workers: AgentHandle[] @@ -50,6 +55,11 @@ export interface SupervisorConfig { onEvent?: TopologyObserver } +/** + * Create a supervisor topology that delegates work to configured agents. + * @param config Agent definitions and supervisor behavior. + * @returns A handle for running and managing the topology. + */ export function supervisor( config: SupervisorConfig, ): AgentHandle { @@ -95,6 +105,9 @@ export function supervisor( // Swarm: broadcast to every member, user-supplied merger picks the output. // --------------------------------------------------------------------------- +/** + * Configuration for a swarm of agents. + */ export interface SwarmConfig { name?: string members: AgentHandle[] @@ -196,6 +209,9 @@ export function swarm(config: SwarmConfig): AgentH // Hierarchical: tree of agents. Root decides which branch to dispatch to. // --------------------------------------------------------------------------- +/** + * A node in a hierarchical agent topology. + */ export interface HierarchicalNode { agent: AgentHandle /** Free-form tags the router can match against. */ @@ -203,6 +219,9 @@ export interface HierarchicalNode { children?: HierarchicalNode[] } +/** + * Configuration for a hierarchy of agents. + */ export interface HierarchicalConfig { name?: string root: HierarchicalNode @@ -213,6 +232,11 @@ export interface HierarchicalConfig { onEvent?: TopologyObserver } +/** + * Create a hierarchical topology with parent and child agents. + * @param config The root and child hierarchy configuration. + * @returns A handle for running and managing the hierarchy. + */ export function hierarchical( config: HierarchicalConfig, ): AgentHandle { @@ -247,6 +271,9 @@ export function hierarchical( // Blackboard: agents read/write a shared scratchpad. Loop until converge. // --------------------------------------------------------------------------- +/** + * Configuration for agents that coordinate through shared blackboard state. + */ export interface BlackboardConfig { name?: string agents: AgentHandle[] @@ -257,6 +284,11 @@ export interface BlackboardConfig { onEvent?: TopologyObserver } +/** + * Create a blackboard topology that lets agents coordinate through shared state. + * @param config Agent and blackboard settings. + * @returns A handle for running and managing the topology. + */ export function blackboard( config: BlackboardConfig, ): AgentHandle { diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index fd1f5a3e8..fd3d70e1f 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -12,6 +12,9 @@ import type { } from '@agentskit/core' import type { SharedContext } from './shared-context' +/** + * Configuration for a named sub-agent, including its skill and optional tools or adapter. + */ export interface DelegateConfig { skill: SkillDefinition tools?: ToolDefinition[] @@ -19,6 +22,9 @@ export interface DelegateConfig { maxSteps?: number } +/** + * Configuration shared by every run of a runtime. + */ export interface RuntimeConfig { adapter: AdapterFactory tools?: ToolDefinition[] @@ -41,6 +47,9 @@ export interface RuntimeConfig { validateArgs?: ArgsValidator } +/** + * Options that override runtime settings for one run. + */ export interface RunOptions { tools?: ToolDefinition[] systemPrompt?: string @@ -53,6 +62,9 @@ export interface RunOptions { sharedContext?: SharedContext } +/** + * The final text, message history, step and tool-call counts, and duration for a run. + */ export interface RunResult { content: string messages: Message[] diff --git a/packages/runtime/src/validator-guard.ts b/packages/runtime/src/validator-guard.ts index b3c079a86..2d2201ccb 100644 --- a/packages/runtime/src/validator-guard.ts +++ b/packages/runtime/src/validator-guard.ts @@ -21,6 +21,9 @@ export type ValidatorAction = 'retry' | 'block' | 'fallback' +/** + * Tool and run metadata supplied to validators. + */ export interface ValidatorCheckContext { /** Attempt index (0-based) for the current run. */ attempt: number @@ -28,6 +31,9 @@ export interface ValidatorCheckContext { output: string } +/** + * Check a value and return a boolean or structured validation result. + */ export interface Validator { /** Stable id for audit logs / dashboards. */ name: string @@ -50,8 +56,14 @@ export interface Validator { repairPrompt?: (ctx: { output: string; reason?: string }) => string } +/** + * Boolean or structured result returned by a validator. + */ export type ValidatorResult = boolean | { ok: boolean; reason?: string } +/** + * Validators, retry limit, and audit callback for a validator guard. + */ export interface ValidatorGuardOptions { validators: Validator[] /** Deterministic fallback text used when `onFail: 'fallback'` fires. */ @@ -60,6 +72,9 @@ export interface ValidatorGuardOptions { audit?: (event: ValidatorAuditEvent) => void } +/** + * Audit record for an argument or output validation decision. + */ export interface ValidatorAuditEvent { /** ISO timestamp. */ at: string @@ -73,6 +88,9 @@ export interface ValidatorAuditEvent { output: string } +/** + * Context and callbacks needed to run a guarded tool operation. + */ export interface ValidatorGuardRun { /** Output that survived the gauntlet (or the fallback). */ output: string @@ -83,6 +101,9 @@ export interface ValidatorGuardRun { failures: Array<{ validator: string; attempt: number; reason?: string; action: ValidatorAction }> } +/** + * Per-run overrides for validator guard execution. + */ export interface ValidatorGuardRunOptions { /** Regenerate the output. Receives the optional repair prompt. */ regenerate: (repair?: string) => Promise @@ -90,6 +111,9 @@ export interface ValidatorGuardRunOptions { seed?: string } +/** + * Guard operations that check arguments and outputs around tool calls. + */ export interface ValidatorGuard { run: (options: ValidatorGuardRunOptions) => Promise } @@ -99,6 +123,12 @@ function normaliseResult(value: ValidatorResult): { ok: boolean; reason?: string return value } +/** + * Create a guard that validates tool inputs and outputs and applies configured retry or block actions. + * @param options Validators, retry settings, and audit callback. + * @returns A guard for wrapping tool execution. + * @throws {ToolError} When validation blocks a tool call. + */ export function createValidatorGuard(options: ValidatorGuardOptions): ValidatorGuard { return { async run({ regenerate, seed }) { From de2aadc69d12b3fa59bdd15b5f3a8412180745d8 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:12:21 -0300 Subject: [PATCH 20/30] docs(runtime): document shared-context API --- .changeset/doc03-runtime-shared-context.md | 5 +++++ packages/runtime/src/shared-context.ts | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 .changeset/doc03-runtime-shared-context.md diff --git a/.changeset/doc03-runtime-shared-context.md b/.changeset/doc03-runtime-shared-context.md new file mode 100644 index 000000000..5d62f0ced --- /dev/null +++ b/.changeset/doc03-runtime-shared-context.md @@ -0,0 +1,5 @@ +--- +'@agentskit/runtime': patch +--- + +Document the shared-context API. diff --git a/packages/runtime/src/shared-context.ts b/packages/runtime/src/shared-context.ts index cf354bdf1..1bb917d35 100644 --- a/packages/runtime/src/shared-context.ts +++ b/packages/runtime/src/shared-context.ts @@ -1,3 +1,4 @@ +/** Mutable key-value context that can be shared across tools in one run. */ export interface SharedContext { get(key: string): unknown set(key: string, value: unknown): void @@ -6,12 +7,14 @@ export interface SharedContext { readOnly(): ReadonlySharedContext } +/** Read-only view of shared context values. */ export interface ReadonlySharedContext { get(key: string): unknown has(key: string): boolean entries(): Record } +/** Create shared context initialized from an optional object. @param initial Initial key-value pairs. @returns Context with read and write operations. @example `const context = createSharedContext({ userId: 'u1' })` */ export function createSharedContext( initial?: Record, ): SharedContext { From 6e2232a13e68ee5c9a7c4ef4ca4f0eb7a177dc6a Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:20:42 -0300 Subject: [PATCH 21/30] docs(sandbox): document public API --- .changeset/doc03-sandbox.md | 5 +++ docs/stability/jsdoc-coverage-v1.json | 45 +-------------------- packages/sandbox/src/container-runtimes.ts | 44 ++++++++++++++++++++ packages/sandbox/src/e2b-backend.ts | 3 ++ packages/sandbox/src/local-registry.ts | 16 ++++++++ packages/sandbox/src/local-runtimes.ts | 27 +++++++++++++ packages/sandbox/src/local-sandbox-types.ts | 21 ++++++++++ packages/sandbox/src/policy.ts | 9 +++++ packages/sandbox/src/sandbox.ts | 6 +++ packages/sandbox/src/types.ts | 9 +++++ 10 files changed, 141 insertions(+), 44 deletions(-) create mode 100644 .changeset/doc03-sandbox.md diff --git a/.changeset/doc03-sandbox.md b/.changeset/doc03-sandbox.md new file mode 100644 index 000000000..47fdbd4ac --- /dev/null +++ b/.changeset/doc03-sandbox.md @@ -0,0 +1,5 @@ +--- +'@agentskit/sandbox': patch +--- + +Document the public API with JSDoc. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..53ea48d3d 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -1003,50 +1003,7 @@ "./shared-context::ReadonlySharedContext", "./shared-context::SharedContext" ], - "@agentskit/sandbox": [ - ".::BwrapPolicy", - ".::bwrapRuntime", - ".::BwrapRuntimeOpts", - ".::ChildHandle", - ".::DockerPolicy", - ".::dockerRuntime", - ".::DockerRuntimeOpts", - ".::E2BConfig", - ".::ExecuteOptions", - ".::ExecuteResult", - ".::exposeAllowedEnvKeys", - ".::getBwrapPath", - ".::isBwrapSupported", - ".::isStrongIsolation", - ".::isWeakIsolation", - ".::MandatorySandboxWrapper", - ".::noneSandbox", - ".::PolicyEvent", - ".::ProcessRuntimeOptions", - ".::processSandbox", - ".::renderBwrapArgs", - ".::renderDockerArgs", - ".::Sandbox", - ".::SANDBOX_LEVELS", - ".::SandboxBackend", - ".::SandboxConfig", - ".::SandboxExecPolicy", - ".::sandboxExecRuntime", - ".::SandboxExecRuntimeOpts", - ".::SandboxLevel", - ".::SandboxPolicy", - ".::SandboxRegistry", - ".::SandboxRuntime", - ".::Spawner", - ".::SpawnerExecOptions", - ".::SpawnerExecResult", - ".::WeakSandboxError", - "./sandbox::Sandbox", - "./sandbox::SandboxConfig", - "./types::ExecuteOptions", - "./types::ExecuteResult", - "./types::SandboxBackend" - ], + "@agentskit/sandbox": [], "@agentskit/skills": [ ".::clinicalNoteSummarizer", ".::coder", diff --git a/packages/sandbox/src/container-runtimes.ts b/packages/sandbox/src/container-runtimes.ts index 3c0fbf534..1c95659c5 100644 --- a/packages/sandbox/src/container-runtimes.ts +++ b/packages/sandbox/src/container-runtimes.ts @@ -16,6 +16,9 @@ import type { SandboxRuntime, Spawner } from './local-sandbox-types' // --- bwrap -------------------------------------------------------------- +/** + * Policy for bubblewrap workspace mounts and network sharing. + */ export type BwrapPolicy = { readonly workspaceRoot: string readonly allowNetwork?: boolean @@ -23,6 +26,9 @@ export type BwrapPolicy = { readonly readWritePaths?: readonly string[] } +/** + * Bubblewrap policy, optional spawner, and optional executable path. + */ export type BwrapRuntimeOpts = { readonly policy: BwrapPolicy readonly spawner?: Spawner @@ -41,8 +47,16 @@ function assertAbsolutePath(path: string, label: string): void { } } +/** + * Check whether bubblewrap is supported on the current Linux platform. + * @returns `true` on Linux and `false` on other platforms. + */ export const isBwrapSupported = (): boolean => process.platform === 'linux' +/** + * Find the `bwrap` executable in the current `PATH`. + * @returns The first matching executable path, or `null` when unavailable. + */ export const getBwrapPath = (): string | null => { if (!isBwrapSupported()) return null const pathEnv = process.env.PATH ?? '' @@ -54,6 +68,12 @@ export const getBwrapPath = (): string | null => { return null } +/** + * Build hardened bubblewrap arguments from a mount and network policy. + * @param policy Workspace root and optional read-only, read-write, and network settings. + * @returns Argument vector for `bwrap`. + * @throws {SandboxError} When a configured path is not absolute. + */ export const renderBwrapArgs = (policy: BwrapPolicy): readonly string[] => { assertAbsolutePath(policy.workspaceRoot, 'workspaceRoot') const ro = policy.readOnlyPaths ? [...policy.readOnlyPaths] : [] @@ -76,6 +96,12 @@ export const renderBwrapArgs = (policy: BwrapPolicy): readonly string[] => { return args } +/** + * Create a local runtime that starts commands inside bubblewrap on Linux. + * @param opts Bubblewrap policy and optional spawner or executable path. + * @returns Runtime adapter reporting the compatibility level `process`. + * @throws {SandboxError} When run on a non-Linux host without an injected spawner. + */ export const bwrapRuntime = (opts: BwrapRuntimeOpts): SandboxRuntime => { const policy: BwrapPolicy = { workspaceRoot: opts.policy.workspaceRoot, @@ -111,6 +137,9 @@ export const bwrapRuntime = (opts: BwrapRuntimeOpts): SandboxRuntime => { // --- docker ------------------------------------------------------------- +/** + * Container image, workspace mount, network, user, and additional safe runtime settings. + */ export type DockerPolicy = { readonly image: string readonly workspaceRoot: string @@ -132,6 +161,9 @@ export type DockerPolicy = { readonly capabilities?: readonly string[] } +/** + * Docker policy, optional spawner, and optional executable path. + */ export type DockerRuntimeOpts = { readonly policy: DockerPolicy readonly spawner?: Spawner @@ -237,6 +269,12 @@ export const assertSafeDockerCapability = (cap: string): void => { } } +/** + * Build hardened `docker run` arguments from a container policy. + * @param policy Image, workspace, network, user, and allowed runtime settings. + * @returns Argument vector for `docker run`. + * @throws {SandboxError} When policy includes an unsafe escape option. + */ export const renderDockerArgs = (policy: DockerPolicy): readonly string[] => { assertAbsolutePath(policy.workspaceRoot, 'workspaceRoot') if (typeof policy.image !== 'string' || policy.image.trim() === '') { @@ -280,6 +318,12 @@ export const renderDockerArgs = (policy: DockerPolicy): readonly string[] => { return args } +/** + * Create a local runtime that executes commands in a Docker container. + * @param opts Container policy and optional spawner or executable path. + * @returns Runtime adapter with container isolation. + * @throws {SandboxError} When the spawner cannot execute commands or options are invalid. + */ export const dockerRuntime = (opts: DockerRuntimeOpts): SandboxRuntime => { const policy: DockerPolicy = { image: opts.policy.image, diff --git a/packages/sandbox/src/e2b-backend.ts b/packages/sandbox/src/e2b-backend.ts index 0ae095ca8..19dcd5541 100644 --- a/packages/sandbox/src/e2b-backend.ts +++ b/packages/sandbox/src/e2b-backend.ts @@ -6,6 +6,9 @@ const DEFAULT_MAX_OUTPUT_BYTES = 1_048_576 /** Default VM lifetime when creating an E2B sandbox (5 minutes). */ const DEFAULT_VM_TIMEOUT_MS = 300_000 +/** + * API key and VM timeout, network, and output-capture settings for the E2B backend. + */ export interface E2BConfig { /** Non-empty E2B API key. */ apiKey: string diff --git a/packages/sandbox/src/local-registry.ts b/packages/sandbox/src/local-registry.ts index 14f39a9ec..8e7f7ce30 100644 --- a/packages/sandbox/src/local-registry.ts +++ b/packages/sandbox/src/local-registry.ts @@ -6,6 +6,9 @@ import { SandboxError } from '@agentskit/core' import { noneSandbox, processSandbox } from './local-runtimes' import type { SandboxLevel, SandboxRuntime } from './local-sandbox-types' +/** + * Registry that maps isolation levels to sandbox runtime adapters. + */ export class SandboxRegistry { private readonly map = new Map() @@ -47,9 +50,22 @@ export class SandboxRegistry { const STRONG_LEVELS: ReadonlySet = new Set(['container', 'vm', 'webcontainer']) const WEAK_LEVELS: ReadonlySet = new Set(['none', 'process']) +/** + * Check whether an isolation level provides a stronger OS boundary. + * @param level Isolation level to inspect. + * @returns `true` for container, VM, or WebContainer levels. + */ export const isStrongIsolation = (level: SandboxLevel): boolean => STRONG_LEVELS.has(level) +/** + * Check whether an isolation level lacks OS-level filesystem and network isolation. + * @param level Isolation level to inspect. + * @returns `true` for `none` or `process`. + */ export const isWeakIsolation = (level: SandboxLevel): boolean => WEAK_LEVELS.has(level) +/** + * Error raised when a caller requires strong isolation but only a weak level is active. + */ export class WeakSandboxError extends Error { readonly code = 'sandbox.weak_isolation' readonly active: SandboxLevel diff --git a/packages/sandbox/src/local-runtimes.ts b/packages/sandbox/src/local-runtimes.ts index 97a560c36..42926df7d 100644 --- a/packages/sandbox/src/local-runtimes.ts +++ b/packages/sandbox/src/local-runtimes.ts @@ -8,6 +8,9 @@ import type { SandboxRuntime, Spawner } from './local-sandbox-types' // --- none --------------------------------------------------------------- +/** + * Runtime placeholder for in-process compute; external command spawning is rejected. + */ export const noneSandbox: SandboxRuntime = { level: 'none', name: 'in-process', @@ -22,6 +25,9 @@ export const noneSandbox: SandboxRuntime = { // --- process ------------------------------------------------------------ +/** + * Optional spawner, default working directory, and filtered default environment for process execution. + */ export type ProcessRuntimeOptions = { readonly spawner?: Spawner readonly defaultEnv?: Readonly> @@ -38,8 +44,17 @@ const filterEnv = (env: Readonly>): Record [...ALLOWED_ENV_KEYS] +/** + * Create a child-process runtime with a restricted default environment. + * @param opts Optional spawner, working directory, and environment. + * @returns Runtime adapter for child-process execution. + */ export const processSandbox = (opts: ProcessRuntimeOptions = {}): SandboxRuntime => { // Snapshot caller-provided env so later mutations cannot widen the allowlist. const frozenEnv = opts.defaultEnv ? filterEnv({ ...opts.defaultEnv }) : {} @@ -100,12 +115,18 @@ export const processSandbox = (opts: ProcessRuntimeOptions = {}): SandboxRuntime // --- sandbox-exec (macOS seatbelt) -------------------------------------- +/** + * Workspace and network policy for the macOS sandbox-exec runtime. + */ export type SandboxExecPolicy = { readonly workspaceRoot: string readonly allowNetwork?: boolean readonly extraReadablePaths?: readonly string[] } +/** + * Sandbox-exec policy and optional spawner or executable path. + */ export type SandboxExecRuntimeOpts = { readonly policy: SandboxExecPolicy readonly spawner?: Spawner @@ -187,6 +208,12 @@ export const renderSandboxExecProfile = (policy: SandboxExecPolicy): string => { return lines.join('\n') } +/** + * Create a macOS sandbox-exec runtime limited to the workspace and configured readable paths. + * @param opts Seatbelt policy and optional spawner or executable path. + * @returns Runtime adapter for sandbox-exec. + * @throws {SandboxError} When paths are invalid or the runtime cannot start. + */ export const sandboxExecRuntime = (opts: SandboxExecRuntimeOpts): SandboxRuntime => { // Snapshot policy so caller mutations after create cannot widen the profile. const policy: SandboxExecPolicy = { diff --git a/packages/sandbox/src/local-sandbox-types.ts b/packages/sandbox/src/local-sandbox-types.ts index af6811047..8961ee824 100644 --- a/packages/sandbox/src/local-sandbox-types.ts +++ b/packages/sandbox/src/local-sandbox-types.ts @@ -6,7 +6,13 @@ // each level implements; `Spawner` abstracts `child_process` so tests inject // an in-memory double. +/** + * Supported isolation level names, ordered from least to stronger isolation. + */ export const SANDBOX_LEVELS = ['none', 'process', 'container', 'vm', 'webcontainer'] as const +/** + * Isolation level label used to select and describe a sandbox runtime. + */ export type SandboxLevel = (typeof SANDBOX_LEVELS)[number] /** Options for {@link SandboxRuntime.exec} — a command run to completion. */ @@ -32,6 +38,9 @@ export interface SandboxExecResult { readonly timedOut: boolean } +/** + * Adapter for a local runtime that can spawn, and optionally complete, commands. + */ export interface SandboxRuntime { readonly level: SandboxLevel readonly name: string @@ -47,11 +56,17 @@ export interface SandboxRuntime { exec?(opts: SandboxExecOptions): Promise } +/** + * Process identifier and asynchronous kill operation returned by a spawner. + */ export interface ChildHandle { readonly pid: number kill(): Promise } +/** + * Command, arguments, working directory, environment, timeout, and output cap for execution. + */ export interface SpawnerExecOptions { command: string args: readonly string[] @@ -63,6 +78,9 @@ export interface SpawnerExecOptions { maxOutputBytes?: number } +/** + * Exit code, captured streams, and truncation or timeout status from a spawner. + */ export interface SpawnerExecResult { exitCode: number stdout: string @@ -71,6 +89,9 @@ export interface SpawnerExecResult { timedOut: boolean } +/** + * Injected process launcher used by local sandbox runtimes and tests. + */ export interface Spawner { spawn(opts: { command: string diff --git a/packages/sandbox/src/policy.ts b/packages/sandbox/src/policy.ts index 857f12db9..30c7452cf 100644 --- a/packages/sandbox/src/policy.ts +++ b/packages/sandbox/src/policy.ts @@ -1,6 +1,9 @@ import { ErrorCodes, SandboxError } from '@agentskit/core' import type { ToolDefinition } from '@agentskit/core' +/** + * Tool allow, deny, sandbox-required, argument validation, and policy-event rules. + */ export interface SandboxPolicy { /** Tool names that MUST run inside a sandbox. Missing → allowed raw. */ requireSandbox?: string[] | '*' @@ -14,11 +17,17 @@ export interface SandboxPolicy { onPolicyEvent?: (event: PolicyEvent) => void } +/** + * Allow, deny, or sandbox-required decision emitted by the mandatory sandbox policy. + */ export type PolicyEvent = | { type: 'allow'; tool: string; reason: 'explicit-allow' | 'not-restricted' } | { type: 'deny'; tool: string; reason: 'denied' | 'not-in-allow-list' | 'validation-failed'; error?: string } | { type: 'sandbox-required'; tool: string } +/** + * Methods for wrapping tools with sandbox policy and checking policy decisions. + */ export interface MandatorySandboxWrapper { /** Returns the wrapped tool or throws if the policy forbids it entirely. */ wrap: (tool: ToolDefinition) => ToolDefinition diff --git a/packages/sandbox/src/sandbox.ts b/packages/sandbox/src/sandbox.ts index a3021b40c..a27155d13 100644 --- a/packages/sandbox/src/sandbox.ts +++ b/packages/sandbox/src/sandbox.ts @@ -4,6 +4,9 @@ import type { E2BConfig } from './e2b-backend' const SUPPORTED_LANGUAGES = new Set(['javascript', 'python'] as const) +/** + * Backend or E2B credentials and default language, timeout, network, and memory hint. + */ export interface SandboxConfig { apiKey?: string backend?: SandboxBackend @@ -20,6 +23,9 @@ export interface SandboxConfig { memoryLimit?: string } +/** + * Facade for executing code and disposing the configured backend. + */ export interface Sandbox { execute(code: string, options?: ExecuteOptions): Promise dispose(): Promise diff --git a/packages/sandbox/src/types.ts b/packages/sandbox/src/types.ts index ee5038bf6..cc98c4b4f 100644 --- a/packages/sandbox/src/types.ts +++ b/packages/sandbox/src/types.ts @@ -1,3 +1,6 @@ +/** + * Per-execution language, timeout, network, memory hint, and output limit. + */ export interface ExecuteOptions { language?: 'javascript' | 'python' timeout?: number @@ -16,6 +19,9 @@ export interface ExecuteOptions { maxOutputBytes?: number } +/** + * Captured stdout and stderr, process exit code, and execution duration. + */ export interface ExecuteResult { stdout: string stderr: string @@ -23,6 +29,9 @@ export interface ExecuteResult { durationMs: number } +/** + * Backend contract for executing code and optionally disposing backend resources. + */ export interface SandboxBackend { execute(code: string, options: ExecuteOptions): Promise dispose?(): Promise From 9abadb888ca89c05cd7529c1faa162318470286c Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:22:53 -0300 Subject: [PATCH 22/30] docs(rag): document public API --- .changeset/calm-docs-rag.md | 5 ++ docs/stability/jsdoc-coverage-v1.json | 90 +-------------------------- packages/rag/src/chunker.ts | 2 + packages/rag/src/errors.ts | 7 +-- packages/rag/src/loaders-node.ts | 5 ++ packages/rag/src/loaders/cloud.ts | 18 ++++++ packages/rag/src/loaders/documents.ts | 60 +++++++++++++++++- packages/rag/src/loaders/s3.ts | 7 +++ packages/rag/src/loaders/shared.ts | 1 + packages/rag/src/rag.ts | 10 +++ packages/rag/src/rerank.ts | 24 ++++++- packages/rag/src/rerankers/jina.ts | 4 ++ packages/rag/src/rerankers/voyage.ts | 4 ++ packages/rag/src/types.ts | 3 + 14 files changed, 143 insertions(+), 97 deletions(-) create mode 100644 .changeset/calm-docs-rag.md diff --git a/.changeset/calm-docs-rag.md b/.changeset/calm-docs-rag.md new file mode 100644 index 000000000..5f7ab95f9 --- /dev/null +++ b/.changeset/calm-docs-rag.md @@ -0,0 +1,5 @@ +--- +"@agentskit/rag": patch +--- + +Document the public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..250cc9175 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -437,54 +437,6 @@ ".::EvalSuite", ".::runEval", ".::RunEvalConfig", - "./braintrust::ALL_SCORERS", - "./braintrust::BraintrustRunOptions", - "./braintrust::citationCorrectness", - "./braintrust::detectRegressions", - "./braintrust::ExperimentResult", - "./braintrust::factualGrounding", - "./braintrust::fallbackResilience", - "./braintrust::formatAlertsMarkdown", - "./braintrust::hitlGateCorrectness", - "./braintrust::noCrashSurvival", - "./braintrust::qualityFamily", - "./braintrust::RegressionAlert", - "./braintrust::RegressionThresholds", - "./braintrust::robustnessFamily", - "./braintrust::runBraintrustEval", - "./braintrust::RunBraintrustEvalArgs", - "./braintrust::schemaSurvival", - "./braintrust::scoreCase", - "./braintrust::ScoredCase", - "./braintrust::Scorer", - "./braintrust::ScorerFamily", - "./braintrust::ScorerInput", - "./braintrust::ScorerResult", - "./braintrust::summarize", - "./braintrust::taskSuccess", - "./braintrust::toolArgValidity", - "./braintrust/ci::detectRegressions", - "./braintrust/ci::formatAlertsMarkdown", - "./braintrust/ci::RegressionAlert", - "./braintrust/ci::RegressionThresholds", - "./braintrust/scorers::ALL_SCORERS", - "./braintrust/scorers::citationCorrectness", - "./braintrust/scorers::CitationMeta", - "./braintrust/scorers::CrashMeta", - "./braintrust/scorers::factualGrounding", - "./braintrust/scorers::FactualGroundingMeta", - "./braintrust/scorers::FallbackMeta", - "./braintrust/scorers::fallbackResilience", - "./braintrust/scorers::hitlGateCorrectness", - "./braintrust/scorers::HitlMeta", - "./braintrust/scorers::noCrashSurvival", - "./braintrust/scorers::qualityFamily", - "./braintrust/scorers::robustnessFamily", - "./braintrust/scorers::schemaSurvival", - "./braintrust/scorers::SchemaValidityMeta", - "./braintrust/scorers::taskSuccess", - "./braintrust/scorers::toolArgValidity", - "./braintrust/scorers::ToolArgValidityInput", "./ci::CiReportOptions", "./ci::CiReportOutput", "./diff::Attribution", @@ -547,7 +499,6 @@ ".::ToolCallStatus", ".::ToolDefinition", ".::ToolExecutionContext", - ".::useChat", ".::UseStreamOptions", ".::UseStreamReturn" ], @@ -836,45 +787,7 @@ "./trace-tracker::TraceSpan", "./trace-tracker::TraceTrackerCallbacks" ], - "@agentskit/rag": [ - ".::BM25Options", - ".::ChunkOptions", - ".::chunkText", - ".::ConfluenceLoaderOptions", - ".::createRAG", - ".::DriveLoaderOptions", - ".::DropboxLoaderOptions", - ".::GcsLoaderOptions", - ".::GitHubLoaderOptions", - ".::GitHubTreeOptions", - ".::HybridRetrieverOptions", - ".::InputDocument", - ".::JinaRerankerOptions", - ".::loadConfluencePage", - ".::loadDropbox", - ".::loadGcs", - ".::loadGitHubFile", - ".::loadGitHubTree", - ".::loadGoogleDriveFile", - ".::loadNotionPage", - ".::loadOneDrive", - ".::loadS3", - ".::loadUrl", - ".::NotionLoaderOptions", - ".::OneDriveLoaderOptions", - ".::PdfLoaderOptions", - ".::RAG", - ".::RAGConfig", - ".::RagErrorCode", - ".::RerankedRetrieverOptions", - ".::RerankFn", - ".::S3LikeClient", - ".::S3LoaderOptions", - ".::UrlLoaderOptions", - ".::VoyageRerankerOptions", - "./chunker::ChunkOptions", - "./chunker::chunkText" - ], + "@agentskit/rag": [], "@agentskit/react": [ ".::AdapterContext", ".::AdapterFactory", @@ -1098,7 +1011,6 @@ "@agentskit/svelte": [ ".::ChatContainer", ".::CodeBlock", - ".::createChatStore", ".::InputBar", ".::Markdown", ".::Message", diff --git a/packages/rag/src/chunker.ts b/packages/rag/src/chunker.ts index 55622b7dd..d7897dafa 100644 --- a/packages/rag/src/chunker.ts +++ b/packages/rag/src/chunker.ts @@ -1,3 +1,4 @@ +/** Options for splitting text into chunks. */ export interface ChunkOptions { chunkSize: number chunkOverlap: number @@ -19,6 +20,7 @@ function resolveChunkOverlap(chunkOverlap: number, chunkSize: number): number { return Math.min(overlap, Math.max(0, chunkSize - 1)) } +/** Splits text into non-empty chunks using an optional custom splitter. */ export function chunkText(text: string, options: ChunkOptions): string[] { if (!text) return [] diff --git a/packages/rag/src/errors.ts b/packages/rag/src/errors.ts index 0c90e34d2..26f5176a5 100644 --- a/packages/rag/src/errors.ts +++ b/packages/rag/src/errors.ts @@ -2,8 +2,7 @@ import { AgentsKitError } from '@agentskit/core' const RAG_DOCS_URL = 'https://www.agentskit.io/docs/data/rag' -/** - * Error codes raised by `@agentskit/rag` loaders and rerankers. Kept local to +/** Stable error codes raised by RAG loaders and rerankers. Kept local to * the package (rather than in core's `ErrorCodes`) because they describe RAG * ingestion/rerank I/O, not a core contract surface. */ @@ -16,10 +15,10 @@ export const RagErrorCodes = { AK_RAG_RERANK_FAILED: 'AK_RAG_RERANK_FAILED', } as const +/** Union of the stable codes exposed through {@link RagErrorCodes}. */ export type RagErrorCode = (typeof RagErrorCodes)[keyof typeof RagErrorCodes] -/** - * Typed error for RAG loaders and rerankers. Extends the core +/** Typed error for RAG loaders and rerankers. Extends the core * `AgentsKitError` so callers can catch the whole AgentsKit family or narrow * on `error.code`. */ diff --git a/packages/rag/src/loaders-node.ts b/packages/rag/src/loaders-node.ts index 9bd158e85..83fd96749 100644 --- a/packages/rag/src/loaders-node.ts +++ b/packages/rag/src/loaders-node.ts @@ -27,6 +27,11 @@ async function loadS3Sdk(): Promise { return cachedS3Sdk } +/** Loads eligible objects from S3 using injected commands or the optional AWS SDK. + * @param options Bucket, client or commands, filtering, and loader limits. + * @returns Successfully loaded objects; fails if every eligible download fails. + * @throws {RagError} When listing fails or all eligible downloads fail. + */ export async function loadS3(options: S3LoaderOptions): Promise { const commands = options.commands ?? await loadS3Sdk() return loadS3Universal({ ...options, commands }) diff --git a/packages/rag/src/loaders/cloud.ts b/packages/rag/src/loaders/cloud.ts index 4b1964adc..955f10f7a 100644 --- a/packages/rag/src/loaders/cloud.ts +++ b/packages/rag/src/loaders/cloud.ts @@ -15,6 +15,7 @@ import { // GCS — Google Cloud Storage // --------------------------------------------------------------------------- +/** Options for loading objects from a Google Cloud Storage bucket. */ export interface GcsLoaderOptions extends LoaderOptions { bucket: string prefix?: string @@ -24,6 +25,11 @@ export interface GcsLoaderOptions extends LoaderOptions { maxFiles?: number } +/** Lists and loads eligible objects from a Google Cloud Storage bucket. + * @param options Bucket, credentials, filtering, and loader limits. + * @returns Successfully loaded objects; fails if every eligible download fails. + * @throws {RagError} When listing fails or all eligible downloads fail. + */ export async function loadGcs(options: GcsLoaderOptions): Promise { const fetchImpl = options.fetch ?? globalThis.fetch const docs: InputDocument[] = [] @@ -86,6 +92,7 @@ export async function loadGcs(options: GcsLoaderOptions): Promise { const fetchImpl = options.fetch ?? globalThis.fetch const docs: InputDocument[] = [] @@ -165,6 +177,7 @@ export async function loadDropbox(options: DropboxLoaderOptions): Promise string | Promise) @@ -176,6 +189,11 @@ export interface OneDriveLoaderOptions extends LoaderOptions { maxFiles?: number } +/** Lists and loads eligible files from OneDrive, including nested folders. + * @param options Access token, folder, filtering, and loader limits. + * @returns Successfully loaded files; fails if every eligible download fails. + * @throws {RagError} When listing fails or all eligible downloads fail. + */ export async function loadOneDrive(options: OneDriveLoaderOptions): Promise { const fetchImpl = options.fetch ?? globalThis.fetch const docs: InputDocument[] = [] diff --git a/packages/rag/src/loaders/documents.ts b/packages/rag/src/loaders/documents.ts index a1de5dc15..e546ea9bf 100644 --- a/packages/rag/src/loaders/documents.ts +++ b/packages/rag/src/loaders/documents.ts @@ -13,6 +13,7 @@ import { rethrowIfAbort, } from './shared' +/** Options for fetching and converting a URL into a document. */ export interface UrlLoaderOptions extends LoaderOptions { headers?: Record /** Explicit egress allowlist for arbitrary URLs. Required for loadUrl. */ @@ -28,6 +29,18 @@ function assertAllowedUrl(url: string, options: UrlLoaderOptions): void { } } +/** Fetches a URL and returns its supported content as one or more documents. + * @param url URL to fetch. + * @param options Origin allowlist, fetch, timeout, and content-size limits. + * @returns Documents extracted from the response. + * @throws {RagError} When fetching, reading, or parsing the response fails. + * @example + * ```ts + * const [document] = await loadUrl('https://example.com/guide', { + * allowedOrigins: ['https://example.com'], + * }) + * ``` + */ export async function loadUrl(url: string, options: UrlLoaderOptions = {}): Promise { assertAllowedUrl(url, options) const fetchImpl = options.fetch ?? globalThis.fetch @@ -41,12 +54,21 @@ export async function loadUrl(url: string, options: UrlLoaderOptions = {}): Prom return [{ content, source: url, metadata: { url } }] } +/** Options for loading a file from a GitHub repository. */ export interface GitHubLoaderOptions extends LoaderOptions { token?: string /** Branch / tag / sha. Default 'HEAD'. */ ref?: string } +/** Loads one GitHub file as a document. + * @param owner Repository owner. + * @param repo Repository name. + * @param path Repository-relative file path. + * @param options GitHub credentials and loader limits. + * @returns The loaded file as a document. + * @throws {RagError} When the request or response parsing fails. + */ export async function loadGitHubFile( owner: string, repo: string, @@ -70,6 +92,7 @@ export async function loadGitHubFile( ] } +/** Options for loading eligible files from a GitHub repository tree. */ export interface GitHubTreeOptions extends GitHubLoaderOptions { /** Only include files matching this regex / test. */ filter?: (path: string) => boolean @@ -77,6 +100,13 @@ export interface GitHubTreeOptions extends GitHubLoaderOptions { maxFiles?: number } +/** Loads matching files from a GitHub repository tree. + * @param owner Repository owner. + * @param repo Repository name. + * @param options Repository, filtering, credentials, and loader limits. + * @returns Successfully loaded documents; fails if every eligible download fails. + * @throws {RagError} When listing fails or all eligible downloads fail. + */ export async function loadGitHubTree( owner: string, repo: string, @@ -121,6 +151,7 @@ export async function loadGitHubTree( return finishTreeLoad('loadGitHubTree', attempted, loaded, docs) } +/** Options for loading a Notion page and its child blocks. */ export interface NotionLoaderOptions extends LoaderOptions { token: string version?: string @@ -140,6 +171,12 @@ type NotionChildrenResponse = { next_cursor?: string | null } +/** Loads supported text blocks from a Notion page, following child pagination. + * @param pageId Notion page identifier. + * @param options Page identifier, credentials, and loader limits. + * @returns The page content as a document. + * @throws {RagError} When loading or pagination fails. + */ export async function loadNotionPage( pageId: string, options: NotionLoaderOptions, @@ -191,6 +228,7 @@ export async function loadNotionPage( return [{ content: text, source: `notion://${pageId}`, metadata: { pageId } }] } +/** Options for loading a Confluence page. */ export interface ConfluenceLoaderOptions extends LoaderOptions { baseUrl: string /** Basic auth token `` in base64, OR pass `authorization` header directly. */ @@ -198,6 +236,12 @@ export interface ConfluenceLoaderOptions extends LoaderOptions { authorization?: string } +/** Loads a Confluence page as a document. + * @param pageId Confluence page identifier. + * @param options Page identifier, credentials, and loader limits. + * @returns The page content as a document. + * @throws {RagError} When the request or response parsing fails. + */ export async function loadConfluencePage( pageId: string, options: ConfluenceLoaderOptions, @@ -221,10 +265,17 @@ export async function loadConfluencePage( return [{ content, source: `${options.baseUrl}/pages/${pageId}`, metadata: { pageId, title: data.title } }] } +/** Options for loading a Google Drive file. */ export interface DriveLoaderOptions extends LoaderOptions { accessToken: string } +/** Loads an exported Google Drive file as a document. + * @param fileId Google Drive file identifier. + * @param options File identifier, credentials, and loader limits. + * @returns The file content as a document. + * @throws {RagError} When the request or response parsing fails. + */ export async function loadGoogleDriveFile( fileId: string, options: DriveLoaderOptions, @@ -240,13 +291,16 @@ export async function loadGoogleDriveFile( return [{ content, source: `gdrive://${fileId}`, metadata: { fileId } }] } +/** Options for fetching and extracting text from a PDF. */ export interface PdfLoaderOptions extends LoaderOptions { parsePdf: (bytes: Uint8Array) => Promise<{ text: string; pages?: number }> | { text: string; pages?: number } } -/** - * PDF loader — parser is BYO so native deps stay out of the bundle. - * Fetch bytes at `url`, hand to `parsePdf`, wrap in `InputDocument`. +/** Fetches a PDF and extracts its text into a document. + * @param url URL of the PDF. + * @param options Fetch and loader limits. + * @returns The extracted PDF document. + * @throws {RagError} When fetching or parsing fails. */ export async function loadPdf(url: string, options: PdfLoaderOptions): Promise { const fetchImpl = options.fetch ?? globalThis.fetch diff --git a/packages/rag/src/loaders/s3.ts b/packages/rag/src/loaders/s3.ts index d9bd5e32b..5fb8978eb 100644 --- a/packages/rag/src/loaders/s3.ts +++ b/packages/rag/src/loaders/s3.ts @@ -12,6 +12,7 @@ import { withDeadline, } from './shared' +/** Minimal S3 client surface accepted by the S3 loader. */ export interface S3LikeClient { /** SDK-compatible send method; `abortSignal` is passed to SDK requests. */ send( @@ -26,6 +27,7 @@ type S3ObjectBody = { [Symbol.asyncIterator]?: () => AsyncIterator } +/** Options for listing and loading objects from an S3-compatible bucket. */ export interface S3LoaderOptions extends LoaderOptions { /** * AWS SDK v3 \`S3Client\`-shaped client. Bring your own to keep the bundle @@ -51,6 +53,11 @@ export interface S3LoaderOptions extends LoaderOptions { maxFiles?: number } +/** Lists and loads eligible objects from S3. + * @param options Bucket, client or commands, filtering, and loader limits. + * @returns Successfully loaded objects; fails if every eligible download fails. + * @throws {RagError} When listing fails or all eligible downloads fail. + */ export async function loadS3(options: S3LoaderOptions): Promise { if (!options.commands) { throw new RagError({ diff --git a/packages/rag/src/loaders/shared.ts b/packages/rag/src/loaders/shared.ts index 7a7944c31..1eaf8876b 100644 --- a/packages/rag/src/loaders/shared.ts +++ b/packages/rag/src/loaders/shared.ts @@ -20,6 +20,7 @@ type S3Body = { * Shared options for remote document loaders. * @throws {RagError} with `AK_RAG_LOAD_FAILED` when a request or response read fails. */ +/** Shared options for remote document loaders. */ export interface LoaderOptions { fetch?: typeof globalThis.fetch /** Optional abort signal forwarded to HTTP and SDK calls when supported. */ diff --git a/packages/rag/src/rag.ts b/packages/rag/src/rag.ts index 47016b8ce..40d7ca6c3 100644 --- a/packages/rag/src/rag.ts +++ b/packages/rag/src/rag.ts @@ -49,6 +49,16 @@ function projectSource(doc: RetrievedDocument): RetrievedDocument { return { ...doc, source: doc.metadata.source } } +/** Creates a retriever that chunks, embeds, stores, and searches documents. + * @param config Store, embedding function, and optional chunking and search settings. + * @returns A RAG retriever with an `ingest` method. + * @example + * ```ts + * const rag = createRAG({ store, embed }) + * await rag.ingest([{ id: 'guide', content: 'Install the package.' }]) + * const results = await rag.retrieve({ query: 'How do I install it?' }) + * ``` + */ export function createRAG(config: RAGConfig): RAG { const { embed, diff --git a/packages/rag/src/rerank.ts b/packages/rag/src/rerank.ts index 839adbf95..1d6c31b46 100644 --- a/packages/rag/src/rerank.ts +++ b/packages/rag/src/rerank.ts @@ -1,10 +1,15 @@ import type { RetrievedDocument, Retriever, RetrieverRequest } from '@agentskit/core' import { RagError, RagErrorCodes } from './errors' +/** Reranks retrieved documents for a query. + * @param input Query and candidate documents. + * @returns The documents ordered by relevance. + */ export type RerankFn = ( input: { query: string; documents: RetrievedDocument[] }, ) => Promise | RetrievedDocument[] +/** Options for wrapping a retriever with a reranking function. */ export interface RerankedRetrieverOptions { /** Pull N candidates from the base retriever before reranking. Default 20. */ candidatePool?: number @@ -110,6 +115,10 @@ function validateRerankOutput(value: unknown): RetrievedDocument[] { * 2. `rerank` re-scores them with a stronger signal (Cohere Rerank, * BGE cross-encoder, or BM25 for keyword-aware hybrid search) * 3. Top `topK` are returned + * @param base Retriever that supplies the candidate documents. + * @param options Reranker and candidate limits. + * @returns A retriever that returns reranked documents. + * @throws {RagError} When reranking returns invalid results or fails. */ export function createRerankedRetriever( base: Retriever, @@ -148,6 +157,7 @@ function tokenize(text: string): string[] { .filter(t => t.length > 0) } +/** Tuning parameters for BM25 lexical relevance scoring. */ export interface BM25Options { /** Term-frequency saturation (k1 ≥ 0). Default 1.5; invalid → default. */ k1?: number @@ -169,6 +179,10 @@ function resolveBm25B(value: number | undefined): number { * Score a set of documents against a query using classic BM25. * Returns new document objects with a finite `.score` field, sorted descending. * Input documents are never mutated. + * @param query Search query. + * @param documents Candidate documents. + * @param options Optional BM25 tuning parameters. + * @returns New documents with finite scores in descending order. */ export function bm25Score( query: string, @@ -214,13 +228,17 @@ export function bm25Score( return scored.sort((a, b) => (b.score ?? 0) - (a.score ?? 0)) } -/** `RerankFn` backed by `bm25Score`. */ +/** `RerankFn` backed by `bm25Score` with default tuning parameters. + * @param input Query and candidate documents. + * @returns New documents with finite BM25 scores in descending order. + */ export const bm25Rerank: RerankFn = ({ query, documents }) => bm25Score(query, documents) // --------------------------------------------------------------------------- // Hybrid search — merge a vector retriever with a keyword (BM25) pass // --------------------------------------------------------------------------- +/** Options for combining vector search with BM25 lexical ranking. */ export interface HybridRetrieverOptions { /** Relative weight of the vector score in the final ranking. Default 0.6. */ vectorWeight?: number @@ -264,6 +282,10 @@ function normalize(docs: RetrievedDocument[]): Map { * over the same candidate pool. Final score is a weighted sum of the * two min-max-normalized scores using a finite relative weight pair * that sums to 1 (both zero → 0.5/0.5). + * @param base Retriever that supplies vector search results. + * @param options Candidate pool and relative score weights. + * @returns A retriever with normalized hybrid scores. + * @throws {RagError} When candidate scores are invalid or retrieval fails. */ export function createHybridRetriever( base: Retriever, diff --git a/packages/rag/src/rerankers/jina.ts b/packages/rag/src/rerankers/jina.ts index 1e2a3ea21..d05d61a81 100644 --- a/packages/rag/src/rerankers/jina.ts +++ b/packages/rag/src/rerankers/jina.ts @@ -3,6 +3,7 @@ import type { RetrievedDocument } from '@agentskit/core' import type { RerankFn } from '../rerank' import { doFetch, readResponseJson, readResponseText } from '../loaders/shared' +/** Credentials and request settings for the Jina reranker. */ export interface JinaRerankerOptions { apiKey: string /** Default `jina-reranker-v2-base-multilingual`. */ @@ -30,6 +31,9 @@ function rerankFailed(message: string, cause?: unknown): RagError { /** * Jina AI cross-encoder reranker. Drop-in `RerankFn` for * `createRerankedRetriever`. + * @param options API key, model, and optional request settings. + * @returns A reranking function for retrieved documents. + * @throws {RagError} When the request fails or the response is invalid. */ export function jinaReranker(options: JinaRerankerOptions): RerankFn { const fetchImpl = options.fetch ?? globalThis.fetch diff --git a/packages/rag/src/rerankers/voyage.ts b/packages/rag/src/rerankers/voyage.ts index fe0bd9dfc..171c50482 100644 --- a/packages/rag/src/rerankers/voyage.ts +++ b/packages/rag/src/rerankers/voyage.ts @@ -3,6 +3,7 @@ import type { RetrievedDocument } from '@agentskit/core' import type { RerankFn } from '../rerank' import { doFetch, readResponseJson, readResponseText } from '../loaders/shared' +/** Credentials and request settings for the Voyage reranker. */ export interface VoyageRerankerOptions { apiKey: string /** Default `rerank-2`. Pass `rerank-2-lite` for cheaper / faster runs. */ @@ -31,6 +32,9 @@ function rerankFailed(message: string, cause?: unknown): RagError { /** * Voyage AI cross-encoder reranker. Drop-in `RerankFn` for * `createRerankedRetriever`. + * @param options API key, model, and optional request settings. + * @returns A reranking function for retrieved documents. + * @throws {RagError} When the request fails or the response is invalid. */ export function voyageReranker(options: VoyageRerankerOptions): RerankFn { const fetchImpl = options.fetch ?? globalThis.fetch diff --git a/packages/rag/src/types.ts b/packages/rag/src/types.ts index 0edee561f..a726973d8 100644 --- a/packages/rag/src/types.ts +++ b/packages/rag/src/types.ts @@ -6,6 +6,7 @@ import type { VectorMemory, } from '@agentskit/core' +/** A source document supplied to or returned from a RAG pipeline. */ export interface InputDocument { id?: string content: string @@ -13,6 +14,7 @@ export interface InputDocument { metadata?: Record } +/** Configuration for a store-backed retrieval-augmented generation pipeline. */ export interface RAGConfig { embed: EmbedFn store: VectorMemory @@ -23,6 +25,7 @@ export interface RAGConfig { threshold?: number } +/** A retriever that can ingest documents into its configured vector store. */ export interface RAG extends Retriever { ingest: (documents: InputDocument[]) => Promise retrieve: (request: RetrieverRequest) => Promise From 3abc93d23ea880014029713c503c64691a9bddd7 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:25:36 -0300 Subject: [PATCH 23/30] docs(runtime): shrink shared-context coverage baseline --- docs/stability/jsdoc-coverage-v1.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..5af77bfb2 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -936,7 +936,6 @@ ".::createDurableRunner", ".::createQuotaTracker", ".::createRuntime", - ".::createSharedContext", ".::createValidatorGuard", ".::createVoteHandler", ".::cronMatches", @@ -965,12 +964,10 @@ ".::QuotaSnapshot", ".::QuotaTracker", ".::QuotaTrackerOptions", - ".::ReadonlySharedContext", ".::RunFlowOptions", ".::RunOptions", ".::RunResult", ".::RuntimeConfig", - ".::SharedContext", ".::SpeculateInput", ".::SpeculateOutput", ".::SpeculatePicker", @@ -998,10 +995,7 @@ ".::WebhookHandler", ".::WebhookOptions", ".::WebhookRequest", - ".::WebhookResponse", - "./shared-context::createSharedContext", - "./shared-context::ReadonlySharedContext", - "./shared-context::SharedContext" + ".::WebhookResponse" ], "@agentskit/sandbox": [ ".::BwrapPolicy", From 0dd8935705edbc1538da1b938ed8767f6acc540a Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:23:11 -0300 Subject: [PATCH 24/30] docs(net): document public API --- .changeset/doc03-net.md | 5 +++++ docs/stability/jsdoc-coverage-v1.json | 16 +--------------- packages/net/src/address.ts | 18 ++++++++++++++++++ packages/net/src/body.ts | 13 +++++++++++++ packages/net/src/errors.ts | 8 ++++++++ packages/net/src/fetch.ts | 13 +++++++++++++ packages/net/src/retry.ts | 8 ++++++++ packages/net/src/sse.ts | 16 ++++++++++++++++ 8 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 .changeset/doc03-net.md diff --git a/.changeset/doc03-net.md b/.changeset/doc03-net.md new file mode 100644 index 000000000..6b19e8255 --- /dev/null +++ b/.changeset/doc03-net.md @@ -0,0 +1,5 @@ +--- +'@agentskit/net': patch +--- + +Document the public API. diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 50ca6d4df..8c5642bd1 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -730,21 +730,7 @@ "./web-storage::WebStorageMemoryMigration", "./web-storage::WebStorageMemoryOptions" ], - "@agentskit/net": [ - ".::AssertPublicUrlOptions", - ".::BackoffOptions", - ".::FetchWithRetryOptions", - ".::isRetryableStatus", - ".::LookupFn", - ".::NetError", - ".::NetErrorCode", - ".::NetErrorCodes", - ".::ParseSSEOptions", - ".::ReadBodyOptions", - ".::RetryContext", - ".::RetryOptions", - ".::SSEEvent" - ], + "@agentskit/net": [], "@agentskit/observability": [ ".::AdvancedCostGuardOptions", ".::AppendAuditInput", diff --git a/packages/net/src/address.ts b/packages/net/src/address.ts index 5e3c6fe4f..a2cda1e67 100644 --- a/packages/net/src/address.ts +++ b/packages/net/src/address.ts @@ -31,8 +31,14 @@ export function isPublicAddress(address: string): boolean { const BLOCKED_HOST_SUFFIXES = ['.localhost', '.local', '.internal', '.localdomain', '.home.arpa'] +/** Resolve a hostname to the IP addresses that should be checked for public access. + * + * @param hostname Hostname to resolve. + * @returns Resolved IP address strings. + */ export type LookupFn = (hostname: string) => Promise +/** Protocol, DNS lookup, and exact-host allowlist settings for {@link assertPublicUrl}. */ export interface AssertPublicUrlOptions { /** Allowed URL protocols. Default `http:` and `https:`. */ protocols?: readonly string[] @@ -59,6 +65,18 @@ function blocked(url: URL, reason: string): NetError { * (or resolves to) public addresses only. Returns the parsed URL and the * addresses checked. Resolve-then-fetch can still race a DNS rebinding; * pin the returned address when the transport allows it. + * + * @param input URL string or URL object to validate. + * @param options Protocol allowlist, optional resolver, and trusted host allowlist. + * @returns The parsed URL and all resolved addresses that were checked. + * @throws {NetError} With code AK_NET_INVALID_INPUT for malformed URLs. + * @throws {NetError} With code AK_NET_BLOCKED_ADDRESS for a disallowed protocol, local host, or non-public address. + * @example + * ```ts + * import { assertPublicUrl } from '@agentskit/net' + * + * const { url } = await assertPublicUrl('https://example.com') + * ``` */ export async function assertPublicUrl( input: string | URL, diff --git a/packages/net/src/body.ts b/packages/net/src/body.ts index e12988d8c..ff7d38a24 100644 --- a/packages/net/src/body.ts +++ b/packages/net/src/body.ts @@ -1,5 +1,6 @@ import { NetError, NetErrorCodes, invalidInput } from './errors' +/** Byte limit used when buffering a response body. */ export interface ReadBodyOptions { /** Refuse bodies larger than this many bytes. */ maxBytes: number @@ -17,6 +18,18 @@ function tooLarge(maxBytes: number, seen: string): NetError { * Read a response body into memory, failing fast when it is larger than * `maxBytes`: a declared `Content-Length` is checked first, then bytes are * counted while streaming and the stream is cancelled on overflow. + * + * @param response Response whose body should be buffered. + * @param options Maximum buffered byte count. + * @returns The body bytes. + * @throws {NetError} With code AK_NET_INVALID_INPUT when `maxBytes` is not a non-negative integer. + * @throws {NetError} With code AK_NET_BODY_TOO_LARGE when the body exceeds `maxBytes`. + * @example + * ```ts + * import { readText } from '@agentskit/net' + * + * const text = await readText(response, { maxBytes: 1_000_000 }) + * ``` */ export async function readBody(response: Response, options: ReadBodyOptions): Promise { const { maxBytes } = options diff --git a/packages/net/src/errors.ts b/packages/net/src/errors.ts index 01babee08..b95710a19 100644 --- a/packages/net/src/errors.ts +++ b/packages/net/src/errors.ts @@ -2,6 +2,7 @@ import { AgentsKitError } from '@agentskit/core' const DOCS_URL = 'https://www.agentskit.io/docs/reference/packages/net' +/** Stable error codes emitted by the HTTP, body, address, and SSE helpers. */ export const NetErrorCodes = { AK_NET_TIMEOUT: 'AK_NET_TIMEOUT', AK_NET_BODY_TOO_LARGE: 'AK_NET_BODY_TOO_LARGE', @@ -10,9 +11,16 @@ export const NetErrorCodes = { AK_NET_SSE_PARSE_FAILED: 'AK_NET_SSE_PARSE_FAILED', } as const +/** Union of the stable codes in {@link NetErrorCodes}. */ export type NetErrorCode = (typeof NetErrorCodes)[keyof typeof NetErrorCodes] +/** Error raised when a network helper rejects invalid input or an unsafe response. */ export class NetError extends AgentsKitError { + /** + * Create a network error with a stable code, message, and optional hint or cause. + * + * @param options Stable code, human-readable message, and optional hint or underlying cause. + */ constructor(options: { code: NetErrorCode; message: string; hint?: string; cause?: unknown }) { super({ docsUrl: DOCS_URL, ...options }) this.name = 'NetError' diff --git a/packages/net/src/fetch.ts b/packages/net/src/fetch.ts index 2691c5543..2f86fa214 100644 --- a/packages/net/src/fetch.ts +++ b/packages/net/src/fetch.ts @@ -4,6 +4,7 @@ import { timeoutSignal } from './timeout' const IDEMPOTENT_METHODS = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'] +/** Retry, timeout, and fetch implementation settings for {@link fetchWithRetry}. */ export interface FetchWithRetryOptions extends BackoffOptions { /** Retries after the first attempt. Default 3. */ retries?: number @@ -40,6 +41,18 @@ function isReplayableBody(body: BodyInit | null | undefined): boolean { * response is returned as-is (a non-2xx status is not an error); network * failures after the last attempt reject. Streaming request bodies are never * retried because they cannot be replayed. + * + * @param input URL, URL string, or request to send. + * @param init Standard fetch request options. + * @param options Retry, timeout, and fetch implementation settings. + * @returns The final response, including non-2xx responses. + * @throws {NetError} With code AK_NET_INVALID_INPUT when no fetch implementation is available. + * @example + * ```ts + * import { fetchWithRetry } from '@agentskit/net' + * + * const response = await fetchWithRetry('https://api.example.com/data') + * ``` */ export async function fetchWithRetry( input: string | URL | Request, diff --git a/packages/net/src/retry.ts b/packages/net/src/retry.ts index 61e5ab9b2..4371ba1c0 100644 --- a/packages/net/src/retry.ts +++ b/packages/net/src/retry.ts @@ -3,10 +3,16 @@ import { invalidInput, isAbortError } from './errors' /** Statuses that are safe to retry: the server did not (fully) handle the request. */ export const RETRYABLE_STATUSES: readonly number[] = [408, 425, 429, 500, 502, 503, 504] +/** Check whether an HTTP status is in {@link RETRYABLE_STATUSES}. + * + * @param status HTTP response status code. + * @returns Whether the status is configured as retryable. + */ export function isRetryableStatus(status: number): boolean { return RETRYABLE_STATUSES.includes(status) } +/** Options for the exponential delay used between retries. */ export interface BackoffOptions { /** Delay before the first retry. Default 250 ms. */ minDelayMs?: number @@ -40,12 +46,14 @@ export function parseRetryAfter(value: string | null | undefined, now: number = return Math.max(0, date - now) } +/** Context passed to each invocation of a retry callback. */ export interface RetryContext { /** 1-based attempt number that is about to run. */ attempt: number signal?: AbortSignal } +/** Retry count, delay, cancellation, and callback settings for {@link retry}. */ export interface RetryOptions extends BackoffOptions { /** Retries after the first attempt. Default 3. */ retries?: number diff --git a/packages/net/src/sse.ts b/packages/net/src/sse.ts index aab479f73..cec659183 100644 --- a/packages/net/src/sse.ts +++ b/packages/net/src/sse.ts @@ -1,8 +1,10 @@ import { createParser, type EventSourceMessage } from 'eventsource-parser' import { NetError, NetErrorCodes } from './errors' +/** Parsed Server-Sent Event fields emitted by {@link parseSSE}. */ export type SSEEvent = EventSourceMessage +/** Cancellation and event-size settings for {@link parseSSE}. */ export interface ParseSSEOptions { signal?: AbortSignal /** Cap for a single unfinished event, protecting against endless lines. Default 1 MiB. */ @@ -15,6 +17,20 @@ export interface ParseSSEOptions { * data joined with `\n`, CRLF/CR/LF line endings, comments and `retry:`. * An event cut off before its terminating blank line is dropped, as in * browsers' `EventSource`. + * + * @param stream Byte stream containing SSE text. + * @param options Optional abort signal and maximum buffered event size. + * @returns An async iterator of complete parsed events. + * @throws {NetError} With code AK_NET_SSE_PARSE_FAILED when parsing fails. + * @example + * ```ts + * import { parseSSE } from '@agentskit/net' + * + * const stream = new Response('data: ready\\n\\n').body! + * for await (const event of parseSSE(stream)) { + * console.log(event.data) + * } + * ``` */ export async function* parseSSE( stream: ReadableStream, From e64083f593fea1cda23bbcb672418eec30a23b96 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 15:39:57 -0300 Subject: [PATCH 25/30] chore(docs): regenerate JSDoc coverage baseline for combined DOC-03 docs --- docs/stability/jsdoc-coverage-v1.json | 616 +------------------------- 1 file changed, 9 insertions(+), 607 deletions(-) diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 7143dc86b..66255b27b 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -1,356 +1,10 @@ { "schemaVersion": 1, "packages": { - "@agentskit/adapters": [ - ".::anthropic", - ".::AnthropicConfig", - ".::ApplyCarbonOptions", - ".::azureOpenAI", - ".::azureOpenAIAdapter", - ".::AzureOpenAIConfig", - ".::bailAdapter", - ".::BailConfig", - ".::bedrock", - ".::bedrockAdapter", - ".::BedrockConfig", - ".::CarbonTable", - ".::cerebrasAdapter", - ".::CerebrasConfig", - ".::CohereConfig", - ".::createAdapter", - ".::createOpenAICompatibleEmbedder", - ".::createRotatingCredentials", - ".::CredentialRefreshable", - ".::DataRegion", - ".::deepseek", - ".::DeepSeekConfig", - ".::deepseekEmbedder", - ".::DeepSeekEmbedderConfig", - ".::DeprecationPolicy", - ".::EnsembleAggregator", - ".::EnsembleBranchResult", - ".::EnsembleCandidate", - ".::EnsembleOptions", - ".::FallbackCandidate", - ".::FallbackOptions", - ".::FireworksConfig", - ".::gemini", - ".::GeminiConfig", - ".::geminiEmbedder", - ".::GeminiEmbedderConfig", - ".::generic", - ".::GenericAdapterConfig", - ".::grok", - ".::GrokConfig", - ".::grokEmbedder", - ".::GrokEmbedderConfig", - ".::GroqConfig", - ".::HuggingFaceConfig", - ".::kimi", - ".::KimiConfig", - ".::kimiEmbedder", - ".::KimiEmbedderConfig", - ".::langchain", - ".::LangChainConfig", - ".::langgraph", - ".::LangGraphConfig", - ".::LlamaCppConfig", - ".::LMStudioConfig", - ".::MistralConfig", - ".::MockAdapterOptions", - ".::MockResponse", - ".::ModelDeprecation", - ".::ollama", - ".::OllamaConfig", - ".::ollamaEmbedder", - ".::OllamaEmbedderConfig", - ".::openai", - ".::OpenAICompatibleEmbedderConfig", - ".::OpenAIConfig", - ".::openaiEmbedder", - ".::OpenAIEmbedderConfig", - ".::OpenRouterConfig", - ".::RecordedTurn", - ".::RecordingFixture", - ".::RecordingSink", - ".::replicate", - ".::replicateAdapter", - ".::ReplicateConfig", - ".::resolveModel", - ".::ResolveModelInput", - ".::ResolveModelResult", - ".::RotatingCredentials", - ".::RouterCandidate", - ".::RouterOptions", - ".::RouterPolicy", - ".::TogetherConfig", - ".::vercelAI", - ".::VercelAIConfig", - ".::vertex", - ".::vertexAdapter", - ".::VertexConfig", - ".::VLLMConfig", - ".::webllm", - ".::webllmAdapter", - ".::WebLlmEngineLike", - "./createAdapter::createAdapter" - ], + "@agentskit/adapters": [], "@agentskit/angular": [], - "@agentskit/cli": [ - ".::AgentsKitConfig", - ".::BuildRagOptions", - ".::ChatApp", - ".::ChatCommandOptions", - ".::ChatProviderOptions", - ".::CheckResult", - ".::CheckStatus", - ".::ComputedCost", - ".::ConfigHookEntry", - ".::ConfigHooksMap", - ".::createCli", - ".::defaultPolicy", - ".::DevOptions", - ".::DevWatcher", - ".::disposeMcpClients", - ".::DoctorOptions", - ".::DoctorReport", - ".::findLatestSession", - ".::findSession", - ".::getPricing", - ".::HookDispatchResult", - ".::HookEvent", - ".::HookHandler", - ".::HookPayload", - ".::HookResult", - ".::IndexResult", - ".::InitCommandOptions", - ".::listSessions", - ".::LoadConfigOptions", - ".::LoadPluginsOptions", - ".::McpBridgeResult", - ".::McpServerSpec", - ".::McpTool", - ".::OpenAiEmbedderConfig", - ".::PermissionAction", - ".::PermissionMode", - ".::PermissionPolicy", - ".::PermissionRule", - ".::PluginContext", - ".::ProviderFactory", - ".::RagConfig", - ".::registerPricing", - ".::renderChatHeader", - ".::renderReport", - ".::resolveChatProvider", - ".::ResolvedChatProvider", - ".::ResolvedSession", - ".::ResolveSessionInput", - ".::runAgent", - ".::RunCommandOptions", - ".::runDoctor", - ".::sessionFilePath", - ".::SessionMetadata", - ".::SessionRecord", - ".::startDev", - ".::StarterKind", - ".::TokenUsageLike", - ".::TunnelController", - ".::TunnelLike", - ".::TunnelOptions", - ".::writeSessionMeta", - ".::writeStarterProject" - ], - "@agentskit/core": [ - ".::activateSkills", - ".::ActivateSkillsResult", - ".::AdapterContext", - ".::AdapterError", - ".::AdapterFactory", - ".::AdapterRequest", - ".::AgentEvent", - ".::AgentsKitError", - ".::ArgsValidationError", - ".::ArgsValidationResult", - ".::audioPart", - ".::AudioPart", - ".::BudgetStrategy", - ".::buildMessage", - ".::buildToolMap", - ".::ChatConfig", - ".::ChatController", - ".::ChatMemory", - ".::ChatReturn", - ".::ChatState", - ".::CompileBudgetInput", - ".::CompileBudgetResult", - ".::ConfigError", - ".::consumeStream", - ".::ConsumeStreamHandlers", - ".::ContentPart", - ".::createChatController", - ".::createEventEmitter", - ".::createInMemoryMemory", - ".::createLocalStorageMemory", - ".::createStaticRetriever", - ".::createToolLifecycle", - ".::DataRegion", - ".::deserializeMessages", - ".::EditOptions", - ".::EmbedFn", - ".::ErrorCodes", - ".::EvalResult", - ".::EvalSuite", - ".::EvalTestCase", - ".::executeSafeTool", - ".::ExecuteSafeToolOptions", - ".::executeToolCall", - ".::filePart", - ".::FilePart", - ".::formatRetrievedDocuments", - ".::ImagePart", - ".::MaybePromise", - ".::MemoryError", - ".::MemoryRecord", - ".::Message", - ".::MessageRole", - ".::MessageStatus", - ".::Observer", - ".::ParsedToolArgs", - ".::parseToolArgs", - ".::PartKind", - ".::ProgressiveArgParser", - ".::ProgressiveExecOptions", - ".::ProgressiveExecResult", - ".::ProgressiveFieldEvent", - ".::RetrievedDocument", - ".::Retriever", - ".::RetrieverRequest", - ".::RuntimeError", - ".::SandboxError", - ".::serializeMessages", - ".::SkillDefinition", - ".::SkillError", - ".::StreamChunk", - ".::StreamSource", - ".::StreamStatus", - ".::StreamToolCallPayload", - ".::TokenUsage", - ".::ToolAuthorizationContext", - ".::ToolAuthorizationDecision", - ".::ToolAuthorizationPhase", - ".::ToolAuthorizer", - ".::ToolCall", - ".::ToolCallHandlerContext", - ".::ToolCallStatus", - ".::ToolDefinition", - ".::ToolError", - ".::ToolExecResult", - ".::ToolExecutionContext", - ".::UseStreamOptions", - ".::UseStreamReturn", - ".::VectorDocument", - ".::VectorFilter", - ".::VectorFilterCompound", - ".::VectorFilterOperator", - ".::VectorFilterPredicate", - ".::VectorMemory", - ".::VectorSearchOptions", - ".::videoPart", - ".::VideoPart", - ".::VirtualizedMemoryOptions", - "./a2a::A2AAgentCard", - "./a2a::A2AApproveParams", - "./a2a::A2ACancelParams", - "./a2a::A2AInvokeParams", - "./a2a::A2AInvokeResult", - "./a2a::A2AMethod", - "./a2a::A2ASkillDescriptor", - "./a2a::A2ATaskStatusNotification", - "./a2a::validateAgentCard", - "./agent-schema::AgentSchema", - "./agent-schema::AgentSchemaMemory", - "./agent-schema::AgentSchemaModel", - "./agent-schema::AgentSchemaTool", - "./agent-schema::ParseAgentSchemaOptions", - "./auto-summarize::AutoSummarizeOptions", - "./compose-tool::ComposeToolOptions", - "./eval-format::EvalCase", - "./eval-format::EvalCaseExpectation", - "./eval-format::EvalRunResult", - "./eval-format::EvalSuiteDoc", - "./eval-format::validateEvalRunResult", - "./eval-format::validateEvalSuite", - "./finding::Finding", - "./fuzzy-match::FuzzyMatch", - "./generative-ui::Artifact", - "./generative-ui::ArtifactChart", - "./generative-ui::ArtifactCode", - "./generative-ui::ArtifactHtml", - "./generative-ui::ArtifactMarkdown", - "./generative-ui::DetectedArtifact", - "./generative-ui::UIElement", - "./generative-ui::UIElementArtifact", - "./generative-ui::UIElementButton", - "./generative-ui::UIElementCard", - "./generative-ui::UIElementHeading", - "./generative-ui::UIElementImage", - "./generative-ui::UIElementList", - "./generative-ui::UIElementStack", - "./generative-ui::UIMessage", - "./generative-ui::validateArtifact", - "./generative-ui::validateElement", - "./generative-ui::validateUIMessage", - "./hitl::Approval", - "./hitl::ApprovalGate", - "./hitl::ApprovalStore", - "./hitl::RequestApprovalInput", - "./manifest::Manifest", - "./manifest::ManifestSkill", - "./manifest::ManifestTool", - "./manifest::validateManifest", - "./memory-validation::validateMemoryRecord", - "./prompt-experiments::PromptDecision", - "./prompt-experiments::PromptExperiment", - "./prompt-experiments::PromptExperimentContext", - "./prompt-experiments::PromptResolver", - "./prompt-experiments::PromptVariant", - "./security::createOidcVerifier", - "./security::createSamlVerifier", - "./security::FenceOptions", - "./security::InjectionDetector", - "./security::InjectionDetectorOptions", - "./security::InjectionHeuristic", - "./security::InjectionVerdict", - "./security::OidcClaims", - "./security::OidcVerifier", - "./security::PIIRedactionHit", - "./security::PIIRedactionMatch", - "./security::PIIRedactionResult", - "./security::PIIRedactor", - "./security::PIIRule", - "./security::PIITaxonomy", - "./security::RateLimitBucket", - "./security::RateLimitDecision", - "./security::RateLimiter", - "./security::RateLimiterOptions", - "./security::RedactionAuditEvent", - "./security::RedactionAuditSink", - "./security::RedactionVault", - "./security::RevealOptions", - "./security::SamlAssertion", - "./security::SamlAttribute", - "./security::SamlVerifier", - "./security::SamlVerifierOptions", - "./security::TaxonomyValidationIssue", - "./security::TaxonomyValidationResult", - "./security::TokenizeOptions", - "./security::VaultEntry", - "./self-debug::SelfDebugger", - "./self-debug::SelfDebugInput", - "./self-debug::SelfDebugOptions", - "./self-debug::SelfDebugResult", - "./tool-proposal::proposeToolCall" - ], + "@agentskit/cli": [], + "@agentskit/core": [], "@agentskit/cross-platform": [ ".::basename", ".::CliIo", @@ -390,92 +44,8 @@ "./pure::RuntimeInfo", "./pure::SplitLinesOptions" ], - "@agentskit/eval": [ - ".::EvalResult", - ".::EvalSuite", - "./braintrust::ALL_SCORERS", - "./braintrust::BraintrustRunOptions", - "./braintrust::citationCorrectness", - "./braintrust::detectRegressions", - "./braintrust::ExperimentResult", - "./braintrust::factualGrounding", - "./braintrust::fallbackResilience", - "./braintrust::formatAlertsMarkdown", - "./braintrust::hitlGateCorrectness", - "./braintrust::noCrashSurvival", - "./braintrust::qualityFamily", - "./braintrust::RegressionAlert", - "./braintrust::RegressionThresholds", - "./braintrust::robustnessFamily", - "./braintrust::runBraintrustEval", - "./braintrust::RunBraintrustEvalArgs", - "./braintrust::schemaSurvival", - "./braintrust::scoreCase", - "./braintrust::ScoredCase", - "./braintrust::Scorer", - "./braintrust::ScorerFamily", - "./braintrust::ScorerInput", - "./braintrust::ScorerResult", - "./braintrust::summarize", - "./braintrust::taskSuccess", - "./braintrust::toolArgValidity", - "./braintrust/ci::detectRegressions", - "./braintrust/ci::formatAlertsMarkdown", - "./braintrust/ci::RegressionAlert", - "./braintrust/ci::RegressionThresholds", - "./braintrust/scorers::ALL_SCORERS", - "./braintrust/scorers::citationCorrectness", - "./braintrust/scorers::CitationMeta", - "./braintrust/scorers::CrashMeta", - "./braintrust/scorers::factualGrounding", - "./braintrust/scorers::FactualGroundingMeta", - "./braintrust/scorers::FallbackMeta", - "./braintrust/scorers::fallbackResilience", - "./braintrust/scorers::hitlGateCorrectness", - "./braintrust/scorers::HitlMeta", - "./braintrust/scorers::noCrashSurvival", - "./braintrust/scorers::qualityFamily", - "./braintrust/scorers::robustnessFamily", - "./braintrust/scorers::schemaSurvival", - "./braintrust/scorers::SchemaValidityMeta", - "./braintrust/scorers::taskSuccess", - "./braintrust/scorers::toolArgValidity", - "./braintrust/scorers::ToolArgValidityInput" - ], - "@agentskit/ink": [ - ".::AdapterContext", - ".::AdapterFactory", - ".::AdapterRequest", - ".::ChatConfig", - ".::ChatController", - ".::ChatMemory", - ".::ChatReturn", - ".::ChatState", - ".::createChatController", - ".::createInMemoryMemory", - ".::createLocalStorageMemory", - ".::createStaticRetriever", - ".::formatRetrievedDocuments", - ".::MaybePromise", - ".::MemoryRecord", - ".::MessageRole", - ".::MessageStatus", - ".::MessageType", - ".::RetrievedDocument", - ".::Retriever", - ".::RetrieverRequest", - ".::StreamChunk", - ".::StreamSource", - ".::StreamStatus", - ".::StreamToolCallPayload", - ".::ToolCall", - ".::ToolCallHandlerContext", - ".::ToolCallStatus", - ".::ToolDefinition", - ".::ToolExecutionContext", - ".::UseStreamOptions", - ".::UseStreamReturn" - ], + "@agentskit/eval": [], + "@agentskit/ink": [], "@agentskit/integrations": [ ".::acuityIntegration", ".::airtableIntegration", @@ -747,167 +317,10 @@ "./trace-tracker::TraceSpan", "./trace-tracker::TraceTrackerCallbacks" ], - "@agentskit/rag": [ - ".::BM25Options", - ".::ChunkOptions", - ".::chunkText", - ".::ConfluenceLoaderOptions", - ".::createRAG", - ".::DriveLoaderOptions", - ".::DropboxLoaderOptions", - ".::GcsLoaderOptions", - ".::GitHubLoaderOptions", - ".::GitHubTreeOptions", - ".::HybridRetrieverOptions", - ".::InputDocument", - ".::JinaRerankerOptions", - ".::loadConfluencePage", - ".::loadDropbox", - ".::loadGcs", - ".::loadGitHubFile", - ".::loadGitHubTree", - ".::loadGoogleDriveFile", - ".::loadNotionPage", - ".::loadOneDrive", - ".::loadS3", - ".::loadUrl", - ".::NotionLoaderOptions", - ".::OneDriveLoaderOptions", - ".::PdfLoaderOptions", - ".::RAG", - ".::RAGConfig", - ".::RagErrorCode", - ".::RerankedRetrieverOptions", - ".::RerankFn", - ".::S3LikeClient", - ".::S3LoaderOptions", - ".::UrlLoaderOptions", - ".::VoyageRerankerOptions", - "./chunker::ChunkOptions", - "./chunker::chunkText" - ], - "@agentskit/react": [ - ".::AdapterContext", - ".::AdapterFactory", - ".::AdapterRequest", - ".::ChatConfig", - ".::ChatController", - ".::ChatMemory", - ".::ChatReturn", - ".::ChatState", - ".::createChatController", - ".::createInMemoryMemory", - ".::createLocalStorageMemory", - ".::createStaticRetriever", - ".::formatRetrievedDocuments", - ".::MaybePromise", - ".::MemoryRecord", - ".::MessageRole", - ".::MessageStatus", - ".::MessageType", - ".::RetrievedDocument", - ".::Retriever", - ".::RetrieverRequest", - ".::StreamChunk", - ".::StreamSource", - ".::StreamStatus", - ".::StreamToolCallPayload", - ".::ToolCall", - ".::ToolCallHandlerContext", - ".::ToolCallStatus", - ".::ToolDefinition", - ".::ToolExecutionContext", - ".::UseStreamOptions", - ".::UseStreamReturn" - ], + "@agentskit/rag": [], + "@agentskit/react": [], "@agentskit/react-native": [], - "@agentskit/runtime": [ - ".::AuctionConfig", - ".::AuctionHandlerOptions", - ".::AuctionScorerFn", - ".::blackboard", - ".::BlackboardConfig", - ".::ChatSurfaceEvent", - ".::ChatSurfaceEventType", - ".::ChatTrigger", - ".::ChatTriggerObserverEvent", - ".::ChatTriggerOptions", - ".::CompareConfig", - ".::CompareEvalFn", - ".::CompareHandlerOptions", - ".::CompareJudgeFn", - ".::CompareSelection", - ".::CompiledFlow", - ".::compileFlow", - ".::CompileFlowOptions", - ".::createAuctionHandler", - ".::createCompareHandler", - ".::createCronScheduler", - ".::createDebateHandler", - ".::createDurableRunner", - ".::createQuotaTracker", - ".::createRuntime", - ".::createValidatorGuard", - ".::createVoteHandler", - ".::cronMatches", - ".::CronScheduler", - ".::CronSchedulerOptions", - ".::DebateConfig", - ".::DebateHandlerOptions", - ".::DelegateConfig", - ".::DurableEvent", - ".::DurableRunner", - ".::DurableRunnerOptions", - ".::FlowDefinition", - ".::FlowHandler", - ".::FlowHandlerContext", - ".::FlowRegistry", - ".::FlowRunEvent", - ".::FlowValidationIssue", - ".::FlowValidationResult", - ".::hierarchical", - ".::HierarchicalConfig", - ".::HierarchicalNode", - ".::InMemoryScratchpadStore", - ".::parseSchedule", - ".::QuotaExceededEvent", - ".::QuotaMap", - ".::QuotaSnapshot", - ".::QuotaTracker", - ".::QuotaTrackerOptions", - ".::RunFlowOptions", - ".::RunOptions", - ".::RunResult", - ".::RuntimeConfig", - ".::SpeculateInput", - ".::SpeculateOutput", - ".::SpeculatePicker", - ".::SpeculativeCandidate", - ".::SpeculativeResult", - ".::StepLogStore", - ".::supervisor", - ".::SupervisorConfig", - ".::SwarmConfig", - ".::TopologyLogEvent", - ".::TopologyObserver", - ".::validateFlow", - ".::Validator", - ".::ValidatorAuditEvent", - ".::ValidatorCheckContext", - ".::ValidatorGuard", - ".::ValidatorGuardOptions", - ".::ValidatorGuardRun", - ".::ValidatorGuardRunOptions", - ".::ValidatorResult", - ".::VoteBallot", - ".::VoteConfig", - ".::VoteHandlerOptions", - ".::VoteJudgeFn", - ".::WebhookHandler", - ".::WebhookOptions", - ".::WebhookRequest", - ".::WebhookResponse" - ], + "@agentskit/runtime": [], "@agentskit/sandbox": [], "@agentskit/skills": [ ".::clinicalNoteSummarizer", @@ -941,18 +354,7 @@ "@agentskit/solid": [], "@agentskit/statechart": [], "@agentskit/svelte": [], - "@agentskit/templates": [ - ".::AdapterTemplateConfig", - ".::createAdapterTemplate", - ".::createSkillTemplate", - ".::createToolTemplate", - ".::ScaffoldType", - ".::SkillTemplateConfig", - ".::ToolTemplateConfig", - ".::validateAdapterTemplate", - ".::validateSkillTemplate", - ".::validateToolTemplate" - ], + "@agentskit/templates": [], "@agentskit/tools": [ ".::DefineZodToolConfig", ".::FetchUrlConfig", From e6aa929d98484b58a53c87f4fc43a512d5af4150 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 16:06:16 -0300 Subject: [PATCH 26/30] docs(svelte): drop index re-export comments duplicated from useChat --- packages/svelte/src/index.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/packages/svelte/src/index.ts b/packages/svelte/src/index.ts index 7d5df340c..faad9766f 100644 --- a/packages/svelte/src/index.ts +++ b/packages/svelte/src/index.ts @@ -1,18 +1,5 @@ -/** - * Create a readable Svelte chat store with the core controller's actions. - * @param config The chat controller configuration. - * @returns A state store with chat actions and a `destroy()` cleanup method. - * @example - * ```ts - * import { onDestroy } from 'svelte' - * import { createChatStore } from '@agentskit/svelte' - * const chat = createChatStore(config) - * onDestroy(chat.destroy) - * ``` - */ export { createChatStore } from './useChat' -/** A readable chat state store with controller actions and cleanup. */ export type { SvelteChatStore } from './useChat' /** A scrollable chat region that follows changes to its rendered content. */ From cff0794c4c52dfecdf1e176006ddffb8627f73a0 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 16:07:32 -0300 Subject: [PATCH 27/30] docs(integrations): document public API --- .changeset/bright-docs-integrations.md | 5 ++++ packages/integrations/src/contract.ts | 11 ++++++++ packages/integrations/src/http.ts | 4 +++ packages/integrations/src/registry.ts | 25 +++++++++++++++++++ .../integrations/src/services/acuity/index.ts | 1 + .../src/services/airtable/index.ts | 1 + .../integrations/src/services/apollo/index.ts | 1 + .../integrations/src/services/asana/index.ts | 1 + .../src/services/assemblyai/index.ts | 1 + .../integrations/src/services/attio/index.ts | 1 + .../src/services/azure-openai/index.ts | 1 + .../src/services/baserow/index.ts | 1 + .../src/services/bigcommerce/index.ts | 1 + .../integrations/src/services/box/index.ts | 1 + .../src/services/cal-com/index.ts | 1 + .../src/services/calendly/index.ts | 1 + .../src/services/coingecko/index.ts | 1 + .../src/services/confluence/index.ts | 1 + .../src/services/deepgram/index.ts | 1 + .../src/services/discord/index.ts | 1 + .../src/services/dropbox/index.ts | 1 + .../src/services/elevenlabs/index.ts | 1 + .../integrations/src/services/email/index.ts | 1 + .../integrations/src/services/email/types.ts | 8 ++++++ .../integrations/src/services/figma/index.ts | 1 + .../src/services/firecrawl/index.ts | 1 + .../src/services/github-actions/index.ts | 1 + .../integrations/src/services/github/index.ts | 1 + .../integrations/src/services/gmail/index.ts | 1 + .../src/services/google-calendar/index.ts | 1 + .../src/services/google-drive/index.ts | 1 + .../src/services/hubspot/index.ts | 1 + .../src/services/intercom/index.ts | 1 + .../integrations/src/services/jira/index.ts | 1 + .../src/services/linear-triage/index.ts | 1 + .../integrations/src/services/linear/index.ts | 1 + .../src/services/mailchimp/index.ts | 1 + .../integrations/src/services/maps/index.ts | 1 + .../integrations/src/services/notion/index.ts | 1 + .../src/services/openai-images/index.ts | 1 + .../src/services/pagerduty/index.ts | 1 + .../src/services/pipedrive/index.ts | 1 + .../integrations/src/services/reader/index.ts | 1 + .../src/services/salesforce/index.ts | 1 + .../src/services/sendgrid/index.ts | 1 + .../integrations/src/services/sentry/index.ts | 1 + .../src/services/shopify/index.ts | 1 + .../integrations/src/services/slack/index.ts | 1 + .../integrations/src/services/stripe/index.ts | 1 + .../integrations/src/services/teams/cards.ts | 6 +++++ .../integrations/src/services/teams/index.ts | 1 + .../src/services/telegram/index.ts | 1 + .../integrations/src/services/twilio/index.ts | 1 + .../src/services/weather/index.ts | 1 + .../src/services/whatsapp/index.ts | 1 + .../src/services/whisper/index.ts | 1 + packages/integrations/src/testing/validate.ts | 10 ++++++++ 57 files changed, 119 insertions(+) create mode 100644 .changeset/bright-docs-integrations.md diff --git a/.changeset/bright-docs-integrations.md b/.changeset/bright-docs-integrations.md new file mode 100644 index 000000000..49a927239 --- /dev/null +++ b/.changeset/bright-docs-integrations.md @@ -0,0 +1,5 @@ +--- +"@agentskit/integrations": patch +--- + +Document the public API. diff --git a/packages/integrations/src/contract.ts b/packages/integrations/src/contract.ts index c993c8f74..3ed10feaa 100644 --- a/packages/integrations/src/contract.ts +++ b/packages/integrations/src/contract.ts @@ -6,6 +6,7 @@ import type { IntegrationHttp } from './http' // Side effects — lets a host enforce an autonomy/approval gate per action. // --------------------------------------------------------------------------- +/** Declared blast radius of an integration action. */ export type SideEffect = 'none' | 'read' | 'write' | 'destructive' | 'external' // --------------------------------------------------------------------------- @@ -27,10 +28,12 @@ export interface OAuth2ProviderSpec { extraAuthParams?: Record } +/** OAuth2 authorization configuration for a service integration. */ export interface OAuth2AuthSpec extends OAuth2ProviderSpec { kind: 'oauth2' } +/** Header-based API key authentication configuration. */ export interface ApiKeyAuthSpec { kind: 'apiKey' /** Header the credential is sent in (e.g. `authorization`). */ @@ -41,16 +44,19 @@ export interface ApiKeyAuthSpec { envHint?: string } +/** Authentication configuration for verifying inbound webhook signatures. */ export interface WebhookSecretAuthSpec { kind: 'webhookSecret' /** Signature scheme used to verify inbound webhooks. */ scheme: 'hmac-sha256' | 'ed25519' | 'custom' } +/** Authentication marker for integrations that require no credentials. */ export interface NoAuthSpec { kind: 'none' } +/** Supported declarative authentication configurations for integrations. */ export type AuthSpec = | OAuth2AuthSpec | ApiKeyAuthSpec @@ -86,6 +92,7 @@ export interface IntegrationActionContext { config: unknown } +/** An executable provider operation that can be projected into a tool. */ export interface IntegrationAction { /** Stable, namespaced id, e.g. `slack_post_message`. */ name: string @@ -107,6 +114,7 @@ export interface IntegrationAction { // canonical normalized event a host trigger layer can consume. // --------------------------------------------------------------------------- +/** Request data supplied to a trigger's webhook verifier. */ export interface WebhookInput { /** Verification secret (signing secret / shared token). */ secret: string @@ -118,6 +126,7 @@ export interface WebhookInput { requestUrl?: string } +/** Result returned by an integration webhook signature verifier. */ export type VerifyResult = { ok: true } | { ok: false; reason: string } /** External thread reference — basis for session stitching across turns. */ @@ -136,6 +145,7 @@ export interface NormalizedEvent { raw?: unknown } +/** Webhook trigger that verifies and normalizes provider events. */ export interface IntegrationTrigger { /** Stable id, e.g. `slack.message`. */ name: string @@ -174,6 +184,7 @@ export interface ConfigField { placeholder?: string } +/** Complete service descriptor shared by integration projections. */ export interface Integration { /** Service slug, e.g. `slack`. */ name: string diff --git a/packages/integrations/src/http.ts b/packages/integrations/src/http.ts index 172985aaa..8f48b8ba1 100644 --- a/packages/integrations/src/http.ts +++ b/packages/integrations/src/http.ts @@ -12,6 +12,7 @@ import { composeTimeoutSignal } from './http-timeout' export { readResponseBytes, readResponseText } from './http-body' export { composeTimeoutSignal } from './http-timeout' +/** Configuration for an authenticated, origin-confined integration HTTP client. */ export interface HttpToolOptions { baseUrl?: string /** Header bag merged into every request (auth, user-agent, etc.). */ @@ -32,6 +33,7 @@ export interface HttpToolOptions { retry?: RetryPolicy } +/** Retry limits and delays for retryable integration HTTP requests. */ export interface RetryPolicy { /** Total attempts, including the first request. Defaults to 1; valid range is 1–100. */ maxAttempts?: number @@ -43,10 +45,12 @@ export interface RetryPolicy { methods?: RetryableHttpMethod[] } +/** HTTP methods for which the integration client can retry requests. */ export type RetryableHttpMethod = NonNullable const MAX_TIMEOUT_MS = 2_147_483_647 +/** Request options accepted by `httpJson` and a bound integration client. */ export interface HttpJsonRequest { /** HTTP method. Defaults to GET. */ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' diff --git a/packages/integrations/src/registry.ts b/packages/integrations/src/registry.ts index 4b04e79f1..2d9a1ccdb 100644 --- a/packages/integrations/src/registry.ts +++ b/packages/integrations/src/registry.ts @@ -16,6 +16,16 @@ export interface IntegrationRegistry { byCategory(category: string): Integration[] } +/** Creates an isolated in-memory registry seeded with optional descriptors. + * @param initial Integrations to register when the registry is created. + * @returns A registry with register, lookup, list, and category methods. + * @throws {ConfigError} When two initial integrations have the same name. + * @example + * ```ts + * const registry = createRegistry([slackIntegration]) + * const slack = registry.get('slack') + * ``` + */ export function createRegistry(initial: Integration[] = []): IntegrationRegistry { const map = new Map() @@ -48,18 +58,33 @@ export function createRegistry(initial: Integration[] = []): IntegrationRegistry */ const defaultRegistry = createRegistry() +/** Adds an integration to the default catalog. + * @param integration Descriptor to register. + * @throws {ConfigError} When an integration with the same name is registered. + */ export function registerIntegration(integration: Integration): void { defaultRegistry.register(integration) } +/** Looks up an integration by its service slug in the default catalog. + * @param name Integration slug. + * @returns The matching descriptor, or `undefined` when not registered. + */ export function getIntegration(name: string): Integration | undefined { return defaultRegistry.get(name) } +/** Returns all descriptors registered in the default catalog. + * @returns A new array of integration descriptors. + */ export function listIntegrations(): Integration[] { return defaultRegistry.list() } +/** Returns default-catalog integrations that include the requested category. + * @param category Category slug to match. + * @returns Matching integration descriptors. + */ export function integrationsByCategory(category: string): Integration[] { return defaultRegistry.byCategory(category) } diff --git a/packages/integrations/src/services/acuity/index.ts b/packages/integrations/src/services/acuity/index.ts index 9b5667be7..4ce99ce8f 100644 --- a/packages/integrations/src/services/acuity/index.ts +++ b/packages/integrations/src/services/acuity/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { acuityActions } from './actions' +/** Descriptor for the Acuity Scheduling service integration. */ export const acuityIntegration = defineIntegration({ name: 'acuity', displayName: 'Acuity Scheduling', diff --git a/packages/integrations/src/services/airtable/index.ts b/packages/integrations/src/services/airtable/index.ts index 80cc9c3e8..935e3078a 100644 --- a/packages/integrations/src/services/airtable/index.ts +++ b/packages/integrations/src/services/airtable/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { airtableActions } from './actions' +/** Descriptor for the Airtable service integration. */ export const airtableIntegration = defineIntegration({ name: 'airtable', displayName: 'Airtable', diff --git a/packages/integrations/src/services/apollo/index.ts b/packages/integrations/src/services/apollo/index.ts index 8c0580179..1869faffe 100644 --- a/packages/integrations/src/services/apollo/index.ts +++ b/packages/integrations/src/services/apollo/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { apolloActions } from './actions' +/** Descriptor for the Apollo.io service integration. */ export const apolloIntegration = defineIntegration({ name: 'apollo', displayName: 'Apollo.io', diff --git a/packages/integrations/src/services/asana/index.ts b/packages/integrations/src/services/asana/index.ts index 3e1d24078..57c09484d 100644 --- a/packages/integrations/src/services/asana/index.ts +++ b/packages/integrations/src/services/asana/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { asanaActions } from './actions' +/** Descriptor for the Asana service integration. */ export const asanaIntegration = defineIntegration({ name: 'asana', displayName: 'Asana', diff --git a/packages/integrations/src/services/assemblyai/index.ts b/packages/integrations/src/services/assemblyai/index.ts index 7553d4c8d..c686840d9 100644 --- a/packages/integrations/src/services/assemblyai/index.ts +++ b/packages/integrations/src/services/assemblyai/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { assemblyaiActions } from './actions' +/** Descriptor for the AssemblyAI service integration. */ export const assemblyaiIntegration = defineIntegration({ name: 'assemblyai', displayName: 'AssemblyAI', diff --git a/packages/integrations/src/services/attio/index.ts b/packages/integrations/src/services/attio/index.ts index 15cb06256..aa54d85f1 100644 --- a/packages/integrations/src/services/attio/index.ts +++ b/packages/integrations/src/services/attio/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { attioActions } from './actions' +/** Descriptor for the Attio service integration. */ export const attioIntegration = defineIntegration({ name: 'attio', displayName: 'Attio', diff --git a/packages/integrations/src/services/azure-openai/index.ts b/packages/integrations/src/services/azure-openai/index.ts index 00a11935d..c7fc02c73 100644 --- a/packages/integrations/src/services/azure-openai/index.ts +++ b/packages/integrations/src/services/azure-openai/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { azureOpenaiActions } from './actions' +/** Descriptor for the Azure OpenAI service integration. */ export const azureOpenaiIntegration = defineIntegration({ name: 'azure-openai', displayName: 'Azure OpenAI', diff --git a/packages/integrations/src/services/baserow/index.ts b/packages/integrations/src/services/baserow/index.ts index d1e91ee83..269671ea5 100644 --- a/packages/integrations/src/services/baserow/index.ts +++ b/packages/integrations/src/services/baserow/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { baserowActions } from './actions' +/** Descriptor for the Baserow service integration. */ export const baserowIntegration = defineIntegration({ name: 'baserow', displayName: 'Baserow', diff --git a/packages/integrations/src/services/bigcommerce/index.ts b/packages/integrations/src/services/bigcommerce/index.ts index ad82dd46c..f536686e8 100644 --- a/packages/integrations/src/services/bigcommerce/index.ts +++ b/packages/integrations/src/services/bigcommerce/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { bigcommerceActions } from './actions' +/** Descriptor for the BigCommerce service integration. */ export const bigcommerceIntegration = defineIntegration({ name: 'bigcommerce', displayName: 'BigCommerce', diff --git a/packages/integrations/src/services/box/index.ts b/packages/integrations/src/services/box/index.ts index bf8db5c8b..20df04c90 100644 --- a/packages/integrations/src/services/box/index.ts +++ b/packages/integrations/src/services/box/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { boxActions } from './actions' +/** Descriptor for the Box service integration. */ export const boxIntegration = defineIntegration({ name: 'box', displayName: 'Box', diff --git a/packages/integrations/src/services/cal-com/index.ts b/packages/integrations/src/services/cal-com/index.ts index e3c08516b..43cb867a6 100644 --- a/packages/integrations/src/services/cal-com/index.ts +++ b/packages/integrations/src/services/cal-com/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { calComActions } from './actions' +/** Descriptor for the Cal.com service integration. */ export const calComIntegration = defineIntegration({ name: 'cal-com', displayName: 'Cal.com', diff --git a/packages/integrations/src/services/calendly/index.ts b/packages/integrations/src/services/calendly/index.ts index a86fd8f1c..835f8d430 100644 --- a/packages/integrations/src/services/calendly/index.ts +++ b/packages/integrations/src/services/calendly/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { calendlyActions } from './actions' +/** Descriptor for the Calendly service integration. */ export const calendlyIntegration = defineIntegration({ name: 'calendly', displayName: 'Calendly', diff --git a/packages/integrations/src/services/coingecko/index.ts b/packages/integrations/src/services/coingecko/index.ts index 6e2bfea90..0b361a13c 100644 --- a/packages/integrations/src/services/coingecko/index.ts +++ b/packages/integrations/src/services/coingecko/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { coingeckoActions } from './actions' +/** Descriptor for the CoinGecko service integration. */ export const coingeckoIntegration = defineIntegration({ name: 'coingecko', displayName: 'CoinGecko', diff --git a/packages/integrations/src/services/confluence/index.ts b/packages/integrations/src/services/confluence/index.ts index ad2a02daa..054bb354f 100644 --- a/packages/integrations/src/services/confluence/index.ts +++ b/packages/integrations/src/services/confluence/index.ts @@ -4,6 +4,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { confluenceActions } from './actions' +/** Descriptor for the Confluence service integration. */ export const confluenceIntegration = defineIntegration({ name: 'confluence', displayName: 'Confluence', diff --git a/packages/integrations/src/services/deepgram/index.ts b/packages/integrations/src/services/deepgram/index.ts index 892f58e90..751a783fc 100644 --- a/packages/integrations/src/services/deepgram/index.ts +++ b/packages/integrations/src/services/deepgram/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { deepgramActions } from './actions' +/** Descriptor for the Deepgram service integration. */ export const deepgramIntegration = defineIntegration({ name: 'deepgram', displayName: 'Deepgram', diff --git a/packages/integrations/src/services/discord/index.ts b/packages/integrations/src/services/discord/index.ts index 70cb9c68a..9219bd07d 100644 --- a/packages/integrations/src/services/discord/index.ts +++ b/packages/integrations/src/services/discord/index.ts @@ -4,6 +4,7 @@ import { OAUTH_SPECS } from '../../oauth-specs' import { discordActions } from './actions' import { discordTriggers } from './triggers' +/** Descriptor for the Discord service integration. */ export const discordIntegration = defineIntegration({ name: 'discord', displayName: 'Discord', diff --git a/packages/integrations/src/services/dropbox/index.ts b/packages/integrations/src/services/dropbox/index.ts index a103a8a1d..ce14c3b02 100644 --- a/packages/integrations/src/services/dropbox/index.ts +++ b/packages/integrations/src/services/dropbox/index.ts @@ -3,6 +3,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { dropboxActions } from './actions' +/** Descriptor for the Dropbox service integration. */ export const dropboxIntegration = defineIntegration({ name: 'dropbox', displayName: 'Dropbox', diff --git a/packages/integrations/src/services/elevenlabs/index.ts b/packages/integrations/src/services/elevenlabs/index.ts index f8fcf2b81..e5f95352c 100644 --- a/packages/integrations/src/services/elevenlabs/index.ts +++ b/packages/integrations/src/services/elevenlabs/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { elevenlabsActions } from './actions' +/** Descriptor for the ElevenLabs service integration. */ export const elevenlabsIntegration = defineIntegration({ name: 'elevenlabs', displayName: 'ElevenLabs', diff --git a/packages/integrations/src/services/email/index.ts b/packages/integrations/src/services/email/index.ts index 1265838f2..ef767754e 100644 --- a/packages/integrations/src/services/email/index.ts +++ b/packages/integrations/src/services/email/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { emailActions } from './actions' +/** Descriptor for the Email (SMTP/IMAP) service integration. */ export const emailIntegration = defineIntegration({ name: 'email', displayName: 'Email (SMTP/IMAP)', diff --git a/packages/integrations/src/services/email/types.ts b/packages/integrations/src/services/email/types.ts index 9e8d837a7..092bb723e 100644 --- a/packages/integrations/src/services/email/types.ts +++ b/packages/integrations/src/services/email/types.ts @@ -1,3 +1,4 @@ +/** File attachment accepted by the email transport. */ export interface EmailAttachment { filename: string /** UTF-8 text contents. Use `contentBase64` for binary. */ @@ -6,6 +7,7 @@ export interface EmailAttachment { contentType?: string } +/** Outbound message data passed to the email transport. */ export interface EmailSendMessage { from: string to: string | string[] @@ -17,16 +19,19 @@ export interface EmailSendMessage { attachments?: EmailAttachment[] } +/** Provider result returned after sending an email. */ export interface EmailSendResult { messageId: string accepted?: string[] rejected?: string[] } +/** Host-provided transport used by the email integration to send messages. */ export interface EmailTransport { send: (msg: EmailSendMessage) => Promise } +/** Email message returned by the IMAP client. */ export interface EmailMessage { id: string uid?: number @@ -40,6 +45,7 @@ export interface EmailMessage { attachments?: Array<{ filename: string; contentType: string; size: number }> } +/** Filters and result limit for an IMAP message fetch. */ export interface ImapFetchOptions { mailbox?: string unseenOnly?: boolean @@ -51,10 +57,12 @@ export interface ImapFetchOptions { limit?: number } +/** Host-provided client used to fetch messages from an IMAP mailbox. */ export interface ImapClient { fetch: (opts: ImapFetchOptions) => Promise } +/** Optional send and receive transports used by the email integration. */ export interface EmailConfig { transport?: EmailTransport imap?: ImapClient diff --git a/packages/integrations/src/services/figma/index.ts b/packages/integrations/src/services/figma/index.ts index 4333b510e..aef092e4b 100644 --- a/packages/integrations/src/services/figma/index.ts +++ b/packages/integrations/src/services/figma/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { figmaActions } from './actions' +/** Descriptor for the Figma service integration. */ export const figmaIntegration = defineIntegration({ name: 'figma', displayName: 'Figma', diff --git a/packages/integrations/src/services/firecrawl/index.ts b/packages/integrations/src/services/firecrawl/index.ts index 19e3c48a5..1a03dfbd2 100644 --- a/packages/integrations/src/services/firecrawl/index.ts +++ b/packages/integrations/src/services/firecrawl/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { firecrawlActions } from './actions' +/** Descriptor for the Firecrawl service integration. */ export const firecrawlIntegration = defineIntegration({ name: 'firecrawl', displayName: 'Firecrawl', diff --git a/packages/integrations/src/services/github-actions/index.ts b/packages/integrations/src/services/github-actions/index.ts index 94cabd24a..f215ca1b2 100644 --- a/packages/integrations/src/services/github-actions/index.ts +++ b/packages/integrations/src/services/github-actions/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { githubActionsActions } from './actions' +/** Descriptor for the GitHub Actions service integration. */ export const githubActionsIntegration = defineIntegration({ name: 'github-actions', displayName: 'GitHub Actions', diff --git a/packages/integrations/src/services/github/index.ts b/packages/integrations/src/services/github/index.ts index c61f30410..a4f7df3c9 100644 --- a/packages/integrations/src/services/github/index.ts +++ b/packages/integrations/src/services/github/index.ts @@ -4,6 +4,7 @@ import { OAUTH_SPECS } from '../../oauth-specs' import { githubActionsList } from './actions' import { githubTriggers } from './triggers' +/** Descriptor for the GitHub service integration. */ export const githubIntegration = defineIntegration({ name: 'github', displayName: 'GitHub', diff --git a/packages/integrations/src/services/gmail/index.ts b/packages/integrations/src/services/gmail/index.ts index 7ca490c32..a1fec7330 100644 --- a/packages/integrations/src/services/gmail/index.ts +++ b/packages/integrations/src/services/gmail/index.ts @@ -3,6 +3,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { gmailActions } from './actions' +/** Descriptor for the Gmail service integration. */ export const gmailIntegration = defineIntegration({ name: 'gmail', displayName: 'Gmail', diff --git a/packages/integrations/src/services/google-calendar/index.ts b/packages/integrations/src/services/google-calendar/index.ts index 31910e086..e9d85edb9 100644 --- a/packages/integrations/src/services/google-calendar/index.ts +++ b/packages/integrations/src/services/google-calendar/index.ts @@ -3,6 +3,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { googleCalendarActions } from './actions' +/** Descriptor for the Google Calendar service integration. */ export const googleCalendarIntegration = defineIntegration({ name: 'google-calendar', displayName: 'Google Calendar', diff --git a/packages/integrations/src/services/google-drive/index.ts b/packages/integrations/src/services/google-drive/index.ts index d5fe68811..9cd61e1c9 100644 --- a/packages/integrations/src/services/google-drive/index.ts +++ b/packages/integrations/src/services/google-drive/index.ts @@ -3,6 +3,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { googleDriveActions } from './actions' +/** Descriptor for the Google Drive service integration. */ export const googleDriveIntegration = defineIntegration({ name: 'google-drive', displayName: 'Google Drive', diff --git a/packages/integrations/src/services/hubspot/index.ts b/packages/integrations/src/services/hubspot/index.ts index c8eb1e858..75146d963 100644 --- a/packages/integrations/src/services/hubspot/index.ts +++ b/packages/integrations/src/services/hubspot/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { hubspotActions } from './actions' +/** Descriptor for the HubSpot service integration. */ export const hubspotIntegration = defineIntegration({ name: 'hubspot', displayName: 'HubSpot', diff --git a/packages/integrations/src/services/intercom/index.ts b/packages/integrations/src/services/intercom/index.ts index 0bda63c3b..602c70cc7 100644 --- a/packages/integrations/src/services/intercom/index.ts +++ b/packages/integrations/src/services/intercom/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { intercomActions } from './actions' +/** Descriptor for the Intercom service integration. */ export const intercomIntegration = defineIntegration({ name: 'intercom', displayName: 'Intercom', diff --git a/packages/integrations/src/services/jira/index.ts b/packages/integrations/src/services/jira/index.ts index 27ae41289..1016f0221 100644 --- a/packages/integrations/src/services/jira/index.ts +++ b/packages/integrations/src/services/jira/index.ts @@ -4,6 +4,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { jiraActions } from './actions' +/** Descriptor for the Jira service integration. */ export const jiraIntegration = defineIntegration({ name: 'jira', displayName: 'Jira', diff --git a/packages/integrations/src/services/linear-triage/index.ts b/packages/integrations/src/services/linear-triage/index.ts index e8b97c458..cc4ec7bd8 100644 --- a/packages/integrations/src/services/linear-triage/index.ts +++ b/packages/integrations/src/services/linear-triage/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { linearTriageActions } from './actions' +/** Descriptor for the Linear Triage service integration. */ export const linearTriageIntegration = defineIntegration({ name: 'linear-triage', displayName: 'Linear Triage', diff --git a/packages/integrations/src/services/linear/index.ts b/packages/integrations/src/services/linear/index.ts index 38fef61c5..945cd91e8 100644 --- a/packages/integrations/src/services/linear/index.ts +++ b/packages/integrations/src/services/linear/index.ts @@ -4,6 +4,7 @@ import { OAUTH_SPECS } from '../../oauth-specs' import { linearActions } from './actions' import { linearTriggers } from './triggers' +/** Descriptor for the Linear service integration. */ export const linearIntegration = defineIntegration({ name: 'linear', displayName: 'Linear', diff --git a/packages/integrations/src/services/mailchimp/index.ts b/packages/integrations/src/services/mailchimp/index.ts index 64c454dee..e81b76de0 100644 --- a/packages/integrations/src/services/mailchimp/index.ts +++ b/packages/integrations/src/services/mailchimp/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { mailchimpActions } from './actions' +/** Descriptor for the Mailchimp service integration. */ export const mailchimpIntegration = defineIntegration({ name: 'mailchimp', displayName: 'Mailchimp', diff --git a/packages/integrations/src/services/maps/index.ts b/packages/integrations/src/services/maps/index.ts index 9091fa6ca..4dd489cbd 100644 --- a/packages/integrations/src/services/maps/index.ts +++ b/packages/integrations/src/services/maps/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { mapsActions } from './actions' +/** Descriptor for the Maps (OpenStreetMap / Nominatim) service integration. */ export const mapsIntegration = defineIntegration({ name: 'maps', displayName: 'Maps (OpenStreetMap / Nominatim)', diff --git a/packages/integrations/src/services/notion/index.ts b/packages/integrations/src/services/notion/index.ts index c5bb8132c..93b31fc41 100644 --- a/packages/integrations/src/services/notion/index.ts +++ b/packages/integrations/src/services/notion/index.ts @@ -3,6 +3,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { notionActions } from './actions' +/** Descriptor for the Notion service integration. */ export const notionIntegration = defineIntegration({ name: 'notion', displayName: 'Notion', diff --git a/packages/integrations/src/services/openai-images/index.ts b/packages/integrations/src/services/openai-images/index.ts index dac0545d9..a8b9dd7ec 100644 --- a/packages/integrations/src/services/openai-images/index.ts +++ b/packages/integrations/src/services/openai-images/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { openaiImagesActions } from './actions' +/** Descriptor for the OpenAI Images service integration. */ export const openaiImagesIntegration = defineIntegration({ name: 'openai-images', displayName: 'OpenAI Images', diff --git a/packages/integrations/src/services/pagerduty/index.ts b/packages/integrations/src/services/pagerduty/index.ts index 8c495cc2f..a4e55ba7c 100644 --- a/packages/integrations/src/services/pagerduty/index.ts +++ b/packages/integrations/src/services/pagerduty/index.ts @@ -5,6 +5,7 @@ import { OAUTH_SPECS } from '../../oauth-specs' import { pagerdutyActions } from './actions' import { pagerdutyTriggers } from './triggers' +/** Descriptor for the PagerDuty service integration. */ export const pagerdutyIntegration = defineIntegration({ name: 'pagerduty', displayName: 'PagerDuty', diff --git a/packages/integrations/src/services/pipedrive/index.ts b/packages/integrations/src/services/pipedrive/index.ts index f38b2356e..b15746f1b 100644 --- a/packages/integrations/src/services/pipedrive/index.ts +++ b/packages/integrations/src/services/pipedrive/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { pipedriveActions } from './actions' +/** Descriptor for the Pipedrive service integration. */ export const pipedriveIntegration = defineIntegration({ name: 'pipedrive', displayName: 'Pipedrive', diff --git a/packages/integrations/src/services/reader/index.ts b/packages/integrations/src/services/reader/index.ts index 3d02490ac..7699d20a0 100644 --- a/packages/integrations/src/services/reader/index.ts +++ b/packages/integrations/src/services/reader/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { readerActions } from './actions' +/** Descriptor for the Jina Reader service integration. */ export const readerIntegration = defineIntegration({ name: 'reader', displayName: 'Jina Reader', diff --git a/packages/integrations/src/services/salesforce/index.ts b/packages/integrations/src/services/salesforce/index.ts index 471b7f504..b52310124 100644 --- a/packages/integrations/src/services/salesforce/index.ts +++ b/packages/integrations/src/services/salesforce/index.ts @@ -3,6 +3,7 @@ import { registerIntegration } from '../../registry' import { OAUTH_SPECS } from '../../oauth-specs' import { salesforceActions } from './actions' +/** Descriptor for the Salesforce service integration. */ export const salesforceIntegration = defineIntegration({ name: 'salesforce', displayName: 'Salesforce', diff --git a/packages/integrations/src/services/sendgrid/index.ts b/packages/integrations/src/services/sendgrid/index.ts index 353017933..c1398ff18 100644 --- a/packages/integrations/src/services/sendgrid/index.ts +++ b/packages/integrations/src/services/sendgrid/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { sendgridActions } from './actions' +/** Descriptor for the SendGrid service integration. */ export const sendgridIntegration = defineIntegration({ name: 'sendgrid', displayName: 'SendGrid', diff --git a/packages/integrations/src/services/sentry/index.ts b/packages/integrations/src/services/sentry/index.ts index c82c9d39a..32720e7d5 100644 --- a/packages/integrations/src/services/sentry/index.ts +++ b/packages/integrations/src/services/sentry/index.ts @@ -4,6 +4,7 @@ import { OAUTH_SPECS } from '../../oauth-specs' import { sentryActions } from './actions' import { sentryTriggers } from './triggers' +/** Descriptor for the Sentry service integration. */ export const sentryIntegration = defineIntegration({ name: 'sentry', displayName: 'Sentry', diff --git a/packages/integrations/src/services/shopify/index.ts b/packages/integrations/src/services/shopify/index.ts index 371099b74..c46246376 100644 --- a/packages/integrations/src/services/shopify/index.ts +++ b/packages/integrations/src/services/shopify/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { shopifyActions } from './actions' +/** Descriptor for the Shopify service integration. */ export const shopifyIntegration = defineIntegration({ name: 'shopify', displayName: 'Shopify', diff --git a/packages/integrations/src/services/slack/index.ts b/packages/integrations/src/services/slack/index.ts index 5ff63ed93..f35d595ef 100644 --- a/packages/integrations/src/services/slack/index.ts +++ b/packages/integrations/src/services/slack/index.ts @@ -5,6 +5,7 @@ import { slackAuth } from './auth' import { slackActions } from './actions' import { slackTriggers } from './triggers' +/** Descriptor for the Slack service integration. */ export const slackIntegration = defineIntegration({ name: 'slack', displayName: 'Slack', diff --git a/packages/integrations/src/services/stripe/index.ts b/packages/integrations/src/services/stripe/index.ts index a308d8b50..8e10dafa6 100644 --- a/packages/integrations/src/services/stripe/index.ts +++ b/packages/integrations/src/services/stripe/index.ts @@ -5,6 +5,7 @@ import { OAUTH_SPECS } from '../../oauth-specs' import { stripeActions } from './actions' import { stripeWebhook } from './webhook' +/** Descriptor for the Stripe service integration. */ export const stripeIntegration = defineIntegration({ name: 'stripe', displayName: 'Stripe', diff --git a/packages/integrations/src/services/teams/cards.ts b/packages/integrations/src/services/teams/cards.ts index 6cc17e189..cbd59ab3e 100644 --- a/packages/integrations/src/services/teams/cards.ts +++ b/packages/integrations/src/services/teams/cards.ts @@ -1,3 +1,4 @@ +/** Button action rendered in a Teams Adaptive Card. */ export interface TeamsAdaptiveCardAction { type: 'Action.OpenUrl' | 'Action.Submit' title: string @@ -5,6 +6,7 @@ export interface TeamsAdaptiveCardAction { data?: Record } +/** Adaptive Card payload supported by the Teams integration. */ export interface TeamsAdaptiveCard { contentType: 'application/vnd.microsoft.card.adaptive' content: { @@ -16,6 +18,7 @@ export interface TeamsAdaptiveCard { } } +/** Legacy Teams connector message card payload. */ export interface TeamsMessageCard { contentType: 'application/vnd.microsoft.teams.card.o365connector' content: { @@ -71,6 +74,7 @@ export function messageCard(input: { } } +/** Message accepted by the host-provided Teams bot client. */ export interface TeamsBotMessage { conversationId: string serviceUrl?: string @@ -80,11 +84,13 @@ export interface TeamsBotMessage { signal?: AbortSignal } +/** Result returned after a Teams bot sends a message. */ export interface TeamsBotSendResult { id: string conversationId: string } +/** Host-provided client used by the Teams integration to send messages. */ export interface TeamsBotClient { send: (msg: TeamsBotMessage) => Promise } diff --git a/packages/integrations/src/services/teams/index.ts b/packages/integrations/src/services/teams/index.ts index e22b05243..872ded66a 100644 --- a/packages/integrations/src/services/teams/index.ts +++ b/packages/integrations/src/services/teams/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { teamsActions } from './actions' +/** Descriptor for the Microsoft Teams service integration. */ export const teamsIntegration = defineIntegration({ name: 'teams', displayName: 'Microsoft Teams', diff --git a/packages/integrations/src/services/telegram/index.ts b/packages/integrations/src/services/telegram/index.ts index d97c00c11..db26f9bdc 100644 --- a/packages/integrations/src/services/telegram/index.ts +++ b/packages/integrations/src/services/telegram/index.ts @@ -4,6 +4,7 @@ import { registerIntegration } from '../../registry' import { telegramActions } from './actions' import { telegramTriggers } from './triggers' +/** Descriptor for the Telegram service integration. */ export const telegramIntegration = defineIntegration({ name: 'telegram', displayName: 'Telegram', diff --git a/packages/integrations/src/services/twilio/index.ts b/packages/integrations/src/services/twilio/index.ts index b3b4df72c..674208c82 100644 --- a/packages/integrations/src/services/twilio/index.ts +++ b/packages/integrations/src/services/twilio/index.ts @@ -4,6 +4,7 @@ import { registerIntegration } from '../../registry' import { twilioActions } from './actions' import { twilioTriggers } from './triggers' +/** Descriptor for the Twilio service integration. */ export const twilioIntegration = defineIntegration({ name: 'twilio', displayName: 'Twilio', diff --git a/packages/integrations/src/services/weather/index.ts b/packages/integrations/src/services/weather/index.ts index a5692d7b7..8916baa94 100644 --- a/packages/integrations/src/services/weather/index.ts +++ b/packages/integrations/src/services/weather/index.ts @@ -2,6 +2,7 @@ import { defineIntegration } from '../../contract' import { registerIntegration } from '../../registry' import { weatherActions } from './actions' +/** Descriptor for the Weather (OpenWeatherMap) service integration. */ export const weatherIntegration = defineIntegration({ name: 'weather', displayName: 'Weather (OpenWeatherMap)', diff --git a/packages/integrations/src/services/whatsapp/index.ts b/packages/integrations/src/services/whatsapp/index.ts index 1f232f333..b2977cf7b 100644 --- a/packages/integrations/src/services/whatsapp/index.ts +++ b/packages/integrations/src/services/whatsapp/index.ts @@ -4,6 +4,7 @@ import { registerIntegration } from '../../registry' import { whatsappActions } from './actions' import { whatsappTriggers } from './triggers' +/** Descriptor for the WhatsApp Cloud API service integration. */ export const whatsappIntegration = defineIntegration({ name: 'whatsapp', displayName: 'WhatsApp Cloud API', diff --git a/packages/integrations/src/services/whisper/index.ts b/packages/integrations/src/services/whisper/index.ts index 7c750616a..7ed6657e7 100644 --- a/packages/integrations/src/services/whisper/index.ts +++ b/packages/integrations/src/services/whisper/index.ts @@ -3,6 +3,7 @@ import { CONFIG_FIELDS } from '../../config-fields' import { registerIntegration } from '../../registry' import { whisperActions } from './actions' +/** Descriptor for the OpenAI Whisper service integration. */ export const whisperIntegration = defineIntegration({ name: 'whisper', displayName: 'OpenAI Whisper', diff --git a/packages/integrations/src/testing/validate.ts b/packages/integrations/src/testing/validate.ts index 1558bbeb4..34b33f5ba 100644 --- a/packages/integrations/src/testing/validate.ts +++ b/packages/integrations/src/testing/validate.ts @@ -21,6 +21,11 @@ function isObjectSchema(schema: JSONSchema7 | undefined): boolean { return !!schema && schema.type === 'object' } +/** Checks an action descriptor and returns every shape problem found. + * @param action Action descriptor to inspect. + * @param path Dotted path used as the problem location prefix. + * @returns Problems found, or an empty array when the action is valid. + */ export function validateAction(action: IntegrationAction, path: string): ValidationProblem[] { const problems: ValidationProblem[] = [] if (!ACTION_NAME_RE.test(action.name)) { @@ -38,6 +43,11 @@ export function validateAction(action: IntegrationAction, path: string): Validat return problems } +/** Checks a trigger descriptor and returns every shape problem found. + * @param trigger Trigger descriptor to inspect. + * @param path Dotted path used as the problem location prefix. + * @returns Problems found, or an empty array when the trigger is valid. + */ export function validateTrigger(trigger: IntegrationTrigger, path: string): ValidationProblem[] { const problems: ValidationProblem[] = [] if (!trigger.name?.trim()) { From 3c8d92a48b00518573cd13554b3518575badbf81 Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 16:09:34 -0300 Subject: [PATCH 28/30] docs(memory): document public API --- .changeset/quiet-docs-memory.md | 5 +++++ packages/memory/src/encrypted.ts | 13 +++++++++++++ packages/memory/src/file-vector.ts | 11 +++++++++++ packages/memory/src/forget.ts | 8 ++++++++ packages/memory/src/graph.ts | 3 +++ packages/memory/src/hierarchical.ts | 5 +++++ packages/memory/src/kv-store-basic.ts | 15 +++++++++++++++ packages/memory/src/kv-store-factory.ts | 23 +++++++++++++++++++++++ packages/memory/src/kv-store-redis.ts | 18 ++++++++++++++++-- packages/memory/src/kv-store-sqlite.ts | 6 ++++++ packages/memory/src/kv-store-types.ts | 15 +++++++++++++++ packages/memory/src/kv-store-vector.ts | 6 ++++++ packages/memory/src/personalization.ts | 1 + packages/memory/src/redaction.ts | 8 ++++++++ packages/memory/src/redis-chat.ts | 6 ++++++ packages/memory/src/redis-client.ts | 7 +++++++ packages/memory/src/redis-vector.ts | 6 ++++++ packages/memory/src/sqlite.ts | 6 ++++++ packages/memory/src/turso.ts | 1 + packages/memory/src/vector-store.ts | 3 +++ packages/memory/src/vector/chroma.ts | 5 +++++ packages/memory/src/vector/http.ts | 1 + packages/memory/src/vector/milvus.ts | 5 +++++ packages/memory/src/vector/mongo-atlas.ts | 5 +++++ packages/memory/src/vector/pgvector.ts | 6 ++++++ packages/memory/src/vector/pinecone.ts | 5 +++++ packages/memory/src/vector/qdrant.ts | 5 +++++ packages/memory/src/vector/supabase.ts | 5 +++++ packages/memory/src/vector/upstash.ts | 1 + packages/memory/src/vector/weaviate.ts | 5 +++++ packages/memory/src/web-storage.ts | 14 ++++++++++++++ 31 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 .changeset/quiet-docs-memory.md diff --git a/.changeset/quiet-docs-memory.md b/.changeset/quiet-docs-memory.md new file mode 100644 index 000000000..53286511d --- /dev/null +++ b/.changeset/quiet-docs-memory.md @@ -0,0 +1,5 @@ +--- +"@agentskit/memory": patch +--- + +Document the public API. diff --git a/packages/memory/src/encrypted.ts b/packages/memory/src/encrypted.ts index cc63dcc78..ae4fcde48 100644 --- a/packages/memory/src/encrypted.ts +++ b/packages/memory/src/encrypted.ts @@ -15,6 +15,7 @@ type MemoryOperationOptions = Parameters[0] * during onboarding and stored only on their device. */ +/** Backing memory, encryption key, and optional Web Crypto adapters. */ export interface EncryptedMemoryOptions { backing: ChatMemory /** 32-byte raw key (e.g. `crypto.getRandomValues(new Uint8Array(32))`). */ @@ -27,6 +28,7 @@ export interface EncryptedMemoryOptions { aad?: Uint8Array } +/** Base64 ciphertext, initialization vector, and content-length marker. */ export interface EncryptedEnvelope { ciphertext: string iv: string @@ -65,6 +67,17 @@ async function resolveKey( return subtle.importKey('raw', raw as BufferSource, { name: 'AES-GCM' }, false, ['encrypt', 'decrypt']) } +/** Wraps chat memory with AES-GCM encryption using caller-owned key material. + * @param options Backing memory, key, and optional Web Crypto settings. + * @returns A chat memory that encrypts saved content and decrypts loaded content. + * @throws {ConfigError} When the key is invalid. + * @throws {MemoryError} When Web Crypto is unavailable. + * @example + * ```ts + * const key = crypto.getRandomValues(new Uint8Array(32)) + * const memory = await createEncryptedMemory({ backing, key }) + * ``` + */ export async function createEncryptedMemory( options: EncryptedMemoryOptions, ): Promise { diff --git a/packages/memory/src/file-vector.ts b/packages/memory/src/file-vector.ts index 66031c7a3..dd144cbf8 100644 --- a/packages/memory/src/file-vector.ts +++ b/packages/memory/src/file-vector.ts @@ -3,6 +3,7 @@ import type { VectorMemory, VectorDocument, RetrievedDocument } from '@agentskit import type { VectorStore } from './vector-store' import { matchesFilter } from './vector/filter' +/** On-disk path and optional vector-store adapter for file vector memory. */ export interface FileVectorMemoryConfig { path: string store?: VectorStore @@ -90,6 +91,16 @@ function createVectraStore(dirPath: string): VectorStore { } } +/** Creates a persistent vector memory backed by a local Vectra index. + * @param config Index path and optional vector-store adapter. + * @returns A vector memory that stores and searches local embeddings. + * @throws {MemoryError} When the optional `vectra` dependency is unavailable. + * @example + * ```ts + * const memory = fileVectorMemory({ path: './vectors' }) + * await memory.store([{ id: 'guide', content: 'Guide text', embedding }]) + * ``` + */ export function fileVectorMemory(config: FileVectorMemoryConfig): VectorMemory { const store = config.store ?? createVectraStore(config.path) const contentCache = new Map() diff --git a/packages/memory/src/forget.ts b/packages/memory/src/forget.ts index cc0db550a..d65351b7d 100644 --- a/packages/memory/src/forget.ts +++ b/packages/memory/src/forget.ts @@ -26,6 +26,7 @@ export interface ForgettableMemory { forgetSubject: (subjectId: string) => Promise } +/** Per-backend result returned by subject-data deletion. */ export interface ForgetReport { backend: string deletedCount: number @@ -35,6 +36,7 @@ export interface ForgetReport { failures?: Array<{ id: string; reason: string }> } +/** Aggregate outcome of deleting a subject from multiple memory backends. */ export interface ForgetSubjectResult { subjectId: string reports: ForgetReport[] @@ -67,6 +69,9 @@ async function hash(input: string): Promise { * Walk every memory passed in and run `forgetSubject(subjectId)` on * any that implement it. Missing capabilities are reported so callers * cannot mistake a partial deletion for a complete one. + * @param memories Memory instances to inspect for deletion capability. + * @param subjectId Subject identifier to delete. + * @returns Per-backend reports and an `incomplete` flag for skipped or failed backends. */ export async function forgetSubject( memories: Array, @@ -100,6 +105,9 @@ export async function forgetSubject( /** * Helper for backends that key records by `metadata.subjectId`. Wraps * any `delete(ids)`-style API into a `ForgettableMemory`. + * @param memory Object to extend with the deletion capability. + * @param options Backend label and functions for listing and deleting matching ids. + * @returns The same object with `ForgettableMemory` methods and metadata. */ export function makeForgettable( memory: M, diff --git a/packages/memory/src/graph.ts b/packages/memory/src/graph.ts index d5f2f6217..4c7722a5b 100644 --- a/packages/memory/src/graph.ts +++ b/packages/memory/src/graph.ts @@ -16,6 +16,7 @@ export interface GraphNode> { updatedAt?: string } +/** Directed relationship between two graph nodes. */ export interface GraphEdge> { id: string /** Verb / relation type — 'knows', 'works-at', 'cites'. */ @@ -27,6 +28,7 @@ export interface GraphEdge> { properties?: TProps } +/** Optional node or edge fields used to filter graph lookups. */ export interface GraphQuery { kind?: string label?: string @@ -34,6 +36,7 @@ export interface GraphQuery { to?: string } +/** Knowledge-graph operations accepted by graph memory consumers. */ export interface GraphMemory { upsertNode: (node: GraphNode) => Promise> upsertEdge: (edge: GraphEdge) => Promise> diff --git a/packages/memory/src/hierarchical.ts b/packages/memory/src/hierarchical.ts index 1b2bafe9f..f297cbe3b 100644 --- a/packages/memory/src/hierarchical.ts +++ b/packages/memory/src/hierarchical.ts @@ -3,6 +3,7 @@ import type { ChatMemory, Message } from '@agentskit/core' type MemoryOperationOptions = Parameters[0] +/** Search and indexing operations for the recall tier of hierarchical memory. */ export interface HierarchicalRecall { /** * Index a message for later retrieval. Called once per message as @@ -20,6 +21,7 @@ export interface HierarchicalRecall { clear?: () => void | Promise } +/** Working, recall, and archival stores used by hierarchical memory. */ export interface HierarchicalMemoryOptions { /** Hot window — the messages always loaded in full. */ working: ChatMemory @@ -42,6 +44,7 @@ export interface HierarchicalMemoryOptions { recallTopK?: number } +/** Tiered chat memory with accessors for archival history and the working window. */ export interface HierarchicalMemory extends ChatMemory { /** Full archival history. Always the source of truth. */ archival: () => Promise @@ -67,6 +70,8 @@ function mergeChronological(a: Message[], b: Message[]): Message[] { * * On every `load`, the hub returns working + up to `recallTopK` * messages surfaced by the recall tier, spliced chronologically. + * @param options Working and archival memories plus optional recall settings. + * @returns A chat memory that keeps an archival history and bounded working window. */ export function createHierarchicalMemory( options: HierarchicalMemoryOptions, diff --git a/packages/memory/src/kv-store-basic.ts b/packages/memory/src/kv-store-basic.ts index 6027c5723..c4c82f082 100644 --- a/packages/memory/src/kv-store-basic.ts +++ b/packages/memory/src/kv-store-basic.ts @@ -27,6 +27,11 @@ const enqueueFileWrite = (path: string, task: () => Promise): Promise { validateKvRetention(config) const store = new Map() @@ -49,6 +54,10 @@ export const createInMemoryStore = (config: InMemoryKvConfig): AgentskitMemorySt } } +/** Creates a JSON file key-value store with atomic file replacement. + * @param config File path and optional retention settings. + * @returns A persistent key-value store backed by the configured file. + */ export const createFileStore = (config: FileKvConfig): AgentskitMemoryStore => { const path = config.path @@ -103,6 +112,7 @@ export const createFileStore = (config: FileKvConfig): AgentskitMemoryStore => { } } +/** Options for creating a browser local-storage or file fallback store. */ export interface CreateLocalStorageStoreOpts { readonly config: LocalStorageKvConfig readonly storage?: LocalStorageLike @@ -116,6 +126,11 @@ const resolveLocalStorage = (): LocalStorageLike | undefined => { const defaultLocalStoragePath = (): string => `${process.cwd()}/.agentskit/memory-localstorage.json` +/** Creates a local-storage store, falling back to a JSON file when unavailable. + * @param options Storage configuration and optional storage/file adapters. + * @returns A key-value store backed by Web Storage or the configured file. + * @throws {ConfigError} When retention limits are invalid. + */ export const createLocalStorageStore = ({ config, storage = resolveLocalStorage(), diff --git a/packages/memory/src/kv-store-factory.ts b/packages/memory/src/kv-store-factory.ts index ec03047d0..f8a2bb27c 100644 --- a/packages/memory/src/kv-store-factory.ts +++ b/packages/memory/src/kv-store-factory.ts @@ -17,6 +17,7 @@ import type { SqliteOpener, } from './kv-store-types' +/** Error raised when a requested key-value memory backend is not implemented. */ export class MemoryBackendNotImplementedError extends Error { readonly code = 'MEMORY_BACKEND_NOT_IMPLEMENTED' readonly backend: KvMemoryConfig['backend'] @@ -29,8 +30,10 @@ export class MemoryBackendNotImplementedError extends Error { } } +/** Availability status reported for a key-value memory backend. */ export type MemoryBackendStatus = 'supported' | 'planned' +/** Current support status for each key-value memory backend. */ export const MEMORY_BACKEND_SUPPORT: Readonly> = { 'in-memory': 'supported', file: 'supported', @@ -40,9 +43,14 @@ export const MEMORY_BACKEND_SUPPORT: Readonly MEMORY_BACKEND_SUPPORT[backend] === 'supported' +/** Options and injected drivers for creating a configured KV memory store. */ export interface CreateKvMemoryFromConfigOpts { readonly config: KvMemoryConfig readonly sqlite?: SqliteOpener @@ -52,6 +60,16 @@ export interface CreateKvMemoryFromConfigOpts { readonly embedder?: MemoryEmbedderLike } +/** Creates a KV store for the selected backend using supplied dependencies. + * @param options Backend config and optional database, cache, vector, and embedding adapters. + * @returns A store implementing asynchronous `get` and `set`. + * @throws {MemoryError} When a selected external backend lacks a required adapter. + * @example + * ```ts + * const store = createKvMemoryFromConfig({ config: { backend: 'in-memory' } }) + * await store.set('job:42', { status: 'ready' }) + * ``` + */ export const createKvMemoryFromConfig = ({ config, sqlite, @@ -109,6 +127,11 @@ export const createKvMemoryFromConfig = ({ throw new MemoryBackendNotImplementedError((exhausted as { backend: KvMemoryConfig['backend'] }).backend) } +/** Creates a KV store and lazy-loads the optional SQLite or Redis driver. + * @param config Backend discriminator and settings. + * @returns A store implementing asynchronous `get` and `set`. + * @throws {MemoryError} When an optional driver is missing or vector adapters are not injected. + */ export const createKvMemoryFromConfigAuto = async (config: KvMemoryConfig): Promise => { if (config.backend === 'sqlite') { const sqlite = await tryDefaultSqliteOpener() diff --git a/packages/memory/src/kv-store-redis.ts b/packages/memory/src/kv-store-redis.ts index 783008daa..1f7b611c3 100644 --- a/packages/memory/src/kv-store-redis.ts +++ b/packages/memory/src/kv-store-redis.ts @@ -8,11 +8,18 @@ interface RedisEnvelope { readonly insertedAt: number } +/** Redis store settings and injected Redis client. */ export interface CreateRedisStoreOpts { readonly config: RedisKvConfig readonly client: RedisLike } +/** Creates a Redis key-value store using the supplied client. + * @param options Redis configuration and client. + * @returns A key-value store backed by the configured Redis prefix. + * @throws {ConfigError} When retention limits are invalid. + * @throws {MemoryError} When Redis commands fail. + */ export const createRedisStore = ({ config, client }: CreateRedisStoreOpts): AgentskitMemoryStore => { validateKvRetention(config) const prefix = config.prefix @@ -70,7 +77,10 @@ export const createRedisStore = ({ config, client }: CreateRedisStoreOpts): Agen } } -/** Bridge an `ioredis`-style client to the {@link RedisLike} options-object shape. */ +/** Bridges an ioredis-style client to the {@link RedisLike} options-object shape. + * @param io Client with positional Redis command options. + * @returns A client using the memory package's Redis contract. + */ export const adaptIoredis = (io: { get(key: string): Promise set(key: string, value: string, mode?: string, ttl?: number): Promise @@ -84,7 +94,11 @@ export const adaptIoredis = (io: { keys: (pattern) => io.keys(pattern), }) -/** Lazy-import `redis` (node-redis v4), connect, and return a client; `undefined` if absent. */ +/** Loads and connects node-redis, returning `undefined` when it is unavailable. + * @param url Redis connection URL. + * @returns A connected client, or `undefined` when the optional package is absent. + * @throws {MemoryError} When the client cannot connect. + */ export const tryDefaultRedisClient = async (url: string): Promise => { try { const moduleId = 'redis' diff --git a/packages/memory/src/kv-store-sqlite.ts b/packages/memory/src/kv-store-sqlite.ts index 647bdd5f7..19ec4eef7 100644 --- a/packages/memory/src/kv-store-sqlite.ts +++ b/packages/memory/src/kv-store-sqlite.ts @@ -9,11 +9,16 @@ import { validateKvRetention, } from './kv-store-types' +/** SQLite store settings and injected database opener. */ export interface CreateSqliteStoreOpts { readonly config: SqliteKvConfig readonly open: SqliteOpener } +/** Creates a SQLite key-value store using the supplied database opener. + * @param options SQLite configuration and opener. + * @returns A key-value store backed by the configured database. + */ export const createSqliteStore = ({ config, open }: CreateSqliteStoreOpts): AgentskitMemoryStore => { validateKvRetention(config) const db = open(config.path) @@ -67,6 +72,7 @@ export const createSqliteStore = ({ config, open }: CreateSqliteStoreOpts): Agen /** * Lazy-import `better-sqlite3` and return an opener, or `undefined` when the * optional peer dep is absent (caller surfaces AK_MEMORY_PEER_MISSING). + * @returns An opener, or `undefined` when `better-sqlite3` is unavailable. */ export const tryDefaultSqliteOpener = async (): Promise => { try { diff --git a/packages/memory/src/kv-store-types.ts b/packages/memory/src/kv-store-types.ts index 15c42f6b2..b3e3fb8df 100644 --- a/packages/memory/src/kv-store-types.ts +++ b/packages/memory/src/kv-store-types.ts @@ -13,6 +13,7 @@ export interface AgentskitMemoryStore { set(key: string, value: unknown): Promise } +/** Stored value and insertion timestamp used by the KV backends. */ export interface KvEntry { readonly value: unknown readonly insertedAt: number @@ -52,32 +53,39 @@ interface CommonKvConfig { readonly ttlSeconds?: number } +/** Configuration for the in-memory key-value backend. */ export interface InMemoryKvConfig extends CommonKvConfig { readonly backend: 'in-memory' } +/** Configuration for the JSON file key-value backend. */ export interface FileKvConfig extends CommonKvConfig { readonly backend: 'file' readonly path: string } +/** Configuration for the SQLite key-value backend. */ export interface SqliteKvConfig extends CommonKvConfig { readonly backend: 'sqlite' readonly path: string } +/** Configuration for the Redis key-value backend. */ export interface RedisKvConfig extends CommonKvConfig { readonly backend: 'redis' readonly url: string readonly prefix: string } +/** Configuration for the vector-backed key-value backend. */ export interface VectorKvConfig extends CommonKvConfig { readonly backend: 'vector' readonly provider: string readonly collection: string } +/** Configuration for the browser local-storage key-value backend. */ export interface LocalStorageKvConfig extends CommonKvConfig { readonly backend: 'localstorage' readonly key: string } +/** Discriminated configuration accepted by the KV memory factories. */ export type KvMemoryConfig = | InMemoryKvConfig | FileKvConfig @@ -88,6 +96,7 @@ export type KvMemoryConfig = // --- Injected-dependency contracts (so the store stays driver-agnostic) --- +/** Minimal Redis client operations required by the memory backends. */ export interface RedisLike { get(key: string): Promise set(key: string, value: string, options?: { readonly EX?: number }): Promise @@ -95,19 +104,23 @@ export interface RedisLike { keys(pattern: string): Promise } +/** Minimal prepared-statement operations used by SQLite memory stores. */ export interface SqliteStmt { run(...params: unknown[]): void get(...params: unknown[]): unknown all(...params: unknown[]): unknown[] } +/** Minimal SQLite database operations required by memory stores. */ export interface SqliteLike { exec(sql: string): void prepare(sql: string): SqliteStmt } +/** Opens a SQLite database at the given path. */ export type SqliteOpener = (path: string) => SqliteLike +/** Minimal vector store operations required by vector-backed KV memory. */ export interface MemoryVectorStoreLike { upsert( rows: readonly { @@ -123,10 +136,12 @@ export interface MemoryVectorStoreLike { ): Promise }[]> } +/** Embedder contract used by vector-backed KV memory. */ export interface MemoryEmbedderLike { embed(texts: readonly string[]): Promise } +/** Minimal Web Storage methods required by the local-storage backend. */ export interface LocalStorageLike { getItem(key: string): string | null setItem(key: string, value: string): void diff --git a/packages/memory/src/kv-store-vector.ts b/packages/memory/src/kv-store-vector.ts index df7c1e53e..6ea9666de 100644 --- a/packages/memory/src/kv-store-vector.ts +++ b/packages/memory/src/kv-store-vector.ts @@ -11,12 +11,18 @@ import { validateKvRetention, } from './kv-store-types' +/** Dependencies for creating a vector-backed key-value store. */ export interface CreateVectorStoreOpts { readonly config: VectorKvConfig readonly vectorStore: MemoryVectorStoreLike readonly embedder: MemoryEmbedderLike } +/** Creates a key-value store that embeds keys and stores values in a vector store. + * @param options Vector config, store, and embedder. + * @returns A key-value store with a similarity-based `recall` method. + * @throws {MemoryError} When the embedder returns no vector. + */ export const createVectorStore = ({ config, vectorStore, diff --git a/packages/memory/src/personalization.ts b/packages/memory/src/personalization.ts index fc7319ffd..f4803e5a9 100644 --- a/packages/memory/src/personalization.ts +++ b/packages/memory/src/personalization.ts @@ -13,6 +13,7 @@ export interface PersonalizationProfile { updatedAt: string } +/** Persistence contract for retrieving, replacing, merging, and deleting profiles. */ export interface PersonalizationStore { get: (subjectId: string) => Promise set: (profile: PersonalizationProfile) => Promise diff --git a/packages/memory/src/redaction.ts b/packages/memory/src/redaction.ts index eca45284e..4296f8c04 100644 --- a/packages/memory/src/redaction.ts +++ b/packages/memory/src/redaction.ts @@ -32,6 +32,7 @@ type MemoryOperationOptions = Parameters[0] export type RedactionMode = 'redact' | 'tokenize' +/** Rules, mode, and token vault settings for chat-memory redaction. */ export interface ChatMemoryRedactionOptions { /** * Rules to apply. Pass `DEFAULT_PII_RULES` for the baseline set, @@ -48,6 +49,7 @@ export interface ChatMemoryRedactionOptions { audit?: RedactionAuditSink } +/** Redaction and tokenization settings for vector document content. */ export interface VectorMemoryRedactionOptions extends ChatMemoryRedactionOptions {} async function transform( @@ -78,6 +80,12 @@ async function transform( return createPIIRedactor({ rules: opts.rules }).redact(input).value } +/** Wraps chat memory to redact or tokenize message content before saves. + * @param inner Chat memory implementation to wrap. + * @param options Redaction rules and optional tokenization settings. + * @returns A chat memory wrapper that redacts saved message content. + * @throws {ConfigError} When tokenization lacks a vault or allowed roles. + */ export function wrapChatMemoryWithRedaction( inner: ChatMemory, options: ChatMemoryRedactionOptions, diff --git a/packages/memory/src/redis-chat.ts b/packages/memory/src/redis-chat.ts index 59cbe727d..2359ee915 100644 --- a/packages/memory/src/redis-chat.ts +++ b/packages/memory/src/redis-chat.ts @@ -9,6 +9,7 @@ import { createRedisClientAdapter } from './redis-client' type MemoryOperationOptions = Parameters[0] +/** Redis connection and key-prefix settings for chat memory. */ export interface RedisChatMemoryConfig extends RedisConnectionConfig { keyPrefix?: string conversationId?: string @@ -23,6 +24,11 @@ function decodeMessages(json: string | null): Message[] { return decodeStoredMessages(json, 'redisChatMemory') } +/** Creates a chat memory that stores conversation snapshots in Redis. + * @param config Redis URL or client and optional namespace settings. + * @returns A chat memory backed by Redis. + * @throws {MemoryError} When the optional Redis dependency is missing or cannot connect. + */ export function redisChatMemory(config: RedisChatMemoryConfig): ChatMemory { const prefix = config.keyPrefix ?? 'agentskit:chat' const convId = config.conversationId ?? 'default' diff --git a/packages/memory/src/redis-client.ts b/packages/memory/src/redis-client.ts index 16e17ea83..1a4f24003 100644 --- a/packages/memory/src/redis-client.ts +++ b/packages/memory/src/redis-client.ts @@ -5,6 +5,7 @@ import { ErrorCodes, MemoryError } from '@agentskit/core' * Abstracts the underlying Redis library so it can be swapped * (e.g., from `redis` to `ioredis`) without changing consumers. */ +/** Redis client operations used by the chat and vector memory backends. */ export interface RedisClientAdapter { get(key: string): Promise set(key: string, value: string): Promise @@ -14,11 +15,17 @@ export interface RedisClientAdapter { call(command: string, ...args: (string | number | Buffer)[]): Promise } +/** Connection URL and optional injected Redis adapter. */ export interface RedisConnectionConfig { url: string client?: RedisClientAdapter } +/** Creates a node-redis adapter and connects it to the supplied URL. + * @param url Redis connection URL. + * @returns A connected Redis client adapter. + * @throws {MemoryError} When the optional Redis dependency is missing. + */ export async function createRedisClientAdapter(url: string): Promise { let redis: typeof import('redis') try { diff --git a/packages/memory/src/redis-vector.ts b/packages/memory/src/redis-vector.ts index f13b28bce..abf31b40c 100644 --- a/packages/memory/src/redis-vector.ts +++ b/packages/memory/src/redis-vector.ts @@ -2,6 +2,7 @@ import type { VectorMemory, VectorDocument, RetrievedDocument } from '@agentskit import type { RedisClientAdapter, RedisConnectionConfig } from './redis-client' import { createRedisClientAdapter } from './redis-client' +/** Redis connection and index settings for vector memory. */ export interface RedisVectorMemoryConfig extends RedisConnectionConfig { indexName?: string keyPrefix?: string @@ -16,6 +17,11 @@ function float32Buffer(vector: number[]): Buffer { return buffer } +/** Creates a vector memory backed by Redis vector search commands. + * @param config Redis URL or client and optional index settings. + * @returns A vector memory backed by the configured Redis index. + * @throws {MemoryError} When the optional Redis dependency is missing or cannot connect. + */ export function redisVectorMemory(config: RedisVectorMemoryConfig): VectorMemory { const indexName = config.indexName ?? 'agentskit:vectors:idx' const prefix = config.keyPrefix ?? 'agentskit:vec' diff --git a/packages/memory/src/sqlite.ts b/packages/memory/src/sqlite.ts index b0929ecbb..b3dce0fc3 100644 --- a/packages/memory/src/sqlite.ts +++ b/packages/memory/src/sqlite.ts @@ -11,6 +11,7 @@ import { decodeStoredMessages } from './decode' type MemoryOperationOptions = Parameters[0] +/** Database path and optional SQLite opener for chat memory. */ export interface SqliteChatMemoryConfig { path: string conversationId?: string @@ -46,6 +47,11 @@ async function openDatabase(path: string): Promise { } } +/** Creates a chat memory that stores conversation snapshots in SQLite. + * @param config Database path and optional opener. + * @returns A chat memory backed by the configured database. + * @throws {MemoryError} When the optional SQLite dependency is missing or cannot open the database. + */ export function sqliteChatMemory(config: SqliteChatMemoryConfig): ChatMemory { const conversationId = config.conversationId ?? 'default' let dbPromise: Promise | null = null diff --git a/packages/memory/src/turso.ts b/packages/memory/src/turso.ts index 2509b6f8d..c7aa39931 100644 --- a/packages/memory/src/turso.ts +++ b/packages/memory/src/turso.ts @@ -11,6 +11,7 @@ import { decodeStoredMessages } from './decode' type MemoryOperationOptions = Parameters[0] +/** Turso URL, auth token, and optional database client settings. */ export interface TursoChatMemoryConfig { /** libSQL URL — file:..., libsql://..., or http://... */ url: string diff --git a/packages/memory/src/vector-store.ts b/packages/memory/src/vector-store.ts index 99780ca06..9e7303e6f 100644 --- a/packages/memory/src/vector-store.ts +++ b/packages/memory/src/vector-store.ts @@ -1,15 +1,18 @@ +/** Vector and metadata fields stored by a backend-neutral vector store. */ export interface VectorStoreDocument { id: string vector: number[] metadata: Record } +/** Search result returned by a backend-neutral vector store. */ export interface VectorStoreResult { id: string score: number metadata: Record } +/** Backend-neutral upsert, query, and delete contract for vector data. */ export interface VectorStore { upsert(docs: VectorStoreDocument[]): Promise query(vector: number[], topK: number): Promise diff --git a/packages/memory/src/vector/chroma.ts b/packages/memory/src/vector/chroma.ts index 9af75d366..28f69588c 100644 --- a/packages/memory/src/vector/chroma.ts +++ b/packages/memory/src/vector/chroma.ts @@ -2,6 +2,7 @@ import { ErrorCodes, MemoryError } from '@agentskit/core' import type { RetrievedDocument, VectorDocument, VectorMemory } from '@agentskit/core' import { remoteJson, type RemoteHttpConfig } from './http' +/** URL, optional API key, and collection settings for Chroma. */ export interface ChromaConfig extends RemoteHttpConfig { /** Base URL of a running Chroma HTTP server. */ url: string @@ -33,6 +34,10 @@ async function call( }) } +/** Creates a vector memory backed by Chroma's HTTP API. + * @param config Chroma URL, collection, credentials, and search defaults. + * @returns A vector memory backed by the configured collection. + */ export function chroma(config: ChromaConfig): VectorMemory { const defaultTopK = Math.max(1, config.topK ?? 10) let urlEnd = config.url.length diff --git a/packages/memory/src/vector/http.ts b/packages/memory/src/vector/http.ts index 340f8f455..8c612b34e 100644 --- a/packages/memory/src/vector/http.ts +++ b/packages/memory/src/vector/http.ts @@ -1,6 +1,7 @@ import { ErrorCodes, MemoryError } from '@agentskit/core' import { NetError, NetErrorCodes, readText } from '@agentskit/net' +/** Shared credentials, fetch, and timeout settings for HTTP vector stores. */ export interface RemoteHttpConfig { /** * Fetch implementation for remote vector calls. Defaults to `globalThis.fetch`. diff --git a/packages/memory/src/vector/milvus.ts b/packages/memory/src/vector/milvus.ts index 538865d3e..160030f73 100644 --- a/packages/memory/src/vector/milvus.ts +++ b/packages/memory/src/vector/milvus.ts @@ -2,6 +2,7 @@ import type { RetrievedDocument, VectorDocument, VectorMemory } from '@agentskit import { remoteJson, type RemoteHttpConfig } from './http' import { validateIdentifier } from './validation' +/** URL, collection, and credentials for a Milvus-compatible HTTP API. */ export interface MilvusConfig extends RemoteHttpConfig { /** Milvus REST endpoint, e.g. `https://in03-xxx.api.gcp-us-west1.zillizcloud.com`. */ url: string @@ -28,6 +29,10 @@ async function call( }) } +/** Creates a vector memory backed by the Milvus HTTP API. + * @param config Endpoint, collection, credentials, and search defaults. + * @returns A vector memory backed by the configured collection. + */ export function milvusVectorStore(config: MilvusConfig): VectorMemory { const collection = validateIdentifier(config.collection, 'collection') const defaultTopK = Math.max(1, config.topK ?? 10) diff --git a/packages/memory/src/vector/mongo-atlas.ts b/packages/memory/src/vector/mongo-atlas.ts index 16929ed1f..036aad6dd 100644 --- a/packages/memory/src/vector/mongo-atlas.ts +++ b/packages/memory/src/vector/mongo-atlas.ts @@ -16,6 +16,7 @@ export interface MongoCollectionLike { } } +/** Collection adapter and search settings for MongoDB Atlas vector memory. */ export interface MongoAtlasVectorConfig { collection: MongoCollectionLike /** Atlas Search index name on the embedding field. */ @@ -27,6 +28,10 @@ export interface MongoAtlasVectorConfig { topK?: number } +/** Creates a vector memory backed by a MongoDB Atlas collection. + * @param config Collection adapter, vector field, and search settings. + * @returns A vector memory backed by the configured collection. + */ export function mongoAtlasVectorStore(config: MongoAtlasVectorConfig): VectorMemory { const defaultTopK = Math.max(1, config.topK ?? 10) const vectorField = config.vectorField ?? 'embedding' diff --git a/packages/memory/src/vector/pgvector.ts b/packages/memory/src/vector/pgvector.ts index fc545a6e6..24096b3b0 100644 --- a/packages/memory/src/vector/pgvector.ts +++ b/packages/memory/src/vector/pgvector.ts @@ -9,6 +9,7 @@ import { validateIdentifier } from './validation' * `metadata jsonb`. */ +/** Async SQL query adapter used by the pgvector backend. */ export interface PgVectorRunner { query: >( sql: string, @@ -16,6 +17,7 @@ export interface PgVectorRunner { ) => Promise<{ rows: T[] }> } +/** SQL runner, table, and search defaults for pgvector memory. */ export interface PgVectorConfig { runner: PgVectorRunner /** Table name. Default 'agentskit_vectors'. */ @@ -28,6 +30,10 @@ function formatVector(embedding: number[]): string { return `[${embedding.join(',')}]` } +/** Creates a vector memory backed by a PostgreSQL pgvector table. + * @param config SQL runner and optional table and result limit. + * @returns A vector memory that upserts and searches the configured table. + */ export function pgvector(config: PgVectorConfig): VectorMemory { const table = validateIdentifier(config.table ?? 'agentskit_vectors', 'table') const defaultTopK = Math.max(1, config.topK ?? 10) diff --git a/packages/memory/src/vector/pinecone.ts b/packages/memory/src/vector/pinecone.ts index 6d29e58af..6c9a96c4a 100644 --- a/packages/memory/src/vector/pinecone.ts +++ b/packages/memory/src/vector/pinecone.ts @@ -1,6 +1,7 @@ import type { RetrievedDocument, VectorDocument, VectorMemory } from '@agentskit/core' import { remoteJson, type RemoteHttpConfig } from './http' +/** Index URL, API key, namespace, and search settings for Pinecone. */ export interface PineconeConfig extends RemoteHttpConfig { /** Full index URL, e.g. `https://-.svc..pinecone.io`. */ indexUrl: string @@ -22,6 +23,10 @@ async function call(config: PineconeConfig, path: string, body: unknown): Pro }) } +/** Creates a vector memory backed by the Pinecone vector API. + * @param config Index endpoint, API key, and optional namespace and result limit. + * @returns A vector memory backed by the configured Pinecone index. + */ export function pinecone(config: PineconeConfig): VectorMemory { const defaultTopK = Math.max(1, config.topK ?? 10) const namespace = config.namespace ?? '' diff --git a/packages/memory/src/vector/qdrant.ts b/packages/memory/src/vector/qdrant.ts index 9253939f6..8cbfab6fb 100644 --- a/packages/memory/src/vector/qdrant.ts +++ b/packages/memory/src/vector/qdrant.ts @@ -2,6 +2,7 @@ import type { RetrievedDocument, VectorDocument, VectorMemory } from '@agentskit import { remoteJson, type RemoteHttpConfig } from './http' import { validateIdentifier } from './validation' +/** Endpoint, collection, credentials, and search defaults for Qdrant. */ export interface QdrantConfig extends RemoteHttpConfig { /** Base URL, e.g. `https://xxx.cluster-qdrant.io`. */ url: string @@ -46,6 +47,10 @@ async function call( }) } +/** Creates a vector memory backed by a Qdrant collection. + * @param config Qdrant endpoint, collection, and optional credentials and result limit. + * @returns A vector memory backed by the configured collection. + */ export function qdrant(config: QdrantConfig): VectorMemory { const collection = encodeURIComponent(validateIdentifier(config.collection, 'collection')) const defaultTopK = Math.max(1, config.topK ?? 10) diff --git a/packages/memory/src/vector/supabase.ts b/packages/memory/src/vector/supabase.ts index 8cdd8f2af..e1f4ebf5f 100644 --- a/packages/memory/src/vector/supabase.ts +++ b/packages/memory/src/vector/supabase.ts @@ -1,6 +1,7 @@ import { ErrorCodes, MemoryError } from '@agentskit/core' import type { RetrievedDocument, VectorMemory, VectorSearchOptions } from '@agentskit/core' +/** Supabase client and table settings for vector memory. */ export interface SupabaseVectorStoreConfig { /** Supabase project URL, e.g. `https://xyz.supabase.co`. */ url: string @@ -76,6 +77,10 @@ function throwOnError(result: SupabaseResult, operation: string): void * purpose-specific similarity-search RPC. The service-role key stays * server-side and `@supabase/supabase-js` is loaded lazily. */ +/** Creates a vector memory backed by a Supabase table and RPC search function. + * @param config Supabase client, table, and optional search settings. + * @returns A vector memory backed by the configured Supabase schema. + */ export function supabaseVectorStore(config: SupabaseVectorStoreConfig): VectorMemory { const table = config.table ?? 'agentskit_vectors' const matchFunction = config.matchFunction ?? 'match_agentskit_vectors' diff --git a/packages/memory/src/vector/upstash.ts b/packages/memory/src/vector/upstash.ts index 2f2333875..09ff9ee3b 100644 --- a/packages/memory/src/vector/upstash.ts +++ b/packages/memory/src/vector/upstash.ts @@ -1,6 +1,7 @@ import type { RetrievedDocument, VectorDocument, VectorMemory } from '@agentskit/core' import { remoteJson, type RemoteHttpConfig } from './http' +/** REST URL, token, and index settings for Upstash Vector. */ export interface UpstashVectorConfig extends RemoteHttpConfig { url: string token: string diff --git a/packages/memory/src/vector/weaviate.ts b/packages/memory/src/vector/weaviate.ts index 8fdcca231..b1ac0fe5b 100644 --- a/packages/memory/src/vector/weaviate.ts +++ b/packages/memory/src/vector/weaviate.ts @@ -2,6 +2,7 @@ import type { RetrievedDocument, VectorDocument, VectorMemory } from '@agentskit import { remoteJson, type RemoteHttpConfig } from './http' import { validateIdentifier } from './validation' +/** Endpoint, class, credentials, and search settings for Weaviate. */ export interface WeaviateConfig extends RemoteHttpConfig { /** Cluster URL, e.g. `https://my-cluster.weaviate.network`. */ url: string @@ -28,6 +29,10 @@ async function call( }) } +/** Creates a vector memory backed by a Weaviate class. + * @param config Weaviate endpoint, class, and optional credentials and result limit. + * @returns A vector memory backed by the configured class. + */ export function weaviateVectorStore(config: WeaviateConfig): VectorMemory { const defaultTopK = Math.max(1, config.topK ?? 10) const className = validateIdentifier(config.className, 'className') diff --git a/packages/memory/src/web-storage.ts b/packages/memory/src/web-storage.ts index facee0c6c..dc972d05f 100644 --- a/packages/memory/src/web-storage.ts +++ b/packages/memory/src/web-storage.ts @@ -2,17 +2,20 @@ import { deserializeMessages, ErrorCodes, MemoryError, serializeMessages } from import { validateMemoryRecord } from '@agentskit/core/memory-validation' import type { ChatMemory, Message } from '@agentskit/core' +/** Minimal Web Storage methods required by browser chat memory. */ export interface WebStorageLike { readonly getItem: (key: string) => string | null readonly setItem: (key: string, value: string) => void readonly removeItem: (key: string) => void } +/** Adapter for reading legacy records into canonical AgentsKit messages. */ export interface WebStorageMemoryMigration { readonly keys: readonly string[] readonly read: (value: unknown, key: string) => readonly Message[] | undefined } +/** Storage key, bounds, and optional migration settings for web memory. */ export interface WebStorageMemoryOptions { readonly key: string readonly getStorage: () => WebStorageLike | undefined @@ -71,6 +74,17 @@ const encodeRecord = (messages: readonly Message[], maxRecordBytes: number): str /** * Creates a validated, bounded ChatMemory over an injected browser Web Storage backend. * The storage getter is evaluated lazily so browser globals can remain SSR-safe. + * @param options Storage key, getter, retention limits, and optional migration. + * @returns A chat memory that validates and bounds records in Web Storage. + * @throws {TypeError} When the key or a configured limit is invalid. + * @throws {MemoryError} When a saved message record is invalid or exceeds its byte limit. + * @example + * ```ts + * const memory = createWebStorageMemory({ + * key: 'agentskit-chat', + * getStorage: () => globalThis.localStorage, + * }) + * ``` */ export function createWebStorageMemory({ key, From e40e737587eb8e7a1136dcc7949878a88ec75a7f Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 16:10:29 -0300 Subject: [PATCH 29/30] docs(observability): document public API --- .changeset/quiet-observability-docs.md | 5 +++ .../src/langfuse-types.ts | 2 + .../observability-langfuse/src/langfuse.ts | 10 ++++- packages/observability/src/audit-log.ts | 20 ++++++++- packages/observability/src/axiom.ts | 7 ++- packages/observability/src/console-logger.ts | 6 +++ packages/observability/src/cost-chargeback.ts | 16 +++++++ .../src/cost-guard-advanced-types.ts | 7 +++ .../observability/src/cost-guard-advanced.ts | 17 ++++--- .../src/cost-guard-alert-sinks.ts | 20 +++++++-- .../src/cost-guard-multi-tenant.ts | 1 + packages/observability/src/cost-guard.ts | 44 +++++++++++++++++++ packages/observability/src/datadog.ts | 7 ++- packages/observability/src/devtools.ts | 27 +++++++----- packages/observability/src/langsmith.ts | 11 ++++- packages/observability/src/new-relic.ts | 7 ++- packages/observability/src/opentelemetry.ts | 11 ++++- packages/observability/src/prod-control.ts | 33 +++++++------- packages/observability/src/redaction.ts | 9 ++++ packages/observability/src/replay-bisect.ts | 3 ++ packages/observability/src/replay-timeline.ts | 24 ++++++++++ packages/observability/src/replay.ts | 7 +++ packages/observability/src/slo.ts | 15 +++++++ packages/observability/src/topology-graph.ts | 26 ++++++++--- packages/observability/src/trace-tracker.ts | 20 ++++++--- packages/observability/src/trace-viewer.ts | 14 ++++-- 26 files changed, 301 insertions(+), 68 deletions(-) create mode 100644 .changeset/quiet-observability-docs.md diff --git a/.changeset/quiet-observability-docs.md b/.changeset/quiet-observability-docs.md new file mode 100644 index 000000000..ddac555f8 --- /dev/null +++ b/.changeset/quiet-observability-docs.md @@ -0,0 +1,5 @@ +--- +'@agentskit/observability': patch +--- + +Document the public API. diff --git a/packages/observability-langfuse/src/langfuse-types.ts b/packages/observability-langfuse/src/langfuse-types.ts index 417790fc5..31d77f382 100644 --- a/packages/observability-langfuse/src/langfuse-types.ts +++ b/packages/observability-langfuse/src/langfuse-types.ts @@ -1,5 +1,6 @@ import type { Observer } from '@agentskit/core' +/** Credentials, trace metadata, batching, and error settings for Langfuse. */ export interface LangfuseConfig { publicKey?: string secretKey?: string @@ -17,6 +18,7 @@ export interface LangfuseConfig { onError?: (error: unknown) => void | Promise } +/** Langfuse observer with explicit flush and shutdown methods. */ export interface LangfuseObserver extends Observer { flush: () => Promise shutdown: () => Promise diff --git a/packages/observability-langfuse/src/langfuse.ts b/packages/observability-langfuse/src/langfuse.ts index 458f9dc16..e6faae875 100644 --- a/packages/observability-langfuse/src/langfuse.ts +++ b/packages/observability-langfuse/src/langfuse.ts @@ -19,8 +19,14 @@ import type { export type { LangfuseConfig, LangfuseObserver } from './langfuse-types' /** - * Langfuse observer factory. Construction is pure (no SDK import / I/O). - * One Langfuse trace per agent run, inferred only by `agent:step` with step 1. + * Create a lazy-loading observer that maps each agent run to a Langfuse trace. + * Construction does not import the SDK or perform I/O; a run boundary is inferred from `agent:step` 1. + * @param config Optional Langfuse credentials, metadata, batching, and error callback. + * @returns An observer with `flush` and idempotent `shutdown` methods. + * @example + * ```ts + * const observer = langfuse({ publicKey: 'pk-lf-...', secretKey: 'sk-lf-...' }) + * ``` */ export function langfuse(config: LangfuseConfig = {}): LangfuseObserver { validateConfig(config) diff --git a/packages/observability/src/audit-log.ts b/packages/observability/src/audit-log.ts index 93c1a6438..c34bbed6e 100644 --- a/packages/observability/src/audit-log.ts +++ b/packages/observability/src/audit-log.ts @@ -1,6 +1,7 @@ import { createHash, createHmac } from 'node:crypto' import type { PIIRedactionHit } from '@agentskit/core/security' +/** Signed, sequence-numbered audit record linked to its predecessor. */ export interface AuditEntry { /** Monotonic sequence within a log. Starts at 1. */ seq: number @@ -14,6 +15,7 @@ export interface AuditEntry { signature: string } +/** Append-only storage operations required by the signed audit log. */ export interface AuditLogStore { append: (entry: AuditEntry) => Promise list: () => Promise @@ -21,6 +23,7 @@ export interface AuditLogStore { clear?: () => Promise } +/** Secret, storage, and clock settings for a signed audit log. */ export interface AuditLogOptions { /** HMAC secret — rotate out-of-band. */ secret: string @@ -29,12 +32,14 @@ export interface AuditLogOptions { now?: () => Date } +/** Caller-supplied values for one audit record. */ export interface AppendAuditInput { actor: string action: string payload: TPayload } +/** Result of validating audit entry signatures and hash links. */ export interface AuditVerifyResult { ok: boolean /** First entry where the chain broke, or null when ok. */ @@ -42,14 +47,17 @@ export interface AuditVerifyResult { entryCount: number } +/** Operations exposed by a signed hash-chained audit log. */ export interface SignedAuditLog { append: (input: AppendAuditInput) => Promise> verify: () => Promise list: () => Promise } +/** Audit action names emitted for PII redaction and reveal events. */ export type PiiAuditAction = 'pii:redact' | 'pii:reveal' | 'pii:reveal-denied' +/** PII scan details converted to signed audit records. */ export interface PiiAuditInput { actor: string action: PiiAuditAction @@ -58,6 +66,7 @@ export interface PiiAuditInput { reason?: string } +/** PII match metadata stored in an audit record without matched text. */ export interface PiiAuditPayload { subjectId?: string rule: string @@ -149,6 +158,12 @@ export function createSignedAuditLog(options: AuditLogOptions): SignedAuditLog { } } +/** + * Append one audit record for each PII hit, storing offsets but no matched text. + * @param log Signed audit log that receives the records. + * @param input Actor, action, subject, hits, and optional reason to record. + * @returns The appended records in hit order. + */ export async function appendPiiAuditEvents( log: SignedAuditLog, input: PiiAuditInput, @@ -175,7 +190,10 @@ export async function appendPiiAuditEvents( return entries } -/** In-memory `AuditLogStore` — tests, demos, transient deployments. */ +/** + * Create a transient in-memory audit store for tests, demos, or short-lived deployments. + * @returns An empty store implementing the audit log storage contract. + */ export function createInMemoryAuditStore(): AuditLogStore { const entries: AuditEntry[] = [] return { diff --git a/packages/observability/src/axiom.ts b/packages/observability/src/axiom.ts index 6fd1e20c4..4c8d7f846 100644 --- a/packages/observability/src/axiom.ts +++ b/packages/observability/src/axiom.ts @@ -6,6 +6,7 @@ import { type LifecycleObserver, } from './http-batch-sink' +/** Axiom dataset credentials, endpoint, service label, and batch settings. */ export interface AxiomSinkConfig extends HttpBatchOptions { /** Axiom API token. */ token: string @@ -17,6 +18,7 @@ export interface AxiomSinkConfig extends HttpBatchOptions { service?: string } +/** Lifecycle observer returned by `axiomSink`. */ export type AxiomSinkObserver = LifecycleObserver function endpointFor(config: AxiomSinkConfig): string { @@ -45,8 +47,9 @@ function spanToEvent( } /** - * Axiom sink. Batches span start/end events to a dataset ingest endpoint. - * Errors are isolated. + * Create a batched HTTP sink that exports span start and end events to an Axiom dataset; failures are isolated. + * @param config Axiom credentials, dataset, and optional endpoint and batch settings. + * @returns A lifecycle observer with `flush` and `shutdown` methods. */ export function axiomSink(config: AxiomSinkConfig): AxiomSinkObserver { return createHttpBatchSink({ diff --git a/packages/observability/src/console-logger.ts b/packages/observability/src/console-logger.ts index d24b4e363..895960460 100644 --- a/packages/observability/src/console-logger.ts +++ b/packages/observability/src/console-logger.ts @@ -1,6 +1,7 @@ import type { AgentEvent, Observer } from '@agentskit/core' import { safeSnapshot } from './trace-tracker' +/** Output format for the console event logger. */ export interface ConsoleLoggerConfig { format?: 'human' | 'json' } @@ -76,6 +77,11 @@ function formatJSON(event: AgentEvent): string { return JSON.stringify(base) } +/** + * Create an observer that writes agent events to stdout in human or JSON form. + * @param config Optional output format; defaults to the human-readable format. + * @returns An observer that writes one formatted line per event. + */ export function consoleLogger(config: ConsoleLoggerConfig = {}): Observer { const { format = 'human' } = config const formatter = format === 'json' ? formatJSON : formatHuman diff --git a/packages/observability/src/cost-chargeback.ts b/packages/observability/src/cost-chargeback.ts index 32d5ba806..ff6de6a0a 100644 --- a/packages/observability/src/cost-chargeback.ts +++ b/packages/observability/src/cost-chargeback.ts @@ -34,6 +34,7 @@ export interface CostSample { costUsd?: number } +/** Fields supported as chargeback report grouping keys. */ export type ChargebackGroupKey = | 'tenant' | 'user' @@ -45,6 +46,7 @@ export type ChargebackGroupKey = | 'tenant+tool' | 'tenant+model' +/** Grouping, pricing, and inclusive time-window options for a chargeback report. */ export interface ChargebackReportOptions { /** Group key. Default `'tenant'`. */ groupBy?: ChargebackGroupKey @@ -58,6 +60,7 @@ export interface ChargebackReportOptions { to?: string } +/** Aggregated token and spend totals for one chargeback group. */ export interface ChargebackRow { /** Composite group key, joined with '/' for multi-field groups. */ group: string @@ -72,6 +75,7 @@ export interface ChargebackRow { lastAt: string } +/** Aggregated chargeback rows and totals for the requested window. */ export interface ChargebackReport { groupBy: ChargebackGroupKey rows: ChargebackRow[] @@ -130,6 +134,13 @@ function validateSample(sample: CostSample, index: number): void { } } +/** + * Group call samples and calculate token and dollar totals. + * @param samples Per-call usage records to aggregate. + * @param options Grouping, price overrides, and time-window filters. + * @returns Rows sorted by descending spend, plus report totals. + * @throws {ConfigError} When a sample has invalid identity, token, or cost fields. + */ export function chargebackReport( samples: CostSample[], options: ChargebackReportOptions = {}, @@ -204,6 +215,11 @@ function escapeCsv(field: string | number): string { return s } +/** + * Serialize a chargeback report as CSV, including a final totals row. + * @param report Aggregated report to serialize. + * @returns CSV text with a trailing newline. + */ export function chargebackReportToCsv(report: ChargebackReport): string { const lines = [CSV_HEADERS.join(',')] const renderRow = (cells: Array): string => diff --git a/packages/observability/src/cost-guard-advanced-types.ts b/packages/observability/src/cost-guard-advanced-types.ts index 45267a0f1..2e5d68c26 100644 --- a/packages/observability/src/cost-guard-advanced-types.ts +++ b/packages/observability/src/cost-guard-advanced-types.ts @@ -1,7 +1,9 @@ import type { TokenPrice, CostGuardErrorHandler, UnknownModelPolicy } from './cost-guard' +/** Enforcement policy: report only, expose rejection state, or disable the tenant. */ export type CostGuardMode = 'warn' | 'reject' | 'kill' +/** Spend limit and rolling duration for one cost cap. */ export interface CostCapWindow { /** Window length in milliseconds. */ windowMs: number @@ -9,6 +11,7 @@ export interface CostCapWindow { budgetUsd: number } +/** Named rolling spend limits applied to a tenant. */ export interface CostCaps { perMinute?: CostCapWindow perDay?: CostCapWindow @@ -17,12 +20,14 @@ export interface CostCaps { custom?: Record } +/** Event kinds emitted when a budget threshold, forecast, or disablement occurs. */ export type CostAlertType = | 'cost:threshold' | 'cost:exceeded' | 'cost:disabled' | 'cost:forecast' +/** JSON-safe details for a cost guard alert. */ export interface CostAlertEvent { type: CostAlertType tenant: string @@ -47,8 +52,10 @@ export interface CostAlertEvent { reason?: string } +/** Receives cost alerts in registration order. */ export type CostAlertSink = (event: CostAlertEvent) => void | Promise +/** Configuration for per-tenant budgets, rolling caps, and enforcement. */ export interface AdvancedCostGuardOptions { /** Per-tenant USD budgets (overall, applied alongside windows). */ budgets: Record diff --git a/packages/observability/src/cost-guard-advanced.ts b/packages/observability/src/cost-guard-advanced.ts index 14c68163e..9b3d8912b 100644 --- a/packages/observability/src/cost-guard-advanced.ts +++ b/packages/observability/src/cost-guard-advanced.ts @@ -42,12 +42,7 @@ export { } from './cost-guard-alert-sinks' export type { WebhookAlertSinkOptions } from './cost-guard-alert-sinks' -/** - * Production-grade cost guard. Extends the multi-tenant guard with modes - * (`warn` / `reject` / `kill`), rolling window caps, threshold + forecast - * alerts, and pluggable sinks. Closes #787–#789. - */ - +/** Observer interface and per-tenant controls returned by `createAdvancedCostGuard`. */ export interface AdvancedCostGuard extends Observer { setTenant: (tenant: string | undefined) => void costUsd: (tenant: string) => number @@ -66,6 +61,16 @@ export interface AdvancedCostGuard extends Observer { tenants: () => string[] } +/** + * Create a per-tenant cost guard with rolling caps and configurable enforcement. + * @param options Budgets, caps, pricing, enforcement mode, and alert sinks. + * @returns An observer with tenant state and control methods. + * @throws {ConfigError} When options are invalid or kill mode has no `disableRuntime` callback. + * @example + * ```ts + * const guard = createAdvancedCostGuard({ budgets: { acme: 10 }, mode: 'reject' }) + * ``` + */ export function createAdvancedCostGuard( options: AdvancedCostGuardOptions, ): AdvancedCostGuard { diff --git a/packages/observability/src/cost-guard-alert-sinks.ts b/packages/observability/src/cost-guard-alert-sinks.ts index 435a2f552..bfcf915c8 100644 --- a/packages/observability/src/cost-guard-alert-sinks.ts +++ b/packages/observability/src/cost-guard-alert-sinks.ts @@ -6,7 +6,10 @@ function resolveGlobalFetch(): typeof fetch | undefined { return typeof candidate === 'function' ? (candidate as typeof fetch) : undefined } -/** Console alert sink — `[cost:] $/$`. */ +/** + * Create an alert sink that writes cost alert details to stderr. + * @returns A sink that formats one concise line for each alert. + */ export function consoleAlertSink(): CostAlertSink { return event => { const line = `[${event.type}] tenant=${event.tenant} window=${event.window} ` + @@ -18,6 +21,7 @@ export function consoleAlertSink(): CostAlertSink { } } +/** HTTP and retry settings for `webhookAlertSink`. */ export interface WebhookAlertSinkOptions { url: string /** Override fetch (tests / custom clients). */ @@ -26,7 +30,11 @@ export interface WebhookAlertSinkOptions { headers?: Record } -/** Generic webhook sink — POSTs the event JSON. Rejects on HTTP !ok. */ +/** + * Create a sink that posts cost alerts as JSON to a webhook endpoint. + * @param options Endpoint and optional fetch implementation and headers. + * @returns An async sink that rejects when the HTTP response is not successful. + */ export function webhookAlertSink(options: WebhookAlertSinkOptions): CostAlertSink { // Prefer injected fetch; fall back to globalThis so missing global never ReferenceErrors. const fetchImpl = options.fetch ?? resolveGlobalFetch() @@ -44,8 +52,12 @@ export function webhookAlertSink(options: WebhookAlertSinkOptions): CostAlertSin } /** - * Throttle wrapper — at most one alert per (tenant, window, type) - * per `windowMs`. Wrap any sink to bound emit rate. + * Throttle alerts by tenant, window, type, and threshold for the given interval. + * @param sink Sink to wrap. + * @param windowMs Minimum interval between matching alerts. + * @param now Clock used to compare alert times; defaults to `Date.now`. + * @returns A sink that forwards at most one matching alert per interval. + * @throws {ConfigError} When `windowMs` is not finite and positive. */ export function throttle( sink: CostAlertSink, diff --git a/packages/observability/src/cost-guard-multi-tenant.ts b/packages/observability/src/cost-guard-multi-tenant.ts index d0e2de5e4..e865f8312 100644 --- a/packages/observability/src/cost-guard-multi-tenant.ts +++ b/packages/observability/src/cost-guard-multi-tenant.ts @@ -12,6 +12,7 @@ import { type CostGuardErrorHandler, } from './cost-guard' +/** Per-tenant budgets, pricing, tenant resolver, and isolated callbacks. */ export interface MultiTenantCostGuardOptions { /** * Per-tenant USD budgets. Tenants not listed here either inherit diff --git a/packages/observability/src/cost-guard.ts b/packages/observability/src/cost-guard.ts index 141410ade..751aefdd3 100644 --- a/packages/observability/src/cost-guard.ts +++ b/packages/observability/src/cost-guard.ts @@ -8,6 +8,7 @@ export interface TokenPrice { output: number } +/** Controls whether pricing an unlisted model fails or treats it as free. */ export type UnknownModelPolicy = 'error' | 'allow-zero' /** Isolated error reporter shared by all cost guards. */ @@ -47,6 +48,7 @@ export const DEFAULT_PRICES: Record = { 'ollama': { input: 0, output: 0 }, } +/** Configuration for an observer that tracks cumulative token spend. */ export interface CostGuardOptions { /** Hard budget in USD. Aborts the run when exceeded. */ budgetUsd: number @@ -109,6 +111,12 @@ export function priceFor( return { input: 0, output: 0 } } +/** + * Check whether a model matches a configured price prefix. + * @param model Model id to look up; missing ids never match. + * @param prices Price prefixes to inspect. Defaults to the built-in table. + * @returns Whether any case-insensitive prefix matches the model. + */ export function hasPriceFor( model: string | undefined, prices: Record = DEFAULT_PRICES, @@ -117,6 +125,14 @@ export function hasPriceFor( return Object.keys(prices).some(key => model.toLowerCase().startsWith(key.toLowerCase())) } +/** + * Resolve a model price, applying the selected policy when no prefix matches. + * @param model Model id to price. + * @param prices Price prefixes to inspect. + * @param policy Behavior when no price matches. Defaults to `error`. + * @returns The first matching price, or zero pricing when allowed. + * @throws {ConfigError} When no price matches and `policy` is `error`. + */ export function resolvePrice( model: string | undefined, prices: Record, @@ -131,6 +147,14 @@ export function resolvePrice( }) } +/** + * Resolve a price and report lookup errors through an isolated error callback. + * @param model Model id to price. + * @param prices Price prefixes to inspect. + * @param policy Behavior when no price matches. + * @param onError Optional isolated error callback. + * @returns The resolved price, or `undefined` when lookup fails. + */ export function resolvePriceSafely( model: string | undefined, prices: Record, @@ -195,6 +219,13 @@ export function invokeCostGuardCallback( } } +/** + * Throw a configuration error unless a value is finite and non-negative. + * @param scope Name of the config or helper being validated. + * @param name Name of the value in that scope. + * @param value Value to validate. + * @throws {ConfigError} When `value` is negative or non-finite. + */ export function assertFiniteNonNegative( scope: string, name: string, @@ -209,6 +240,13 @@ export function assertFiniteNonNegative( } } +/** + * Throw a configuration error unless a value is finite and greater than zero. + * @param scope Name of the config or helper being validated. + * @param name Name of the value in that scope. + * @param value Value to validate. + * @throws {ConfigError} When `value` is not finite and positive. + */ export function assertFinitePositive( scope: string, name: string, @@ -223,6 +261,12 @@ export function assertFinitePositive( } } +/** + * Validate every input and output price in an optional price table. + * @param scope Name included in validation errors. + * @param prices Optional model-to-price table to validate. + * @throws {ConfigError} When any configured price is negative or non-finite. + */ export function validateTokenPrices( scope: string, prices: Record | undefined, diff --git a/packages/observability/src/datadog.ts b/packages/observability/src/datadog.ts index ba51747be..92654ec17 100644 --- a/packages/observability/src/datadog.ts +++ b/packages/observability/src/datadog.ts @@ -6,6 +6,7 @@ import { type LifecycleObserver, } from './http-batch-sink' +/** Datadog API key, site, service tags, and batch settings. */ export interface DatadogSinkConfig extends HttpBatchOptions { apiKey: string /** Datadog site, defaults to `datadoghq.com` (US1). Use `datadoghq.eu`, `us5.datadoghq.com`, etc. */ @@ -16,6 +17,7 @@ export interface DatadogSinkConfig extends HttpBatchOptions { env?: string } +/** Lifecycle observer returned by `datadogSink`. */ export type DatadogSinkObserver = LifecycleObserver function siteEndpoint(site = 'datadoghq.com'): string { @@ -48,8 +50,9 @@ function spanToLog( } /** - * Datadog Logs sink. Batches span start/end as JSON log entries to Datadog's - * HTTP intake. Failures are isolated — observability never breaks the main loop. + * Create a batched HTTP sink that exports span events as JSON logs to Datadog; failures are isolated. + * @param config API key, Datadog site, service tags, and batch settings. + * @returns A lifecycle observer with `flush` and `shutdown` methods. */ export function datadogSink(config: DatadogSinkConfig): DatadogSinkObserver { return createHttpBatchSink({ diff --git a/packages/observability/src/devtools.ts b/packages/observability/src/devtools.ts index 7b767d133..d79e04ca9 100644 --- a/packages/observability/src/devtools.ts +++ b/packages/observability/src/devtools.ts @@ -1,17 +1,20 @@ import type { AgentEvent, Observer } from '@agentskit/core' import { ConfigError, createId, ErrorCodes } from '@agentskit/core' +/** Transport endpoint that receives devtools envelopes. */ export interface DevtoolsClient { id: string send: (event: DevtoolsEnvelope) => void close?: () => void } +/** Wire messages for connection setup, event delivery, and replay completion. */ export type DevtoolsEnvelope = | { type: 'hello'; protocol: 1; serverId: string; since: string } | { type: 'agent-event'; seq: number; at: number; event: AgentEvent } | { type: 'replay-end'; seq: number } +/** Buffer and server identity settings for the in-process devtools hub. */ export interface DevtoolsServerOptions { /** Max events to retain in the ring buffer. Default 500. */ bufferSize?: number @@ -19,6 +22,7 @@ export interface DevtoolsServerOptions { serverId?: string } +/** Observer, transport hooks, and retained event buffer returned by the hub. */ export interface DevtoolsServer { /** Observer you can plug into `createRuntime({ observers: [...] })`. */ observer: Observer @@ -33,14 +37,15 @@ export interface DevtoolsServer { } /** - * In-process pub/sub hub for agent events. Transport-agnostic — hand - * the returned `attach` function any object that can `send` envelopes - * (an SSE response, a WebSocket, a test sink). Designed as the - * contract a browser devtools extension speaks against. - * - * New clients receive a `hello` envelope followed by a replay of the - * ring buffer (so the extension can jump in mid-session and see - * recent history), then `replay-end`, then the live feed. + * Create a transport-agnostic event hub; new clients receive hello, buffered replay, and the live feed. + * @param options Optional buffer size and server id. + * @returns A runtime observer and transport-agnostic client management methods. + * @throws {ConfigError} When `bufferSize` is not a positive integer. + * @example + * ```ts + * const devtools = createDevtoolsServer() + * const detach = devtools.attach({ id: 'panel', send: envelope => socket.send(toSseFrame(envelope)) }) + * ``` */ export function createDevtoolsServer(options: DevtoolsServerOptions = {}): DevtoolsServer { if (options.bufferSize !== undefined && @@ -123,9 +128,9 @@ export function createDevtoolsServer(options: DevtoolsServerOptions = {}): Devto } /** - * Serialize a devtools envelope as a single `data: ...\n\n` SSE frame. - * Framework-agnostic — hook into Express / Hono / plain http by - * writing the returned string to your response. + * Serialize one devtools envelope as an SSE data frame for Express, Hono, or Node HTTP. + * @param envelope Message to serialize. + * @returns A complete `data:` frame terminated by a blank line. */ export function toSseFrame(envelope: DevtoolsEnvelope): string { return `data: ${JSON.stringify(envelope)}\n\n` diff --git a/packages/observability/src/langsmith.ts b/packages/observability/src/langsmith.ts index 1945314c5..11639f4ac 100644 --- a/packages/observability/src/langsmith.ts +++ b/packages/observability/src/langsmith.ts @@ -2,6 +2,7 @@ import type { AgentEvent, Observer } from '@agentskit/core' import { createTraceTracker, type TraceSpan } from './trace-tracker' import { snapshotAttributes } from './http-batch-sink' +/** API key, project, endpoint, and isolated error callback for LangSmith. */ export interface LangSmithConfig { apiKey: string projectName?: string @@ -10,6 +11,7 @@ export interface LangSmithConfig { onError?: (error: unknown) => void | Promise } +/** LangSmith observer with explicit batch flushing and shutdown lifecycle. */ export interface LangSmithObserver extends Observer { flush(): Promise shutdown(): Promise @@ -43,8 +45,13 @@ function emitError( } /** - * LangSmith observer. Construction is pure (no SDK import). The SDK is loaded - * lazily on the first span that needs a remote run. + * Create a lazy-loading observer that exports tracked spans to LangSmith without construction-time I/O. + * @param config LangSmith credentials and optional project, endpoint, and error handler. + * @returns An observer with `flush` and idempotent `shutdown` methods. + * @example + * ```ts + * const observer = langsmith({ apiKey: process.env.LANGSMITH_API_KEY! }) + * ``` */ export function langsmith(config: LangSmithConfig): LangSmithObserver { const { apiKey, projectName = 'agentskit', endpoint = 'https://api.smith.langchain.com' } = config diff --git a/packages/observability/src/new-relic.ts b/packages/observability/src/new-relic.ts index e30e31545..10f8c1f9b 100644 --- a/packages/observability/src/new-relic.ts +++ b/packages/observability/src/new-relic.ts @@ -6,6 +6,7 @@ import { type LifecycleObserver, } from './http-batch-sink' +/** New Relic API key, region, service label, and batch settings. */ export interface NewRelicSinkConfig extends HttpBatchOptions { /** New Relic license / API key (NRAK-... or license key). */ apiKey: string @@ -15,6 +16,7 @@ export interface NewRelicSinkConfig extends HttpBatchOptions { service?: string } +/** Lifecycle observer returned by `newRelicSink`. */ export type NewRelicSinkObserver = LifecycleObserver function endpointFor(region: 'US' | 'EU' = 'US'): string { @@ -45,8 +47,9 @@ function spanToLog( } /** - * New Relic Logs sink. Batches span start/end events to New Relic's Log API. - * Errors are isolated. + * Create a batched HTTP sink that exports span events to New Relic Logs; failures are isolated. + * @param config API key, region, service name, and batch settings. + * @returns A lifecycle observer with `flush` and `shutdown` methods. */ export function newRelicSink(config: NewRelicSinkConfig): NewRelicSinkObserver { return createHttpBatchSink({ diff --git a/packages/observability/src/opentelemetry.ts b/packages/observability/src/opentelemetry.ts index 8bdaceb33..ec7738f97 100644 --- a/packages/observability/src/opentelemetry.ts +++ b/packages/observability/src/opentelemetry.ts @@ -2,6 +2,7 @@ import type { AgentEvent, Observer } from '@agentskit/core' import { createTraceTracker, type TraceSpan } from './trace-tracker' import { snapshotAttributes } from './http-batch-sink' +/** OTLP endpoint, service name, and isolated error callback. */ export interface OpenTelemetryConfig { endpoint?: string serviceName?: string @@ -9,6 +10,7 @@ export interface OpenTelemetryConfig { onError?: (error: unknown) => void | Promise } +/** OpenTelemetry observer with explicit flush and shutdown lifecycle. */ export interface OpenTelemetryObserver extends Observer { flush(): Promise shutdown(): Promise @@ -67,8 +69,13 @@ function emitError( } /** - * OpenTelemetry observer. Construction is pure. SDK modules load lazily on the - * first span. Owned providers use OTel JS v2 `spanProcessors` constructor config. + * Create a lazy-loading observer that exports tracked spans through OpenTelemetry using the v2 `spanProcessors` config. + * @param config Optional OTLP endpoint, service name, and error callback. + * @returns An observer with `flush` and idempotent `shutdown` methods. + * @example + * ```ts + * const observer = opentelemetry({ endpoint: 'http://localhost:4318/v1/traces' }) + * ``` */ export function opentelemetry(config: OpenTelemetryConfig = {}): OpenTelemetryObserver { const { endpoint = 'http://localhost:4318/v1/traces', serviceName = 'agentskit' } = config diff --git a/packages/observability/src/prod-control.ts b/packages/observability/src/prod-control.ts index fb9c6aa8b..f6e4e9f35 100644 --- a/packages/observability/src/prod-control.ts +++ b/packages/observability/src/prod-control.ts @@ -1,22 +1,6 @@ import { ConfigError, ErrorCodes, type AgentEvent, type Observer } from '@agentskit/core' -/** - * Production agent control surface. Devtools (#35) is dev-only; this - * is the auth-gated production counterpart that lets ops: - * - * - pause an agent loop - * - step a paused loop one iteration - * - inject tool overrides for the next call to a tool - * - snapshot the current state for support tickets - * - replay from a previously-captured snapshot - * - * Designed as a transport-agnostic engine — the same `ControlSurface` - * sits behind an HTTP endpoint, an MCP server, or in-process tests. - * `httpHandler()` ships a bearer-token-gated REST surface so a - * default deployment is one `createServer(handler)` call. - * - * Closes issue #784. - */ +/** Auth-gated, transport-agnostic controls for pausing runs, overriding tools, and capturing or restoring snapshots. */ export interface ToolOverride { /** Tool to override on the next call. */ @@ -33,6 +17,7 @@ export interface ToolOverride { reason?: string } +/** Captured paused state, retained events, and pending tool overrides for a run. */ export interface RunSnapshot { runId: string /** ISO timestamp. */ @@ -48,6 +33,7 @@ export interface RunSnapshot { metadata?: Record } +/** Retention, run correlation, audit, and HTTP authentication settings. */ export interface ControlSurfaceOptions { /** Max events retained per run for snapshots. Default 200. */ snapshotBufferSize?: number @@ -72,6 +58,7 @@ export interface ControlSurfaceOptions { maxRuns?: number } +/** Audit record for a production control action. */ export interface ControlAuditEntry { /** ISO timestamp. */ at: string @@ -83,6 +70,7 @@ export interface ControlAuditEntry { payload?: Record } +/** Runtime hooks and administrative controls returned by `createControlSurface`. */ export interface ControlSurface { /** Plug into `createRuntime({ observers: [control.observer] })`. */ observer: Observer @@ -197,6 +185,17 @@ function assertRunId(runId: string): void { } } +/** + * Create a transport-agnostic control surface for pausing, stepping, and inspecting runs. + * @param options Event retention, run-id resolution, audit, and optional bearer-token settings. + * @returns Observer and control methods for runtime hooks or an HTTP handler. + * @throws {ConfigError} When configured limits are not positive integers or a run id is invalid. + * @example + * ```ts + * const control = createControlSurface({ defaultRunId: 'run-1' }) + * await control.awaitResume('run-1') + * ``` + */ export function createControlSurface(options: ControlSurfaceOptions = {}): ControlSurface { if (options.snapshotBufferSize !== undefined) { assertPositiveInteger('snapshotBufferSize', options.snapshotBufferSize) diff --git a/packages/observability/src/redaction.ts b/packages/observability/src/redaction.ts index ba6ec8f3a..dad028980 100644 --- a/packages/observability/src/redaction.ts +++ b/packages/observability/src/redaction.ts @@ -23,8 +23,10 @@ import { * Closes issue #792. */ +/** Whether observer payloads replace PII or tokenize it through a vault. */ export type RedactionMode = 'redact' | 'tokenize' +/** Rules, mode, vault, roles, and audit sink used to sanitize observer events. */ export interface ObserverRedactionOptions { /** * Rules to apply. Pass `DEFAULT_PII_RULES` for the baseline set, @@ -136,6 +138,13 @@ async function redactEvent( } } +/** + * Wrap an observer so supported event content is redacted or tokenized before delivery. + * @param inner Observer that receives the sanitized event copy. + * @param options PII rules and optional tokenization or audit settings. + * @returns An observer that forwards sanitized events to `inner`. + * @throws {ConfigError} In tokenize mode when vault or allowed roles are missing. + */ export function wrapObserverWithRedaction( inner: Observer, options: ObserverRedactionOptions, diff --git a/packages/observability/src/replay-bisect.ts b/packages/observability/src/replay-bisect.ts index d868f2b4e..ce3af6546 100644 --- a/packages/observability/src/replay-bisect.ts +++ b/packages/observability/src/replay-bisect.ts @@ -3,14 +3,17 @@ // that replays the run at a given change-index and returns ok/fail. The // bisector walks the history with O(log n) probes. +/** Result of probing a change history for the earliest pass-to-fail transition. */ export type BisectVerdict = | { readonly kind: 'culprit'; readonly index: number; readonly probes: number } | { readonly kind: 'all_clean'; readonly probes: number } | { readonly kind: 'all_broken'; readonly probes: number } | { readonly kind: 'inconsistent'; readonly probes: number; readonly detail: string } +/** Replays a history prefix ending at an index and reports whether it passes. */ export type ReplayOracle = (changeIndex: number) => Promise<'pass' | 'fail'> +/** Probe limit and optional callback for `replayBisect`. */ export type BisectOpts = { readonly maxProbes?: number readonly onProbe?: (changeIndex: number, result: 'pass' | 'fail') => void diff --git a/packages/observability/src/replay-timeline.ts b/packages/observability/src/replay-timeline.ts index 1ad0eb9a0..cad8b1f5d 100644 --- a/packages/observability/src/replay-timeline.ts +++ b/packages/observability/src/replay-timeline.ts @@ -13,6 +13,7 @@ import { ErrorCodes, RuntimeError } from '@agentskit/core' +/** Recorded execution checkpoint consumed by the replay timeline helpers. */ export type ReplayStep = { readonly id: string readonly nodeId: string @@ -25,6 +26,7 @@ export type ReplayStep = { readonly outcome: 'ok' | 'failed' | 'paused' | 'skipped' } +/** Cumulative metrics and outcome at one recorded replay checkpoint. */ export type TimelineRow = { readonly index: number readonly stepId: string @@ -36,6 +38,7 @@ export type TimelineRow = { readonly outcome: ReplayStep['outcome'] } +/** Timeline rows, totals, and start/end timestamps for a replay. */ export type Timeline = { readonly rows: readonly TimelineRow[] readonly totalCostUsd: number @@ -44,6 +47,11 @@ export type Timeline = { readonly span: { readonly startedAt: number; readonly endedAt: number } } +/** + * Build cumulative cost, token, and latency totals from recorded steps. + * @param steps Checkpoints in chronological order. + * @returns Timeline rows and totals, with a zero-length span for no steps. + */ export const buildTimeline = (steps: readonly ReplayStep[]): Timeline => { let cost = 0 let tokens = 0 @@ -76,11 +84,18 @@ export const buildTimeline = (steps: readonly ReplayStep[]): Timeline => { } } +/** One property addition, removal, or change between two state snapshots. */ export type StateDiffEntry = | { readonly kind: 'add'; readonly key: string; readonly value: unknown } | { readonly kind: 'remove'; readonly key: string; readonly previous: unknown } | { readonly kind: 'change'; readonly key: string; readonly previous: unknown; readonly value: unknown } +/** + * Compare two shallow state records and return changed property entries. + * @param previous State before the checkpoint. + * @param next State at the checkpoint. + * @returns Added, removed, or changed top-level properties in key order. + */ export const diffState = ( previous: Readonly>, next: Readonly>, @@ -101,12 +116,21 @@ export const diffState = ( return entries } +/** Selected timeline row and its state difference from the previous step. */ export type ReplayPosition = { readonly index: number readonly cumulative: TimelineRow readonly stateDiffFromPrevious: readonly StateDiffEntry[] } +/** + * Select a replay step and calculate its difference from the prior state. + * @param steps Recorded steps used to read adjacent state snapshots. + * @param timeline Timeline built from the same step sequence. + * @param index Zero-based row index to select. + * @returns The selected cumulative row and state difference. + * @throws {RuntimeError} When the index is outside the timeline rows. + */ export const positionAt = ( steps: readonly ReplayStep[], timeline: Timeline, diff --git a/packages/observability/src/replay.ts b/packages/observability/src/replay.ts index dc70eb7ae..44e545525 100644 --- a/packages/observability/src/replay.ts +++ b/packages/observability/src/replay.ts @@ -6,8 +6,15 @@ // (`AgentEvent`, `TraceSpan`, or a host application's own event union) without // coupling the replay driver to a specific schema. +/** Asynchronous or synchronous consumer invoked for each replayed event. */ export type ReplayHandler = (event: E) => void | Promise +/** + * Replay events sequentially through each handler in registration order. + * @param events Ordered event history to replay. + * @param handlers Consumers invoked for each event. + * @returns A promise that resolves after every handler completes. + */ export const replayEvents = async ( events: readonly E[], handlers: readonly ReplayHandler[], diff --git a/packages/observability/src/slo.ts b/packages/observability/src/slo.ts index 14a511674..efd3bbb67 100644 --- a/packages/observability/src/slo.ts +++ b/packages/observability/src/slo.ts @@ -21,6 +21,7 @@ import type { CostAlertEvent, CostAlertSink } from './cost-guard-advanced' * Closes issue #796. */ +/** Target rates and latency used to evaluate the SLO snapshot. */ export interface SloTargets { /** 0–1. Default 0.99. */ successRate?: number @@ -32,6 +33,7 @@ export interface SloTargets { streamingStallRate?: number } +/** Target, stall threshold, burn windows, alert sink, and clock for an SLO observer. */ export interface SloOptions { targets?: SloTargets /** First-token latency above this counts as a stall. Default 8000ms. */ @@ -44,6 +46,7 @@ export interface SloOptions { now?: () => number } +/** Default SLO thresholds used when an observer does not override them. */ export const DEFAULT_SLO_TARGETS: Required = { successRate: 0.99, latencyP95Ms: 5_000, @@ -70,6 +73,7 @@ interface ActiveOp { stall: boolean } +/** Aggregated rates and latency quantiles for a time window. */ export interface SloSnapshot { windowMs: number total: number @@ -81,6 +85,7 @@ export interface SloSnapshot { streamingStallRate: number } +/** Observer with metric snapshots, exporters, and timer cleanup. */ export interface SloObserver extends Observer { snapshot: (windowMs?: number) => SloSnapshot /** Prometheus exposition text (`# HELP / # TYPE / metric{...} value`). */ @@ -154,6 +159,16 @@ function validateOptions(options: SloOptions): void { if (t.latencyP95Ms !== undefined) assertFiniteNonNegative('targets.latencyP95Ms', t.latencyP95Ms) } +/** + * Create an observer that records SLO metrics and periodically emits burn-rate alerts. + * @param options Optional targets, windows, alert sink, and clock. + * @returns An observer with snapshot, Prometheus, OTEL, and stop methods. + * @throws {ConfigError} When a target or window has an invalid value. + * @example + * ```ts + * const slo = sloObserver({ targets: { successRate: 0.995 } }) + * ``` + */ export function sloObserver(options: SloOptions = {}): SloObserver { validateOptions(options) diff --git a/packages/observability/src/topology-graph.ts b/packages/observability/src/topology-graph.ts index 1af84a822..5e91f622f 100644 --- a/packages/observability/src/topology-graph.ts +++ b/packages/observability/src/topology-graph.ts @@ -1,8 +1,4 @@ -/** - * Mirrors the `TopologyLogEvent` shape from `@agentskit/runtime`. We - * redefine it here to avoid a runtime → observability dependency - * cycle; the contract is stable (defined alongside topologies.ts). - */ +/** Runtime topology event mirrored here to avoid an observability-to-runtime dependency cycle. */ export interface TopologyLogEvent { topology: string phase: 'dispatch' | 'agent:start' | 'agent:end' | 'merge' | 'done' @@ -27,6 +23,7 @@ export interface TopologyLogEvent { * Closes issue #785. */ +/** Agent node and activity counters in a topology graph. */ export interface TopologyNode { id: string /** Display label. Defaults to the agent id. */ @@ -41,6 +38,7 @@ export interface TopologyNode { lastActiveAt: number } +/** Directed communication edge between agents in a topology graph. */ export interface TopologyEdge { /** `from→to` (stable id). */ id: string @@ -53,6 +51,7 @@ export interface TopologyEdge { lastResult?: string } +/** Mutable topology graph with serializers and change subscriptions. */ export interface TopologyGraph { nodes: Map edges: Map @@ -73,6 +72,7 @@ export interface TopologyGraph { reset: () => void } +/** JSON-serializable node and edge snapshot with update time. */ export interface TopologyGraphSnapshot { nodes: TopologyNode[] edges: TopologyEdge[] @@ -80,6 +80,7 @@ export interface TopologyGraphSnapshot { updatedAt: string } +/** Snippet length and clock overrides for topology graph creation. */ export interface TopologyGraphOptions { /** Truncation length for task/result tooltips. Default 80. */ snippetLength?: number @@ -94,6 +95,16 @@ function trim(value: string | undefined, max: number): string | undefined { const ROOT = '__root__' +/** + * Create an in-memory graph for topology dispatch and agent activity events. + * @param options Optional snippet length and clock override. + * @returns A mutable graph with JSON, Mermaid, ASCII, and subscription APIs. + * @example + * ```ts + * const graph = createTopologyGraph() + * graph.ingest({ topology: 'swarm', phase: 'agent:start', agent: 'writer' }) + * ``` + */ export function createTopologyGraph(options: TopologyGraphOptions = {}): TopologyGraph { const snippet = options.snippetLength ?? 80 const now = options.now ?? (() => Date.now()) @@ -208,7 +219,10 @@ export function createTopologyGraph(options: TopologyGraphOptions = {}): Topolog for (const edge of childEdges) { const child = nodes.get(edge.to) if (!child) continue - const tag = child.errorCount > 0 ? '✗' : child.endCount > 0 ? '✓' : '…' + let tag: string + if (child.errorCount > 0) tag = '✗' + else if (child.endCount > 0) tag = '✓' + else tag = '…' lines.push(` ├─ ${tag} ${child.label} (${child.startCount} starts, ${child.endCount} done)`) } return lines.join('\n') diff --git a/packages/observability/src/trace-tracker.ts b/packages/observability/src/trace-tracker.ts index b96735edb..b0c42d33f 100644 --- a/packages/observability/src/trace-tracker.ts +++ b/packages/observability/src/trace-tracker.ts @@ -11,6 +11,7 @@ type CorrelationContext = { type CorrelatedAgentEvent = AgentEvent & { readonly correlation?: CorrelationContext } +/** Span identity, timing, attributes, and completion status produced by the tracker. */ export interface TraceSpan { id: string name: string @@ -21,6 +22,7 @@ export interface TraceSpan { status: 'ok' | 'error' } +/** Callbacks invoked when the tracker starts or completes a span. */ export interface TraceTrackerCallbacks { onSpanStart: (span: TraceSpan) => void onSpanEnd: (span: TraceSpan) => void @@ -33,8 +35,9 @@ function boundSnapshot(value: string): string { } /** - * JSON-ish snapshot that never throws on circular refs or BigInt. - * Result is always a string, bounded to SNAPSHOT_LIMIT. + * Convert a value to a bounded JSON-like string without throwing on circular references or BigInt. + * @param value Value to serialize. + * @returns A string no longer than 500 characters, or a fallback for unserializable values. */ export function safeSnapshot(value: unknown): string { try { @@ -72,11 +75,14 @@ function generateSpanId(): string { } /** - * Builds nested spans from a sequential AgentEvent stream. - * - * Assumption: events for the same kind (llm/tool/delegate) are sequential - * and non-interleaved. When present, the optional correlation envelope is - * copied to span attributes; it does not change the ordering contract. + * Build nested spans from a sequential AgentsKit event stream; same-kind events are assumed non-interleaved. + * @param callbacks Receivers for span start and completion events. + * @returns An event handler and `flush` method for closing open spans; correlation fields are copied to attributes. + * @example + * ```ts + * const tracker = createTraceTracker({ onSpanStart: save, onSpanEnd: save }) + * tracker.handle(event) + * ``` */ export function createTraceTracker(callbacks: TraceTrackerCallbacks) { const spanStack: TraceSpan[] = [] diff --git a/packages/observability/src/trace-viewer.ts b/packages/observability/src/trace-viewer.ts index e87764676..cc27b4591 100644 --- a/packages/observability/src/trace-viewer.ts +++ b/packages/observability/src/trace-viewer.ts @@ -1,6 +1,7 @@ import type { TraceSpan } from './trace-tracker' import { ConfigError, ErrorCodes } from '@agentskit/core' +/** Summary metrics and spans for one trace, used by JSON and HTML exporters. */ export interface TraceReport { traceId: string startTime: number @@ -93,6 +94,7 @@ ${rows} ` } +/** Span collector with a disk flush operation that writes JSON and optional HTML. */ export interface FileTraceSink { /** Observer-compatible span callbacks. Plug into `createTraceTracker`. */ onSpanStart: (span: TraceSpan) => void @@ -104,10 +106,14 @@ export interface FileTraceSink { } /** - * Collect spans in memory and write them to disk on demand. The - * default layout under `dir` is: - * .json — TraceReport (JSON) - * .html — offline viewer page (when html !== false) + * Collect spans in memory and write a JSON report and optional offline HTML viewer to a directory. + * @param dir Destination directory created on the first flush. + * @returns Span callbacks, a copy of collected spans, and an async flush method. + * @example + * ```ts + * const sink = createFileTraceSink('./traces') + * const paths = await sink.flush({ traceId: 'run-42' }) + * ``` */ export function createFileTraceSink(dir: string): FileTraceSink { const spans: TraceSpan[] = [] From 49d7f62cf9a66cf620110d25384b29b3cc1a1b8f Mon Sep 17 00:00:00 2001 From: EmersonBraun Date: Sat, 3 Oct 2026 16:16:56 -0300 Subject: [PATCH 30/30] chore(docs): update DOC-03 coverage baseline --- docs/stability/jsdoc-coverage-v1.json | 284 +------------------------- 1 file changed, 3 insertions(+), 281 deletions(-) diff --git a/docs/stability/jsdoc-coverage-v1.json b/docs/stability/jsdoc-coverage-v1.json index 66255b27b..5ffdd1a52 100644 --- a/docs/stability/jsdoc-coverage-v1.json +++ b/docs/stability/jsdoc-coverage-v1.json @@ -46,277 +46,16 @@ ], "@agentskit/eval": [], "@agentskit/ink": [], - "@agentskit/integrations": [ - ".::acuityIntegration", - ".::airtableIntegration", - ".::ApiKeyAuthSpec", - ".::apolloIntegration", - ".::asanaIntegration", - ".::assemblyaiIntegration", - ".::attioIntegration", - ".::AuthSpec", - ".::azureOpenaiIntegration", - ".::baserowIntegration", - ".::bigcommerceIntegration", - ".::boxIntegration", - ".::calComIntegration", - ".::calendlyIntegration", - ".::coingeckoIntegration", - ".::confluenceIntegration", - ".::createRegistry", - ".::deepgramIntegration", - ".::discordIntegration", - ".::dropboxIntegration", - ".::elevenlabsIntegration", - ".::EmailAttachment", - ".::EmailConfig", - ".::emailIntegration", - ".::EmailMessage", - ".::EmailSendMessage", - ".::EmailSendResult", - ".::EmailTransport", - ".::figmaIntegration", - ".::firecrawlIntegration", - ".::getIntegration", - ".::githubActionsIntegration", - ".::githubIntegration", - ".::gmailIntegration", - ".::googleCalendarIntegration", - ".::googleDriveIntegration", - ".::HttpJsonRequest", - ".::HttpToolOptions", - ".::hubspotIntegration", - ".::ImapClient", - ".::ImapFetchOptions", - ".::Integration", - ".::IntegrationAction", - ".::integrationsByCategory", - ".::IntegrationTrigger", - ".::intercomIntegration", - ".::jiraIntegration", - ".::linearIntegration", - ".::linearTriageIntegration", - ".::listIntegrations", - ".::mailchimpIntegration", - ".::mapsIntegration", - ".::NoAuthSpec", - ".::notionIntegration", - ".::OAuth2AuthSpec", - ".::openaiImagesIntegration", - ".::pagerdutyIntegration", - ".::pipedriveIntegration", - ".::readerIntegration", - ".::registerIntegration", - ".::RetryableHttpMethod", - ".::RetryPolicy", - ".::salesforceIntegration", - ".::sendgridIntegration", - ".::sentryIntegration", - ".::shopifyIntegration", - ".::SideEffect", - ".::slackIntegration", - ".::stripeIntegration", - ".::TeamsAdaptiveCard", - ".::TeamsAdaptiveCardAction", - ".::TeamsBotClient", - ".::TeamsBotMessage", - ".::TeamsBotSendResult", - ".::teamsIntegration", - ".::TeamsMessageCard", - ".::telegramIntegration", - ".::twilioIntegration", - ".::VerifyResult", - ".::weatherIntegration", - ".::WebhookInput", - ".::WebhookSecretAuthSpec", - ".::whatsappIntegration", - ".::whisperIntegration", - "./testing::validateAction", - "./testing::validateTrigger" - ], + "@agentskit/integrations": [], "@agentskit/mcp": [ ".::AgentsKitMcpServerOptions", ".::AgentToolConfig", ".::McpServer", ".::TypedAgentToolConfig" ], - "@agentskit/memory": [ - ".::ChatMemoryRedactionOptions", - ".::chroma", - ".::ChromaConfig", - ".::createEncryptedMemory", - ".::createFileStore", - ".::createInMemoryStore", - ".::createKvMemoryFromConfig", - ".::createKvMemoryFromConfigAuto", - ".::CreateKvMemoryFromConfigOpts", - ".::createLocalStorageStore", - ".::CreateLocalStorageStoreOpts", - ".::createRedisStore", - ".::CreateRedisStoreOpts", - ".::createSqliteStore", - ".::CreateSqliteStoreOpts", - ".::createVectorStore", - ".::CreateVectorStoreOpts", - ".::EncryptedEnvelope", - ".::FileKvConfig", - ".::fileVectorMemory", - ".::FileVectorMemoryConfig", - ".::ForgetReport", - ".::ForgetSubjectResult", - ".::GraphEdge", - ".::GraphMemory", - ".::GraphQuery", - ".::HierarchicalMemory", - ".::HierarchicalMemoryOptions", - ".::HierarchicalRecall", - ".::InMemoryKvConfig", - ".::isMemoryBackendSupported", - ".::KvEntry", - ".::KvMemoryConfig", - ".::LocalStorageKvConfig", - ".::LocalStorageLike", - ".::MEMORY_BACKEND_SUPPORT", - ".::MemoryBackendNotImplementedError", - ".::MemoryBackendStatus", - ".::MemoryEmbedderLike", - ".::MemoryVectorStoreLike", - ".::MilvusConfig", - ".::milvusVectorStore", - ".::MongoAtlasVectorConfig", - ".::mongoAtlasVectorStore", - ".::PersonalizationStore", - ".::pgvector", - ".::PgVectorConfig", - ".::pinecone", - ".::PineconeConfig", - ".::qdrant", - ".::QdrantConfig", - ".::redisChatMemory", - ".::RedisChatMemoryConfig", - ".::RedisConnectionConfig", - ".::RedisKvConfig", - ".::RedisLike", - ".::redisVectorMemory", - ".::RedisVectorMemoryConfig", - ".::RemoteHttpConfig", - ".::sqliteChatMemory", - ".::SqliteChatMemoryConfig", - ".::SqliteKvConfig", - ".::SqliteLike", - ".::SqliteOpener", - ".::SqliteStmt", - ".::SupabaseVectorStoreConfig", - ".::TursoChatMemoryConfig", - ".::UpstashVectorConfig", - ".::VectorKvConfig", - ".::VectorMemoryRedactionOptions", - ".::VectorStore", - ".::VectorStoreDocument", - ".::VectorStoreResult", - ".::WeaviateConfig", - ".::weaviateVectorStore", - ".::WebStorageLike", - ".::WebStorageMemoryMigration", - ".::WebStorageMemoryOptions", - ".::wrapChatMemoryWithRedaction", - "./personalization::PersonalizationStore", - "./web-storage::WebStorageLike", - "./web-storage::WebStorageMemoryMigration", - "./web-storage::WebStorageMemoryOptions" - ], + "@agentskit/memory": [], "@agentskit/net": [], - "@agentskit/observability": [ - ".::AdvancedCostGuardOptions", - ".::AppendAuditInput", - ".::appendPiiAuditEvents", - ".::AuditEntry", - ".::AuditLogOptions", - ".::AuditLogStore", - ".::AuditVerifyResult", - ".::AxiomSinkConfig", - ".::AxiomSinkObserver", - ".::BisectOpts", - ".::BisectVerdict", - ".::buildTimeline", - ".::ChargebackGroupKey", - ".::chargebackReport", - ".::ChargebackReport", - ".::ChargebackReportOptions", - ".::chargebackReportToCsv", - ".::ChargebackRow", - ".::consoleLogger", - ".::ConsoleLoggerConfig", - ".::ControlAuditEntry", - ".::ControlSurface", - ".::ControlSurfaceOptions", - ".::CostAlertEvent", - ".::CostAlertSink", - ".::CostAlertType", - ".::CostCaps", - ".::CostCapWindow", - ".::CostGuardMode", - ".::CostGuardOptions", - ".::createAdvancedCostGuard", - ".::createControlSurface", - ".::createTopologyGraph", - ".::DatadogSinkConfig", - ".::DatadogSinkObserver", - ".::DEFAULT_SLO_TARGETS", - ".::DevtoolsClient", - ".::DevtoolsEnvelope", - ".::DevtoolsServer", - ".::DevtoolsServerOptions", - ".::diffState", - ".::FileTraceSink", - ".::LangSmithConfig", - ".::LangSmithObserver", - ".::MultiTenantCostGuardOptions", - ".::NewRelicSinkConfig", - ".::NewRelicSinkObserver", - ".::ObserverRedactionOptions", - ".::OpenTelemetryConfig", - ".::OpenTelemetryObserver", - ".::PiiAuditAction", - ".::PiiAuditInput", - ".::PiiAuditPayload", - ".::positionAt", - ".::replayEvents", - ".::ReplayHandler", - ".::ReplayOracle", - ".::ReplayPosition", - ".::RunSnapshot", - ".::SignedAuditLog", - ".::sloObserver", - ".::SloObserver", - ".::SloOptions", - ".::SloSnapshot", - ".::StateDiffEntry", - ".::Timeline", - ".::TimelineRow", - ".::TopologyEdge", - ".::TopologyGraph", - ".::TopologyGraphOptions", - ".::TopologyGraphSnapshot", - ".::TraceReport", - ".::TraceSpan", - ".::TraceTrackerCallbacks", - ".::UnknownModelPolicy", - ".::WebhookAlertSinkOptions", - ".::wrapObserverWithRedaction", - "./cost-guard::assertFiniteNonNegative", - "./cost-guard::assertFinitePositive", - "./cost-guard::CostGuardOptions", - "./cost-guard::hasPriceFor", - "./cost-guard::resolvePrice", - "./cost-guard::resolvePriceSafely", - "./cost-guard::UnknownModelPolicy", - "./cost-guard::validateTokenPrices", - "./langfuse::LangfuseConfig", - "./langfuse::LangfuseObserver", - "./trace-tracker::TraceSpan", - "./trace-tracker::TraceTrackerCallbacks" - ], + "@agentskit/observability": [], "@agentskit/rag": [], "@agentskit/react": [], "@agentskit/react-native": [], @@ -392,16 +131,6 @@ "./integrations::cloudflareR2SignedUrl", "./integrations::documentParsers", "./integrations::DocumentParsersConfig", - "./integrations::EmailAttachment", - "./integrations::EmailConfig", - "./integrations::EmailMessage", - "./integrations::EmailSendMessage", - "./integrations::EmailSendResult", - "./integrations::EmailTransport", - "./integrations::HttpJsonRequest", - "./integrations::HttpToolOptions", - "./integrations::ImapClient", - "./integrations::ImapFetchOptions", "./integrations::parseDocx", "./integrations::parsePdf", "./integrations::parseXlsx", @@ -417,18 +146,11 @@ "./integrations::postgresQuery", "./integrations::PostgresRolesConfig", "./integrations::R2ClientLike", - "./integrations::RetryPolicy", "./integrations::s3", "./integrations::S3Config", "./integrations::s3GetObject", "./integrations::s3ListObjects", "./integrations::s3PutObject", - "./integrations::TeamsAdaptiveCard", - "./integrations::TeamsAdaptiveCardAction", - "./integrations::TeamsBotClient", - "./integrations::TeamsBotMessage", - "./integrations::TeamsBotSendResult", - "./integrations::TeamsMessageCard", "./mcp-devtools::devtoolsTools", "./mcp-devtools::EvalResult", "./mcp-devtools::EvalSummary",