Skip to content

acpx-ai-provider-v0.0.6

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 21 May 09:13
· 131 commits to main since this release
ffb5440

First combined release after v0.0.4 — four feature PRs land in one version since v0.0.5 was bumped but never tagged or published.

Features

  • onPermissionRequest callback on AcpxProviderSettings (#17). Hosts can intercept per-call permission requests (write, shell, delete, …) with their own UI instead of relying on the up-front permissionMode. Returning undefined falls through to the existing mode resolver — zero behavior change for consumers that don't opt in. Driven by the BrowserOS chat flow that wanted inline approve/deny CTA cards.

    createAcpxProvider({
      agent: 'codex',
      permissionMode: 'approve-reads', // fallback for unhandled cases
      onPermissionRequest: async (req) => {
        const decision = await myUi.prompt({
          title: req.raw.toolCall.title,
          kind: req.inferredKind, // 'edit' | 'shell' | 'delete' | …
        })
        return decision // undefined falls through to the mode resolver
      },
    })
  • AcpxProvider.getModels() helper (#19). Typed access to the agent's advertised model list without reaching into the untyped runtime.getStatus().details bag. Returns { currentModelId, availableModelIds } for agents that advertise models (claude, codex), or undefined for those that don't (gemini, custom adapters).

    const provider = createAcpxProvider({ agent: 'claude-code', cwd })
    const models = await provider.getModels()
    // → { currentModelId: 'claude-opus-4-7',
    //     availableModelIds: ['claude-haiku-4-5', 'claude-sonnet-4-6', 'claude-opus-4-7'] }
  • sessionOptions forwarded into runtime.ensureSession (#23). Set per-session systemPrompt / model / allowedTools / maxTurns on a fresh ACP session without bypassing the runtime. System prompts are applied at session/new time; changing them later requires a distinct sessionKey (calling provider.close() keeps the persistent record by default and won't help here).

    createAcpxProvider({
      agent: 'claude-code',
      sessionOptions: {
        systemPrompt: 'You are an expert Rust reviewer. Be terse.',
        // or { append: 'When you finish, also propose tests.' }
      },
    })
  • fullStream now emits an error part on failed turns (#32, #34). When an ACP turn ends with a failed result (model rejected, agent internal error, network blip, auth expired), the stream now emits { type: 'error', error: AcpxError } immediately before the terminal finish part. Previously the only signal was finishReason: "error" on finish plus diagnostic data stashed on providerMetadata.acpx — invisible to a streamText consumer iterating fullStream, which saw a completely silent empty assistant turn. The new error part carries the agent's actual code / message and the underlying AcpRuntimeTurnResultError as cause.

Behavior change — doGenerate / generateText throw on failed turns

The new error stream part is treated as throwable by doGenerate's accumulator (already the contract for ACP-thrown errors). On a failed-turn result, doGenerate and AI SDK's generateText now reject with an AcpxError instead of resolving with { finishReason: "error", providerMetadata: { acpx: { errorCode, errorMessage } } }. Aligns the three failure paths (thrown ACP error, mid-stream error event, failed result) on a single contract.

  • Consumers that read providerMetadata.acpx.{errorCode,errorMessage} on finish keep working — that field is preserved verbatim on the finish part for the streaming path.
  • streamText callers that iterate fullStream (or use the onError hook) automatically receive the new diagnostic. No code change required — they just stop seeing silent empty turns.

Compatibility

  • Peer dependency acpx is now >=0.8.0 (upstream contract changes that ship the new permission callback, session-options threading, and getStatus().models shape).
  • Public API: three new settings (onPermissionRequest, sessionOptions) and one new method (getModels()); no removals or renames.
  • Re-exports added: AcpPermissionRequest, AcpPermissionDecision, SessionAgentOptions, SystemPromptOption, AcpRuntimeSessionModels, AcpRuntimeStatus.

Internal

  • EventTranslator.errorPartIfFailed(result) new helper sitting alongside finish(). createTranslatingStream calls it between flush() and finish().
  • Real-codex e2e contract test for the permission callback round-trip (gated behind SMOKE_AGENTS=codex).
  • Unit + integration coverage across all four PRs uses the existing MockAcpRuntime harness; full provider suite is 186 pass / 0 fail.

⚠️ Alpha software

Both this package and its underlying runtime (acpx) are pre-1.0. Public APIs may change in any minor release. Pin exact versions. Bug reports + design feedback welcome on DaniAkash/acpx.

Full Changelog: acpx-ai-provider-v0.0.4...acpx-ai-provider-v0.0.6