@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 +103 -0
- package/dist/index.d.ts +2129 -0
- package/dist/index.js +6 -0
- package/package.json +32 -0
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)
|