Skip to content

think: lifecycle hook follow-ups (from #1340) — remaining items #1343

Description

@threepointone

Remaining follow-ups from #1340 / #1339. Each is non-blocking and self-contained.

Follow-ups 1 (preserve streaming preliminary tool results), 2 — output half (per-tool typing for ToolCallResultContext.output), 4 (needsApproval × ToolCallDecision ordering test), and 5 (counter-based "block prevents execute" test) were addressed in #1823.

2. Per-tool typing for ToolCallDecision.input

The output half of this item shipped in #1823 (narrowing on ctx.toolName now narrows ctx.output on afterToolCall, and ctx.input on beforeToolCall). The remaining half:

  • ToolCallDecision.input is Record<string, unknown> for { action: "allow", input } and { action: "substitute", input? }. Users would expect this to be the input shape of the tool whose call is being intercepted.

This requires threading the tool name being decided about into the return type — either a second generic parameter on ToolCallDecision (the tool name) or making it a discriminated mapped type. Unlike the output half, the AI SDK doesn't give us this for free, and it would be a breaking change to the exported ToolCallDecision type, so it's deferred.

3. Skip _wrapToolsWithDecision when no subscriber overrides beforeToolCall and no extensions subscribe

Think wraps every tool on every turn, even when beforeToolCall is the default no-op and no extensions subscribe — pure overhead in that case. Could detect those conditions at construction time (or memoize per-turn) and pass the original toolset straight through to streamText.

Note: since #1340/#1823 the wrapper also enforces action approval-input integrity and the AsyncIterable handling, so a skip path must additionally require that no approval-configured actions are present (not just "no beforeToolCall override and no extension subscribers"). Worth doing only if profiling shows it matters — premature otherwise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requeston the roadmapFeature accepted and planned for implementation

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions