Skip to content

Releases: openintent-ai/openintent

v0.17.0

24 Mar 23:44
f9ebb35

Choose a tag to compare

OpenIntent v0.17.0

Released: 2026-03-24


RFC-0026: Suspension Propagation & Retry

This release closes the three gaps left open by RFC-0025 (Human-in-the-Loop Intent
Suspension, v0.16.0): how suspension propagates through containers (intent graphs,
portfolios, plans, workflows), how agents can re-notify operators who don't respond,
and how downstream workflow phases observe upstream suspension.


Highlights

Container Propagation Rules

Five normative rules define how suspended_awaiting_input spreads through the
protocol's container hierarchy:

  1. Intent graph — A suspended child intent blocks all dependents from proceeding.
    The parent aggregate status becomes suspended_awaiting_input.
  2. Portfolio — The portfolio aggregate gains has_suspended_members (bool) and
    suspended_member_count (int). Two new events are emitted:
    portfolio.member_suspended and portfolio.member_resumed.
  3. Plan / Task — When an intent suspends, its corresponding plan task transitions
    to blocked with blocked_reason: "intent_suspended" and suspended_intent_id.
    Plan progress gains a suspended_tasks list. The mirror is bidirectional: when the
    intent resumes, the task unblocks automatically.
  4. Workflow — Downstream phases that declare inputs from a suspended upstream phase
    receive UpstreamIntentSuspendedError at claim time rather than a generic failure.
    Workflow progress gains a suspended_phases list.
  5. Deadline — The suspension deadline governs expiry. It MUST NOT exceed the
    portfolio due_before constraint if the intent is a portfolio member.

Human Re-Notification: HumanRetryPolicy

A new dataclass for configuring automatic re-notification when operators don't respond
to a suspension within the initial timeout_seconds window.

from openintent import HumanRetryPolicy, EscalationStep

policy = HumanRetryPolicy(
    max_attempts=3,
    interval_seconds=3600,          # 1 hour between attempts
    strategy="exponential",         # fixed | linear | exponential
    escalation_ladder=[
        EscalationStep(
            attempt=2,
            channel_hint="slack",
            notify_to="manager@example.com",
        ),
        EscalationStep(
            attempt=3,
            channel_hint="sms",
            notify_to="+15551234567",
        ),
    ],
    final_fallback_policy="escalate",  # fail | escalate | auto_resume | skip
)

On each re-notification attempt the SDK:

  • Re-fires @on_input_requested hooks
  • Emits intent.suspension_renotified event
  • Fires intent.suspension_escalated when an escalation ladder step is reached
  • Applies final_fallback_policy once all attempts are exhausted

EscalationStep

EscalationStep(attempt=2, channel_hint="slack", notify_to="manager@example.com")

Backwards-compatible field aliases: after_attempt, channel, notify.

Three-Level Policy Cascade

Retry policy resolution follows a cascade so platform operators can set a sensible
default without requiring every agent to configure one explicitly:

request_input(retry_policy=...)          ← call-site (highest priority)
  → BaseAgent.default_human_retry_policy ← agent class default
    → server suspension.default_retry_policy  ← platform default (lowest)

UpstreamIntentSuspendedError

from openintent import UpstreamIntentSuspendedError

try:
    spec.validate_claim_inputs(task_id, completed_outputs)
except UpstreamIntentSuspendedError as e:
    print(e.task_id)            # the claiming task
    print(e.phase_name)         # the upstream phase that is suspended
    print(e.suspended_intent_id)
    print(e.expected_resume_at) # ISO 8601, may be None

Raised by WorkflowSpec.validate_claim_inputs() when a declared input references an
upstream phase whose intent is currently suspended_awaiting_input. Subclass of
WorkflowError.

New EventType Constants

Constant Fired when
EventType.SUSPENSION_RENOTIFIED Each re-notification attempt fires
EventType.SUSPENSION_ESCALATED An escalation ladder step fires
EventType.PORTFOLIO_MEMBER_SUSPENDED A portfolio member intent suspends
EventType.PORTFOLIO_MEMBER_RESUMED A portfolio member intent resumes

retry_policy on SuspensionRecord

SuspensionRecord gains an optional retry_policy: HumanRetryPolicy | None field.
Existing single-attempt behaviour is fully preserved when the field is absent.
timeout_seconds is now documented as a per-attempt window when retry_policy is set.


New Exports

from openintent import (
    HumanRetryPolicy,
    EscalationStep,
    UpstreamIntentSuspendedError,
)

Cross-RFC Patches

RFC Change
RFC-0002 suspended_awaiting_input counter in aggregate status; completion-gate clarification
RFC-0007 Portfolio suspension-aware aggregate fields; member_suspended / member_resumed events
RFC-0010 Relationship note — RFC-0010 retries on agent failure; RFC-0026 re-notifies on human non-response
RFC-0012 Task/intent suspension mirror; suspended_tasks in plan progress
RFC-0024 UpstreamIntentSuspendedError at claim time; suspended_phases in workflow progress
RFC-0025 retry_policy on SuspensionRecord; per-attempt timeout_seconds semantics; fallback_policy alias; extended cross-RFC table

What's Not Changed

  • Existing single-attempt request_input() calls require no changes.
  • Agents that don't set retry_policy behave exactly as before.
  • suspended_awaiting_input status is still intent-local — it is not the same as
    completed, and dependents remain blocked (not failed) until the intent resumes.

Testing

  • 41 new tests in test_hitl.py and test_workflow_io.py
  • 1052+ tests across 19 test files — all passing
  • ruff check clean (80 files, 0 issues)
  • mkdocs build --strict passes

Installation

pip install openintent==0.17.0

Or with server extras:

pip install "openintent[server]==0.17.0"

Full Changelog

See CHANGELOG.md for the complete change log.

v0.16.0

24 Mar 01:51
3fd5a4f

Choose a tag to compare

OpenIntent SDK v0.16.0

Released: 2026-03-23

This release ships two new protocol RFCs — typed workflow I/O contracts (RFC-0024) and human-in-the-loop intent suspension (RFC-0025) — plus a fix that hardens the OpenAI adapter against the max_tokens deprecation in gpt-5+ and o-series models. All changes are fully backward compatible.


What's new

RFC-0024: Workflow I/O Contracts

Agents no longer need to agree on data formats at runtime. Declare what each phase produces and consumes in YAML; the executor handles all wiring automatically.

Output schemas — declare what a phase produces:

workflow:
  analyze:
    title: Analyze document
    assign: analyst-agent
    outputs:
      summary: string
      confidence: number
      decision:
        type: ApprovalDecision
        required: false

Input wiring — map local names to upstream phase outputs, trigger payload, or initial state:

  review:
    title: Human review
    assign: review-agent
    depends_on: [analyze]
    inputs:
      doc_summary: analyze.summary
      trigger_owner: $trigger.owner
    outputs:
      approved: boolean

Parse-time validation — broken wiring is caught at startup (from_yaml()), not at runtime.

Three executor gates:

  • resolve_task_inputs() — pre-populates ctx.input before the agent runs
  • validate_claim_inputs() — rejects a claim early if upstream outputs aren't ready
  • validate_task_outputs() — validates the agent's return dict against declared types

Named error types (all exported from openintent):

from openintent import (
    MissingOutputError,        # required key absent from return value
    OutputTypeMismatchError,   # value doesn't match declared type
    UnresolvableInputError,    # input ref can't be resolved
    InputWiringError,          # structural error at parse time
)

Named types — define reusable struct and enum types in a top-level types: block:

types:
  ApprovalDecision:
    enum: [approved, rejected, needs_review]
  DocumentSummary:
    fields: [title, body, word_count]

Incremental adoption: phases without outputs or inputs are fully unaffected.


RFC-0025: Human-in-the-Loop Intent Suspension

Agents can now pause mid-execution, present a structured question to an operator, and resume after a response arrives.

Suspend and wait for input:

decision = await self.request_input(
    question="Refund amount exceeds policy limit. Approve?",
    response_type=ResponseType.CONFIRM,
    confidence=0.45,
    timeout_seconds=3600,
    fallback_policy="reject",
)
if decision == "yes":
    await self.approve_refund(intent)

Structured choices:

decision = await self.request_input(
    question="How should we handle this duplicate order?",
    response_type=ResponseType.CHOICE,
    choices=[
        SuspensionChoice(value="cancel_new", label="Cancel new order", style="danger"),
        SuspensionChoice(value="cancel_old", label="Cancel original order"),
        SuspensionChoice(value="keep_both", label="Keep both orders", style="primary"),
    ],
)

Engagement decision engine:

signals = EngagementSignals(confidence=0.4, risk=0.8, reversibility=0.9)
decision = await self.should_request_input(signals)
# decision.mode → "require_input"
# decision.rationale → "Low confidence and high risk require operator approval"

Lifecycle decorators:

@on_input_requested
async def notify_slack(self, suspension: SuspensionRecord):
    await slack.post(channel="#ops", text=suspension.question)

@on_input_received
async def log_response(self, response: InputResponse):
    await audit_log.record(response)

@on_suspension_expired
async def apply_fallback(self, suspension: SuspensionRecord):
    await metrics.increment("suspension.expired")

@on_engagement_decision
async def audit_decision(self, decision: EngagementDecision):
    await audit_log.record(decision)

Operator REST API:

POST /api/v1/intents/{id}/suspend/respond
{
  "suspension_id": "susp_abc123",
  "value": "yes",
  "responded_by": "operator@example.com"
}

Returns choice_label, choice_description, and the updated intent state. Returns 422 with valid_choices if the value is not among the declared options.

Fallback policies"reject", "approve", "fail", "escalate" — control what happens if the suspension window expires with no response.


Bug fixes

OpenAI max_tokensmax_completion_tokens for gpt-5+ and o-series models

OpenAI deprecated the max_tokens parameter for newer model families, causing 400 errors with gpt-5-mini, o1, o3, and similar models. This release fixes it in two places:

  • OpenAIAdapter — automatically remaps max_tokens to max_completion_tokens for any model matching gpt-5*, o1*, or o3*. Existing callers passing max_tokens get correct behaviour transparently; callers already using max_completion_tokens are unaffected. Older models (gpt-4, gpt-3.5-turbo, etc.) are unchanged.

  • try demo script — both ResearchAgent and SummarizerAgent now pass max_completion_tokens directly in all call paths (streaming and non-streaming).

Demo script model name — corrected gpt-5.2-mini to gpt-5-mini.


Upgrade guide

This release is fully backward compatible. No changes are required to existing code.

To adopt RFC-0024 I/O contracts on a phase, add outputs: and/or inputs: keys to that phase's YAML config. All other phases are unaffected.

To adopt RFC-0025 HITL, call await self.request_input(...) anywhere inside an agent run() method. Install the new decorators as needed.

If you were working around the max_tokens 400 error by passing max_completion_tokens directly, you can continue doing so — it takes precedence and nothing changes. If you were passing max_tokens, the adapter now handles the translation for you.

Install:

pip install openintent==0.16.0

MCP server:

npm install @openintentai/mcp-server@0.16.0

Full changelog

See CHANGELOG.md for the complete list of changes.


Stats

  • 25 RFCs implemented
  • 228 tests passing (93 new for RFC-0024 · 110 for RFC-0025 · 7 new adapter tests · 18 existing)
  • ruff check / ruff format clean
  • tsc --noEmit clean

v0.15.1

06 Mar 01:50
ea81048

Choose a tag to compare

v0.15.1 — Gemini Adapter Rebuild for google-genai SDK

Changed

  • Gemini SDK Migration — Replaced deprecated google-generativeai SDK with google-genai (v1.0+). The GeminiAdapter now uses the modern genai.Client pattern (client.models.generate_content / client.models.generate_content_stream) instead of the legacy genai.configure() + GenerativeModel() approach.

  • GeminiAdapter Rewrite — Full protocol parity with OpenAI/Anthropic adapters:

    • Prompt/completion/total token counts from usage_metadata
    • Finish reason mapping from candidates
    • Function call tracking with provider-native IDs
    • Streaming usage metadata from final chunks
    • Multi-turn GeminiChatSession with proper history management (including during streaming)
  • LLMEngine Gemini Integration — Added _messages_to_gemini_contents() for proper message conversion (system messages become system_instruction, assistant messages use model role), _tools_to_gemini_format() for tool schema conversion to Gemini function declarations, and raw provider fallback paths for Gemini in both _call_raw_provider and _stream_raw_provider.

  • Default model names updated from gemini-1.5-pro / gemini-2.0-flash to gemini-3-flash across SDK, docs, and frontend.

  • Dependencygoogle-generativeai>=0.4.0 replaced with google-genai>=1.0.0 in gemini and all-adapters optional extras.

Updated

  • All version references updated to 0.15.1 across Python SDK, MCP server package, documentation, and changelog.
  • Documentation and examples updated to reflect new SDK patterns and model names.

Install

pip install openintent[gemini]==0.15.1

0.15.0

04 Mar 02:59
273e41d

Choose a tag to compare

v0.15.0 — Native FastAPI SSE & RFC-0010 Retry MCP Tools

Highlights

RFC-0010 Retry Policy MCP Tools — The protocol server already had retry policy endpoints, and the Python SDK already had client methods, but neither MCP implementation exposed them. This release closes that gap with 4 new tools in both the TypeScript MCP server and the Python MCP bridge:

Tool Tier Description
openintent_set_retry_policy admin Configure retry policy (strategy, max retries, backoff, fallback agent)
openintent_get_retry_policy read Retrieve current retry policy
openintent_record_failure write Record a failure with attempt number, error code, and scheduled retry
openintent_get_failures read Query failure history

MCP tool surface: 66 → 70 tools. RBAC counts: reader=25, operator=43, admin=70.

Native FastAPI SSE — Replaced sse-starlette with FastAPI's built-in SSE support (EventSourceResponse + ServerSentEvent). One fewer dependency, cleaner streaming, spec-compliant keep-alive pings.

What's New

Added

  • 4 RFC-0010 MCP tools in TypeScript MCP server (tools.ts, client.ts, security.ts)
  • build_retry_failure_tools() in Python MCP bridge (openintent.mcp)
  • MCP tool access documentation in cost-retry guide

Changed

  • SSE endpoints migrated to native FastAPI (fastapi>=0.135.0)
  • All version references updated to 0.15.0

Removed

  • sse-starlette dependency

Install

pip install openintent==0.15.0

v0.14.1

02 Mar 03:34
1c23487

Choose a tag to compare

[0.14.1] - 2026-02-27

Fixed

  • SDK/Server field format mismatches — Fixed three categories of mismatches between the Python SDK client and the protocol server's Pydantic models:

    • constraints type mismatchcreate_intent(), create_child_intent(), and IntentSpec sent constraints as a list[str] (e.g., ["rule1", "rule2"]), but the server expects Dict[str, Any] (e.g., {"rules": [...]}). All three methods (sync and async) now accept and send dict[str, Any]. Intent.from_dict() retains backward compatibility for legacy list-format constraints.
    • createdBycreated_by for portfolioscreate_portfolio() sent createdBy and governancePolicy (camelCase) but the server's PortfolioCreate model expects created_by and governance_policy (snake_case). Fixed in both sync and async clients.
    • get_portfolio_intents() response parsing — The server returns a raw JSON array from GET /api/v1/portfolios/{id}/intents, but the SDK expected a {"intents": [...]} wrapper dict, silently returning an empty list.
  • Silent empty results from list endpoints — Seven additional list-returning methods used data.get("key", []) which silently returned empty lists when the server sent raw JSON arrays. All now use isinstance(data, list) detection to handle both raw array and wrapped dict responses:

    • list_portfolios() — expected {"portfolios": [...]}
    • get_intent_portfolios() — expected {"portfolios": [...]}
    • get_attachments() — expected {"attachments": [...]}
    • get_costs() — expected {"costs": [], "summary": {}}
    • get_failures() — expected {"failures": [...]}
    • get_subscriptions() — expected {"subscriptions": [...]}
    • federation_list_agents() — expected {"agents": [...]}
  • IntentLease.from_dict() KeyError on server responsesacquire_lease() threw KeyError('status') because the server's LeaseResponse model does not include a status field (it uses acquired_at, expires_at, and released_at to represent lease state). IntentLease.from_dict() now derives status from these fields: RELEASED if released_at is set, EXPIRED if expires_at is in the past, otherwise ACTIVE. Also handles the field name difference acquired_at (server) vs created_at (SDK). Backward compatible with the SDK's own serialization format.

  • Stale database singleton after server restartget_database() cached the Database instance at module level and never checked whether database_url changed between calls. When the protocol server restarted on a different port (e.g., openintent_server_8001.dbopenintent_server_8002.db), the singleton kept pointing at the old file. Writes went to the old database; reads came from the new (empty) one — intents appeared created but were invisible to list_intents. The singleton now tracks its URL and recreates the connection when the URL changes.

  • Example and test updates — All examples (basic_usage.py, openai_multi_agent.py, multi_agent/coordinator.py, compliance_review/coordinator.py) and tests updated to use dict-format constraints.

Changed

  • All version references updated to 0.14.1 across Python SDK, MCP server package, and changelog.

v0.14.0

26 Feb 03:59
ac86b49

Choose a tag to compare

v0.14.0 — Federation Protocol & Security

Adds RFC-0022 (Federation Protocol) and RFC-0023 (Federation Security), providing cross-server agent coordination with cryptographic identity, signed envelopes, UCAN delegation tokens, and trust policy enforcement. Includes a complete Python SDK implementation, Express.js endpoints, MCP tools, and documentation.

Protocol Specifications

  • RFC-0022: Federation Protocol — Federation contract for cross-server agent coordination: envelope format, agent visibility (public/unlisted/private), peer relationships (peer/upstream/downstream), callbacks with at-least-once delivery, intent authority model, delegation scope with UCAN-style attenuation, governance propagation (strictest-wins), federation attestation (OpenTelemetry conventions), discovery via /.well-known/openintent-federation.json, and federation-aware leasing.
  • RFC-0023: Federation Security — Authentication, authorization, and verification layer: server identity via did:web, signed envelopes (HTTP Message Signatures, RFC 9421), UCAN delegation tokens with attenuation and expiry, trust policies (open/allowlist/trustless), agent access policies, signed attestations, and cross-server event log reconciliation via RFC-0019 Merkle primitives.

Python SDK — 5-Layer Federation Implementation

Layer Module Contents
Models openintent/federation/models.py FederationEnvelope, FederationCallback, FederationPolicy, FederationAttestation, DelegationScope, FederationManifest, FederationStatus, DispatchResult, ReceiveResult, FederatedAgent, PeerInfo. Enums: AgentVisibility, PeerRelationship, TrustPolicy, CallbackEventType, DispatchStatus.
Client openintent/client.py federation_status(), list_federated_agents(), federation_dispatch(), federation_receive(), send_federation_callback(), federation_discover() — sync and async variants.
Server openintent/server/federation.py FastAPI router: GET /status, GET /agents, POST /dispatch, POST /receive, GET /.well-known/openintent-federation.json, GET /.well-known/did.json. SSRF validation, callback delivery with retry, governance enforcement, idempotency keys.
Security openintent/federation/security.py ServerIdentity (Ed25519, did:web), sign_envelope()/verify_envelope_signature(), MessageSignature (RFC 9421), TrustEnforcer (open/allowlist/trustless), UCANToken (create/encode/decode/attenuate), resolve_did_web(), validate_ssrf().
Decorators openintent/federation/decorators.py @Federation (class decorator), federation_visibility on @Agent, federation_policy on @Coordinator, lifecycle hooks: @on_federation_received, @on_federation_callback, @on_budget_warning.

Express.js Server

  • 4 REST endpoints: GET /api/v1/federation/status, GET /api/v1/federation/agents, POST /api/v1/federation/dispatch, POST /api/v1/federation/receive
  • Federation audit trail: dispatch IDs, provenance in state._federation, RFC-0020 trace propagation
  • origin_server_url field on agent_records table for federated agents

MCP Tools

  • 4 new tools: federation_status (read), list_federated_agents (read), federation_dispatch (admin), federation_receive (admin)
  • Tool surface: 62 → 66 tools. RBAC counts: reader 23, operator 40, admin 66.

Federation Event Types

FEDERATION_DISPATCHED, FEDERATION_RECEIVED, FEDERATION_CALLBACK, FEDERATION_BUDGET_WARNING, FEDERATION_COMPLETED, FEDERATION_FAILED

Key Algorithms

  • DelegationScope.attenuate() — Scope narrowing per hop: intersection of permissions, union of denied operations, minimum delegation depth.
  • FederationPolicy.compose_strictest() — Strictest-wins governance: minimum for numerics, OR for booleans, merge for observability.

Documentation

  • Federation sections added to all 5 website pages: Docs, API Reference, Agents, Examples, Adapters.
  • MkDocs site rebuilt with federation content:
    • guide/federation.md — Concepts, configuration, code examples
    • examples/federation.md — Runnable examples for dispatch, signing, UCAN, trust enforcement
    • api/federation.md — Complete class and method reference
    • rfcs/0022-federation-protocol.md — Full RFC specification
    • rfcs/0023-federation-security.md — Full RFC specification
  • Homepage updated: 23 RFCs, 800+ tests, v0.14.0, federation feature cards.

Discovery & Compatibility

  • /.well-known/openintent.jsonfederation capability added, RFC-0022/0023 in rfcUrls
  • /.well-known/openintent-compat.json — RFC-0022 (full), RFC-0023 (partial)
  • /.well-known/openintent-federation.json — New federation discovery endpoint
  • /.well-known/did.json — DID document for server identity

Tests

82 new federation tests covering:

  • Model serialization round-trips
  • Security: sign/verify, UCAN create/encode/decode/attenuate, SSRF blocking, trust enforcement
  • Server endpoints via TestClient + SQLite
  • Decorator configuration and lifecycle hooks
  • Integration flows (dispatch → receive → callback)

Breaking Changes

None. Federation is additive — existing APIs and behavior are unchanged. Federation operates in trusted mode by default; RFC-0023 security is opt-in.

v0.13.5

14 Feb 20:50
317fc32

Choose a tag to compare

v0.13.5 — MCP Governance Tool Surface Complete

Date: 2026-02-14

What's New in v0.13.5

MCP Governance Enforcement Tools

The MCP server now exposes the complete 62-tool surface with all 4 governance enforcement tools fully implemented end-to-end:

Tool Tier Description
set_governance_policy admin Set or update governance policy on an intent (uses If-Match for optimistic concurrency)
get_governance_policy reader Retrieve the effective governance policy for an intent
approve_approval admin Approve a pending approval gate created by request_approval
deny_approval admin Deny a pending approval gate with optional reason

Each tool has the full implementation chain: tool definition, input schema, client method, handler case, and RBAC tier assignment.

