@x-otto/provider 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @otto/provider
2
+
3
+ > Provider-neutral protocol types, chat-completions protocol base, OAuth templates, stream error classification, and stream recording/replay — the LLM provider insertion point package.
4
+
5
+ `@otto/provider` is the public interface package for LLM provider implementations. It provides the `ProviderStream`/`ProviderFactory`/`StreamContext` contract types, the chat-completions protocol base (shared by OpenAI-compatible and custom providers), OAuth login/refresh templates (PKCE, device-flow), stream error classification, stream recording/replay for diagnostics, and request header assembly.
6
+
7
+ **Zero vendor implementations**: all concrete provider implementations live in extensions/plugins (see `extensions/plugin-otto-wire-protocols` for standard wire protocols, `extensions/plugin-github-copilot` for the Copilot custom provider). This package provides only the insertion point contracts and shared tooling.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pnpm add @otto/provider
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { streamChatCompletions } from '@otto/provider'
19
+ import { buildChatCompletionsBody } from '@otto/provider'
20
+ import { sanitizeToolRoundtrips } from '@otto/provider'
21
+ import { classifyStreamError, isAuthError } from '@otto/provider'
22
+ import { buildRequestHeaders } from '@otto/provider'
23
+ import { recordStream, replayStream } from '@otto/provider'
24
+
25
+ // Streaming chat completions
26
+ const events = streamChatCompletions({
27
+ model,
28
+ messages,
29
+ tools,
30
+ signal,
31
+ })
32
+
33
+ // Build request body
34
+ const body = buildChatCompletionsBody({
35
+ model,
36
+ messages: sanitizeToolRoundtrips(messages),
37
+ tools,
38
+ })
39
+
40
+ // Classify errors
41
+ try { /* ... */ } catch (err) {
42
+ if (isAuthError(err)) { /* handle auth */ }
43
+ if (isContextOverflowError(err)) { /* compact context */ }
44
+ const cls = classifyStreamError(err)
45
+ }
46
+
47
+ // Record + replay streams (diagnostics)
48
+ const recording = recordStream(streamEvents, { model, messages })
49
+ // ...save recording to disk...
50
+ const replay = replayStream(loadRecording('path/to/recording.json'))
51
+ ```
52
+
53
+ ## API
54
+
55
+ ### Chat Completions Protocol Base
56
+ - `streamChatCompletions(params)` — SSE streaming loop for chat-completions-compatible APIs
57
+ - `buildChatCompletionsBody(params)` — construct request body from model/messages/tools
58
+ - `buildChatCompletionsMessages(messages, model)` — prepare messages array for the body
59
+ - `clampThinkingLevel(level)` — normalize thinking effort to known levels
60
+ - `mapChatFinishReason(reason)` — map native finish reason → canonical StopReason
61
+
62
+ ### Protocol-Neutral Primitives
63
+ - `sanitizeToolRoundtrips(messages)` — deduplicate tool roundtrips, fix placement
64
+ - `initStreamUsage()` / `parseToolArgumentsWithStatus(items, warn)` — stream state management
65
+ - `assembleAssistantMessage(state, meta)` — build final AssistantMessage from accumulated state
66
+ - `sanitizeSurrogates(text)` / `toJsonSchema(schema)` — encoding utilities
67
+ - `assertSystemNotificationPlacement(messages)` / `degradedSystemNotificationText(text)` — message ordering
68
+
69
+ ### OAuth Templates
70
+ - `PKCEOAuthTemplate(params)` — PKCE flow template (used by Anthropic, OpenAI Codex plugins)
71
+ - `DeviceFlowOAuthTemplate(params)` — device code flow template (used by GitHub Copilot plugin)
72
+ - `createPkcePair()` / `generateVerifier()` / `generateChallenge()` / `generateState()` — PKCE primitives
73
+ - `startLoopbackServer(options)` — OAuth callback server
74
+ - `extractJwtClaim(token)` — JWT decoding utility
75
+
76
+ ### Stream Error Classification
77
+ - `classifyStreamError(error)` → `StreamErrorClass` — unified error classification
78
+ - `isContextOverflowError(error)` — 413 / "prompt too long" detection
79
+ - `isNetworkDisconnectError(error)` — ECONNRESET / socket hang-up detection
80
+ - `isAuthError(error)` — 401/403 auth failure detection
81
+ - `classifyAuthErrorType(error)` → `AuthErrorType` — specific auth failure subtype
82
+ - `extractRetryAfterMs(error)` — parse Retry-After header or rate limit info
83
+ - `extractAnthropicRateLimit(headers)` — parse Anthropic-specific rate limit headers
84
+
85
+ ### Rate Limit & Usage Headers
86
+ - `extractStandardRateLimitHeaders(headers)` — parse `x-ratelimit-*` headers from any provider
87
+ - `buildRequestHeaders(sources)` — assemble outbound request headers with 5-tier priority
88
+
89
+ ### Stream Recording & Replay (RFC-200)
90
+ - `recordStream(stream, meta)` — capture StreamEvent sequence to Recording
91
+ - `loadRecording(path)` / `saveRecording(recording, path)` — persist recordings
92
+ - `replayStream(recording, options?)` — replay a recording as an AsyncIterable
93
+ - `ReplayProviderStream` / `createReplayProviderFactory(buildReplayModel)` — replay as a ProviderStream
94
+ - `recordingsDir()` — default recordings directory path
95
+
96
+ ## Dependencies
97
+
98
+ - Internal: `@otto/interchange` (protocol types), `@otto/shared` (logger, error types, header utils)
99
+ - External: none (only Node.js builtins + `@otto/*` internal packages)
100
+
101
+ ## Related
102
+
103
+ - [Architecture](./ARCHITECTURE.md)