type: user/message

type: text

text: Inspect the exact tools service API and tools/pre-execute event with cordis_inspect, then reply with exactly CORDIS_INSPECT_JSDOC_OK.

kind: user

surfaceOp: append


type: session/title

title: Inspect the exact tools service

kind: fallback


type: request/header

provider: deepseek

[System] {{system}}

tools: {{tools}}

reason: initial


type: assistant/message

type: tool-call

tools

what: api


type: tool/result

callId: inspect-tools-api

text:
## api
- tools — Tool registry and execution pipeline.
    /**
     * Register globally or in the calling agent scope. Scoped tools shadow
     * globals; duplicates within one layer and the reserved `run_code` name fail.
     * @param definition - tool schema, execution, and optional finalization/presentation callbacks.
     * @returns the exact disposer that unregisters the tool.
     */
    register(definition: ToolDefinition): () => void
    /**
     * Restrict global tools for the calling agent scope. Empty filters, unknown
     * names, scope-local names, and reserved transport names fail. Restrictions
     * intersect; scoped registrations remain visible.
     * @param filter - global-surface mask: `allow` (keep only) and/or `deny` (remove).
     * @returns the exact disposer that lifts this restriction.
     */
    restrict(filter: ToolRestriction): () => void
    /**
     * Register a monotonic guard after the extensible `tools/pre-execute`
     * waterfall. A plain-context guard applies globally; one registered through
     * `agent.ctx` applies only to that agent. Any matching guard may deny by
     * returning a reason, while no guard can force-allow a call another guard
     * denied. The exact effect disposer is returned for ordered ownership and
     * HMR cleanup.
     * @param guard - synchronous check; a returned string denies the execution.
     * @returns the exact disposer that unregisters the guard.
     */
    guard(guard: ToolGuard): () => void
    /**
     * Look up a tool as one scope sees it (scoped
     * shadows global; a restricted-away global reads as absent). Presenters pass
     * the calling agent so the rendered card matches the definition that
     * actually executed.
     * @param name - the tool name as registered.
     * @param scope - the viewing scope (the agent); omitted = the global view.
     * @returns the definition the scope resolves, or undefined when none is visible.
     */
    get(name: string, scope?: ScopeKey): ToolDefinition | undefined
    /**
     * Project visible definitions onto the allowlisted model-facing schema fields,
     * excluding execution and presentation callbacks.
     * @param scope - the viewing scope (the agent); omitted = the global view.
     * @returns one deep-cloned schema per visible tool.
     */
    schemas(scope?: ScopeKey): ToolSchema[]
    /**
     * Classify a pending call through the caller's visible tool definition. Only
     * an exact `true` is parallel; unknown, hidden, undeclared, invalid, or
     * throwing classifiers are exclusive.
     * @param exec - call name, parsed arguments, and optional agent scope.
     * @returns the fail-closed scheduling mode.
     */
    executionMode(exec: ToolExecutionInput): ToolExecutionMode
    /**
     * Execute through pre-policy, guards, around-dispatch, post-policy,
     * definition-owned content finalization, and final notification. Tool and
     * listener failures resolve as materialized error results; an invisible tool
     * reports `UNKNOWN_TOOL`. The returned outcome is the same lossless, frozen
     * snapshot final observers receive. Cancellation
     * arriving after entry and before final result materialization skips a
     * not-yet-started body with `ABORTED_BEFORE_DISPATCH` or replaces a
     * successful started outcome with `ABORTED`; already-started work is still
     * drained and may retain a tool-owned structured error.
     * @param exec - the typed same-process call input. The registry assigns its
     *   correlation token before policy begins.
     * @returns the materialized final result.
     */
    async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
type shapes (referenced by the signatures above — read these before assuming a field is a string):
    export interface Agent {
        readonly id: SessionId;
        readonly options: AgentOptions;
        readonly session: Session;
        readonly status: AgentStatus;
        readonly ctx: Context;
        followup(content: ContentBlock[], options?: SendOptions): AgentMessageId;
        queue(content: ContentBlock[], options?: SendOptions): AgentMessageId;
        steer(content: ContentBlock[], options?: SendOptions): AgentMessageId;
        inject(content: ContentBlock[], options?: InjectOptions): AgentMessageId;
        send(input: ResolvedAgentInput): AgentMessageId;
        cancel(cause?: AgentCancelCause, options?: CancelOptions): void;
        whenIdle(): Promise<void>;
    }
    export type AgentCancelCause = {
        readonly kind: 'user';
    } | {
        readonly kind: 'parent';
    };
    export type AgentMessageId = Branded<'AgentMessageId'>;
    export interface AgentOptions {
        provider?: string;
        model?: string;
    }
    export type AgentStatus = 'idle' | 'running' | 'disposed';
    export interface AssistantProvenance {
        provider: string;
        model: string;
        replayState?: unknown;
    }
    export type Branded<B extends string> = string & {
        readonly [BRAND]: B;
    };
    export type CallId = Branded<'CallId'>;
    export interface CancelOptions {
        keepInbox?: boolean;
    }
    export interface ContentBlockMap {
        'text': TextBlock;
        'reasoning': ReasoningBlock;
        'tool-call': ToolCallBlock;
        'tool-result': ToolResultBlock;
    }
    export type ContentBlockType = keyof ContentBlockMap;
    export interface DiffCallView {
        card: 'diff';
        title: string;
        diffs: FileDiff[];
        locations?: FileLocation[];
    }
    export interface DiffResultView {
        card: 'diff';
        title?: string;
        diffs: FileDiff[];
    }
    export interface EpochHeader {
        config: LlmCallConfig;
        system?: string;
        tools?: ToolSchema[];
        messagePrefix?: Message[];
    }
    export interface FileDiff {
        path: string;
        oldText: string | null;
        newText: string;
    }
    export interface FileLocation {
        path: string;
        line?: number;
    }
    export type FinishReason = FinishReasonMap[keyof FinishReasonMap];
    export interface FinishReasonMap {
        'stop': {
            kind: 'stop';
        };
        'tool-calls': {
            kind: 'tool-calls';
        };
        'max-tokens': {
            kind: 'max-tokens';
        };
        'aborted': {
            kind: 'aborted';
            failure: LlmFailure;
        };
        'error': {
            kind: 'error';
            failure: LlmFailure;
        };
    }
    export interface GenericCallView {
        card: 'generic';
        title: string;
        kind?: ToolCallKind;
        rawInput?: unknown;
        content?: ContentBlock[];
        locations?: FileLocation[];
    }
    export interface GenericResultView {
        card: 'generic';
        title?: string;
        content?: ContentBlock[];
    }
    export interface HookContext {
        content: ContentBlock[];
        source: MessageSource;
        placement?: 'separate' | 'prompt-prefix';
        meta?: JsonValue;
    }
    export interface InjectOptions {
        source?: MessageSource;
        meta?: JsonValue;
    }
    export interface JsonSchemaNode {
        type?: JsonSchemaType;
        oneOf?: JsonSchemaNode[];
        properties?: Record<string, JsonSchemaNode>;
        required?: string[];
        additionalProperties?: boolean;
        items?: JsonSchemaNode;
        enum?: JsonSchemaScalar[];
        const?: JsonSchemaScalar;
        description?: string;
        title?: string;
        default?: JsonValue;
        examples?: JsonValue;
    }
    export type JsonSchemaScalar = string | number | boolean | null;
    export type JsonSchemaType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
    export type JsonValue = null | boolean | number | string | JsonValue[] | {
        [key: string]: JsonValue;
    };
    export interface LlmCallConfig {
        provider: string;
        model: string;
        reasoningEffort?: ReasoningEffortId;
        temperature?: number;
        maxTokens?: number;
        stop?: string[];
    }
    export interface LlmFailure {
        readonly message: string;
        readonly code: string;
        readonly status?: number;
        readonly providerRetryAfterMs?: number;
        readonly requestId?: ProviderRequestId;
    }
    export interface Message {
        role: 'system' | 'user' | 'assistant';
        content: ContentBlock[];
        provenance?: AssistantProvenance;
    }
    export type MessageSource = MessageSourceMap[keyof MessageSourceMap];
    export interface MessageSourceMap {
        user: {
            kind: 'user';
        };
        plugin: {
            kind: 'plugin';
            plugin: string;
        };
    }
    export interface PromptMessageData {
        content: ContentBlock[];
        source: MessageSource;
        envelope?: PromptMessageEnvelope;
        meta?: JsonValue;
    }
    export interface PromptMessageEnvelope {
        displayContent: ContentBlock[];
        prefixContexts: PromptPrefixContext[];
    }
    export interface PromptPrefixContext {
        source: MessageSource;
        meta?: JsonValue;
    }
    export type ProviderRequestId = Branded<'ProviderRequestId'>;
    export interface ReasoningBlock {
        type: 'reasoning';
        text: string;
    }
    export type ReasoningEffortId = Branded<'ReasoningEffortId'>;
    export type RequestHeaderReason = 'initial' | 'resume' | 'change';
    export type ResolvedAgentInput = {
        content: ContentBlock[];
        source: MessageSource;
        meta: JsonValue | undefined;
    } & ({
        target: 'next-turn';
        wakeup: boolean;
        contexts: HookContext[];
    } | {
        target: 'next-step';
        wakeup: true;
        contexts: HookContext[];
    } | {
        target: 'next-step';
        wakeup: false;
        contexts: [
        ];
    });
    export type ScopeKey = object;
    export interface SendOptions {
        source?: MessageSource;
        contexts?: HookContext[];
        meta?: JsonValue;
    }
    export class Session {
        get surface(): SessionSurface;
        readonly header: SessionHeader;
        get id(): SessionId;
        constructor(id: SessionId, seed?: readonly SessionEvent[], header?: SessionHeader);
        get events(): readonly SessionEvent[];
        get seq(): number;
        append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [
            opts: SurfaceIntent
        ] : [
        ]): SessionEvent<T>;
        requestHeader(): EpochHeader | undefined;
        deriveMessages(): Message[];
        deriveEventMessage(event: SessionEvent): Message | null;
    }
    export type SessionEvent<T extends SessionEventType = SessionEventType> = {
        [K in SessionEventType]: {
            type: K;
            seq: number;
            time: number;
            data: SessionEventMap[K];
        } & (K extends SurfaceEventType ? {
            sourceEventSeqs?: number[];
            surfaceOp?: SurfaceOp;
        } : object);
    }[T];
    export interface SessionEventMap {
        'turn/start': {
            turn: number;
            trigger: TurnTrigger;
        };
        'turn/end': {
            turn: number;
            reason: TurnEndReason;
        };
        'step/start': {
            turn: number;
            step: number;
        };
        'step/end': {
            turn: number;
            step: number;
        };
        'user/message': PromptMessageData;
        'prompt/blocked': {
            content: ContentBlock[];
            source: MessageSource;
            reason: string;
        };
        'assistant/chunk': {
            turn: number;
            step: number;
            chunk: StreamChunk;
        };
        'assistant/message': {
            turn: number;
            step: number;
            content: ContentBlock[];
            provenance: AssistantProvenance;
            usage?: TokenUsage;
        };
        'tool/call': {
            turn: number;
            step: number;
            callId: CallId;
            name: string;
            arguments: string;
        };
        'tool/result': {
            turn: number;
            step: number;
            callId: CallId;
            content: ContentBlock[];
            isError: boolean;
            error?: {
                name: string;
                code: string;
            };
            meta?: JsonValue;
        };
        'steering/message': PromptMessageData & {
            turn: number;
        };
        'todo/write': {
            todos: TodoItem[];
        };
        'request/header': {
            header: EpochHeader;
            reason: RequestHeaderReason;
        };
    }
    export type SessionEventType = keyof SessionEventMap;
    export interface SessionHeader {
        readonly version: number;
        readonly id: SessionId;
        readonly createdAt: number;
        readonly cwd?: string;
        readonly parentSession?: SessionId;
        readonly seedLength?: number;
        readonly delegationDepth?: number;
    }
    export type SessionId = Branded<'SessionId'>;
    export interface SessionSurface {
        readonly nodes: readonly number[];
        readonly replaceGeneration: number;
    }
    export type StreamChunk = {
        type: 'block-start';
        index: number;
        blockType: ContentBlockType;
    } | {
        type: 'text-delta';
        index: number;
        text: string;
    } | {
        type: 'reasoning-delta';
        index: number;
        text: string;
    } | {
        type: 'tool-call-delta';
        index: number;
        id: CallId;
        name?: string;
        argumentsDelta: string;
    } | {
        type: 'block-end';
        index: number;
        block: ContentBlock;
    } | {
        type: 'usage';
        usage: TokenUsage;
    } | {
        type: 'finish';
        reason: FinishReason;
        replayState?: unknown;
    };
    export type SurfaceEventType = 'user/message' | 'assistant/message' | 'tool/result' | 'steering/message';
    export interface SurfaceIntent {
        surfaceOp: SurfaceOp;
        sourceEventSeqs?: number[];
    }
    export type SurfaceOp = 'append' | {
        op: 'replace';
        start: number;
        end: number;
    };
    export interface TerminalCallView {
        card: 'terminal';
        title: string;
        description?: string;
        cwd?: string;
    }
    export interface TerminalResultView {
        card: 'terminal';
        title?: string;
        output?: string;
        exitCode?: number;
        signal?: string;
    }
    export interface TodoItem {
        content: string;
        status: 'pending' | 'in_progress' | 'completed';
    }
    export interface TokenUsage {
        inputTokens: number;
        outputTokens: number;
        cacheReadTokens?: number;
        cacheWriteTokens?: number;
        reasoningTokens?: number;
    }
    export interface ToolCallBlock {
        type: 'tool-call';
        id: CallId;
        name: string;
        arguments: string;
    }
    export type ToolCallKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other';
    export type ToolCallView = GenericCallView | TerminalCallView | DiffCallView;
    export interface ToolDefinition extends ToolSchema {
        readonly output: ToolOutputDefinition;
        execute(args: unknown, exec: ToolRunContext): Promise<unknown>;
        finalizeContent?(exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): ContentBlock[] | undefined;
        timeoutMs?: number;
        isConcurrencySafe?(args: unknown): boolean;
        presentCall?(args: unknown): ToolCallView | undefined;
        presentResult?(args: unknown, result: ToolResult): ToolResultView | undefined;
    }
    export interface ToolErrorInfo {
        name: string;
        code: string;
    }
    export interface ToolExecution extends ToolExecutionInput {
        readonly token: ToolExecutionToken;
    }
    export interface ToolExecutionFailure {
        readonly isError: true;
        readonly error: ToolFailure;
        readonly value?: never;
        readonly content: ContentBlock[];
        readonly meta?: JsonValue;
        readonly additionalContexts?: HookContext[];
    }
    export interface ToolExecutionInput {
        readonly callId: CallId;
        readonly name: string;
        readonly arguments: unknown;
        readonly agent?: Agent;
        readonly parent?: ToolExecutionToken;
        readonly signal: AbortSignal;
    }
    export type ToolExecutionMode = {
        kind: 'parallel';
    } | {
        kind: 'exclusive';
    };
    export type ToolExecutionResult = ToolExecutionSuccess | ToolExecutionFailure;
    export interface ToolExecutionSuccess {
        readonly isError: false;
        readonly value: JsonValue;
        readonly content: ContentBlock[];
        readonly error?: never;
        readonly meta?: JsonValue;
        readonly additionalContexts?: HookContext[];
    }
    export type ToolExecutionToken = symbol & {
        readonly [toolExecutionTokenBrand]: true;
    };
    export interface ToolFailure {
        message: string;
        info?: ToolErrorInfo;
    }
    export type ToolGuard = (execution: Readonly<ToolExecution>) => string | undefined;
    export interface ToolOutputDefinition {
        readonly schema: JsonSchemaNode;
        render(args: unknown, value: JsonValue): ContentBlock[];
        presentationMeta?(args: unknown, value: JsonValue): JsonValue;
    }
    export interface ToolRestriction {
        readonly allow?: readonly string[];
        readonly deny?: readonly string[];
    }
    export interface ToolResult {
        content: ContentBlock[];
        isError: boolean;
        meta?: JsonValue;
    }
    export interface ToolResultBlock {
        type: 'tool-result';
        toolCallId: CallId;
        content: ContentBlock[];
        isError?: boolean;
    }
    export type ToolResultView = GenericResultView | TerminalResultView | DiffResultView;
    export interface ToolRunContext extends ToolExecution {
        deferContext(context: HookContext): void;
    }
    export interface ToolSchema {
        name: string;
        description: string;
        parameters: Record<string, unknown>;
    }
    export type TurnEndReason = TurnEndReasonMap[keyof TurnEndReasonMap];
    export interface TurnEndReasonMap {
        completed: {
            kind: 'completed';
        };
        aborted: {
            kind: 'aborted';
        };
        error: {
            kind: 'error';
            step: number;
        } & ({
            failure: LlmFailure;
            message?: never;
            code?: never;
        } | {
            message: string;
            code?: string;
            failure?: never;
        });
        disposed: {
            kind: 'disposed';
        };
        'max-tokens': {
            kind: 'max-tokens';
        };
        rejected: {
            kind: 'rejected';
            reason: string;
        };
        interrupted: {
            kind: 'interrupted';
        };
    }
    export type TurnTrigger = TurnTriggerMap[keyof TurnTriggerMap];
    export interface TurnTriggerMap {
        message: {
            kind: 'message';
            source: MessageSource;
        };
        injection: {
            kind: 'injection';
            source: MessageSource;
        };
    }


tools/pre-execute

what: events


callId: inspect-tools-event

text:
## events
- tools/pre-execute [waterfall] — Allow, deny, or ask before dispatch.
    /**
     * Allow, deny, or ask before dispatch. `next()` delegates to allow; missing
     * approval support turns `ask` into denial. Async gates must observe
     * `exec.signal`; the registry rechecks cancellation after they settle but
     * never abandons their promise.
     * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
     * @param exec - the pending call (name, parsed arguments, caller agent).
     * @mode waterfall
     */
    'tools/pre-execute'(this: Scoped<ToolRegistry>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>
waterfall listeners receive a trailing next() and MUST call it to delegate — returning without next() vetoes the chain.