typebulb 0.16.1 → 0.17.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 +43 -8
- package/dist/agents/claude/client.js +131 -35
- package/dist/ai/aiProviders.d.ts.map +1 -1
- package/dist/ai/aiProviders.js +3 -1
- package/dist/ai/aiProviders.js.map +1 -1
- package/dist/ai/index.d.ts +2 -1
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +2 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/protocol.d.ts +15 -2
- package/dist/ai/protocol.d.ts.map +1 -1
- package/dist/ai/providers/gemini.d.ts +12 -1
- package/dist/ai/providers/gemini.d.ts.map +1 -1
- package/dist/ai/providers/gemini.js +24 -14
- package/dist/ai/providers/gemini.js.map +1 -1
- package/dist/ai/providers/ollama.d.ts +56 -0
- package/dist/ai/providers/ollama.d.ts.map +1 -0
- package/dist/ai/providers/ollama.js +58 -0
- package/dist/ai/providers/ollama.js.map +1 -0
- package/dist/ai/sseParser.d.ts +17 -1
- package/dist/ai/sseParser.d.ts.map +1 -1
- package/dist/ai/sseParser.js +71 -8
- package/dist/ai/sseParser.js.map +1 -1
- package/dist/dts/definitelyTypedProvider.d.ts +9 -0
- package/dist/dts/definitelyTypedProvider.d.ts.map +1 -1
- package/dist/dts/definitelyTypedProvider.js +21 -1
- package/dist/dts/definitelyTypedProvider.js.map +1 -1
- package/dist/dts/tbTypings.d.ts +2 -2
- package/dist/dts/tbTypings.d.ts.map +1 -1
- package/dist/dts/tbTypings.js +44 -13
- package/dist/dts/tbTypings.js.map +1 -1
- package/dist/index.js +322 -210
- package/dist/render.js +170 -74
- package/dist/servers.js +70 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ A `.bulb.md` file bundles code, styles, data, and config in one file.
|
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
-
- **Server-side code** — Add a `**server.ts**` section; exported functions become callable from the browser via `tb.server.<name>()` (e.g., `export async function query(...)` → `await tb.server.query(...)`). Requires `--trust`.
|
|
17
|
+
- **Server-side code** — Add a `**server.ts**` section; exported functions become callable from the browser via `tb.server.<name>()` (e.g., `export async function query(...)` → `await tb.server.query(...)`). An `export async function*` **streams**: consume it with `for await (const chunk of tb.server.gen())`. Requires `--trust`.
|
|
18
18
|
- **CLI logging** — `tb.server.log(...)` prints to the CLI's stdout
|
|
19
19
|
- **Wake-on-event** — `typebulb wait <file|agent>` blocks until the target server logs a new line, prints it, and exits. Run in the background, that exit *is* an agent's wake-up: a user action a bulb logs, or an embed's render outcome — no polling.
|
|
20
20
|
- **Env files** — `.env` / `.env.local` load from cwd, `.env.local` overriding `.env` (an exported shell var wins over both). `--mode <name>` adds `.env.<name>` to switch environments (local/staging/prod); a startup line reports which keys loaded from where.
|
|
@@ -29,6 +29,7 @@ A `.bulb.md` file bundles code, styles, data, and config in one file.
|
|
|
29
29
|
- **Restricted by default** — A plain `npx typebulb my-app.bulb.md` runs with no filesystem or `server.ts` (like typebulb.com); `--trust` grants those for a run. Trust is **remembered**: `typebulb trust <file>` elevates a bulb once so later plain runs are trusted, `untrust` revokes it, and `--no-trust` forces a Restricted run.
|
|
30
30
|
- **Predict trust** — `typebulb predict <file>` reports the capability a bulb will likely need (fs / AI / `server.ts`) without running it, so you can decide on `--trust` up front rather than after a mid-run permission failure.
|
|
31
31
|
- **Agent mirror** — a browser view of your project's Claude Code sessions that renders embedded bulbs, KaTeX, and mermaid live inline, plus runs/stops local bulbs (see [Claude](#claude)). `typebulb agent:claude` opens it. `typebulb agent` (no target) is the first command an agent runs: it brings up the mirror without opening a browser, prints its link, and points at the authoring skill. `typebulb skill` prints this whole README as an Agent Skill the agent can read and save.
|
|
32
|
+
- **Proxying Claude** — the agent mirror lets you proxy Claude with a model from [OpenRouter](https://openrouter.ai). This will apply to your project only.
|
|
32
33
|
|
|
33
34
|
## Usage
|
|
34
35
|
|
|
@@ -180,6 +181,7 @@ npm install -g typebulb
|
|
|
180
181
|
| `tb.fs.read/readBytes/write` | Read and write local files | ✅ `--trust` | ❌ |
|
|
181
182
|
| `tb.server.<name>(...)` | Call a function exported from the `server.ts` block | ✅ `--trust` | ❌ |
|
|
182
183
|
| `tb.ai({ messages, … })` | General-purpose AI call (chat, agents) | ✅ `--trust` | ❌ |
|
|
184
|
+
| `tb.ai.stream({ … })` | Streaming AI — `for await` an `AsyncIterable<{ kind, text }>` of deltas | ✅ `--trust` | ❌ |
|
|
183
185
|
| `tb.infer()` | One-shot LLM call driven by the `infer.md` block | ❌ | ❌ |
|
|
184
186
|
|
|
185
187
|
- **❌ (embedded):** the call throws `"not available in an embedded bulb"` — an embed is a client-only sandboxed iframe with **no persistent storage** either (`localStorage`, `IndexedDB`, cookies, same-origin Workers all fail), so keep state in memory. `tb.mode === 'embedded'` lets a bulb detect this and self-adjust.
|
|
@@ -260,7 +262,7 @@ Run a bulb **once** and let hot reload drive the loop.
|
|
|
260
262
|
- **Mount to the container your `index.html` declares.** The corpus convention is `<div id="root"></div>` with `createRoot(document.getElementById("root")!)`.
|
|
261
263
|
- **All imports at the top of `code.tsx`.** Bare imports (`react`, `d3`, `three`, …) auto-resolve from a CDN — no install step. Declare them in `config.json` `dependencies` anyway: that's what lets `npx typebulb check` fetch type defs (without it you get errors like `TS2875: react/jsx-runtime`) and pins versions.
|
|
262
264
|
- **Theme-aware styling.** Style off CSS variables / `currentColor` so the bulb reads correctly in both light and dark; the host sets the theme.
|
|
263
|
-
- **`tb.ai()` takes more than the basics** — the full shape is `tb.ai({ messages, system?, reasoning?, provider?, model?, webSearch? })` → `Promise<{ text }
|
|
265
|
+
- **`tb.ai()` takes more than the basics** — the full shape is `tb.ai({ messages, system?, reasoning?, provider?, model?, webSearch? })` → `Promise<{ text }>`. `webSearch` defaults **on** in the CLI (you supply your own key); pass `webSearch: false` to turn it off. For token-by-token output use `tb.ai.stream(...)` (see [`tb.ai()` § Streaming](#streaming)).
|
|
264
266
|
- **`tb.theme` drives the `html[data-theme]` attribute** — style off that selector (`html[data-theme="dark"] { … }`); don't read `tb.theme` to branch your rendering.
|
|
265
267
|
- **`color-scheme` is set for you** — the host always applies `html[data-theme="dark"] { color-scheme: dark }` / `html[data-theme="light"] { color-scheme: light }` on top of your `styles.css`.
|
|
266
268
|
- **Math (KaTeX) renders in your replies** — write inline `$…$` / display `$$…$$` (prefer `$y = x^2$` over inline-code or a Unicode `y = x²`). The mirror's KaTeX renders only in prose and doesn't reach inside a fenced block (bulb, mermaid, svg, code).
|
|
@@ -322,9 +324,16 @@ Which must be declared in the dependencies section:
|
|
|
322
324
|
|
|
323
325
|
Typebulb has a package resolver that will load and cache these packages from `esm.sh` when the bulb runs.
|
|
324
326
|
|
|
325
|
-
##
|
|
327
|
+
## Custom AI Models
|
|
326
328
|
|
|
327
|
-
|
|
329
|
+
Two ways to use non-default models in typebulb:
|
|
330
|
+
|
|
331
|
+
* **`tb.ai()`** — a bulb's own code calling AI providers with your keys
|
|
332
|
+
* **proxy claude** — backs your `claude` sessions with an alternate (OpenRouter) model
|
|
333
|
+
|
|
334
|
+
### .env setup
|
|
335
|
+
|
|
336
|
+
Add API keys to your `.env` file:
|
|
328
337
|
|
|
329
338
|
| Provider name | API key env var |
|
|
330
339
|
|---------------|-----------------|
|
|
@@ -332,17 +341,24 @@ Trusted bulbs can call AI providers **from their own code** at runtime, billed t
|
|
|
332
341
|
| `openai` | `OPENAI_API_KEY` |
|
|
333
342
|
| `gemini` | `GOOGLE_API_KEY` |
|
|
334
343
|
| `openrouter` | `OPENROUTER_API_KEY` |
|
|
344
|
+
| `ollama` | *(none — local server)* |
|
|
335
345
|
|
|
336
|
-
|
|
346
|
+
Optionally, set your default provider and model:
|
|
337
347
|
|
|
338
348
|
```
|
|
339
349
|
TB_AI_PROVIDER=anthropic
|
|
340
350
|
TB_AI_MODEL=claude-haiku-4-5-20251001
|
|
341
351
|
```
|
|
342
352
|
|
|
343
|
-
|
|
353
|
+
Run `typebulb models` to list the models available for the providers specified.
|
|
354
|
+
|
|
355
|
+
### `tb.ai()`
|
|
344
356
|
|
|
345
|
-
|
|
357
|
+
Trusted bulbs can call AI providers **from their own code** at runtime, billed to your API keys.
|
|
358
|
+
|
|
359
|
+
You can call the provider and model explicitly like this: `tb.ai({ provider: "gemini", model: "gemini-3.1-flash-lite", ... })`.
|
|
360
|
+
|
|
361
|
+
Or you can rely on the default provider and model if you set them in `.env`.
|
|
346
362
|
|
|
347
363
|
### Reasoning
|
|
348
364
|
|
|
@@ -362,7 +378,26 @@ const { text } = await tb.ai({
|
|
|
362
378
|
});
|
|
363
379
|
```
|
|
364
380
|
|
|
365
|
-
|
|
381
|
+
### Streaming
|
|
382
|
+
|
|
383
|
+
`tb.ai.stream({ … })` is the streaming counterpart of `tb.ai()` — an async iterable of `{ kind: "text" | "reasoning", text }` deltas. `tb.ai()` (await the full text) is unchanged; reach for `.stream` only when a response is long enough to be worth showing as it arrives.
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
let answer = "";
|
|
387
|
+
for await (const c of tb.ai.stream({ messages })) {
|
|
388
|
+
if (c.kind === "text") { answer += c.text; render(answer); } // c.kind === "reasoning" for thinking deltas
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
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
|
+
### Local Models
|
|
395
|
+
|
|
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`). CLI-only (typebulb.com can't reach your localhost). `typebulb models` lists your installed Ollama models alongside cloud ones.
|
|
397
|
+
|
|
398
|
+
### Proxying Claude
|
|
399
|
+
|
|
400
|
+
The user can proxy claude with the agent mirror's model switcher, to any model on [OpenRouter](https://openrouter.ai) model instead of Anthropic. This lets the user use OpenRouter models with Claude Code's harness.
|
|
366
401
|
|
|
367
402
|
## Charts
|
|
368
403
|
|
|
@@ -940,6 +940,128 @@ const something = require('module-name') // NOT SUPPORTED!
|
|
|
940
940
|
} catch { console.log(...args); }
|
|
941
941
|
};
|
|
942
942
|
|
|
943
|
+
// Streaming. The server tunnels an async iterable as enveloped NDJSON over
|
|
944
|
+
// the bridge POST; isStreamResp flags it via a response header so a normal single-return call is
|
|
945
|
+
// untouched. readStream yields each {type:'chunk'} value; a {type:'error'} line rejects the
|
|
946
|
+
// iterator (so try/catch around for-await fires); breaking the loop cancels the body (finally),
|
|
947
|
+
// which disconnects the server and tears down the source generator \u2014 that's how Stop/unmount
|
|
948
|
+
// actually aborts the upstream rather than just hiding it.
|
|
949
|
+
const isStreamResp = (resp) => resp.headers.get('X-TB-Stream') === '1';
|
|
950
|
+
async function* readStream(resp) {
|
|
951
|
+
const reader = resp.body.getReader();
|
|
952
|
+
const dec = new TextDecoder();
|
|
953
|
+
let buf = '';
|
|
954
|
+
const decodeLine = (line) => {
|
|
955
|
+
if (!line.trim()) return undefined;
|
|
956
|
+
const env = JSON.parse(line);
|
|
957
|
+
if (env.type === 'error') {
|
|
958
|
+
const e = new Error((env.error && env.error.message) || 'stream error');
|
|
959
|
+
e.code = env.error && env.error.code;
|
|
960
|
+
e.retryable = !!(env.error && env.error.retryable);
|
|
961
|
+
throw e;
|
|
962
|
+
}
|
|
963
|
+
return env.type === 'chunk' ? { value: env.value } : undefined;
|
|
964
|
+
};
|
|
965
|
+
try {
|
|
966
|
+
while (true) {
|
|
967
|
+
const { done, value } = await reader.read();
|
|
968
|
+
if (done) break;
|
|
969
|
+
buf += dec.decode(value, { stream: true });
|
|
970
|
+
let nl;
|
|
971
|
+
while ((nl = buf.indexOf('\\n')) !== -1) {
|
|
972
|
+
const r = decodeLine(buf.slice(0, nl));
|
|
973
|
+
buf = buf.slice(nl + 1);
|
|
974
|
+
if (r) yield r.value;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
const r = decodeLine(buf);
|
|
978
|
+
if (r) yield r.value;
|
|
979
|
+
} finally {
|
|
980
|
+
try { await reader.cancel(); } catch {}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// tb.ai(): non-streaming, resolves with the full { text } (unchanged 90% path).
|
|
985
|
+
const aiCall = async ({ messages, system, reasoning, provider, model, webSearch, signal } = {}) => {
|
|
986
|
+
if (isEmbedded) throw embedErr('tb.ai()');
|
|
987
|
+
const resp = await fetch('/__ai', {
|
|
988
|
+
method: 'POST',
|
|
989
|
+
headers: { 'Content-Type': 'application/json' },
|
|
990
|
+
body: JSON.stringify({ messages, system, reasoning, provider, model, webSearch }),
|
|
991
|
+
signal
|
|
992
|
+
});
|
|
993
|
+
if (resp.status === 403) throw new Error((await resp.text().catch(() => '')) || 'tb.ai() is blocked \u2014 re-run with --trust');
|
|
994
|
+
const data = await resp.json();
|
|
995
|
+
if (!resp.ok) {
|
|
996
|
+
const err = new Error(data.message || 'tb.ai() call failed');
|
|
997
|
+
err.code = data.code || 'unknown';
|
|
998
|
+
err.retryable = !!data.retryable;
|
|
999
|
+
throw err;
|
|
1000
|
+
}
|
|
1001
|
+
return data;
|
|
1002
|
+
};
|
|
1003
|
+
// tb.ai.stream(): async iterable of AiChunk ({ kind:'text'|'reasoning', text }). Same idiom as a
|
|
1004
|
+
// streaming tb.server.<gen>(). Break the loop (or abort the signal) to cancel.
|
|
1005
|
+
const aiStream = (opts = {}) => (async function* () {
|
|
1006
|
+
if (isEmbedded) throw embedErr('tb.ai.stream()');
|
|
1007
|
+
const { messages, system, reasoning, provider, model, webSearch, signal } = opts;
|
|
1008
|
+
const resp = await fetch('/__ai', {
|
|
1009
|
+
method: 'POST',
|
|
1010
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1011
|
+
body: JSON.stringify({ messages, system, reasoning, provider, model, webSearch, stream: true }),
|
|
1012
|
+
signal
|
|
1013
|
+
});
|
|
1014
|
+
if (resp.status === 403) throw new Error((await resp.text().catch(() => '')) || 'tb.ai() is blocked \u2014 re-run with --trust');
|
|
1015
|
+
if (!resp.ok && !isStreamResp(resp)) {
|
|
1016
|
+
const data = await resp.json().catch(() => ({}));
|
|
1017
|
+
const err = new Error(data.message || 'tb.ai() call failed');
|
|
1018
|
+
err.code = data.code || 'unknown';
|
|
1019
|
+
err.retryable = !!data.retryable;
|
|
1020
|
+
throw err;
|
|
1021
|
+
}
|
|
1022
|
+
yield* readStream(resp);
|
|
1023
|
+
})();
|
|
1024
|
+
const ai = Object.assign(aiCall, { stream: aiStream });
|
|
1025
|
+
|
|
1026
|
+
// tb.server.<fn>(...) \u2014 one call object that is both awaitable (single result) and async-iterable
|
|
1027
|
+
// (a streamed async-generator export). The server picks by export kind; this stays graceful if
|
|
1028
|
+
// they're mismatched (await a stream \u2192 array of chunks; for-await a normal result \u2192 one value).
|
|
1029
|
+
const serverCall = (name, args) => {
|
|
1030
|
+
const ensureOk403 = async (resp) => {
|
|
1031
|
+
if (resp.status === 403) throw new Error((await resp.text().catch(() => '')) || ('tb.server.' + name + '() is blocked \u2014 re-run with --trust'));
|
|
1032
|
+
};
|
|
1033
|
+
let respP = null;
|
|
1034
|
+
const start = () => respP || (respP = fetch('/__api/' + name, {
|
|
1035
|
+
method: 'POST',
|
|
1036
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1037
|
+
body: JSON.stringify({ args })
|
|
1038
|
+
}));
|
|
1039
|
+
const single = async () => {
|
|
1040
|
+
if (isEmbedded) throw embedErr('tb.server.' + name + '()');
|
|
1041
|
+
const resp = await start();
|
|
1042
|
+
await ensureOk403(resp);
|
|
1043
|
+
if (isStreamResp(resp)) { const out = []; for await (const v of readStream(resp)) out.push(v); return out; }
|
|
1044
|
+
const data = await resp.json();
|
|
1045
|
+
if (!resp.ok) throw new Error(data.error || 'API call failed');
|
|
1046
|
+
return data.result;
|
|
1047
|
+
};
|
|
1048
|
+
const iterate = async function* () {
|
|
1049
|
+
if (isEmbedded) throw embedErr('tb.server.' + name + '()');
|
|
1050
|
+
const resp = await start();
|
|
1051
|
+
await ensureOk403(resp);
|
|
1052
|
+
if (isStreamResp(resp)) { yield* readStream(resp); return; }
|
|
1053
|
+
const data = await resp.json();
|
|
1054
|
+
if (!resp.ok) throw new Error(data.error || 'API call failed');
|
|
1055
|
+
yield data.result;
|
|
1056
|
+
};
|
|
1057
|
+
return {
|
|
1058
|
+
then: (f, r) => single().then(f, r),
|
|
1059
|
+
catch: (r) => single().catch(r),
|
|
1060
|
+
finally: (f) => single().finally(f),
|
|
1061
|
+
[Symbol.asyncIterator]: iterate
|
|
1062
|
+
};
|
|
1063
|
+
};
|
|
1064
|
+
|
|
943
1065
|
// tb namespace
|
|
944
1066
|
globalThis.tb = Object.freeze({
|
|
945
1067
|
data: (index) => getData()[index],
|
|
@@ -956,24 +1078,8 @@ const something = require('module-name') // NOT SUPPORTED!
|
|
|
956
1078
|
setData: () => {},
|
|
957
1079
|
resetInferenceState: () => {},
|
|
958
1080
|
|
|
959
|
-
// AI -
|
|
960
|
-
ai
|
|
961
|
-
if (isEmbedded) throw embedErr('tb.ai()');
|
|
962
|
-
const resp = await fetch('/__ai', {
|
|
963
|
-
method: 'POST',
|
|
964
|
-
headers: { 'Content-Type': 'application/json' },
|
|
965
|
-
body: JSON.stringify({ messages, system, reasoning, provider, model, webSearch })
|
|
966
|
-
});
|
|
967
|
-
if (resp.status === 403) throw new Error((await resp.text().catch(() => '')) || 'tb.ai() is blocked \u2014 re-run with --trust');
|
|
968
|
-
const data = await resp.json();
|
|
969
|
-
if (!resp.ok) {
|
|
970
|
-
const err = new Error(data.message || 'tb.ai() call failed');
|
|
971
|
-
err.code = data.code || 'unknown';
|
|
972
|
-
err.retryable = !!data.retryable;
|
|
973
|
-
throw err;
|
|
974
|
-
}
|
|
975
|
-
return data;
|
|
976
|
-
},
|
|
1081
|
+
// AI - tb.ai() proxies to the provider via the local server; tb.ai.stream() streams AiChunks.
|
|
1082
|
+
ai,
|
|
977
1083
|
|
|
978
1084
|
// Model discovery - fetches catalog from typebulb.com, filtered by local API keys
|
|
979
1085
|
models: async () => {
|
|
@@ -1003,27 +1109,17 @@ const something = require('module-name') // NOT SUPPORTED!
|
|
|
1003
1109
|
return '/proxy/' + clean;
|
|
1004
1110
|
},
|
|
1005
1111
|
|
|
1006
|
-
// Server API - call functions from **server.ts
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
const resp = await fetch('/__api/' + name, {
|
|
1010
|
-
method: 'POST',
|
|
1011
|
-
headers: { 'Content-Type': 'application/json' },
|
|
1012
|
-
body: JSON.stringify({ args })
|
|
1013
|
-
});
|
|
1014
|
-
if (resp.status === 403) throw new Error((await resp.text().catch(() => '')) || ('tb.server.' + name + '() is blocked \u2014 re-run with --trust'));
|
|
1015
|
-
const data = await resp.json();
|
|
1016
|
-
if (!resp.ok) throw new Error(data.error || 'API call failed');
|
|
1017
|
-
return data.result;
|
|
1018
|
-
},
|
|
1112
|
+
// Server API - call functions from **server.ts**. Returns the hybrid call object: await it for
|
|
1113
|
+
// a normal export's result, or for-await it for an async-generator export's stream.
|
|
1114
|
+
api: (name, ...args) => serverCall(name, args),
|
|
1019
1115
|
|
|
1020
|
-
// Server proxy - tb.server.fn(...) delegates to
|
|
1021
|
-
//
|
|
1022
|
-
//
|
|
1116
|
+
// Server proxy - tb.server.fn(...) delegates to serverCall. 'log' is special: it's the ungated
|
|
1117
|
+
// diagnostic (serverLog -> /__log, built-in only), so it prints untrusted; everything else is a
|
|
1118
|
+
// gated /__api call into the bulb's own server.ts.
|
|
1023
1119
|
server: new Proxy({}, {
|
|
1024
1120
|
get: (_, name) => name === 'log'
|
|
1025
1121
|
? (...args) => serverLog(...args)
|
|
1026
|
-
: (...args) =>
|
|
1122
|
+
: (...args) => serverCall(name, args)
|
|
1027
1123
|
}),
|
|
1028
1124
|
|
|
1029
1125
|
// Filesystem - local CLI extension
|
|
@@ -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;AAe5C,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,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
|
@@ -2,11 +2,13 @@ import { OpenAIProvider } from './providers/openAI.js';
|
|
|
2
2
|
import { OpenRouterProvider } from './providers/openRouter.js';
|
|
3
3
|
import { AnthropicProvider } from './providers/anthropic.js';
|
|
4
4
|
import { GeminiProvider } from './providers/gemini.js';
|
|
5
|
+
import { OllamaProvider } from './providers/ollama.js';
|
|
5
6
|
const providers = new Map([
|
|
6
7
|
['openai', new OpenAIProvider()],
|
|
7
8
|
['openrouter', new OpenRouterProvider()],
|
|
8
9
|
['anthropic', new AnthropicProvider()],
|
|
9
|
-
['gemini', new GeminiProvider()]
|
|
10
|
+
['gemini', new GeminiProvider()],
|
|
11
|
+
['ollama', new OllamaProvider()]
|
|
10
12
|
]);
|
|
11
13
|
/** Get the provider implementation for a given protocol. */
|
|
12
14
|
export function getProvider(protocol) {
|
|
@@ -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;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;CACjC,CAAC,CAAA;AAEF,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,QAA0B;IACpD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAuBD,uCAAuC;AACvC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAA4B,EAC5B,IAAuB;IAEvB,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAClD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAEtD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAC/B,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,KAAK,EACV,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACxD,IAAI,CAAC,MAAM,CACe,CAAA;IAE5B,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,CAAA;IAE7B,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAA;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAkB,EAClB,QAA0B;IAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;IAClC,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IACvD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;IAE9B,IAAI,IAAI,GAA+B,SAAS,CAAA;IAChD,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,YAAY,CAAA;SAClC,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,kBAAkB,CAAA;IAElD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,GAAG,EAAE,CAAA;AACrD,CAAC"}
|
|
1
|
+
{"version":3,"file":"aiProviders.js","sourceRoot":"","sources":["../../ai/src/aiProviders.ts"],"names":[],"mappings":"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"}
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export * from './protocol.js';
|
|
2
2
|
export { AIProvider, ProviderStreamError, type ChatRequestOpts } from './aiProvider.js';
|
|
3
3
|
export { getProvider, sendAIRequest, normalizeUpstreamError, type ResolvedAIProvider, type SendAIRequestOpts } from './aiProviders.js';
|
|
4
|
-
export { parseSseBlock, consumeSseStream, consumeStreamText } from './sseParser.js';
|
|
4
|
+
export { parseSseBlock, consumeSseStream, consumeSseStreamGen, consumeStreamText, streamAiChunks } from './sseParser.js';
|
|
5
5
|
export * from './providers/anthropic.js';
|
|
6
6
|
export * from './providers/gemini.js';
|
|
7
7
|
export * from './providers/openAI.js';
|
|
8
8
|
export * from './providers/openRouter.js';
|
|
9
|
+
export * from './providers/ollama.js';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ai/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ai/src/index.ts"],"names":[],"mappings":"AACA,cAAc,eAAe,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACvF,OAAO,EACL,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ai/src/index.ts"],"names":[],"mappings":"AACA,cAAc,eAAe,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACvF,OAAO,EACL,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAGxH,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA"}
|
package/dist/ai/index.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
export * from './protocol.js';
|
|
3
3
|
export { AIProvider, ProviderStreamError } from './aiProvider.js';
|
|
4
4
|
export { getProvider, sendAIRequest, normalizeUpstreamError } from './aiProviders.js';
|
|
5
|
-
export { parseSseBlock, consumeSseStream, consumeStreamText } from './sseParser.js';
|
|
5
|
+
export { parseSseBlock, consumeSseStream, consumeSseStreamGen, consumeStreamText, streamAiChunks } from './sseParser.js';
|
|
6
6
|
// Per-provider wire DTOs + provider implementations.
|
|
7
7
|
export * from './providers/anthropic.js';
|
|
8
8
|
export * from './providers/gemini.js';
|
|
9
9
|
export * from './providers/openAI.js';
|
|
10
10
|
export * from './providers/openRouter.js';
|
|
11
|
+
export * from './providers/ollama.js';
|
|
11
12
|
//# sourceMappingURL=index.js.map
|
package/dist/ai/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../ai/src/index.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,cAAc,eAAe,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAwB,MAAM,iBAAiB,CAAA;AACvF,OAAO,EACL,WAAW,EACX,aAAa,EACb,sBAAsB,EAGvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../ai/src/index.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,cAAc,eAAe,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAwB,MAAM,iBAAiB,CAAA;AACvF,OAAO,EACL,WAAW,EACX,aAAa,EACb,sBAAsB,EAGvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAExH,qDAAqD;AACrD,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA"}
|
package/dist/ai/protocol.d.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
export * from './chat.js';
|
|
2
2
|
export * from './stream.js';
|
|
3
|
-
/** AI provider wire protocol identifier
|
|
4
|
-
|
|
3
|
+
/** AI provider wire protocol identifier.
|
|
4
|
+
* `ollama` is CLI-only (talks to a local server over its OpenAI-compatible endpoint); it
|
|
5
|
+
* resolves with no API key and is never reachable from the web runtime. See
|
|
6
|
+
* specs/TB-AI-Local-Models.md. */
|
|
7
|
+
export type ProviderProtocol = 'openai' | 'anthropic' | 'openrouter' | 'gemini' | 'ollama';
|
|
5
8
|
/** Extended-thinking hint, 0 (off) – 3 (max) */
|
|
6
9
|
export type ReasoningDepth = 0 | 1 | 2 | 3;
|
|
10
|
+
/** A streamed delta from `tb.ai.stream()`. Discriminated union — exactly one kind per chunk, so
|
|
11
|
+
* `switch (chunk.kind)` is exhaustive and no `{}`/both-fields state is representable. The public
|
|
12
|
+
* shape; the internal wire piece (`ChatStreamPieceDto { text?, reasoning? }`) stays loose. */
|
|
13
|
+
export type AiChunk = {
|
|
14
|
+
kind: 'text';
|
|
15
|
+
text: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'reasoning';
|
|
18
|
+
text: string;
|
|
19
|
+
};
|
|
7
20
|
/** tb.models() response — model available to the current user */
|
|
8
21
|
export interface TbModelDto {
|
|
9
22
|
/** Provider protocol: "anthropic", "openai", "gemini", "openrouter" */
|
|
@@ -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;;;mCAGmC;AACnC,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1F,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"}
|
|
@@ -7,6 +7,8 @@ import { AIProvider, type ChatRequestOpts } from '../aiProvider.js';
|
|
|
7
7
|
export type GeminiRole = 'user' | 'model' | 'system';
|
|
8
8
|
export interface GeminiTextPart {
|
|
9
9
|
text: string;
|
|
10
|
+
/** When true, this part is a thought summary (reasoning), not answer text. */
|
|
11
|
+
thought?: boolean;
|
|
10
12
|
}
|
|
11
13
|
export interface GeminiContent {
|
|
12
14
|
role: GeminiRole;
|
|
@@ -16,6 +18,12 @@ export interface GeminiGoogleSearchTool {
|
|
|
16
18
|
google_search: Record<string, never>;
|
|
17
19
|
}
|
|
18
20
|
export type GeminiTool = GeminiGoogleSearchTool;
|
|
21
|
+
export interface GeminiThinkingConfig {
|
|
22
|
+
/** Surface thought summaries as `thought` parts in the response. */
|
|
23
|
+
includeThoughts?: boolean;
|
|
24
|
+
/** Token budget for thinking; -1 = dynamic (model self-regulates depth). */
|
|
25
|
+
thinkingBudget?: number;
|
|
26
|
+
}
|
|
19
27
|
export interface GeminiGenerationConfig {
|
|
20
28
|
temperature?: number;
|
|
21
29
|
topP?: number;
|
|
@@ -23,6 +31,7 @@ export interface GeminiGenerationConfig {
|
|
|
23
31
|
maxOutputTokens?: number;
|
|
24
32
|
stopSequences?: string[];
|
|
25
33
|
candidateCount?: number;
|
|
34
|
+
thinkingConfig?: GeminiThinkingConfig;
|
|
26
35
|
}
|
|
27
36
|
export type GeminiFinishReason = 'FINISH_REASON_UNSPECIFIED' | 'STOP' | 'MAX_TOKENS' | 'SAFETY' | 'RECITATION' | 'LANGUAGE' | 'OTHER';
|
|
28
37
|
export interface GeminiCandidate {
|
|
@@ -55,7 +64,9 @@ export declare class GeminiProvider extends AIProvider {
|
|
|
55
64
|
parseNonStreamingResponse(json: ProviderResponseDto): ChatResponseDto;
|
|
56
65
|
protected parseProviderStreamChunk(json: ProviderStreamEventDto): ChatStreamPieceDto | null;
|
|
57
66
|
private isGeminiResponse;
|
|
58
|
-
|
|
67
|
+
/** Split a candidate's parts into answer text and thought (reasoning) summaries — Gemini marks
|
|
68
|
+
* thought parts with `thought: true`. Returns the `{ text?, reasoning? }` stream-piece shape. */
|
|
69
|
+
private extractParts;
|
|
59
70
|
private checkGeminiError;
|
|
60
71
|
}
|
|
61
72
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,UAAU,EAAuB,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIxF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEpD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,9 +35,13 @@ export class GeminiProvider extends AIProvider {
|
|
|
35
35
|
parts: [{ text: system }]
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
// Request thought summaries when reasoning is on. `thinkingBudget: -1` = dynamic, so the model
|
|
39
|
+
// self-regulates depth — the robust analog of a 1-3 dial across Gemini models (avoids per-model
|
|
40
|
+
// budget maxes); `includeThoughts` makes those thoughts stream as `thought` parts, which the
|
|
41
|
+
// parser maps to AiChunk `{ kind: "reasoning" }`.
|
|
38
42
|
if (this.isReasoningEnabled(opts)) {
|
|
39
43
|
payload.generationConfig = {
|
|
40
|
-
|
|
44
|
+
thinkingConfig: { includeThoughts: true, thinkingBudget: -1 }
|
|
41
45
|
};
|
|
42
46
|
}
|
|
43
47
|
return payload;
|
|
@@ -75,7 +79,7 @@ export class GeminiProvider extends AIProvider {
|
|
|
75
79
|
if (!this.isGeminiResponse(json)) {
|
|
76
80
|
return { text: '', status: 'failed', error: 'Invalid response format' };
|
|
77
81
|
}
|
|
78
|
-
const text = this.
|
|
82
|
+
const text = this.extractParts(json).text || '';
|
|
79
83
|
const finishReason = json.candidates?.[0]?.finishReason;
|
|
80
84
|
let status = 'complete';
|
|
81
85
|
if (finishReason === 'MAX_TOKENS') {
|
|
@@ -90,10 +94,8 @@ export class GeminiProvider extends AIProvider {
|
|
|
90
94
|
this.checkGeminiError(json);
|
|
91
95
|
if (!this.isGeminiResponse(json))
|
|
92
96
|
return null;
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
return null;
|
|
96
|
-
return { text };
|
|
97
|
+
const piece = this.extractParts(json);
|
|
98
|
+
return (piece.text || piece.reasoning) ? piece : null;
|
|
97
99
|
}
|
|
98
100
|
// ── Private helpers ──────────────────────────────────────────────
|
|
99
101
|
isGeminiResponse(json) {
|
|
@@ -102,14 +104,22 @@ export class GeminiProvider extends AIProvider {
|
|
|
102
104
|
'candidates' in json &&
|
|
103
105
|
Array.isArray(json.candidates));
|
|
104
106
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
/** Split a candidate's parts into answer text and thought (reasoning) summaries — Gemini marks
|
|
108
|
+
* thought parts with `thought: true`. Returns the `{ text?, reasoning? }` stream-piece shape. */
|
|
109
|
+
extractParts(response) {
|
|
110
|
+
const parts = response.candidates?.[0]?.content?.parts;
|
|
111
|
+
if (!parts)
|
|
112
|
+
return {};
|
|
113
|
+
let text = '', reasoning = '';
|
|
114
|
+
for (const part of parts) {
|
|
115
|
+
if (!part.text)
|
|
116
|
+
continue;
|
|
117
|
+
if (part.thought)
|
|
118
|
+
reasoning += part.text;
|
|
119
|
+
else
|
|
120
|
+
text += part.text;
|
|
121
|
+
}
|
|
122
|
+
return { text: text || undefined, reasoning: reasoning || undefined };
|
|
113
123
|
}
|
|
114
124
|
checkGeminiError(json) {
|
|
115
125
|
if (typeof json === 'object' && json !== null && 'error' in json) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../ai/src/providers/gemini.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAwB,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../ai/src/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama via its OpenAI-compatible endpoint (`/v1/chat/completions`, Chat Completions style
|
|
3
|
+
* with choices[]) — wire types and provider implementation.
|
|
4
|
+
*
|
|
5
|
+
* CLI-only. Ollama runs locally and needs no API key, so `buildHeaders` sends no auth and the
|
|
6
|
+
* resolver supplies an empty key (see runtime/cli/src/serve/server.ts `resolveLocalProvider`).
|
|
7
|
+
* The base URL defaults to http://localhost:11434 and is overridable via OLLAMA_HOST.
|
|
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.
|
|
13
|
+
*/
|
|
14
|
+
import type { ChatMessageDto, UpstreamErrorDto, ChatStreamPieceDto, ChatResponseDto, ProviderResponseDto, ProviderStreamEventDto } from '../protocol.js';
|
|
15
|
+
import { AIProvider, type ChatRequestOpts } from '../aiProvider.js';
|
|
16
|
+
export interface OllamaMessageDto {
|
|
17
|
+
content: string;
|
|
18
|
+
reasoning?: string;
|
|
19
|
+
reasoning_content?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface OllamaChoiceDto {
|
|
22
|
+
message?: OllamaMessageDto;
|
|
23
|
+
}
|
|
24
|
+
export interface OllamaResponseDto extends ProviderResponseDto {
|
|
25
|
+
choices: OllamaChoiceDto[];
|
|
26
|
+
}
|
|
27
|
+
export interface OllamaDeltaDto {
|
|
28
|
+
content?: string;
|
|
29
|
+
reasoning?: string;
|
|
30
|
+
reasoning_content?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface OllamaStreamChoiceDto {
|
|
33
|
+
delta?: OllamaDeltaDto;
|
|
34
|
+
message?: OllamaDeltaDto;
|
|
35
|
+
}
|
|
36
|
+
export interface OllamaStreamEventDto extends ProviderStreamEventDto {
|
|
37
|
+
choices: OllamaStreamChoiceDto[];
|
|
38
|
+
}
|
|
39
|
+
/** Ollama OpenAI-compatible request payload */
|
|
40
|
+
export type OllamaRequestPayload = {
|
|
41
|
+
model: string;
|
|
42
|
+
messages: ChatMessageDto[];
|
|
43
|
+
stream: boolean;
|
|
44
|
+
};
|
|
45
|
+
export declare class OllamaProvider extends AIProvider {
|
|
46
|
+
protected readonly providerName = "Ollama";
|
|
47
|
+
readonly defaultBaseUrl = "http://localhost:11434";
|
|
48
|
+
readonly path = "/v1/chat/completions";
|
|
49
|
+
buildHeaders(_apiKey: string): Record<string, string>;
|
|
50
|
+
buildPayload(messages: ChatMessageDto[], model: string, _opts: ChatRequestOpts, stream: boolean): OllamaRequestPayload;
|
|
51
|
+
parseError(errorText: string, status: number): UpstreamErrorDto;
|
|
52
|
+
parseNonStreamingResponse(json: ProviderResponseDto): ChatResponseDto;
|
|
53
|
+
protected parseProviderStreamChunk(json: ProviderStreamEventDto): ChatStreamPieceDto | null;
|
|
54
|
+
private hasChoices;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=ollama.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../ai/src/providers/ollama.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;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;IAC1C,QAAQ,CAAC,cAAc,4BAA2B;IAClD,QAAQ,CAAC,IAAI,0BAAyB;IAMtC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUrD,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"}
|