Bug Fixes

  • MCP Startup Tool Count — Fixed a mismatch where the RBAC security tier definitions listed 62 tools but only 58 tool definitions existed in tools.ts. The MCP server startup log now correctly reports tools=62/62 for admin role.
  • RBAC Operator Count — Corrected the operator role count from 37 to 38 across all documentation and changelog entries.

Version Notes

  • v0.13.3 and v0.13.4 were npm publish patch releases for the @openintentai/mcp-server package (GitHub Actions OIDC configuration and provenance fixes).
  • v0.13.5 is the first release where the MCP TypeScript implementation fully matches the protocol specification for all 21 RFCs.

RBAC Tool Counts

Role Tools Description
reader 21 Read-only tools (default role)
operator 38 Read + write tools
admin 62 Full access including governance, lifecycle, and identity tools

Version Matrix

Component Version
Python SDK (openintent) 0.13.5
MCP Server (@openintentai/mcp-server) 0.13.5

Upgrade Guide

# Python SDK
pip install openintent==0.13.5

# MCP Server
npm install @openintentai/mcp-server@0.13.5

# Or run directly
npx @openintentai/mcp-server@0.13.5

MCP Server Usage

# Start with admin role (all 62 tools)
OPENINTENT_MCP_ROLE=admin npx @openintentai/mcp-server

# Start with operator role (38 tools)
OPENINTENT_MCP_ROLE=operator npx @openintentai/mcp-server

# YAML workflow shorthand
tools:
  - "mcp://npx/-y/@openintentai/mcp-server?role=admin"

Full Changelog

See CHANGELOG.md for the complete history.

v0.13.4

14 Feb 19:14
8c40ef6

Choose a tag to compare

Fixes for mcp-server publishing.

v0.13.3

14 Feb 18:58
a0f664f

Choose a tag to compare

Publishing mcp-server to npm.

v0.13.2

14 Feb 18:48
f00c697

Choose a tag to compare

v0.13.2 — npm Scope Rename + Codex & Streaming Fixes

Date: 2026-02-14

What's New in v0.13.2

npm Package Scope Rename

The MCP server TypeScript package has been renamed from @openintent/mcp-server to @openintentai/mcp-server to match the secured npm organization.

Update your install commands:

npm install @openintentai/mcp-server
# or
npx @openintentai/mcp-server

Update mcp:// URIs in YAML workflows:

tools:
  - "mcp://npx/-y/@openintentai/mcp-server?role=operator"

All documentation, examples, YAML workflows, Makefile targets, and website pages updated accordingly.

OpenAI Codex Model Support (from v0.13.1)

Automatic routing for codex-family models (gpt-5.2-codex, o3-codex, etc.) that use the /v1/completions endpoint instead of /v1/chat/completions.

  • New codex_utils module with is_codex_model(), messages_to_prompt(), and chat_kwargs_to_completions_kwargs() helpers
  • OpenAICompletions wrapper class normalizes completions-API responses to the standard content interface
  • LLM engine routing updated in _call_llm, _stream_llm, and raw provider paths to auto-detect and redirect codex models

Anthropic Streaming Usage Fix (from v0.13.1)

Fixed two bugs causing token usage data to be silently lost during streaming:

  • Wrapped event consumption loop in try/finally so usage is saved even when the stream consumer exits early (GeneratorExit)
  • Added _resolve_usage() fallback that calls get_final_message() when event parsing misses usage data, ensuring accurate cost tracking for all Anthropic models including those with extended thinking

Version Matrix

Component Version
Python SDK (openintent) 0.13.2
MCP Server (@openintentai/mcp-server) 0.13.2

Upgrade Guide

# Python SDK
pip install openintent==0.13.2

# MCP Server
npm install @openintentai/mcp-server@0.13.2

If upgrading from v0.13.0 or earlier, update any @openintent/mcp-server references to @openintentai/mcp-server in your config files and YAML workflows.