@inbrowser/model 0.2.0 → 0.4.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/AGENTS.md +1 -1
- package/README.md +5 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/oai-compat.d.ts +17 -4
- package/dist/providers/oai-compat.d.ts.map +1 -1
- package/dist/providers/oai-compat.js +53 -2
- package/dist/providers/oai-compat.js.map +1 -1
- package/dist/providers/openrouter.d.ts +8 -5
- package/dist/providers/openrouter.d.ts.map +1 -1
- package/dist/providers/openrouter.js +19 -210
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/requesty.d.ts +16 -0
- package/dist/providers/requesty.d.ts.map +1 -0
- package/dist/providers/requesty.js +27 -0
- package/dist/providers/requesty.js.map +1 -0
- package/dist/usage.d.ts +6 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +55 -0
- package/dist/usage.js.map +1 -0
- package/package.json +7 -3
package/AGENTS.md
CHANGED
|
@@ -7,7 +7,7 @@ The model layer. Two halves:
|
|
|
7
7
|
1. **Contract + cloud providers.** `src/contract.ts` defines the one
|
|
8
8
|
`ModelClient` contract the whole stack shares (relay + agent both
|
|
9
9
|
consume it). `src/providers/*` are the cloud providers (Gemini,
|
|
10
|
-
OpenRouter, Anthropic, Ollama, Claude-CLI, Claude-Code), each a
|
|
10
|
+
OpenRouter, Requesty, Anthropic, Ollama, Claude-CLI, Claude-Code), each a
|
|
11
11
|
factory returning a `ModelClient`. `src/with-retry.ts` decorates one.
|
|
12
12
|
2. **On-device engine.** Wraps `@huggingface/transformers` behind a
|
|
13
13
|
narrow `Engine` surface (`src/engine.ts`) that streams `EngineEvent`.
|
package/README.md
CHANGED
|
@@ -11,9 +11,10 @@ Two halves, one package:
|
|
|
11
11
|
- **The contract + cloud providers.** `@inbrowser/model`
|
|
12
12
|
defines `ModelClient` / `ModelRequest` / `ModelEvent`. The cloud
|
|
13
13
|
providers (`geminiModelClient`, `openrouterModelClient`,
|
|
14
|
-
`
|
|
15
|
-
`llamaServerModelClient`, `claudeCliModelClient`,
|
|
16
|
-
are factories that each return a `ModelClient`.
|
|
14
|
+
`requestyModelClient`, `anthropicModelClient`, `openaiCompatModelClient`,
|
|
15
|
+
`ollamaModelClient`, `llamaServerModelClient`, `claudeCliModelClient`,
|
|
16
|
+
`claudeCodeModelClient`) are factories that each return a `ModelClient`.
|
|
17
|
+
`withRetry` decorates one.
|
|
17
18
|
- **The on-device engine.** `createEngine` loads ONNX models in the
|
|
18
19
|
browser via `@huggingface/transformers` + ONNX Runtime Web (WebGPU /
|
|
19
20
|
WASM) and exposes them behind a narrow `Engine` surface that streams
|
|
@@ -132,7 +133,7 @@ Everything is imported from the package root `@inbrowser/model`.
|
|
|
132
133
|
| Export | What it gives you |
|
|
133
134
|
|---|---|
|
|
134
135
|
| `ModelClient`, `ModelRequest`, `ModelEvent`, `ModelMessage`, `ModelUsage`, `ToolSpec`, `ReasoningEffort` | The shared contract (type-only) |
|
|
135
|
-
| `geminiModelClient`, `openrouterModelClient`, `anthropicModelClient`, `openaiCompatModelClient`, `ollamaModelClient`, `llamaServerModelClient`, `claudeCliModelClient`, `claudeCodeModelClient` | Cloud + local provider factories; each returns a `ModelClient` |
|
|
136
|
+
| `geminiModelClient`, `openrouterModelClient`, `requestyModelClient`, `anthropicModelClient`, `openaiCompatModelClient`, `ollamaModelClient`, `llamaServerModelClient`, `claudeCliModelClient`, `claudeCodeModelClient` | Cloud + local provider factories; each returns a `ModelClient` |
|
|
136
137
|
| `OpenAiCompatConfig`, `OllamaConfig`, `LlamaServerConfig` | Config shapes for the OpenAI-compatible factory and its local presets |
|
|
137
138
|
| `withRetry(client, opts?)` | Decorator that retries transient upstream errors while nothing has streamed |
|
|
138
139
|
| `CloudProviderConfig`, `ModelClientFactory` | Shared provider config + the factory type the relay routes on |
|
package/dist/index.d.ts
CHANGED
|
@@ -18,9 +18,11 @@ export { createEngine, definePreset } from './engine.js';
|
|
|
18
18
|
export { createEngineModelClient } from './engine-client.js';
|
|
19
19
|
export { parseToolCalls, type ToolCallParseOpts } from './parse-tool-calls.js';
|
|
20
20
|
export { splitThinking, type ThinkingSplitOpts } from './think.js';
|
|
21
|
+
export { emptyModelUsage, normalizeModelUsage, sumModelUsage, type ModelUsageInput, } from './usage.js';
|
|
21
22
|
export { connectWorkerEngine, hostEngineInWorker, type ConnectWorkerEngineOpts, type HostEngineInWorkerOpts, type WorkerHostHandle, } from './worker.js';
|
|
22
23
|
export { geminiModelClient, buildGeminiRequest, geminiEventsFromResponse, sanitizeGeminiSchema, type GeminiConfig, } from './providers/gemini.js';
|
|
23
24
|
export { openrouterModelClient, toOaiTools as toOpenRouterTools, type OpenRouterConfig, } from './providers/openrouter.js';
|
|
25
|
+
export { requestyModelClient, toOaiTools as toRequestyTools, type RequestyConfig, } from './providers/requesty.js';
|
|
24
26
|
export { beginOpenRouterOAuth, completeOpenRouterOAuth, type BeginOpenRouterOAuthOpts, type CompleteOpenRouterOAuthOpts, type OpenRouterOAuthResult, type OpenRouterOAuthStart, } from './providers/openrouter-oauth.js';
|
|
25
27
|
export { anthropicModelClient, toAnthropicTools, type AnthropicConfig, } from './providers/anthropic.js';
|
|
26
28
|
export { openaiCompatModelClient, toOaiTools, type OpenAiCompatConfig, } from './providers/oai-compat.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,UAAU,IAAI,iBAAiB,EAC/B,KAAK,gBAAgB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mBAAmB,EACnB,UAAU,IAAI,eAAe,EAC7B,KAAK,cAAc,GACpB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,eAAe,GACrB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,KAAK,kBAAkB,GACxB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,iBAAiB,EACjB,UAAU,IAAI,aAAa,EAC3B,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAG7F,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG1F,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAIpF,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,OAAO,EACP,gBAAgB,EAChB,KAAK,EACL,MAAM,EACN,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,MAAM,YAAY,CAAC;AAIpB,YAAY,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export { createEngine, definePreset } from './engine.js';
|
|
|
20
20
|
export { createEngineModelClient } from './engine-client.js';
|
|
21
21
|
export { parseToolCalls } from './parse-tool-calls.js';
|
|
22
22
|
export { splitThinking } from './think.js';
|
|
23
|
+
export { emptyModelUsage, normalizeModelUsage, sumModelUsage, } from './usage.js';
|
|
23
24
|
// In-worker transport: host an `Engine` inside a Web Worker and connect a
|
|
24
25
|
// matching `Engine` stub on the main thread.
|
|
25
26
|
export { connectWorkerEngine, hostEngineInWorker, } from './worker.js';
|
|
@@ -28,6 +29,7 @@ export { connectWorkerEngine, hostEngineInWorker, } from './worker.js';
|
|
|
28
29
|
// settings (messages / tools / sampling) come in the `ModelRequest`.
|
|
29
30
|
export { geminiModelClient, buildGeminiRequest, geminiEventsFromResponse, sanitizeGeminiSchema, } from './providers/gemini.js';
|
|
30
31
|
export { openrouterModelClient, toOaiTools as toOpenRouterTools, } from './providers/openrouter.js';
|
|
32
|
+
export { requestyModelClient, toOaiTools as toRequestyTools, } from './providers/requesty.js';
|
|
31
33
|
// OpenRouter OAuth (PKCE): a browser "Connect OpenRouter" flow that mints a
|
|
32
34
|
// user-controlled, revocable key for `openrouterModelClient` with no backend.
|
|
33
35
|
export { beginOpenRouterOAuth, completeOpenRouterOAuth, } from './providers/openrouter-oauth.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,gFAAgF;AAChF,0BAA0B;AAC1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAA0B,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAA0B,MAAM,YAAY,CAAC;AACnE,0EAA0E;AAC1E,6CAA6C;AAC7C,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GAInB,MAAM,aAAa,CAAC;AAErB,uEAAuE;AACvE,2EAA2E;AAC3E,qEAAqE;AACrE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,GAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,UAAU,IAAI,iBAAiB,GAEhC,MAAM,2BAA2B,CAAC;AACnC,4EAA4E;AAC5E,8EAA8E;AAC9E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GAKxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,GAEjB,MAAM,0BAA0B,CAAC;AAClC,yEAAyE;AACzE,sEAAsE;AACtE,2CAA2C;AAC3C,OAAO,EACL,uBAAuB,EACvB,UAAU,GAEX,MAAM,2BAA2B,CAAC;AACnC,2EAA2E;AAC3E,oDAAoD;AACpD,OAAO,EACL,iBAAiB,EACjB,UAAU,IAAI,aAAa,GAE5B,MAAM,uBAAuB,CAAC;AAC/B,4EAA4E;AAC5E,OAAO,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAC7F,wEAAwE;AACxE,qDAAqD;AACrD,OAAO,EACL,oBAAoB,EACpB,YAAY,GAGb,MAAM,2BAA2B,CAAC;AACnC,0EAA0E;AAC1E,0EAA0E;AAC1E,2EAA2E;AAC3E,OAAO,EAAE,qBAAqB,EAAyB,MAAM,4BAA4B,CAAC;AAE1F,wEAAwE;AACxE,OAAO,EAAE,SAAS,EAAsB,MAAM,iBAAiB,CAAC;AAKhE,yEAAyE;AACzE,+CAA+C;AAC/C,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,YAAY,GACb,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,gFAAgF;AAChF,0BAA0B;AAC1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAA0B,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAA0B,MAAM,YAAY,CAAC;AACnE,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,aAAa,GAEd,MAAM,YAAY,CAAC;AACpB,0EAA0E;AAC1E,6CAA6C;AAC7C,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GAInB,MAAM,aAAa,CAAC;AAErB,uEAAuE;AACvE,2EAA2E;AAC3E,qEAAqE;AACrE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,GAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,UAAU,IAAI,iBAAiB,GAEhC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mBAAmB,EACnB,UAAU,IAAI,eAAe,GAE9B,MAAM,yBAAyB,CAAC;AACjC,4EAA4E;AAC5E,8EAA8E;AAC9E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GAKxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,GAEjB,MAAM,0BAA0B,CAAC;AAClC,yEAAyE;AACzE,sEAAsE;AACtE,2CAA2C;AAC3C,OAAO,EACL,uBAAuB,EACvB,UAAU,GAEX,MAAM,2BAA2B,CAAC;AACnC,2EAA2E;AAC3E,oDAAoD;AACpD,OAAO,EACL,iBAAiB,EACjB,UAAU,IAAI,aAAa,GAE5B,MAAM,uBAAuB,CAAC;AAC/B,4EAA4E;AAC5E,OAAO,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAC7F,wEAAwE;AACxE,qDAAqD;AACrD,OAAO,EACL,oBAAoB,EACpB,YAAY,GAGb,MAAM,2BAA2B,CAAC;AACnC,0EAA0E;AAC1E,0EAA0E;AAC1E,2EAA2E;AAC3E,OAAO,EAAE,qBAAqB,EAAyB,MAAM,4BAA4B,CAAC;AAE1F,wEAAwE;AACxE,OAAO,EAAE,SAAS,EAAsB,MAAM,iBAAiB,CAAC;AAKhE,yEAAyE;AACzE,+CAA+C;AAC/C,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,YAAY,GACb,MAAM,cAAc,CAAC"}
|
|
@@ -5,15 +5,16 @@ import type { CloudProviderConfig } from './types.js';
|
|
|
5
5
|
*
|
|
6
6
|
* Every server that speaks the OpenAI `POST /v1/chat/completions` wire
|
|
7
7
|
* shape — Ollama, llama.cpp's `llama-server`, vLLM, LM Studio, LocalAI,
|
|
8
|
-
* TGI, … — streams the same SSE deltas and reports the
|
|
9
|
-
* fields. This module holds that one implementation:
|
|
8
|
+
* TGI, API gateways, … — streams the same SSE deltas and reports the
|
|
9
|
+
* same core `usage` fields. This module holds that one implementation:
|
|
10
10
|
*
|
|
11
11
|
* - `toOaiMessages` / `toOaiTools` — translate the unified contract's
|
|
12
12
|
* messages + nested `ToolSpec` into the OAI wire shape.
|
|
13
13
|
* - `makeOaiClient` — the streaming engine: builds the request body,
|
|
14
14
|
* fetches, parses SSE, accumulates tool-calls by index, and emits
|
|
15
|
-
* `text` / `tool_call` / `usage` / `error` events. It
|
|
16
|
-
* fully-resolved params so each server is just a set
|
|
15
|
+
* `text` / `thinking` / `tool_call` / `usage` / `error` events. It
|
|
16
|
+
* takes fully-resolved params so each server or gateway is just a set
|
|
17
|
+
* of defaults.
|
|
17
18
|
* - `openaiCompatModelClient` — the public, generic factory. Point it
|
|
18
19
|
* at any OAI-compatible server via `baseUrl` (or a full `endpoint`).
|
|
19
20
|
*
|
|
@@ -44,6 +45,12 @@ interface OaiMessage {
|
|
|
44
45
|
}
|
|
45
46
|
export declare function toOaiMessages(messages: ModelMessage[]): OaiMessage[];
|
|
46
47
|
export declare function toOaiTools(tools: ToolSpec[]): unknown[];
|
|
48
|
+
export interface OaiGatewayAttribution {
|
|
49
|
+
referer?: string;
|
|
50
|
+
title?: string;
|
|
51
|
+
}
|
|
52
|
+
export type OaiReasoningMode = 'openrouter-compatible';
|
|
53
|
+
export declare function oaiGatewayAttributionHeaders(attribution?: OaiGatewayAttribution): Record<string, string>;
|
|
47
54
|
/**
|
|
48
55
|
* Trim trailing slashes off a base URL, falling back to `fallback` when
|
|
49
56
|
* the value is empty or not an http(s) URL. Shared by the presets, whose
|
|
@@ -68,6 +75,12 @@ export interface OaiClientParams {
|
|
|
68
75
|
connectHint?: (base: string) => string;
|
|
69
76
|
/** Construction-time temperature default; a per-request value always wins. */
|
|
70
77
|
temperatureDefault?: number;
|
|
78
|
+
/** Request final gateway usage/cost telemetry with `usage: { include: true }`. */
|
|
79
|
+
includeUsage?: boolean;
|
|
80
|
+
/** Gateway-specific reasoning request shape. */
|
|
81
|
+
reasoningMode?: OaiReasoningMode;
|
|
82
|
+
/** Delta fields that carry streamed reasoning/thought text. */
|
|
83
|
+
thinkingDeltaFields?: readonly string[];
|
|
71
84
|
}
|
|
72
85
|
/** Build a `ModelClient` from fully-resolved OAI params. */
|
|
73
86
|
export declare function makeOaiClient(p: OaiClientParams): ModelClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oai-compat.d.ts","sourceRoot":"","sources":["../../src/providers/oai-compat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,YAAY,EAAgB,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"oai-compat.d.ts","sourceRoot":"","sources":["../../src/providers/oai-compat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,YAAY,EAAgB,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAGpG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,CAmCpE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,CASvD;AASD,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEvD,wBAAgB,4BAA4B,CAC1C,WAAW,CAAC,EAAE,qBAAqB,GAClC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKxB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,CAAC,EAAE,eAAe,GAAG,WAAW,CAiK7D;AA8BD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,WAAW,CAkB/E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readSseDataLines } from '../sse.js';
|
|
2
|
+
import { normalizeModelUsage } from '../usage.js';
|
|
2
3
|
export function toOaiMessages(messages) {
|
|
3
4
|
const out = [];
|
|
4
5
|
for (const m of messages) {
|
|
@@ -46,6 +47,12 @@ export function toOaiTools(tools) {
|
|
|
46
47
|
},
|
|
47
48
|
}));
|
|
48
49
|
}
|
|
50
|
+
export function oaiGatewayAttributionHeaders(attribution) {
|
|
51
|
+
return {
|
|
52
|
+
...(attribution?.referer ? { 'HTTP-Referer': attribution.referer } : {}),
|
|
53
|
+
...(attribution?.title ? { 'X-Title': attribution.title } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
49
56
|
/**
|
|
50
57
|
* Trim trailing slashes off a base URL, falling back to `fallback` when
|
|
51
58
|
* the value is empty or not an http(s) URL. Shared by the presets, whose
|
|
@@ -67,9 +74,11 @@ export function makeOaiClient(p) {
|
|
|
67
74
|
model: p.model,
|
|
68
75
|
messages: toOaiMessages(req.messages),
|
|
69
76
|
stream: true,
|
|
77
|
+
...(p.includeUsage ? { usage: { include: true } } : {}),
|
|
70
78
|
...(typeof temperature === 'number' ? { temperature } : {}),
|
|
71
79
|
...(typeof req.topP === 'number' ? { top_p: req.topP } : {}),
|
|
72
80
|
...(typeof req.topK === 'number' ? { top_k: req.topK } : {}),
|
|
81
|
+
...buildReasoningRequest(p.reasoningMode, req),
|
|
73
82
|
...(req.tools.length > 0
|
|
74
83
|
? { tools: toOaiTools(req.tools), tool_choice: 'auto' }
|
|
75
84
|
: {}),
|
|
@@ -102,6 +111,9 @@ export function makeOaiClient(p) {
|
|
|
102
111
|
}
|
|
103
112
|
let promptTokens = 0;
|
|
104
113
|
let completionTokens = 0;
|
|
114
|
+
let cachedTokens;
|
|
115
|
+
let reasoningTokens;
|
|
116
|
+
let costUsd;
|
|
105
117
|
const pending = new Map();
|
|
106
118
|
try {
|
|
107
119
|
for await (const payload of readSseDataLines(response.body)) {
|
|
@@ -121,6 +133,10 @@ export function makeOaiClient(p) {
|
|
|
121
133
|
if (delta?.content) {
|
|
122
134
|
yield { kind: 'text', text: delta.content };
|
|
123
135
|
}
|
|
136
|
+
const thinking = findThinkingDelta(delta, p.thinkingDeltaFields);
|
|
137
|
+
if (thinking) {
|
|
138
|
+
yield { kind: 'thinking', text: thinking };
|
|
139
|
+
}
|
|
124
140
|
if (delta?.tool_calls) {
|
|
125
141
|
for (const d of delta.tool_calls) {
|
|
126
142
|
let pc = pending.get(d.index);
|
|
@@ -139,6 +155,17 @@ export function makeOaiClient(p) {
|
|
|
139
155
|
if (e.usage) {
|
|
140
156
|
promptTokens = e.usage.prompt_tokens ?? promptTokens;
|
|
141
157
|
completionTokens = e.usage.completion_tokens ?? completionTokens;
|
|
158
|
+
if (typeof e.usage.prompt_tokens_details?.cached_tokens === 'number') {
|
|
159
|
+
cachedTokens = e.usage.prompt_tokens_details.cached_tokens;
|
|
160
|
+
}
|
|
161
|
+
if (typeof e.usage.completion_tokens_details?.reasoning_tokens === 'number') {
|
|
162
|
+
reasoningTokens = e.usage.completion_tokens_details.reasoning_tokens;
|
|
163
|
+
}
|
|
164
|
+
else if (typeof e.usage.reasoning_tokens === 'number') {
|
|
165
|
+
reasoningTokens = e.usage.reasoning_tokens;
|
|
166
|
+
}
|
|
167
|
+
if (typeof e.usage.cost === 'number')
|
|
168
|
+
costUsd = e.usage.cost;
|
|
142
169
|
}
|
|
143
170
|
}
|
|
144
171
|
}
|
|
@@ -170,14 +197,38 @@ export function makeOaiClient(p) {
|
|
|
170
197
|
}
|
|
171
198
|
yield {
|
|
172
199
|
kind: 'usage',
|
|
173
|
-
usage: {
|
|
200
|
+
usage: normalizeModelUsage({
|
|
174
201
|
promptTokens,
|
|
175
202
|
outputTokens: completionTokens,
|
|
176
|
-
|
|
203
|
+
...(typeof cachedTokens === 'number' ? { cachedTokens } : {}),
|
|
204
|
+
...(typeof reasoningTokens === 'number' ? { reasoningTokens } : {}),
|
|
205
|
+
...(typeof costUsd === 'number' ? { costUsd } : {}),
|
|
206
|
+
}),
|
|
177
207
|
};
|
|
178
208
|
},
|
|
179
209
|
};
|
|
180
210
|
}
|
|
211
|
+
function buildReasoningRequest(mode, req) {
|
|
212
|
+
if (mode !== 'openrouter-compatible')
|
|
213
|
+
return {};
|
|
214
|
+
const effort = req.reasoningEffort ?? 'off';
|
|
215
|
+
return effort === 'off'
|
|
216
|
+
? { reasoning: { enabled: false } }
|
|
217
|
+
: {
|
|
218
|
+
reasoning: { effort, summary: 'auto' },
|
|
219
|
+
include_reasoning: true,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function findThinkingDelta(delta, fields) {
|
|
223
|
+
if (!delta || !fields)
|
|
224
|
+
return undefined;
|
|
225
|
+
for (const field of fields) {
|
|
226
|
+
const value = delta[field];
|
|
227
|
+
if (typeof value === 'string' && value.length > 0)
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
181
232
|
const DEFAULT_BASE_URL = 'http://localhost:8080';
|
|
182
233
|
/**
|
|
183
234
|
* Build a `ModelClient` for any OpenAI-compatible chat-completions server.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oai-compat.js","sourceRoot":"","sources":["../../src/providers/oai-compat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"oai-compat.js","sourceRoot":"","sources":["../../src/providers/oai-compat.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import type { ModelClient
|
|
1
|
+
import type { ModelClient } from '../contract.js';
|
|
2
|
+
import { type OaiGatewayAttribution, toOaiTools } from './oai-compat.js';
|
|
2
3
|
import type { CloudProviderConfig } from './types.js';
|
|
3
4
|
/** Construction config for the OpenRouter provider. */
|
|
4
5
|
export interface OpenRouterConfig extends CloudProviderConfig {
|
|
6
|
+
appAttribution?: OaiGatewayAttribution;
|
|
5
7
|
}
|
|
6
|
-
export
|
|
8
|
+
export { toOaiTools };
|
|
7
9
|
/**
|
|
8
|
-
* Build an OpenRouter `ModelClient`.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Build an OpenRouter `ModelClient`.
|
|
11
|
+
*
|
|
12
|
+
* OpenRouter speaks the OpenAI chat-completions stream plus gateway extensions
|
|
13
|
+
* for final cost telemetry and streamed reasoning summaries.
|
|
11
14
|
*/
|
|
12
15
|
export declare function openrouterModelClient(config: OpenRouterConfig): ModelClient;
|
|
13
16
|
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,KAAK,qBAAqB,EAG1B,UAAU,EACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAItD,uDAAuD;AACvD,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D,cAAc,CAAC,EAAE,qBAAqB,CAAC;CACxC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAgB3E"}
|
|
@@ -1,218 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
* OpenRouter provider — talks to /api/v1/chat/completions with
|
|
4
|
-
* streaming SSE. Environment-agnostic: runs unchanged page-side and
|
|
5
|
-
* inside the relay. The only globals it touches are `fetch`,
|
|
6
|
-
* `TextDecoder` (via ../sse), and `JSON`.
|
|
7
|
-
*
|
|
8
|
-
* Same OAI message conversion, same tool-call accumulation by index,
|
|
9
|
-
* same `usage.include` request for real-dollar cost, same
|
|
10
|
-
* reasoning-token pass-through.
|
|
11
|
-
*/
|
|
1
|
+
import { makeOaiClient, oaiGatewayAttributionHeaders, toOaiTools, } from './oai-compat.js';
|
|
12
2
|
const ENDPOINT = 'https://openrouter.ai/api/v1/chat/completions';
|
|
13
|
-
|
|
14
|
-
const out = [];
|
|
15
|
-
for (const m of messages) {
|
|
16
|
-
if (m.role === 'system' || m.role === 'user') {
|
|
17
|
-
out.push({ role: m.role, content: m.text ?? '' });
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
if (m.role === 'assistant') {
|
|
21
|
-
const msg = { role: 'assistant', content: m.text ?? '' };
|
|
22
|
-
if (m.toolCalls && m.toolCalls.length > 0) {
|
|
23
|
-
msg.tool_calls = m.toolCalls.map((c) => ({
|
|
24
|
-
id: c.id,
|
|
25
|
-
type: 'function',
|
|
26
|
-
function: {
|
|
27
|
-
name: c.name,
|
|
28
|
-
arguments: typeof c.args === 'string' ? c.args : JSON.stringify(c.args ?? {}),
|
|
29
|
-
},
|
|
30
|
-
}));
|
|
31
|
-
// OpenAI dislikes assistant messages with both empty content
|
|
32
|
-
// and tool_calls present — null content is the documented form.
|
|
33
|
-
if (!msg.content)
|
|
34
|
-
msg.content = null;
|
|
35
|
-
}
|
|
36
|
-
out.push(msg);
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (m.role === 'tool') {
|
|
40
|
-
out.push({
|
|
41
|
-
role: 'tool',
|
|
42
|
-
tool_call_id: m.toolCallId ?? '',
|
|
43
|
-
name: m.name ?? '',
|
|
44
|
-
content: m.resultJson ?? '',
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return out;
|
|
49
|
-
}
|
|
50
|
-
export function toOaiTools(tools) {
|
|
51
|
-
return tools.map((t) => ({
|
|
52
|
-
type: 'function',
|
|
53
|
-
function: {
|
|
54
|
-
name: t.function.name,
|
|
55
|
-
description: t.function.description,
|
|
56
|
-
parameters: t.function.parameters,
|
|
57
|
-
},
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
3
|
+
export { toOaiTools };
|
|
60
4
|
/**
|
|
61
|
-
* Build an OpenRouter `ModelClient`.
|
|
62
|
-
*
|
|
63
|
-
*
|
|
5
|
+
* Build an OpenRouter `ModelClient`.
|
|
6
|
+
*
|
|
7
|
+
* OpenRouter speaks the OpenAI chat-completions stream plus gateway extensions
|
|
8
|
+
* for final cost telemetry and streamed reasoning summaries.
|
|
64
9
|
*/
|
|
65
10
|
export function openrouterModelClient(config) {
|
|
66
|
-
return {
|
|
11
|
+
return makeOaiClient({
|
|
67
12
|
id: `openrouter:${config.model}`,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const temperature = req.temperature ?? config.temperature;
|
|
74
|
-
const body = {
|
|
75
|
-
model: config.model,
|
|
76
|
-
messages: toOaiMessages(req.messages),
|
|
77
|
-
stream: true,
|
|
78
|
-
// Ask OpenRouter to include cost + cached-token telemetry in the
|
|
79
|
-
// final usage chunk.
|
|
80
|
-
usage: { include: true },
|
|
81
|
-
...(typeof temperature === 'number' ? { temperature } : {}),
|
|
82
|
-
...(typeof req.topP === 'number' ? { top_p: req.topP } : {}),
|
|
83
|
-
...(typeof req.topK === 'number' ? { top_k: req.topK } : {}),
|
|
84
|
-
// OpenRouter's unified reasoning parameter:
|
|
85
|
-
// - `effort: 'off'` → send `reasoning: { enabled: false }`.
|
|
86
|
-
// Just OMITTING the field doesn't actually disable reasoning
|
|
87
|
-
// on Anthropic / DeepSeek / GLM / Kimi / MiniMax thinking
|
|
88
|
-
// models — OpenRouter falls back to each model's default
|
|
89
|
-
// thinking budget, the models burn minutes producing
|
|
90
|
-
// reasoning, and slow connections time out streaming it back.
|
|
91
|
-
// `{ enabled: false }` is the documented explicit-disable.
|
|
92
|
-
// - effort low/medium/high → set effort + ask for the summary
|
|
93
|
-
// and reasoning deltas (`summary: 'auto'` is required for
|
|
94
|
-
// GPT-5 to surface reasoning deltas; `include_reasoning: true`
|
|
95
|
-
// is the legacy alias still honored by older proxy versions).
|
|
96
|
-
...(effort === 'off'
|
|
97
|
-
? { reasoning: { enabled: false } }
|
|
98
|
-
: {
|
|
99
|
-
reasoning: { effort, summary: 'auto' },
|
|
100
|
-
include_reasoning: true,
|
|
101
|
-
}),
|
|
102
|
-
...(req.tools.length > 0
|
|
103
|
-
? { tools: toOaiTools(req.tools), tool_choice: 'auto' }
|
|
104
|
-
: {}),
|
|
105
|
-
};
|
|
106
|
-
let response;
|
|
107
|
-
try {
|
|
108
|
-
response = await fetch(ENDPOINT, {
|
|
109
|
-
method: 'POST',
|
|
110
|
-
headers: {
|
|
111
|
-
Authorization: `Bearer ${config.apiKey}`,
|
|
112
|
-
'Content-Type': 'application/json',
|
|
113
|
-
'HTTP-Referer': 'https://pyric-playground.web.app',
|
|
114
|
-
'X-Title': 'Pyric Playground',
|
|
115
|
-
},
|
|
116
|
-
body: JSON.stringify(body),
|
|
117
|
-
...(signal ? { signal } : {}),
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
if (signal?.aborted)
|
|
122
|
-
return;
|
|
123
|
-
yield { kind: 'error', message: e instanceof Error ? e.message : String(e) };
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
if (!response.ok) {
|
|
127
|
-
const text = await response.text().catch(() => response.statusText);
|
|
128
|
-
yield { kind: 'error', message: `OpenRouter ${response.status}: ${text.slice(0, 240)}` };
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
let promptTokens = 0;
|
|
132
|
-
let completionTokens = 0;
|
|
133
|
-
let costUsd;
|
|
134
|
-
const pending = new Map();
|
|
135
|
-
try {
|
|
136
|
-
for await (const payload of readSseDataLines(response.body)) {
|
|
137
|
-
if (payload === '[DONE]')
|
|
138
|
-
break;
|
|
139
|
-
if (signal?.aborted)
|
|
140
|
-
return;
|
|
141
|
-
let evt;
|
|
142
|
-
try {
|
|
143
|
-
evt = JSON.parse(payload);
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
const e = evt;
|
|
149
|
-
const delta = e.choices?.[0]?.delta;
|
|
150
|
-
if (delta?.content) {
|
|
151
|
-
yield { kind: 'text', text: delta.content };
|
|
152
|
-
}
|
|
153
|
-
const reasoning = delta?.reasoning ?? delta?.reasoning_content;
|
|
154
|
-
if (reasoning) {
|
|
155
|
-
yield { kind: 'thinking', text: reasoning };
|
|
156
|
-
}
|
|
157
|
-
if (delta?.tool_calls) {
|
|
158
|
-
for (const d of delta.tool_calls) {
|
|
159
|
-
let p = pending.get(d.index);
|
|
160
|
-
if (!p) {
|
|
161
|
-
p = { id: d.id ?? '', name: '', args: '', emitted: false };
|
|
162
|
-
pending.set(d.index, p);
|
|
163
|
-
}
|
|
164
|
-
if (d.id)
|
|
165
|
-
p.id = d.id;
|
|
166
|
-
if (d.function?.name)
|
|
167
|
-
p.name = d.function.name;
|
|
168
|
-
if (d.function?.arguments)
|
|
169
|
-
p.args += d.function.arguments;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
if (e.usage) {
|
|
173
|
-
promptTokens = e.usage.prompt_tokens ?? promptTokens;
|
|
174
|
-
completionTokens = e.usage.completion_tokens ?? completionTokens;
|
|
175
|
-
if (typeof e.usage.cost === 'number')
|
|
176
|
-
costUsd = e.usage.cost;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
catch (e) {
|
|
181
|
-
if (signal?.aborted)
|
|
182
|
-
return;
|
|
183
|
-
yield { kind: 'error', message: e instanceof Error ? e.message : String(e) };
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
// Tool calls are streamed argument-by-argument; we wait until the
|
|
187
|
-
// stream closes before parsing + emitting so we don't fire on
|
|
188
|
-
// half-parsed JSON.
|
|
189
|
-
for (const p of pending.values()) {
|
|
190
|
-
if (p.emitted)
|
|
191
|
-
continue;
|
|
192
|
-
let parsedArgs = {};
|
|
193
|
-
try {
|
|
194
|
-
parsedArgs = p.args ? JSON.parse(p.args) : {};
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
parsedArgs = { _raw: p.args };
|
|
198
|
-
}
|
|
199
|
-
yield {
|
|
200
|
-
kind: 'tool_call',
|
|
201
|
-
id: p.id || `or_${Math.random().toString(36).slice(2, 10)}`,
|
|
202
|
-
name: p.name,
|
|
203
|
-
args: parsedArgs,
|
|
204
|
-
};
|
|
205
|
-
p.emitted = true;
|
|
206
|
-
}
|
|
207
|
-
yield {
|
|
208
|
-
kind: 'usage',
|
|
209
|
-
usage: {
|
|
210
|
-
promptTokens,
|
|
211
|
-
outputTokens: completionTokens,
|
|
212
|
-
...(typeof costUsd === 'number' ? { costUsd } : {}),
|
|
213
|
-
},
|
|
214
|
-
};
|
|
13
|
+
endpoint: ENDPOINT,
|
|
14
|
+
model: config.model,
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
17
|
+
...oaiGatewayAttributionHeaders(config.appAttribution),
|
|
215
18
|
},
|
|
216
|
-
|
|
19
|
+
errorLabel: 'OpenRouter',
|
|
20
|
+
idPrefix: 'or',
|
|
21
|
+
temperatureDefault: config.temperature,
|
|
22
|
+
includeUsage: true,
|
|
23
|
+
reasoningMode: 'openrouter-compatible',
|
|
24
|
+
thinkingDeltaFields: ['reasoning', 'reasoning_content'],
|
|
25
|
+
});
|
|
217
26
|
}
|
|
218
27
|
//# sourceMappingURL=openrouter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,aAAa,EACb,4BAA4B,EAC5B,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,MAAM,QAAQ,GAAG,+CAA+C,CAAC;AAOjE,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAwB;IAC5D,OAAO,aAAa,CAAC;QACnB,EAAE,EAAE,cAAc,MAAM,CAAC,KAAK,EAAE;QAChC,QAAQ,EAAE,QAAQ;QAClB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;YACxC,GAAG,4BAA4B,CAAC,MAAM,CAAC,cAAc,CAAC;SACvD;QACD,UAAU,EAAE,YAAY;QACxB,QAAQ,EAAE,IAAI;QACd,kBAAkB,EAAE,MAAM,CAAC,WAAW;QACtC,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,uBAAuB;QACtC,mBAAmB,EAAE,CAAC,WAAW,EAAE,mBAAmB,CAAC;KACxD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ModelClient } from '../contract.js';
|
|
2
|
+
import { type OaiGatewayAttribution, toOaiTools } from './oai-compat.js';
|
|
3
|
+
import type { CloudProviderConfig } from './types.js';
|
|
4
|
+
/** Construction config for the Requesty provider. */
|
|
5
|
+
export interface RequestyConfig extends CloudProviderConfig {
|
|
6
|
+
appAttribution?: OaiGatewayAttribution;
|
|
7
|
+
}
|
|
8
|
+
export { toOaiTools };
|
|
9
|
+
/**
|
|
10
|
+
* Build a Requesty `ModelClient`.
|
|
11
|
+
*
|
|
12
|
+
* Requesty speaks the OpenAI chat-completions stream plus OpenRouter-compatible
|
|
13
|
+
* gateway extensions for final cost telemetry and streamed reasoning summaries.
|
|
14
|
+
*/
|
|
15
|
+
export declare function requestyModelClient(config: RequestyConfig): ModelClient;
|
|
16
|
+
//# sourceMappingURL=requesty.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requesty.d.ts","sourceRoot":"","sources":["../../src/providers/requesty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,KAAK,qBAAqB,EAG1B,UAAU,EACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAItD,qDAAqD;AACrD,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,cAAc,CAAC,EAAE,qBAAqB,CAAC;CACxC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CAgBvE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { makeOaiClient, oaiGatewayAttributionHeaders, toOaiTools, } from './oai-compat.js';
|
|
2
|
+
const ENDPOINT = 'https://router.requesty.ai/v1/chat/completions';
|
|
3
|
+
export { toOaiTools };
|
|
4
|
+
/**
|
|
5
|
+
* Build a Requesty `ModelClient`.
|
|
6
|
+
*
|
|
7
|
+
* Requesty speaks the OpenAI chat-completions stream plus OpenRouter-compatible
|
|
8
|
+
* gateway extensions for final cost telemetry and streamed reasoning summaries.
|
|
9
|
+
*/
|
|
10
|
+
export function requestyModelClient(config) {
|
|
11
|
+
return makeOaiClient({
|
|
12
|
+
id: `requesty:${config.model}`,
|
|
13
|
+
endpoint: ENDPOINT,
|
|
14
|
+
model: config.model,
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
17
|
+
...oaiGatewayAttributionHeaders(config.appAttribution),
|
|
18
|
+
},
|
|
19
|
+
errorLabel: 'Requesty',
|
|
20
|
+
idPrefix: 'rq',
|
|
21
|
+
temperatureDefault: config.temperature,
|
|
22
|
+
includeUsage: true,
|
|
23
|
+
reasoningMode: 'openrouter-compatible',
|
|
24
|
+
thinkingDeltaFields: ['reasoning', 'reasoning_content'],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=requesty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requesty.js","sourceRoot":"","sources":["../../src/providers/requesty.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,aAAa,EACb,4BAA4B,EAC5B,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,MAAM,QAAQ,GAAG,gDAAgD,CAAC;AAOlE,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,OAAO,aAAa,CAAC;QACnB,EAAE,EAAE,YAAY,MAAM,CAAC,KAAK,EAAE;QAC9B,QAAQ,EAAE,QAAQ;QAClB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;YACxC,GAAG,4BAA4B,CAAC,MAAM,CAAC,cAAc,CAAC;SACvD;QACD,UAAU,EAAE,UAAU;QACtB,QAAQ,EAAE,IAAI;QACd,kBAAkB,EAAE,MAAM,CAAC,WAAW;QACtC,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,uBAAuB;QACtC,mBAAmB,EAAE,CAAC,WAAW,EAAE,mBAAmB,CAAC;KACxD,CAAC,CAAC;AACL,CAAC"}
|
package/dist/usage.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModelUsage } from './contract.js';
|
|
2
|
+
export type ModelUsageInput = Partial<ModelUsage> | null | undefined;
|
|
3
|
+
export declare function emptyModelUsage(): ModelUsage;
|
|
4
|
+
export declare function normalizeModelUsage(input: ModelUsageInput): ModelUsage;
|
|
5
|
+
export declare function sumModelUsage(usages: Iterable<ModelUsageInput>): ModelUsage;
|
|
6
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAErE,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAatE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,UAAU,CAmC3E"}
|
package/dist/usage.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export function emptyModelUsage() {
|
|
2
|
+
return { promptTokens: 0, outputTokens: 0 };
|
|
3
|
+
}
|
|
4
|
+
export function normalizeModelUsage(input) {
|
|
5
|
+
const promptTokens = nonNegative(input?.promptTokens) ?? 0;
|
|
6
|
+
const outputTokens = nonNegative(input?.outputTokens) ?? 0;
|
|
7
|
+
const cachedTokens = nonNegative(input?.cachedTokens);
|
|
8
|
+
const reasoningTokens = nonNegative(input?.reasoningTokens);
|
|
9
|
+
const costUsd = nonNegative(input?.costUsd);
|
|
10
|
+
return {
|
|
11
|
+
promptTokens,
|
|
12
|
+
outputTokens,
|
|
13
|
+
...(cachedTokens !== undefined ? { cachedTokens } : {}),
|
|
14
|
+
...(reasoningTokens !== undefined ? { reasoningTokens } : {}),
|
|
15
|
+
...(costUsd !== undefined ? { costUsd } : {}),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function sumModelUsage(usages) {
|
|
19
|
+
let promptTokens = 0;
|
|
20
|
+
let outputTokens = 0;
|
|
21
|
+
let cachedTokens = 0;
|
|
22
|
+
let reasoningTokens = 0;
|
|
23
|
+
let costUsd = 0;
|
|
24
|
+
let hasCachedTokens = false;
|
|
25
|
+
let hasReasoningTokens = false;
|
|
26
|
+
let hasCostUsd = false;
|
|
27
|
+
for (const raw of usages) {
|
|
28
|
+
const usage = normalizeModelUsage(raw);
|
|
29
|
+
promptTokens += usage.promptTokens;
|
|
30
|
+
outputTokens += usage.outputTokens;
|
|
31
|
+
if (usage.cachedTokens !== undefined) {
|
|
32
|
+
cachedTokens += usage.cachedTokens;
|
|
33
|
+
hasCachedTokens = true;
|
|
34
|
+
}
|
|
35
|
+
if (usage.reasoningTokens !== undefined) {
|
|
36
|
+
reasoningTokens += usage.reasoningTokens;
|
|
37
|
+
hasReasoningTokens = true;
|
|
38
|
+
}
|
|
39
|
+
if (usage.costUsd !== undefined) {
|
|
40
|
+
costUsd += usage.costUsd;
|
|
41
|
+
hasCostUsd = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
promptTokens,
|
|
46
|
+
outputTokens,
|
|
47
|
+
...(hasCachedTokens ? { cachedTokens } : {}),
|
|
48
|
+
...(hasReasoningTokens ? { reasoningTokens } : {}),
|
|
49
|
+
...(hasCostUsd ? { costUsd } : {}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function nonNegative(value) {
|
|
53
|
+
return typeof value === 'number' && Number.isFinite(value) ? Math.max(0, value) : undefined;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inbrowser/model",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The model layer for the inbrowser stack: it OWNS the shared ModelClient contract that @inbrowser/relay (transport) and @inbrowser/agent (runtime) both consume, the cloud provider factories (Gemini, OpenRouter, Anthropic, Ollama, Claude-CLI, Claude-Code) that each return a ModelClient, a withRetry decorator, and the on-device LLM engine (lazy-loads @huggingface/transformers + ONNX Runtime Web behind a narrow EngineEvent-streaming Engine surface; Gemma 4 + Qwen + SmolLM2 presets; in-worker host/connect helpers). The engine is also a ModelClient via createEngineModelClient. Everything is exported from the package root.",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "The model layer for the inbrowser stack: it OWNS the shared ModelClient contract that @inbrowser/relay (transport) and @inbrowser/agent (runtime) both consume, the cloud provider factories (Gemini, OpenRouter, Requesty, Anthropic, Ollama, Claude-CLI, Claude-Code) that each return a ModelClient, a withRetry decorator, and the on-device LLM engine (lazy-loads @huggingface/transformers + ONNX Runtime Web behind a narrow EngineEvent-streaming Engine surface; Gemma 4 + Qwen + SmolLM2 presets; in-worker host/connect helpers). The engine is also a ModelClient via createEngineModelClient. Everything is exported from the package root.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"files": ["dist", "README.md", "AGENTS.md"],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "tsc",
|
|
18
|
+
"prepublishOnly": "bun run build",
|
|
18
19
|
"test": "bun test",
|
|
19
20
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
20
21
|
},
|
|
@@ -41,5 +42,8 @@
|
|
|
41
42
|
"url": "git+https://github.com/davideast/inbrowser-agent.git",
|
|
42
43
|
"directory": "packages/model"
|
|
43
44
|
},
|
|
44
|
-
"license": "MIT"
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
45
49
|
}
|