Skip to content

chore: version packages#57

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Open

chore: version packages#57
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@openrouter/[email protected]

Minor Changes

  • #66 c83cceb Thanks @LukasParke! - Add a versioned ConversationState serialization contract.

    • Optional version field on ConversationState (absence means v1); createInitialState now stamps version: 1.
    • New helpers: serializeConversationState / deserializeConversationState (package root + @openrouter/agent/conversation-state).
    • Typed errors: UnsupportedStateVersionError ({found, supported}) and InvalidStateError for malformed payloads.
    • Compat policy: treat JSON as opaque; additive changes within a major; migrations run in deserializeConversationState on version bump. StateAccessor load/save is unchanged — helpers are opt-in wrappers over what consumers already do with JSON.stringify/parse.
  • #64 e4d06e3 Thanks @LukasParke! - Persist unresolved manual tool calls (execute: false / no execute fn) to ConversationState.pendingToolCalls when the loop stops, and set status to the new value 'awaiting_client_tools'.

    Previously, HITL pauses (onToolCalled → null) correctly populated pendingToolCalls with status 'awaiting_hitl', but bare manual tools only break'd the loop — getPendingToolCalls() returned [] and status was left in_progress/complete. Cold-start consumers could not recover the unresolved calls from serialized state.

    • New ConversationStatus value: 'awaiting_client_tools' (additive; does not replace 'awaiting_hitl').
    • Mixed auto+manual rounds still execute/persist regular tool outputs, then pause with only the unresolved manual calls in pendingToolCalls.
    • A successful resume with new input from 'awaiting_client_tools' clears the stale pendings and continues as a normal turn. Failed resume requests leave the paused state intact. Manual tools are not approved/rejected via call IDs (unlike HITL/awaiting_approval).
  • #7 80ff8a7 Thanks @mattapperson! - Add a typed lifecycle hook system to callModel, inspired by the Claude Agent SDK hooks pattern.

    Two usage modes: an inline config object (built-in hooks only) or a HooksManager instance (custom hooks, dynamic registration via on()/off()/removeAll(), programmatic emit()).

    Eight built-in hooks: PreToolUse (block or mutate tool input before every client-tool execution), PostToolUse / PostToolUseFailure (observe results and errors with timing), UserPromptSubmit (mutate or reject the prompt before the initial request), PermissionRequest (programmatically allow/deny/ask for tools requiring approval), Stop (force-resume a halted loop or inject a follow-up prompt, capped against runaway handlers), and SessionStart / SessionEnd (paired once per run on every exit path, including approval pauses, interruptions, errors, and no-tools streaming paths).

    Features: tool matchers (string / RegExp / predicate), payload filter predicates, sequential mutation piping, short-circuit on block/reject, async fire-and-forget handlers with drain() / abortInflight() / per-handler timeouts and cooperative cancellation via ctx.signal, configurable error handling (throwOnHandlerError), and custom hook definitions via Zod schema pairs with full TypeScript inference (transforms/defaults are honored — handlers receive parsed output values).

    The API is additive: existing onTurnStart, onTurnEnd, and requireApproval are unchanged. Public exports: HooksManager, HookName, isAsyncOutput, and the payload/result/config types; also available via the @openrouter/agent/hooks-manager subpath.

  • #56 209499a Thanks @mattapperson! - Add a source discriminant to tool results so untyped MCP tools no longer collapse the type safety of typed tools.

    Previously, mixing an MCP tool (whose output schema is unknown) with fully-typed tools in one callModel({ tools }) array collapsed the entire result union to unknown — one untyped tool poisoned every other tool's result type.

    • ToolExecutionResult (and ToolExecutionResultUnion) now carry source: 'client' | 'mcp'. Narrowing on source === 'client' recovers the precise, schema-derived results for your own tools; MCP results stay isolated as unknown under source === 'mcp'.
    • ToolResultEvent (streaming: getFullResponsesStream, getToolStream) gains the same source field. Breaking: the tool.result event payload now includes source; consumers that constructed or exhaustively matched these events may need to account for it.
    • @openrouter/agent exports a markMcp() helper, an isMcpTool() guard, and the McpBranded type. @openrouter/mcp brands every wrapped tool (including synthetic list_resources/read_resource) so the discrimination is automatic — callers just spread mcp.tools as before.
    • MCP tools continue to execute locally and serialize to the wire as type: 'function'; the brand is purely informational and does not change runtime behavior.
  • #67 cb83f45 Thanks @LukasParke! - Add a PostModelCall lifecycle hook and aggregate usage totals on SessionEnd — the telemetry primitives for tracing and benchmark consumers.

    PostModelCall fires once per completed model response, on every request the agent loop makes: the initial request, each tool-round follow-up, the empty-final retry, the allowFinalResponse final turn, and approval-resume requests. The payload carries responseId (the OpenRouter generation id, deep-linkable), model, durationMs (dispatch to fully materialized response, including stream consumption), turnType ('initial' | 'resume' | 'tool_round' | 'final' | 'retry'), turnNumber, and a normalized usage block (inputTokens, outputTokens, totalTokens, cachedTokens, reasoningTokens, cost?) when the server reported usage accounting. Purely observational: handlers cannot mutate or block.

    SessionEnd now carries an optional totalUsage aggregate (modelCalls plus the summed usage fields, with cost present when any call reported one) whenever at least one model call completed during the run.

    New exported types: PostModelCallPayload, ModelCallUsage, SessionUsageTotals.

