import type { AgentIdentity, RunAgentOptions } from '../agents/runAgent.js'; import type { Message } from '../types/message/index.js'; import type { LLMProvider } from '../types/provider/index.js'; import type { Skill } from '../types/skills/index.js'; import type { ToolDefinition } from '../types/tool/index.js'; /** * A directory in the convention this package reads. * * `channels/` and `schedules/` are deliberately absent. They were scoped in * and then cut: a trigger definition of `{id, handler}` cannot express a * signed webhook, because signature verification needs the RAW body and a * handler that receives a parsed one can never check an HMAC. It carries no * idempotency key either, while webhooks retry and schedules double-fire, and * a cron field with no timezone story is a declaration nothing drives. Each of * those is a `major` waiting to happen on a published type. The layering * question — does a convention belong outside the kernel — was answered yes * and stands; the shape question had simply never been asked. */ export type DirectorySlot = 'agent' | 'instructions' | 'tools' | 'skills' | 'agents'; export declare const ALL_SLOTS: readonly DirectorySlot[]; /** * Whether the loader executes the project's code. * * `'evaluate'` imports every module-backed file, and importing a module RUNS * it — a top-level side effect in `tools/search.ts` happens during * `loadDirectory`, in this process, with this process's privileges. * * `'skip'` imports nothing. The manifest still carries the full structural * truth — every path, the instructions, the skills, duplicate and ambiguity * detection — and module-backed entries report `'not_loaded'`. This is what a * CI gate, a UI file tree, and triage of a directory you did not write all * actually want, and it is the only mode that is safe against a directory * whose author you are not. */ export type ModuleMode = 'evaluate' | 'skip'; export type ModuleImporter = (fileUrl: string) => Promise; export type SourceOutcome = 'loaded' | 'failed' /** Refused, or not a code file. Carries a diagnostic unless `.`/`_`-prefixed. */ | 'skipped' /** `modules: 'skip'` — never imported, so nothing is known about its exports. */ | 'not_loaded' /** * The import outran `moduleTimeoutMs`. * * NOT a synonym for `'failed'`. `import()` cannot be cancelled: the module * is still executing, may still complete, and its top-level side effects * may land after `loadDirectory` has returned. Node then caches it, so a * second load in the same process can see the same file succeed instantly. * A distinct outcome because "we stopped waiting" and "it did not work" * lead a reader to different places. */ | 'abandoned'; export interface SourceRef { /** Absolute and canonical — symlinks already resolved. */ readonly path: string; /** Posix, relative to the project root: `tools/search.ts`. */ readonly relativePath: string; readonly slot: DirectorySlot; /** Path-derived, extension stripped. `tools/search.ts` → `search`. */ readonly id: string; readonly outcome: SourceOutcome; } export type DirectoryDiagnosticSeverity = 'error' | 'warning'; export type DirectoryDiagnosticCode = 'instructions_missing' | 'instructions_empty' | 'module_load_failed' | 'module_load_abandoned' | 'no_default_export' | 'not_a_tool' | 'duplicate_tool_name' | 'invalid_config' | 'skill_load_failed' | 'symlink_refused' | 'path_escapes_root' | 'unscanned_directory' | 'root_missing' | 'subagent_load_failed' | 'subagent_too_deep'; /** * Something the loader could not do, reported rather than dropped. * * A loader that quietly skips a broken tool produces a project running with * half its capabilities and nothing to say so. Every refusal names its file * and its reason, and an inspector can render the list without re-reading the * directory. */ export interface DirectoryDiagnostic { readonly code: DirectoryDiagnosticCode; readonly severity: DirectoryDiagnosticSeverity; readonly message: string; /** Absolute path, when the diagnostic is about a file. */ readonly path?: string; /** * The underlying error's message, when there was one. * * This package never reads file CONTENTS into a diagnostic. What appears * here is text produced by Node or thrown by the authored module, and is * exactly as trustworthy as that module — a `throw new Error(secret)` puts * the secret here, and no amount of redaction on our side changes that. */ readonly cause?: string; } export interface ToolEntry { readonly source: SourceRef; readonly definition: ToolDefinition; } /** * A delegate this project declares, loaded as a project in its own right. * * Recursion rather than a new concept: a sub-agent directory has the same * shape as its parent, so `agents/researcher/` is read by the same loader * that read the root. One level only — a delegate may not declare delegates of its * own in this version. Unbounded nesting is a topology decision (who may * spawn whom, and how deep) that belongs to whoever composes the system, and * shipping it before that decision means shipping a default nobody chose. */ export interface SubAgentEntry { readonly source: SourceRef; /** The delegate's own manifest — its instructions, tools and config. */ readonly manifest: DirectoryManifest; /** Directory-derived, and the id a supervisor delegates to. */ readonly id: string; } export interface SkillEntry { readonly source: SourceRef; readonly skill: Skill; } /** * What `agent.ts` may declare. * * Deliberately a plain object, default-exported, with no authoring helper. A * `defineAgent` here would collide with the SDK's existing export of that * name, and `export default { model: 'x' } satisfies DirectoryConfig` already * gets the type checking a helper would provide. * * There is no factory form. It would buy environment-conditioned config that * `model: process.env.MODEL` already does inside a module that is being * evaluated anyway, and it would cost a user-function-invocation phase with a * hang mode outside what `moduleTimeoutMs` promises to bound. */ export interface DirectoryConfig { readonly model?: string; readonly temperature?: number; readonly maxIterations?: number; readonly tokenBudget?: number; readonly timeoutMs?: number; /** Maximum provider-stream silence in milliseconds; `0` disables the bound. */ readonly streamIdleTimeoutMs?: number; /** Accumulated inline image/document bytes per provider request; `0` disables. */ readonly maxRequestRichContentBytes?: number; /** Maximum stored-attachment materialization time; `0` disables the bound. */ readonly attachmentResolveTimeoutMs?: number; /** Names the agent in traces and events when declared. */ readonly name?: string; /** Free-form labels for an inspector. Never interpreted by this package. */ readonly metadata?: Readonly>; } export interface DirectoryManifest { /** Absolute, canonical path to the `agent/` directory. */ readonly root: string; /** * A DISPLAY LABEL — `config.name`, else the directory's basename, else * `'agent'`. * * Not a trace key, and `deriveTurnOptions` forwards it to `runAgent` only * when `agent.ts` declared one. A name guessed from a directory basename * would collide across sibling projects and silently merge their traces, * which is worse than the SDK's own default. */ readonly name: string; /** Verbatim `instructions.md`, trailing whitespace removed. */ readonly instructions: string; readonly config: DirectoryConfig; readonly tools: readonly ToolEntry[]; readonly skills: readonly SkillEntry[]; /** Delegates this project declares. Empty unless it has an `agents/` slot. */ readonly agents: readonly SubAgentEntry[]; /** Every file considered, with its outcome. An inspector's ground truth. */ readonly sources: readonly SourceRef[]; /** Which slots were scanned. What `ok` is scoped to. */ readonly included: readonly DirectorySlot[]; readonly modules: ModuleMode; } export interface DirectoryLoadResult { readonly manifest: DirectoryManifest; readonly diagnostics: readonly DirectoryDiagnostic[]; /** * True when no diagnostic is an error. * * Scoped to `manifest.included`: it means "every slot you asked for is * sound", never "this directory is complete". A caller that scanned only * `tools` learns nothing here about `instructions`. */ readonly ok: boolean; } export interface LoadDirectoryOptions { /** See {@link ModuleMode}. Default `'evaluate'`. */ readonly modules?: ModuleMode; /** * Replace the import. * * The exit for a project Node's own type stripping cannot read — enums, * decorators, tsconfig path aliases — where a host passes `jiti.import` or * a `tsx`-registered importer. Three lines in the host, and no bundler * dependency in this tree; the same rule `LLMProvider` follows. * * Ignored under `modules: 'skip'`, where nothing is imported at all. */ readonly importModule?: ModuleImporter; /** * Slots to scan. Default: all of them. * * The tuple type makes an empty array unrepresentable in TypeScript on * purpose. This is an allow-list, and an allow-list that admits everything * when empty is the fail-open shape this estate removed elsewhere; here an * empty list scans nothing, which is the closed reading. */ readonly include?: readonly [DirectorySlot, ...DirectorySlot[]]; /** * Per-module deadline. Default 10_000ms. * * Bounds THIS LOADER, not the module. An import that expires is not * cancelled — see {@link SourceOutcome} `'abandoned'`. */ readonly moduleTimeoutMs?: number; } export interface DeriveTurnOptionsInput { readonly provider: LLMProvider; readonly prompt: string | Message[]; /** Wins over `agent.ts`. Required when `agent.ts` names no model. */ readonly model?: string; readonly identity?: AgentIdentity; readonly overrides?: Partial>; } //# sourceMappingURL=types.d.ts.map