typebulb 0.17.0 → 0.17.1
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 +5 -2
- package/dist/agents/claude/styles.css +1 -1
- package/dist/ai/aiProviders.d.ts +11 -0
- package/dist/ai/aiProviders.d.ts.map +1 -1
- package/dist/ai/aiProviders.js +19 -2
- package/dist/ai/aiProviders.js.map +1 -1
- package/dist/ai/protocol.d.ts +5 -5
- package/dist/ai/protocol.d.ts.map +1 -1
- package/dist/ai/providers/ollama.d.ts +13 -12
- package/dist/ai/providers/ollama.d.ts.map +1 -1
- package/dist/ai/providers/ollama.js +16 -6
- package/dist/ai/providers/ollama.js.map +1 -1
- package/dist/ai/providers/openRouter.d.ts +1 -1
- package/dist/ai/providers/openRouter.d.ts.map +1 -1
- package/dist/ai/providers/openRouter.js +7 -1
- package/dist/ai/providers/openRouter.js.map +1 -1
- package/dist/index.js +128 -128
- package/dist/servers.js +24 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -342,6 +342,7 @@ Add API keys to your `.env` file:
|
|
|
342
342
|
| `gemini` | `GOOGLE_API_KEY` |
|
|
343
343
|
| `openrouter` | `OPENROUTER_API_KEY` |
|
|
344
344
|
| `ollama` | *(none — local server)* |
|
|
345
|
+
| `openai-compat` | `TB_AI_API_KEY` *(optional)* + `TB_AI_BASE_URL` |
|
|
345
346
|
|
|
346
347
|
Optionally, set your default provider and model:
|
|
347
348
|
|
|
@@ -391,9 +392,11 @@ for await (const c of tb.ai.stream({ messages })) {
|
|
|
391
392
|
|
|
392
393
|
Breaking the loop stops the stream; same options as `tb.ai()`. **`kind: "reasoning"` chunks require `reasoning: 1-3` and a thinking-capable model**.
|
|
393
394
|
|
|
394
|
-
###
|
|
395
|
+
### Ollama & OpenAI-compatible endpoints
|
|
395
396
|
|
|
396
|
-
`provider: "ollama"` talks to a local [Ollama](https://ollama.com) server over its OpenAI-compatible endpoint — no API key, defaults to `http://localhost:11434` (override with `OLLAMA_HOST`).
|
|
397
|
+
`provider: "ollama"` is the zero-config local preset: it talks to a local [Ollama](https://ollama.com) server over its OpenAI-compatible endpoint — no API key, defaults to `http://localhost:11434` (override with `OLLAMA_HOST`). `typebulb models` lists your installed Ollama models alongside cloud ones.
|
|
398
|
+
|
|
399
|
+
`provider: "openai-compat"` is the generic escape hatch to *any* OpenAI-compatible endpoint — local or remote (LM Studio, vLLM, a self-hosted box, a keyed proxy, a cloud OpenAI-compat vendor). Set `TB_AI_BASE_URL` (the OpenAI-style base URL ending in `/v1`, e.g. `http://localhost:1234/v1` — `/chat/completions` is appended) and an optional `TB_AI_API_KEY`. Set `TB_AI_MODEL` explicitly (no auto-discovery).
|
|
397
400
|
|
|
398
401
|
### Proxying Claude
|
|
399
402
|
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
html[data-theme="dark"] {
|
|
31
31
|
/* Neutral ramp, same tint as the main app: page 18 → surface 32 → border 52. */
|
|
32
32
|
--bg: rgb(18, 19, 20);
|
|
33
|
-
--fg: rgb(
|
|
33
|
+
--fg: rgb(190, 190, 190);
|
|
34
34
|
--muted: rgb(150, 150, 150);
|
|
35
35
|
--panel: rgb(32, 32, 32);
|
|
36
36
|
--border: rgb(52, 52, 52);
|
package/dist/ai/aiProviders.d.ts
CHANGED
|
@@ -21,6 +21,17 @@ export interface SendAIRequestOpts {
|
|
|
21
21
|
signal?: AbortSignal;
|
|
22
22
|
modifyPayload?: (payload: Record<string, unknown>) => void;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Join an operation path onto a base URL, **preserving the base's path prefix**.
|
|
26
|
+
*
|
|
27
|
+
* `new URL(absolutePath, base)` resolves the absolute path against the base's *origin*, so any
|
|
28
|
+
* path in the base is silently dropped — a prefixed/gateway/proxy base (Azure, a corporate proxy,
|
|
29
|
+
* an `openai-compat` endpoint) loses its prefix. This keeps the base intact and appends the path
|
|
30
|
+
* with exactly one `/` between. The OpenAI-SDK model: `baseUrl` is the true API root, the
|
|
31
|
+
* operation path (from `getPath`) is joined onto it. Trailing slashes on the base are collapsed so
|
|
32
|
+
* a user-supplied `…/v1/` and `…/v1` behave identically.
|
|
33
|
+
*/
|
|
34
|
+
export declare function joinUrl(base: string, path: string): string;
|
|
24
35
|
/** Send a request to an AI provider */
|
|
25
36
|
export declare function sendAIRequest(provider: ResolvedAIProvider, opts: SendAIRequestOpts): Promise<Response>;
|
|
26
37
|
/** Parse an upstream error response into our standard error payload */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiProviders.d.ts","sourceRoot":"","sources":["../../ai/src/aiProviders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACzG,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"aiProviders.d.ts","sourceRoot":"","sources":["../../ai/src/aiProviders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACzG,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAmB5C,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,UAAU,CAMlE;AAED,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAC3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,uCAAuC;AACvC,wBAAsB,aAAa,CACjC,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,QAAQ,CAAC,CAqBnB;AAED,uEAAuE;AACvE,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAWvC"}
|
package/dist/ai/aiProviders.js
CHANGED
|
@@ -3,12 +3,16 @@ import { OpenRouterProvider } from './providers/openRouter.js';
|
|
|
3
3
|
import { AnthropicProvider } from './providers/anthropic.js';
|
|
4
4
|
import { GeminiProvider } from './providers/gemini.js';
|
|
5
5
|
import { OllamaProvider } from './providers/ollama.js';
|
|
6
|
+
// One OpenAI-compatible client backs both the `ollama` zero-config preset and the generic
|
|
7
|
+
// `openai-compat` protocol; they differ only in how the resolver sources base URL + key.
|
|
8
|
+
const openAICompat = new OllamaProvider();
|
|
6
9
|
const providers = new Map([
|
|
7
10
|
['openai', new OpenAIProvider()],
|
|
8
11
|
['openrouter', new OpenRouterProvider()],
|
|
9
12
|
['anthropic', new AnthropicProvider()],
|
|
10
13
|
['gemini', new GeminiProvider()],
|
|
11
|
-
['ollama',
|
|
14
|
+
['ollama', openAICompat],
|
|
15
|
+
['openai-compat', openAICompat]
|
|
12
16
|
]);
|
|
13
17
|
/** Get the provider implementation for a given protocol. */
|
|
14
18
|
export function getProvider(protocol) {
|
|
@@ -18,11 +22,24 @@ export function getProvider(protocol) {
|
|
|
18
22
|
}
|
|
19
23
|
return provider;
|
|
20
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Join an operation path onto a base URL, **preserving the base's path prefix**.
|
|
27
|
+
*
|
|
28
|
+
* `new URL(absolutePath, base)` resolves the absolute path against the base's *origin*, so any
|
|
29
|
+
* path in the base is silently dropped — a prefixed/gateway/proxy base (Azure, a corporate proxy,
|
|
30
|
+
* an `openai-compat` endpoint) loses its prefix. This keeps the base intact and appends the path
|
|
31
|
+
* with exactly one `/` between. The OpenAI-SDK model: `baseUrl` is the true API root, the
|
|
32
|
+
* operation path (from `getPath`) is joined onto it. Trailing slashes on the base are collapsed so
|
|
33
|
+
* a user-supplied `…/v1/` and `…/v1` behave identically.
|
|
34
|
+
*/
|
|
35
|
+
export function joinUrl(base, path) {
|
|
36
|
+
return base.replace(/\/+$/, '') + (path.startsWith('/') ? path : `/${path}`);
|
|
37
|
+
}
|
|
21
38
|
/** Send a request to an AI provider */
|
|
22
39
|
export async function sendAIRequest(provider, opts) {
|
|
23
40
|
const spec = getProvider(provider.protocol);
|
|
24
41
|
const path = spec.getPath(opts.model, opts.stream);
|
|
25
|
-
const url =
|
|
42
|
+
const url = joinUrl(provider.baseUrl, path);
|
|
26
43
|
const headers = spec.buildHeaders(provider.apiKey, opts.origin);
|
|
27
44
|
const payload = spec.buildPayload(opts.messages, opts.model, { reasoning: opts.reasoning, webSearch: opts.webSearch }, opts.stream);
|
|
28
45
|
opts.modifyPayload?.(payload);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiProviders.js","sourceRoot":"","sources":["../../ai/src/aiProviders.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,SAAS,GAAG,IAAI,GAAG,CAA+B;IACtD,CAAC,QAAQ,EAAE,IAAI,cAAc,EAAE,CAAC;IAChC,CAAC,YAAY,EAAE,IAAI,kBAAkB,EAAE,CAAC;IACxC,CAAC,WAAW,EAAE,IAAI,iBAAiB,EAAE,CAAC;IACtC,CAAC,QAAQ,EAAE,IAAI,cAAc,EAAE,CAAC;IAChC,CAAC,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"aiProviders.js","sourceRoot":"","sources":["../../ai/src/aiProviders.ts"],"names":[],"mappings":"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"}
|
package/dist/ai/protocol.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from './chat.js';
|
|
2
2
|
export * from './stream.js';
|
|
3
|
-
/** AI provider wire protocol identifier.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* specs/TB-
|
|
7
|
-
export type ProviderProtocol = 'openai' | 'anthropic' | 'openrouter' | 'gemini' | 'ollama';
|
|
3
|
+
/** AI provider wire protocol identifier. `ollama` and `openai-compat` are CLI-only: both talk to an
|
|
4
|
+
* OpenAI-compatible endpoint (local, self-hosted, or remote) and are never reachable from the web
|
|
5
|
+
* runtime. `ollama` is the zero-config preset; `openai-compat` is the generic form. See
|
|
6
|
+
* runtime-specs/TB-Custom-Providers.md. */
|
|
7
|
+
export type ProviderProtocol = 'openai' | 'anthropic' | 'openrouter' | 'gemini' | 'ollama' | 'openai-compat';
|
|
8
8
|
/** Extended-thinking hint, 0 (off) – 3 (max) */
|
|
9
9
|
export type ReasoningDepth = 0 | 1 | 2 | 3;
|
|
10
10
|
/** A streamed delta from `tb.ai.stream()`. Discriminated union — exactly one kind per chunk, so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../ai/src/protocol.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAE3B;;;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../ai/src/protocol.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAE3B;;;4CAG4C;AAC5C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,CAAA;AAE5G,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAE1C;;+FAE+F;AAC/F,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC,iEAAiE;AACjE,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAA;CACrB"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* A generic OpenAI-compatible Chat Completions client (`/v1/chat/completions`, choices[]) — wire
|
|
3
|
+
* types and provider implementation. Backs two CLI-only protocols (see
|
|
4
|
+
* runtime/cli/src/serve/server.ts `resolveLocalProvider`):
|
|
5
|
+
* - `ollama` — zero-config preset: keyless, base URL OLLAMA_HOST / http://localhost:11434.
|
|
6
|
+
* - `openai-compat` — generic: base URL TB_AI_BASE_URL, optional key TB_AI_API_KEY (LM Studio,
|
|
7
|
+
* vLLM, a self-hosted endpoint, a keyed proxy, a cloud OpenAI-compat vendor).
|
|
8
|
+
* Auth is optional — `buildHeaders` sends `Bearer <key>` only when a key is present.
|
|
4
9
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Ollama does NOT implement the OpenAI Responses API the `openai` protocol targets, which is why
|
|
10
|
-
* this is its own provider rather than a reuse of OpenAIProvider. The native `/api/chat` endpoint
|
|
11
|
-
* (NDJSON, first-class `message.thinking`) is the richer path for reasoning streaming and Ollama
|
|
12
|
-
* options — a deliberate follow-up; see specs/TB-AI-Local-Models.md.
|
|
10
|
+
* It's its own class (not OpenAIProvider) because the `openai` protocol targets the Responses API
|
|
11
|
+
* (`/v1/responses`), which these endpoints don't implement. Ollama's native `/api/chat` (NDJSON,
|
|
12
|
+
* first-class `message.thinking`, `num_ctx`/`think` options) is out of scope for tb.ai — reach it
|
|
13
|
+
* via a server.ts export. See runtime-specs/TB-Custom-Providers.md.
|
|
13
14
|
*/
|
|
14
15
|
import type { ChatMessageDto, UpstreamErrorDto, ChatStreamPieceDto, ChatResponseDto, ProviderResponseDto, ProviderStreamEventDto } from '../protocol.js';
|
|
15
16
|
import { AIProvider, type ChatRequestOpts } from '../aiProvider.js';
|
|
@@ -45,8 +46,8 @@ export type OllamaRequestPayload = {
|
|
|
45
46
|
export declare class OllamaProvider extends AIProvider {
|
|
46
47
|
protected readonly providerName = "Ollama";
|
|
47
48
|
readonly defaultBaseUrl = "http://localhost:11434";
|
|
48
|
-
readonly path = "/
|
|
49
|
-
buildHeaders(
|
|
49
|
+
readonly path = "/chat/completions";
|
|
50
|
+
buildHeaders(apiKey: string): Record<string, string>;
|
|
50
51
|
buildPayload(messages: ChatMessageDto[], model: string, _opts: ChatRequestOpts, stream: boolean): OllamaRequestPayload;
|
|
51
52
|
parseError(errorText: string, status: number): UpstreamErrorDto;
|
|
52
53
|
parseNonStreamingResponse(json: ProviderResponseDto): ChatResponseDto;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/ollama.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/ollama.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAKnE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IAEf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,gBAAgB,CAAA;CAC3B;AAED,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,OAAO,EAAE,eAAe,EAAE,CAAA;CAC3B;AAGD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAED,MAAM,WAAW,oBAAqB,SAAQ,sBAAsB;IAClE,OAAO,EAAE,qBAAqB,EAAE,CAAA;CACjC;AAID,+CAA+C;AAC/C,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC5C,SAAS,CAAC,QAAQ,CAAC,YAAY,YAAW;IAQ1C,QAAQ,CAAC,cAAc,4BAA2B;IAClD,QAAQ,CAAC,IAAI,uBAAsB;IAMnC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAYpD,YAAY,CACV,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,OAAO,GACd,oBAAoB;IAIvB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAM/D,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe;IAUrE,SAAS,CAAC,wBAAwB,CAAC,IAAI,EAAE,sBAAsB,GAAG,kBAAkB,GAAG,IAAI;IAmB3F,OAAO,CAAC,UAAU;CAInB"}
|
|
@@ -3,21 +3,31 @@ export class OllamaProvider extends AIProvider {
|
|
|
3
3
|
constructor() {
|
|
4
4
|
super(...arguments);
|
|
5
5
|
this.providerName = 'Ollama';
|
|
6
|
+
// Bring-your-own-endpoint convention: the base is the OpenAI-style root ending in `/v1` and the
|
|
7
|
+
// operation path is just `/chat/completions` — paste-compatible with every OpenAI-compat vendor
|
|
8
|
+
// (OpenAI `…/v1`, Groq `…/openai/v1`, vLLM/LM Studio `…/v1`). The `/v1` is supplied by the base,
|
|
9
|
+
// not the path: the CLI resolver hands `openai-compat` the user's TB_AI_BASE_URL (a `/v1` base)
|
|
10
|
+
// and `ollama` a `${OLLAMA_HOST}/v1` base (resolveLocalProvider in runtime/cli/src/serve/server.ts).
|
|
11
|
+
// `defaultBaseUrl` stays the bare origin because it's only the fallback for OLLAMA_HOST (Ollama's
|
|
12
|
+
// own env var, an origin); the resolver appends `/v1` to it.
|
|
6
13
|
this.defaultBaseUrl = 'http://localhost:11434';
|
|
7
|
-
this.path = '/
|
|
14
|
+
this.path = '/chat/completions';
|
|
8
15
|
}
|
|
9
16
|
// ── Request building ─────────────────────────────────────────────
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
buildHeaders(
|
|
13
|
-
|
|
17
|
+
// Auth-optional: keyless for local Ollama (empty key from the resolver), or `Bearer <key>` when
|
|
18
|
+
// the OpenAI-compatible endpoint requires one (vLLM --api-key, a self-hosted/proxy, etc.).
|
|
19
|
+
buildHeaders(apiKey) {
|
|
20
|
+
const headers = {
|
|
14
21
|
'Content-Type': 'application/json',
|
|
15
22
|
'Accept': 'application/json'
|
|
16
23
|
};
|
|
24
|
+
if (apiKey)
|
|
25
|
+
headers['Authorization'] = `Bearer ${apiKey}`;
|
|
26
|
+
return headers;
|
|
17
27
|
}
|
|
18
28
|
// Web search and the reasoning-effort knob have no equivalent on the OpenAI-compat endpoint,
|
|
19
29
|
// so the payload stays minimal. Ollama-specific options (num_ctx, think, …) are intentionally
|
|
20
|
-
// out of scope for tb.ai — use a server.ts export for those (specs/TB-Server-Streaming.md).
|
|
30
|
+
// out of scope for tb.ai — use a server.ts export for those (runtime-specs/TB-Server-Streaming.md).
|
|
21
31
|
buildPayload(messages, model, _opts, stream) {
|
|
22
32
|
return { model, messages, stream };
|
|
23
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../ai/src/providers/ollama.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../ai/src/providers/ollama.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAA;AA6CnE,MAAM,OAAO,cAAe,SAAQ,UAAU;IAA9C;;QACqB,iBAAY,GAAG,QAAQ,CAAA;QAC1C,gGAAgG;QAChG,gGAAgG;QAChG,iGAAiG;QACjG,gGAAgG;QAChG,qGAAqG;QACrG,kGAAkG;QAClG,6DAA6D;QACpD,mBAAc,GAAG,wBAAwB,CAAA;QACzC,SAAI,GAAG,mBAAmB,CAAA;IAkErC,CAAC;IAhEC,oEAAoE;IAEpE,gGAAgG;IAChG,2FAA2F;IAC3F,YAAY,CAAC,MAAc;QACzB,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,QAAQ,EAAE,kBAAkB;SAC7B,CAAA;QACD,IAAI,MAAM;YAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAA;QACzD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,6FAA6F;IAC7F,8FAA8F;IAC9F,oGAAoG;IACpG,YAAY,CACV,QAA0B,EAC1B,KAAa,EACb,KAAsB,EACtB,MAAe;QAEf,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;IACpC,CAAC;IAED,UAAU,CAAC,SAAiB,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IACrD,CAAC;IAED,oEAAoE;IAEpE,yBAAyB,CAAC,IAAyB;QACjD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;QAE/C,MAAM,MAAM,GAAI,IAA0B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACrD,MAAM,GAAG,GAAG,MAAM,EAAE,OAAO,CAAA;QAC3B,MAAM,IAAI,GAAG,GAAG,EAAE,OAAO,IAAI,EAAE,CAAA;QAC/B,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS,IAAI,GAAG,EAAE,iBAAiB,CAAA;QAC1D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC5B,CAAC;IAES,wBAAwB,CAAC,IAA4B;QAC7D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAEvC,MAAM,MAAM,GAAI,IAA6B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACxD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAExB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,CAAA;QAC5C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,IAAI,SAAS,CAAA;QACvC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,iBAAiB,IAAI,SAAS,CAAA;QAEzE,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAA;QAEpC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC5B,CAAC;IAED,oEAAoE;IAE5D,UAAU,CAAC,IAAa;QAC9B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;eAC3C,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAE,IAA8B,CAAC,OAAO,CAAC,CAAA;IAClF,CAAC;CACF"}
|
|
@@ -51,7 +51,7 @@ export type OpenRouterRequestPayload = {
|
|
|
51
51
|
};
|
|
52
52
|
export declare class OpenRouterProvider extends AIProvider {
|
|
53
53
|
protected readonly providerName = "OpenRouter";
|
|
54
|
-
readonly defaultBaseUrl = "https://openrouter.ai
|
|
54
|
+
readonly defaultBaseUrl = "https://openrouter.ai";
|
|
55
55
|
readonly path: string;
|
|
56
56
|
private readonly effortMap;
|
|
57
57
|
buildHeaders(apiKey: string, origin?: string): Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openRouter.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/openRouter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAEhB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAKnE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,oBAAoB,CAAA;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,OAAO,EAAE,mBAAmB,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAGD,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAC7B;AAED,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,OAAO,EAAE,yBAAyB,EAAE,CAAA;CACrC;AAGD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAGD,MAAM,MAAM,qBAAqB,GAC7B,wBAAwB,GACxB,0BAA0B,CAAA;AAI9B,mCAAmC;AACnC,UAAU,mBAAmB;IAC3B,EAAE,EAAE,KAAK,CAAA;IACT,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,iCAAiC;AACjC,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;KAAE,CAAA;IACjD,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAA;CAChC,CAAA;AAED,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,SAAS,CAAC,QAAQ,CAAC,YAAY,gBAAe;
|
|
1
|
+
{"version":3,"file":"openRouter.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/openRouter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAEhB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAKnE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,oBAAoB,CAAA;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,OAAO,EAAE,mBAAmB,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAGD,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAC7B;AAED,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,OAAO,EAAE,yBAAyB,EAAE,CAAA;CACrC;AAGD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAGD,MAAM,MAAM,qBAAqB,GAC7B,wBAAwB,GACxB,0BAA0B,CAAA;AAI9B,mCAAmC;AACnC,UAAU,mBAAmB;IAC3B,EAAE,EAAE,KAAK,CAAA;IACT,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,iCAAiC;AACjC,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;KAAE,CAAA;IACjD,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAA;CAChC,CAAA;AAED,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,SAAS,CAAC,QAAQ,CAAC,YAAY,gBAAe;IAO9C,QAAQ,CAAC,cAAc,2BAA0B;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAA6B;IAElD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAKzB;IAID,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAkBrE,YAAY,CACV,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,OAAO,GACd,wBAAwB;IAqB3B,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAM/D,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe;IAarE,SAAS,CAAC,wBAAwB,CAAC,IAAI,EAAE,sBAAsB,GAAG,kBAAkB,GAAG,IAAI;IAmB3F,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -3,7 +3,13 @@ export class OpenRouterProvider extends AIProvider {
|
|
|
3
3
|
constructor() {
|
|
4
4
|
super(...arguments);
|
|
5
5
|
this.providerName = 'OpenRouter';
|
|
6
|
-
|
|
6
|
+
// First-party convention (like anthropic/openai/gemini): the base is the bare origin and the
|
|
7
|
+
// full versioned mount lives in `path`. OpenRouter mounts its OpenAI-compatible API at `/api/v1`
|
|
8
|
+
// (not `/v1`), so the path carries `/api/v1/…` — the vendor's real mount, the way gemini's path
|
|
9
|
+
// carries `/v1beta`. Keeping `/api` in the path (not the base) also matches the web-side stored
|
|
10
|
+
// `apiUrl` of `https://openrouter.ai`, so the prefix-preserving join yields the identical URL on
|
|
11
|
+
// both web and CLI. (Do NOT put `/api` in the base too — the join would then double it to `/api/api`.)
|
|
12
|
+
this.defaultBaseUrl = 'https://openrouter.ai';
|
|
7
13
|
this.path = '/api/v1/chat/completions';
|
|
8
14
|
this.effortMap = {
|
|
9
15
|
0: 'low',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openRouter.js","sourceRoot":"","sources":["../../../ai/src/providers/openRouter.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAA;AAkEnE,MAAM,OAAO,kBAAmB,SAAQ,UAAU;IAAlD;;QACqB,iBAAY,GAAG,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"openRouter.js","sourceRoot":"","sources":["../../../ai/src/providers/openRouter.ts"],"names":[],"mappings":"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"}
|