Patch Changes

  • #62 1362232 Thanks @LukasParke! - Docs: fix three README/API drifts found while building production agents — tool context is ctx.local (not ctx.context); the state option takes a StateAccessor ({load, save}) and state is read via result.getState() (not (await getResponse()).state); getToolStream() emits argument deltas + generator preliminary results, while execution results are on getFullResponsesStream(). Adds a streams cheat-sheet table.

  • #65 09a041e Thanks @LukasParke! - Infer tool context types from contextSchema end-to-end: tool() now preserves the concrete Zod schema through its overloads, so execute's ctx.local is typed from the schema and callModel's context map slots accept/reject the real per-tool shape — no more ctx.local as X or context: map as any. Tools without a contextSchema still resolve their map slot to Record<string, never>. Types-only; runtime behavior unchanged.

  • #61 c020bc7 Thanks @LukasParke! - Fix: bare string input is now normalized into a message item when resuming a conversation with loaded history. Previously the raw string was appended to the request input array un-normalized, causing an OpenResponses 400 validation error on the advertised string-input style.

  • #63 d96cd9f Thanks @LukasParke! - Tolerate empty final output after completed tool rounds: retry the follow-up request once, then resolve successfully with empty text instead of throwing Invalid final response: empty or invalid output. Mini-class models intermittently treat a successful tool call as the terminal answer. Opt into the old throw with strictFinalResponse: true. Runs with no completed tool work still throw on empty output.

  • #59 8edae63 Thanks @ayush-or! - Stop the tool-execution loop when a round contains unresolved manual (client-executed) tool calls, instead of sending a follow-up request whose input carries a function_call with no matching function_call_output — a history providers reject with a 400 "No tool output found for function call ...". The response is surfaced so the caller can execute the manual calls and continue, mirroring the existing all-manual behavior.

@openrouter/[email protected]

Minor Changes

  • #56 209499a Thanks @mattapperson! - Add a source discriminant to tool results so untyped MCP tools no longer collapse the type safety of typed tools.

    Previously, mixing an MCP tool (whose output schema is unknown) with fully-typed tools in one callModel({ tools }) array collapsed the entire result union to unknown — one untyped tool poisoned every other tool's result type.

    • ToolExecutionResult (and ToolExecutionResultUnion) now carry source: 'client' | 'mcp'. Narrowing on source === 'client' recovers the precise, schema-derived results for your own tools; MCP results stay isolated as unknown under source === 'mcp'.
    • ToolResultEvent (streaming: getFullResponsesStream, getToolStream) gains the same source field. Breaking: the tool.result event payload now includes source; consumers that constructed or exhaustively matched these events may need to account for it.
    • @openrouter/agent exports a markMcp() helper, an isMcpTool() guard, and the McpBranded type. @openrouter/mcp brands every wrapped tool (including synthetic list_resources/read_resource) so the discrimination is automatic — callers just spread mcp.tools as before.
    • MCP tools continue to execute locally and serialize to the wire as type: 'function'; the brand is purely informational and does not change runtime behavior.
  • #56 26336b5 Thanks @mattapperson! - Add @openrouter/mcp: expose remote MCP server tools (Streamable HTTP / SSE) as callModel tools.

    • createMCPTools() connects to a non-stdio MCP server, authenticates once (bearer token, custom headers, or a pluggable OAuthClientProvider), and returns a handle whose .tools drop straight into callModel({ tools }). The same auth is reused for tool discovery and every tool call.
    • Faithful runtime JSON-Schema → Zod v4 conversion (convertMcpInputSchema) so the model sees real parameters; tool output schemas are mapped too.
    • Serializable, rehydratable cache (serialize() / rehydrateMCPTools() / pluggable MCPCacheStore + InMemoryMCPCacheStore) that skips re-listing and, opt-in, re-authentication. Credential caching is off by default.
    • MCP feature support: progress notifications surfaced as generator-tool events, tools/list_changed auto-refresh, cancellation via an abort signal, resources exposed as synthetic list_resources/read_resource tools, and elicitation with an optional handler (auto-declines when none is provided).

Patch Changes

perry-the-pr-reviewer[bot]

This comment was marked as outdated.

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 8fef5b9 to f030a4d Compare July 8, 2026 17:00

@perry-the-pr-reviewer perry-the-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ APPROVE unavailable on this installation — the maintainer GitHub App is not
configured with write access on this org, so the verdict below is posted as COMMENT.
Event-level approval (for branch-protection / review requirements) must be added out-of-band.

Perry's Review

Automated Changesets "version packages" PR — deletes 3 consumed changeset files and bumps @openrouter/agent (0.7.2→0.8.0) and @openrouter/mcp (0.1.0→0.2.0) with matching CHANGELOG entries.

Verdict: ✅ LGTM

Details

Risk: 🟢 Low — mechanical version/changelog bump only, no source code touched

CI: all passing ✅ (e2e-tests, lint, structural-gate, typecheck, unit-tests)

Findings: none

Research: n/a — small tier, no deep research pass

Security: no concerns — diff touches only changeset markdown files, CHANGELOG.md entries, and package.json version fields; no secrets, no code paths

Test coverage: n/a — no code changed

Unresolved threads: none

Verification: all 3 deleted changesets correspond exactly to entries appended to both CHANGELOGs; both version bumps are minor bumps matching their "### Minor Changes" sections; @openrouter/mcp's workspace dependency on @openrouter/agent resolves automatically, no other file needed updating.

Scope: first review (full)
Review: tier=small · model=claude-sonnet-latest · score=0.8

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 7 times, most recently from 5cae45f to c7c8835 Compare July 17, 2026 15:56
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from c7c8835 to c14950a Compare July 17, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants