universal-llm-client 4.3.0 → 4.5.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/CHANGELOG.md +27 -24
- package/README.md +60 -11
- package/dist/ai-model.d.ts +12 -1
- package/dist/ai-model.d.ts.map +1 -1
- package/dist/ai-model.js +36 -1
- package/dist/ai-model.js.map +1 -1
- package/dist/auditor.js.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/gemma-channel.d.ts +14 -0
- package/dist/gemma-channel.d.ts.map +1 -0
- package/dist/gemma-channel.js +38 -0
- package/dist/gemma-channel.js.map +1 -0
- package/dist/gemma-diffusion.d.ts +49 -0
- package/dist/gemma-diffusion.d.ts.map +1 -0
- package/dist/gemma-diffusion.js +147 -0
- package/dist/gemma-diffusion.js.map +1 -0
- package/dist/http.d.ts +4 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +14 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +163 -7
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +28 -3
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/google.d.ts +22 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +223 -13
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama.d.ts +2 -0
- package/dist/providers/ollama.d.ts.map +1 -1
- package/dist/providers/ollama.js +59 -30
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +14 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +200 -22
- package/dist/providers/openai.js.map +1 -1
- package/dist/router.d.ts +2 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +4 -0
- package/dist/router.js.map +1 -1
- package/dist/stream-decoder.d.ts +12 -0
- package/dist/stream-decoder.d.ts.map +1 -1
- package/dist/stream-decoder.js +182 -5
- package/dist/stream-decoder.js.map +1 -1
- package/dist/structured-output.js.map +1 -1
- package/dist/thinking.d.ts +36 -0
- package/dist/thinking.d.ts.map +1 -0
- package/dist/thinking.js +52 -0
- package/dist/thinking.js.map +1 -0
- package/dist/tools.js.map +1 -1
- package/dist/zod-adapter.js.map +1 -1
- package/package.json +4 -1
- package/src/ai-model.ts +400 -0
- package/src/auditor.ts +213 -0
- package/src/client.ts +402 -0
- package/src/debug/debug-google-streaming.ts +97 -0
- package/src/debug/debug-tool-execution.ts +86 -0
- package/src/debug/test-lmstudio-tools.ts +155 -0
- package/src/demos/README.md +47 -0
- package/src/demos/basic/universal-llm-examples.ts +161 -0
- package/src/demos/diffusion-gemma/.env +29 -0
- package/src/demos/diffusion-gemma/.env.example +27 -0
- package/src/demos/diffusion-gemma/CLAUDE.md +95 -0
- package/src/demos/diffusion-gemma/README.md +59 -0
- package/src/demos/diffusion-gemma/canvas.ts +1606 -0
- package/src/demos/diffusion-gemma/docker-compose.yml +29 -0
- package/src/demos/diffusion-gemma/probe-stream.ts +51 -0
- package/src/demos/diffusion-gemma/probe-tools.ts +55 -0
- package/src/demos/diffusion-gemma/server.ts +1205 -0
- package/src/demos/diffusion-gemma/start-vllm.sh +98 -0
- package/src/demos/mcp/astrid-memory-demo.ts +295 -0
- package/src/demos/mcp/astrid-persona-memory.ts +357 -0
- package/src/demos/mcp/mcp-mongodb-demo.ts +275 -0
- package/src/demos/mcp/simple-astrid-memory.ts +148 -0
- package/src/demos/mcp/simple-mcp-demo.ts +68 -0
- package/src/demos/mcp/working-mcp-demo.ts +62 -0
- package/src/demos/model-alias-demo.ts +0 -0
- package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +267 -0
- package/src/demos/tools/astrid-memory-demo.ts +270 -0
- package/src/demos/tools/astrid-production-memory-clean.ts +785 -0
- package/src/demos/tools/astrid-production-memory.ts +558 -0
- package/src/demos/tools/basic-translation-test.ts +66 -0
- package/src/demos/tools/chromadb-similarity-tuning.ts +390 -0
- package/src/demos/tools/clean-multilingual-conversation.ts +209 -0
- package/src/demos/tools/clean-translation-test.ts +119 -0
- package/src/demos/tools/clean-universal-multilingual-test.ts +131 -0
- package/src/demos/tools/complete-rag-demo.ts +369 -0
- package/src/demos/tools/complete-tool-demo.ts +132 -0
- package/src/demos/tools/demo-tool-calling.ts +124 -0
- package/src/demos/tools/dynamic-language-switching-test.ts +251 -0
- package/src/demos/tools/hybrid-thinking-test.ts +154 -0
- package/src/demos/tools/memory-integration-test.ts +420 -0
- package/src/demos/tools/multilingual-memory-system.ts +802 -0
- package/src/demos/tools/ondemand-translation-demo.ts +655 -0
- package/src/demos/tools/production-tool-demo.ts +245 -0
- package/src/demos/tools/revolutionary-multilingual-test.ts +151 -0
- package/src/demos/tools/rigorous-language-analysis.ts +218 -0
- package/src/demos/tools/test-universal-memory-system.ts +126 -0
- package/src/demos/tools/translation-integration-guide.ts +346 -0
- package/src/demos/tools/universal-memory-system.ts +560 -0
- package/src/gemma-channel.ts +47 -0
- package/src/gemma-diffusion.ts +167 -0
- package/src/http.ts +261 -0
- package/src/index.ts +180 -0
- package/src/interfaces.ts +843 -0
- package/src/mcp.ts +345 -0
- package/src/providers/anthropic.ts +796 -0
- package/src/providers/google.ts +840 -0
- package/src/providers/index.ts +8 -0
- package/src/providers/ollama.ts +503 -0
- package/src/providers/openai.ts +587 -0
- package/src/router.ts +785 -0
- package/src/stream-decoder.ts +535 -0
- package/src/structured-output.ts +759 -0
- package/src/test-scripts/test-advanced-tools.ts +310 -0
- package/src/test-scripts/test-google-deep-research.ts +33 -0
- package/src/test-scripts/test-google-streaming-enhanced.ts +147 -0
- package/src/test-scripts/test-google-streaming.ts +63 -0
- package/src/test-scripts/test-google-system-prompt-comprehensive.ts +189 -0
- package/src/test-scripts/test-google-thinking.ts +46 -0
- package/src/test-scripts/test-mcp-config.ts +28 -0
- package/src/test-scripts/test-mcp-connection.ts +29 -0
- package/src/test-scripts/test-system-message-positions.ts +163 -0
- package/src/test-scripts/test-system-prompt-improvement-demo.ts +83 -0
- package/src/test-scripts/test-tool-calling.ts +231 -0
- package/src/test-scripts/test-vllm-qwen36.ts +256 -0
- package/src/tests/ai-model.test.ts +1614 -0
- package/src/tests/auditor.test.ts +224 -0
- package/src/tests/gemma-diffusion.test.ts +115 -0
- package/src/tests/http.test.ts +200 -0
- package/src/tests/interfaces.test.ts +117 -0
- package/src/tests/providers/anthropic.test.ts +118 -0
- package/src/tests/providers/google.test.ts +841 -0
- package/src/tests/providers/ollama.test.ts +1034 -0
- package/src/tests/providers/openai.test.ts +1511 -0
- package/src/tests/router.test.ts +254 -0
- package/src/tests/stream-decoder.test.ts +263 -0
- package/src/tests/structured-output.test.ts +1450 -0
- package/src/tests/thinking.test.ts +65 -0
- package/src/tests/tools.test.ts +175 -0
- package/src/thinking.ts +73 -0
- package/src/tools.ts +246 -0
- package/src/zod-adapter.ts +72 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,41 +5,44 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [4.
|
|
8
|
+
## [4.5.0] - 2026-06-14
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- **Server-side reasoning field support (OpenAI-compatible provider)** — Reasoning models served over the OpenAI-compatible API (vLLM `--reasoning-parser`, DeepSeek-R1, etc.) return their chain-of-thought in a dedicated `reasoning_content` (vLLM) / `reasoning` (some gateways) field instead of inline `<think>` tags. The OpenAI provider now surfaces it:
|
|
13
|
+
- `chat()` populates `LLMChatResponse.reasoning` from `message.reasoning_content` / `message.reasoning`, keeping `message.content` clean
|
|
14
|
+
- `chatStream()` emits `delta.reasoning_content` / `delta.reasoning` chunks as `thinking` stream events and accumulates them into the final `reasoning`
|
|
15
|
+
- Inline `<think>` parsing (via `StandardChatDecoder`) is preserved as a fallback for servers run without a reasoning parser
|
|
16
|
+
- `OpenAIResponse` message type extended with optional `reasoning` / `reasoning_content`
|
|
17
|
+
- Verified end-to-end against vLLM serving `nvidia/Qwen3.6-35B-A3B-NVFP4` (NVFP4) on Blackwell — reasoning, streaming `thinking` events, tool calling (`qwen3_xml`), and structured output all pass
|
|
18
|
+
- **Unified `thinking` flag with levels across all providers** — `thinking` (model config) and per-call `ChatOptions.thinking` accept `true`/`false` **or a level `'minimal' | 'low' | 'medium' | 'high'`** (new `ThinkingLevel` type), mapped to each backend's native control so apps switch providers without reasoning-specific code. A shared `resolveThinking` helper (`src/thinking.ts`) normalizes the value; each provider maps it:
|
|
19
|
+
- **OpenAI-compatible** → OpenAI reasoning models (o-series / GPT-5, by name) get `reasoning_effort:<level>`; vLLM / Qwen get `chat_template_kwargs.enable_thinking`. Emitted only when explicitly set.
|
|
20
|
+
- **Google / Gemini** → Gemini 3.x `thinkingConfig.thinkingLevel`; Gemini 2.5/2.0 `thinkingBudget` (level→budget map, `0` off, `-1` dynamic). `includeThoughts` enabled when thinking is on.
|
|
21
|
+
- **Anthropic** → extended thinking `budget_tokens` from the level (kept `< max_tokens`; temperature omitted, per API).
|
|
22
|
+
- **Ollama** → `think` on/off (no native levels).
|
|
23
|
+
- Per-call overrides model config everywhere. Verified live against vLLM (Qwen3.6-NVFP4) and **Gemini 3.5 Flash** (levels produce distinct reasoning-token counts); unit-tested per provider + `resolveThinking`.
|
|
24
|
+
- **Gemini reasoning text surfaced** — with thinking on, the Google provider sets `includeThoughts:true` and routes `thought:true` parts into `response.reasoning` (non-streaming) and live `thinking` stream events, matching how Qwen/Anthropic expose chain-of-thought (previously only `reasoningTokens` was reported). Verified live on `gemini-3.5-flash` (654–976 chars of reasoning across levels).
|
|
25
|
+
- **Gemini Deep Research API** — new Google-only `AIModel.deepResearch(input, opts)` (creates a `/v1beta/interactions` background interaction and polls to completion → `{ id, status, report, steps }`) and `AIModel.deepResearchStream(input, opts)` (live `thought`/`text`/`status` events). New `DeepResearchOptions`/`DeepResearchResult`/`DeepResearchStep`/`DeepResearchEvent` types. Throws a clear error if no Google provider is configured. Create + poll plumbing verified live.
|
|
26
|
+
- **Generation stats — `usage.durationMs` and `usage.tokensPerSecond`** — decode throughput is now reported on `LLMChatResponse.usage`: server-precise for Ollama (from `eval_count` / `eval_duration`, which were previously discarded), and client-measured wall-clock for OpenAI-compatible / vLLM (which return no timing in `usage`). `OllamaResponse` gained `total_duration` / `load_duration` typings.
|
|
27
|
+
- **OpenAI-compatible transport flexibility** — `ProviderConfig` gains `headers`, `queryParams`, `authHeader`, `authPrefix`, and `apiBasePath` for Azure OpenAI, custom gateways, and non-`/v1` servers (no custom code needed). Honored by the OpenAI-compatible provider (`headers`/`authHeader`/`authPrefix` also by Ollama, via `buildHeaders`); a `buildUrl` helper applies `queryParams`/`apiBasePath` across all endpoints and preserves any query string already on the base URL. Includes a 2026 provider-API-landscape research doc (`docs/research/`).
|
|
14
28
|
|
|
15
|
-
###
|
|
16
|
-
|
|
17
|
-
- **Slimmer published tarball** — `src/` is no longer shipped to npm. The published package drops from ~271 kB / 144 files to ~146 kB / 72 files. Source maps now embed original sources (`inlineSources: true`), so debuggers stepping into the library continue to show TypeScript source without needing the raw `.ts` files in the tarball.
|
|
18
|
-
|
|
19
|
-
## [4.2.0] - Previously released
|
|
20
|
-
|
|
21
|
-
### Added
|
|
29
|
+
### Fixed
|
|
22
30
|
|
|
23
|
-
- **
|
|
24
|
-
- **Ollama stream idle timeout** — `OllamaClient` enforces a minimum response wait time to avoid hung streams.
|
|
25
|
-
- **Ollama live context length** — provider now fetches the running context length from `/api/ps` and reports model capabilities.
|
|
26
|
-
- **Google Gemini service tiers** — configurable service tier with per-tier timeouts and retry logic.
|
|
27
|
-
- **`LLMAudioContent` type** — audio content support across providers.
|
|
28
|
-
- **Structured output tolerates markdown fences** — JSON output wrapped in ```` ```json ```` fences is now parsed correctly.
|
|
31
|
+
- **README** — the tool-execution trace field is `response.toolExecutions` (array of `{ tool_call_id, output, error?, duration? }`), not `toolTrace`; corrected the `chatWithTools` example.
|
|
29
32
|
|
|
30
|
-
## [4.
|
|
33
|
+
## [4.4.0] - 2026-06-11
|
|
31
34
|
|
|
32
35
|
### Added
|
|
33
36
|
|
|
34
|
-
- **
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
- **
|
|
37
|
+
- **Diffusion LM support (DiffusionGemma family)** — First-class client-side protocol for diffusion language models served by OpenAI-compatible endpoints that ship without server-side reasoning or tool-call parsers (e.g. current vLLM diffusion builds, which reject request-level `tools` with auto tool choice):
|
|
38
|
+
- `gemma-diffusion.ts` — model detection (`isGemmaDiffusionModel`), native channel parsing (`<|channel>thought … <channel|>` reasoning, `<|tool_call>call:name{…}<tool_call|>` tool calls), and pseudo-JSON argument conversion (`gemmaArgsToJson`: `<|"|>` quote tokens, bare keys, nested objects/arrays)
|
|
39
|
+
- OpenAI provider native mode (auto-detected from the model name, `gemmaNativeProtocol` option to override): sends `skip_special_tokens: false` and `tools` + `tool_choice: "none"` (declarations still render into the chat template), parses reasoning and tool calls client-side, and yields decoder-classified `thinking`/`text` streaming events
|
|
40
|
+
- Full agentic `chatWithTools` loop works end-to-end against DiffusionGemma; history tool turns use standard structured `tool_calls` + `role: "tool"` messages
|
|
41
|
+
- **"Signal from Noise" demo** (`src/demos/diffusion-gemma/`) — vLLM test harness plus a diffusion chat canvas that animates block-parallel denoising paced by real block arrivals, with replay/scrubbing, reasoning-channel separation, a rendered-markdown reading view, and an engine-reload entropy control
|
|
39
42
|
|
|
40
|
-
###
|
|
43
|
+
### Fixed
|
|
41
44
|
|
|
42
|
-
-
|
|
45
|
+
- Stray unbalanced `<channel|>` / `<turn|>` markers emitted by diffusion models are stripped from parsed content
|
|
43
46
|
|
|
44
47
|
## [4.0.0] - 2026-03-13
|
|
45
48
|
|
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# universal-llm-client
|
|
2
2
|
|
|
3
|
-
A universal LLM client for JavaScript/TypeScript with **transparent provider failover
|
|
3
|
+
A universal LLM client for JavaScript/TypeScript with **transparent provider failover** and a **provider-agnostic reasoning API** — one set of code across OpenAI, Anthropic, Google Gemini, Ollama, vLLM, and any OpenAI-compatible endpoint. Streaming tool execution, structured output, generation stats, and native observability included.
|
|
4
4
|
|
|
5
5
|
```typescript
|
|
6
6
|
import { AIModel } from 'universal-llm-client';
|
|
7
7
|
|
|
8
8
|
const model = new AIModel({
|
|
9
|
-
model: 'gemini-
|
|
9
|
+
model: 'gemini-3.5-flash',
|
|
10
10
|
providers: [
|
|
11
11
|
{ type: 'google', apiKey: process.env.GOOGLE_API_KEY },
|
|
12
12
|
{ type: 'openai', url: 'https://openrouter.ai/api', apiKey: process.env.OPENROUTER_KEY },
|
|
@@ -26,10 +26,13 @@ const response = await model.chat([
|
|
|
26
26
|
## Features
|
|
27
27
|
|
|
28
28
|
- 🔄 **Transparent Failover** — Priority-ordered provider chain with retries, health tracking, and cooldowns
|
|
29
|
+
- 🧠 **Unified Reasoning** — One `thinking` flag (`true`/`false` or a level: `'minimal' | 'low' | 'medium' | 'high'`) mapped to each backend's native control; chain-of-thought surfaced as `response.reasoning` + streaming `thinking` events (with `<think>`-tag parsing as a fallback)
|
|
29
30
|
- 🛠️ **Tool Calling** — Register tools once, works across all providers. Autonomous multi-turn execution loop
|
|
30
31
|
- 📋 **Structured Output** — Zod schema validation, JSON Schema support, streaming, and type-safe responses
|
|
31
32
|
- 🌊 **Streaming** — First-class async generator streaming with pluggable decoder strategies
|
|
32
|
-
-
|
|
33
|
+
- 🔬 **Deep Research** — Drive Google Gemini's agentic Deep Research (background interactions with polling + streaming)
|
|
34
|
+
- 📈 **Generation Stats** — `usage.tokensPerSecond` and `durationMs` reported across providers
|
|
35
|
+
- 🔌 **Flexible Transport** — Custom headers, query params, auth header/prefix, and base path for Azure OpenAI and gateways
|
|
33
36
|
- 🔍 **Observability** — Built-in auditor interface for logging, cost tracking, and behavioral analysis
|
|
34
37
|
- 🌐 **Universal Runtime** — Node.js 22+, Bun, Deno, and modern browsers
|
|
35
38
|
- 🤖 **MCP Native** — Bridge MCP servers to LLM tools with zero glue code
|
|
@@ -39,11 +42,14 @@ const response = await model.chat([
|
|
|
39
42
|
|
|
40
43
|
| Provider | Type | Notes |
|
|
41
44
|
|---|---|---|
|
|
42
|
-
| **Ollama** | `ollama` | Local or cloud models, NDJSON streaming, model pulling, vision/multimodal |
|
|
43
|
-
| **OpenAI** | `openai` | GPT-
|
|
44
|
-
| **Google AI Studio** | `google` | Gemini models, system instructions, multimodal |
|
|
45
|
-
| **Vertex AI** | `vertex` | Same as Google AI but with regional endpoints
|
|
46
|
-
| **
|
|
45
|
+
| **Ollama** | `ollama` | Local or cloud models, NDJSON streaming, model pulling, vision/multimodal, native thinking |
|
|
46
|
+
| **OpenAI + Compat** | `openai` | GPT series, o-series + **any OpenAI-compatible endpoint**: xAI/Grok, Mistral, DeepSeek, Cohere Compatibility, Groq, Together, Fireworks, OpenRouter, Perplexity Sonar, vLLM, LM Studio, TGI, most self-hosted servers |
|
|
47
|
+
| **Google AI Studio** | `google` | Gemini models, system instructions, multimodal, native thinking + grounding |
|
|
48
|
+
| **Vertex AI** | `vertex` | Same as Google AI but with regional endpoints, Bearer tokens, service tiers (flex/priority) |
|
|
49
|
+
| **Anthropic (Claude)** | `anthropic` | Claude 3.5/4 models via native Messages API. Excellent tool use, extended thinking with signatures, strong prompt caching |
|
|
50
|
+
| **LlamaCpp** | `llamacpp` | Local llama.cpp / llama-server instances (OpenAI-compatible under the hood) |
|
|
51
|
+
|
|
52
|
+
**Most of the world** is reachable via `type: 'openai'` + a `url` override. We only maintain dedicated clients for fundamentally different protocols (Anthropic Messages, Google Gemini) that offer unique high-value capabilities, plus Ollama for local developer experience. See `docs/guide/providers.md` and the research survey in `docs/research/provider-api-landscape-2026.md`.
|
|
47
53
|
|
|
48
54
|
---
|
|
49
55
|
|
|
@@ -98,6 +104,44 @@ for await (const event of model.chatStream([
|
|
|
98
104
|
}
|
|
99
105
|
```
|
|
100
106
|
|
|
107
|
+
### Thinking & Reasoning
|
|
108
|
+
|
|
109
|
+
Set one `thinking` value — `true`/`false` or a level (`'minimal' | 'low' | 'medium' | 'high'`) —
|
|
110
|
+
and it maps to each provider's native control (Gemini `thinkingLevel`/`thinkingBudget`, OpenAI
|
|
111
|
+
`reasoning_effort`, vLLM `enable_thinking`, Anthropic `budget_tokens`, Ollama `think`):
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
const model = new AIModel({
|
|
115
|
+
model: 'gemini-3.5-flash',
|
|
116
|
+
thinking: 'high', // true | false | 'minimal' | 'low' | 'medium' | 'high'
|
|
117
|
+
providers: [{ type: 'google', apiKey: process.env.GOOGLE_API_KEY }],
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const res = await model.chat([{ role: 'user', content: 'Solve this step by step: ...' }]);
|
|
121
|
+
console.log(res.message.content); // final answer (clean)
|
|
122
|
+
console.log(res.reasoning); // chain-of-thought, when the model exposes it
|
|
123
|
+
|
|
124
|
+
// Per-call override (e.g. turn thinking off for structured output)
|
|
125
|
+
await model.chat(messages, { thinking: false });
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Deep Research (Gemini)
|
|
129
|
+
|
|
130
|
+
Run Google's agentic Deep Research — creates a background interaction and polls to completion:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const result = await model.deepResearch('Research the history of Google TPUs.', {
|
|
134
|
+
tools: ['google_search', 'url_context'],
|
|
135
|
+
});
|
|
136
|
+
console.log(result.status, result.report);
|
|
137
|
+
|
|
138
|
+
// Or stream intermediate thoughts and steps as they arrive:
|
|
139
|
+
for await (const ev of model.deepResearchStream('Compare RISC-V vs ARM in 2026.')) {
|
|
140
|
+
if (ev.type === 'thought') console.log('[thinking]', ev.content);
|
|
141
|
+
else if (ev.type === 'text') process.stdout.write(ev.content);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
101
145
|
### Tool Calling
|
|
102
146
|
|
|
103
147
|
```typescript
|
|
@@ -124,8 +168,8 @@ const response = await model.chatWithTools([
|
|
|
124
168
|
|
|
125
169
|
console.log(response.message.content);
|
|
126
170
|
// "The weather in Tokyo is 22°C and sunny."
|
|
127
|
-
console.log(response.
|
|
128
|
-
// [{
|
|
171
|
+
console.log(response.toolExecutions);
|
|
172
|
+
// [{ tool_call_id: 'call_abc', output: { temperature: 22, condition: 'sunny', city: 'Tokyo' }, duration: 5 }]
|
|
129
173
|
```
|
|
130
174
|
|
|
131
175
|
### Provider Failover
|
|
@@ -421,13 +465,18 @@ new AIModel(config: AIModelConfig)
|
|
|
421
465
|
|
|
422
466
|
| Property | Type | Description |
|
|
423
467
|
|---|---|---|
|
|
424
|
-
| `type` | `string` | `'ollama'`, `'openai'`, `'google'`, `'vertex'`, `'llamacpp'` |
|
|
468
|
+
| `type` | `string` | `'ollama'`, `'openai'`, `'google'`, `'vertex'`, `'llamacpp'`, `'anthropic'` |
|
|
425
469
|
| `url` | `string` | Provider URL (has sensible defaults) |
|
|
426
470
|
| `apiKey` | `string` | API key or Bearer token |
|
|
427
471
|
| `priority` | `number` | Lower = tried first (defaults to array index) |
|
|
428
472
|
| `model` | `string` | Override model name for this provider |
|
|
429
473
|
| `region` | `string` | Vertex AI region (e.g., `'us-central1'`) |
|
|
430
474
|
| `apiVersion` | `string` | API version (e.g., `'v1beta'`) |
|
|
475
|
+
| `headers` | `Record<string,string>` | Extra headers merged into requests — OpenAI-compatible & Ollama (Azure `api-key`, gateways) |
|
|
476
|
+
| `queryParams` | `Record<string,string>` | Query params appended to URLs — OpenAI-compatible only (e.g. Azure `api-version`) |
|
|
477
|
+
| `authHeader` | `string` | Header name for the key — OpenAI-compatible & Ollama (e.g. `'api-key'`) |
|
|
478
|
+
| `authPrefix` | `string` | Prefix before the key value — OpenAI-compatible & Ollama (e.g. `''` for api-key style) |
|
|
479
|
+
| `apiBasePath` | `string` | OpenAI-compatible only: override or disable the `/v1` suffix (use `''` for full Azure deployment URLs) |
|
|
431
480
|
|
|
432
481
|
**Methods:**
|
|
433
482
|
|
package/dist/ai-model.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Provider classes are internal — the user never imports them.
|
|
8
8
|
*/
|
|
9
|
-
import { type AIModelConfig, type LLMChatMessage, type LLMChatResponse, type ChatOptions, type ModelMetadata, type LLMFunction, type ToolHandler } from './interfaces.js';
|
|
9
|
+
import { type AIModelConfig, type LLMChatMessage, type LLMChatResponse, type ChatOptions, type ModelMetadata, type LLMFunction, type ToolHandler, type DeepResearchOptions, type DeepResearchResult, type DeepResearchEvent } from './interfaces.js';
|
|
10
10
|
import type { DecodedEvent } from './stream-decoder.js';
|
|
11
11
|
import { type ProviderStatus } from './router.js';
|
|
12
12
|
import { type StructuredOutputResult, type SchemaConfig } from './structured-output.js';
|
|
@@ -113,6 +113,17 @@ export declare class AIModel {
|
|
|
113
113
|
embed(text: string): Promise<number[]>;
|
|
114
114
|
/** Generate embeddings for multiple texts */
|
|
115
115
|
embedArray(texts: string[]): Promise<number[][]>;
|
|
116
|
+
private getGoogleClient;
|
|
117
|
+
/**
|
|
118
|
+
* Run an agentic Deep Research interaction (Gemini only): creates it and
|
|
119
|
+
* polls until completion. Throws if no Google provider is configured.
|
|
120
|
+
*/
|
|
121
|
+
deepResearch(input: string, options?: DeepResearchOptions): Promise<DeepResearchResult>;
|
|
122
|
+
/**
|
|
123
|
+
* Stream a Deep Research interaction's intermediate thought/text/step events
|
|
124
|
+
* (Gemini only), returning the final result. Throws if no Google provider.
|
|
125
|
+
*/
|
|
126
|
+
deepResearchStream(input: string, options?: DeepResearchOptions): AsyncGenerator<DeepResearchEvent, DeepResearchResult, unknown>;
|
|
116
127
|
/** Register a tool callable by the LLM (broadcast to all providers) */
|
|
117
128
|
registerTool(name: string, description: string, parameters: LLMFunction['parameters'], handler: ToolHandler): void;
|
|
118
129
|
/** Register multiple tools at once */
|
package/dist/ai-model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model.d.ts","sourceRoot":"","sources":["../src/ai-model.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEH,KAAK,aAAa,EAGlB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"ai-model.d.ts","sourceRoot":"","sources":["../src/ai-model.ts"],"names":[],"mappings":"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"}
|
package/dist/ai-model.js
CHANGED
|
@@ -172,6 +172,34 @@ export class AIModel {
|
|
|
172
172
|
return this.router.embedArray(texts);
|
|
173
173
|
}
|
|
174
174
|
// ========================================================================
|
|
175
|
+
// Deep Research (Gemini-only)
|
|
176
|
+
// ========================================================================
|
|
177
|
+
getGoogleClient(method) {
|
|
178
|
+
const googleClients = this.router.getClients().filter((c) => c instanceof GoogleClient);
|
|
179
|
+
// Prefer an AI Studio client — Vertex AI doesn't support Deep Research.
|
|
180
|
+
const aiStudio = googleClients.find(c => c.supportsDeepResearch());
|
|
181
|
+
if (aiStudio)
|
|
182
|
+
return aiStudio;
|
|
183
|
+
if (googleClients.length > 0) {
|
|
184
|
+
throw new Error(`${method} requires an AI Studio Google provider (type: "google"); Vertex AI is not supported for Deep Research.`);
|
|
185
|
+
}
|
|
186
|
+
throw new Error(`${method} requires a Google provider (type: "google"). None is configured.`);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Run an agentic Deep Research interaction (Gemini only): creates it and
|
|
190
|
+
* polls until completion. Throws if no Google provider is configured.
|
|
191
|
+
*/
|
|
192
|
+
async deepResearch(input, options) {
|
|
193
|
+
return this.getGoogleClient('deepResearch').deepResearch(input, options);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Stream a Deep Research interaction's intermediate thought/text/step events
|
|
197
|
+
* (Gemini only), returning the final result. Throws if no Google provider.
|
|
198
|
+
*/
|
|
199
|
+
async *deepResearchStream(input, options) {
|
|
200
|
+
return yield* this.getGoogleClient('deepResearchStream').deepResearchStream(input, options);
|
|
201
|
+
}
|
|
202
|
+
// ========================================================================
|
|
175
203
|
// Tool Registration
|
|
176
204
|
// ========================================================================
|
|
177
205
|
/** Register a tool callable by the LLM (broadcast to all providers) */
|
|
@@ -232,9 +260,16 @@ export class AIModel {
|
|
|
232
260
|
retries: this.config.retries ?? 2,
|
|
233
261
|
debug: this.config.debug ?? false,
|
|
234
262
|
defaultParameters: this.config.defaultParameters,
|
|
235
|
-
|
|
263
|
+
// Preserve `undefined` (not set) vs explicit false so providers can
|
|
264
|
+
// decide whether to send a thinking toggle at all.
|
|
265
|
+
thinking: this.config.thinking,
|
|
236
266
|
region: providerConfig.region,
|
|
237
267
|
apiVersion: providerConfig.apiVersion,
|
|
268
|
+
extraHeaders: providerConfig.headers,
|
|
269
|
+
queryParams: providerConfig.queryParams,
|
|
270
|
+
authHeader: providerConfig.authHeader,
|
|
271
|
+
authPrefix: providerConfig.authPrefix,
|
|
272
|
+
apiBasePath: providerConfig.apiBasePath,
|
|
238
273
|
};
|
|
239
274
|
switch (type) {
|
|
240
275
|
case 'ollama':
|
package/dist/ai-model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model.js","sourceRoot":"","sources":["../src/ai-model.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,OAAO,EAAE,MAAM,EAA0C,MAAM,aAAa,CAAC;AAE7E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAO3D,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,MAAM,YAAY,GAA2B;IACzC,MAAM,EAAE,wBAAwB;IAChC,MAAM,EAAE,wBAAwB;IAChC,QAAQ,EAAE,uBAAuB;IACjC,SAAS,EAAE,2BAA2B;IACtC,oDAAoD;CACvD,CAAC;AAEF,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAE/E,MAAM,OAAO,OAAO;IACR,MAAM,CAAS;IACf,OAAO,CAAU;IACjB,MAAM,CAAgB;IAE9B,YAAY,MAAqB;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,WAAW,EAAE,CAAC;QAEnD,MAAM,YAAY,GAAiB;YAC/B,kBAAkB,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;YACvC,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,gCAAgC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;YACjD,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAE7D,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;gBACpB,EAAE;gBACF,MAAM;gBACN,QAAQ,EAAE,cAAc,CAAC,QAAQ,IAAI,CAAC;gBACtC,aAAa,EAAE,cAAc,CAAC,KAAK;aACtC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,2EAA2E;IAC3E,OAAO;IACP,2EAA2E;IAE3E,mEAAmE;IACnE,KAAK,CAAC,IAAI,CACN,QAA0B,EAC1B,OAAqB;QAErB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,aAAa,CACf,QAA0B,EAC1B,OAAkD;QAElD,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,CAAC,UAAU,CACb,QAA0B,EAC1B,OAAqB;QAErB,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,2EAA2E;IAC3E,oBAAoB;IACpB,2EAA2E;IAE3E;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,KAAK,CAAC,kBAAkB,CACpB,MAAuB,EACvB,QAA0B,EAC1B,OAAqB;QAErB,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,kBAAkB,CACpB,MAAuB,EACvB,QAA0B,EAC1B,OAAqB;QAErB,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,KAAK,CAAC,CAAC,wBAAwB,CAC3B,MAAuB,EACvB,QAA0B,EAC1B,OAAqB;QAErB,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClF,CAAC;IAED,2EAA2E;IAC3E,aAAa;IACb,2EAA2E;IAE3E,2CAA2C;IAC3C,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,UAAU,CAAC,KAAe;QAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,2EAA2E;IAC3E,oBAAoB;IACpB,2EAA2E;IAE3E,uEAAuE;IACvE,YAAY,CACR,IAAY,EACZ,WAAmB,EACnB,UAAqC,EACrC,OAAoB;QAEpB,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,sCAAsC;IACtC,aAAa,CACT,KAKE;QAEF,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,2EAA2E;IAC3E,mBAAmB;IACnB,2EAA2E;IAE3E,yDAAyD;IACzD,KAAK,CAAC,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,YAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;IACtC,CAAC;IAED,sDAAsD;IACtD,QAAQ,CAAC,IAAY;QACjB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;QACzB,2DAA2D;QAC3D,qCAAqC;IACzC,CAAC;IAED,iCAAiC;IACjC,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED,2EAA2E;IAC3E,kBAAkB;IAClB,2EAA2E;IAE3E,oDAAoD;IACpD,iBAAiB;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,2EAA2E;IAC3E,YAAY;IACZ,2EAA2E;IAE3E,2DAA2D;IAC3D,KAAK,CAAC,OAAO;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,2EAA2E;IAC3E,6BAA6B;IAC7B,2EAA2E;IAEnE,YAAY,CAAC,cAA8B;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAE5D,MAAM,aAAa,GAAqB;YACpC,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,cAAc,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;YACnD,OAAO,EAAE,IAAsB;YAC/B,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK;YACrC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC;YACjC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK;YACjC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;YAChD,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK;YACvC,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,UAAU,EAAE,cAAc,CAAC,UAAU;SACxC,CAAC;QAEF,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,QAAQ;gBACT,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEzD,KAAK,QAAQ,CAAC;YACd,KAAK,UAAU;gBACX,OAAO,IAAI,sBAAsB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEnE,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ;gBACT,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEzD,KAAK,WAAW;gBACZ,OAAO,IAAI,eAAe,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAE5D;gBACI,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC9B,CAAC;CACJ","sourcesContent":["/**\r\n * Universal LLM Client v3 — AIModel (The Universal Client)\r\n *\r\n * The only public-facing class. Developers configure one model with\r\n * multiple provider backends for transparent failover.\r\n *\r\n * Provider classes are internal — the user never imports them.\r\n */\r\n\r\nimport {\r\n AIModelApiType,\r\n type AIModelConfig,\r\n type ProviderConfig,\r\n type LLMClientOptions,\r\n type LLMChatMessage,\r\n type LLMChatResponse,\r\n type ChatOptions,\r\n type ModelMetadata,\r\n type LLMFunction,\r\n type ToolHandler,\r\n} from './interfaces.js';\r\nimport type { DecodedEvent } from './stream-decoder.js';\r\nimport { Router, type RouterConfig, type ProviderStatus } from './router.js';\r\nimport type { Auditor } from './auditor.js';\r\nimport { NoopAuditor } from './auditor.js';\r\nimport { OllamaClient } from './providers/ollama.js';\r\nimport { OpenAICompatibleClient } from './providers/openai.js';\r\nimport { GoogleClient } from './providers/google.js';\r\nimport { AnthropicClient } from './providers/anthropic.js';\r\nimport { BaseLLMClient } from './client.js';\r\nimport {\r\n type StructuredOutputResult,\r\n type SchemaConfig,\r\n} from './structured-output.js';\r\n\r\n// ============================================================================\r\n// Default Provider URLs\r\n// ============================================================================\r\n\r\nconst DEFAULT_URLS: Record<string, string> = {\r\n ollama: 'http://localhost:11434',\r\n openai: 'https://api.openai.com',\r\n llamacpp: 'http://localhost:8080',\r\n anthropic: 'https://api.anthropic.com',\r\n // google and vertex build their own URLs internally\r\n};\r\n\r\n// ============================================================================\r\n// AIModel — The Universal Client\r\n// ============================================================================\r\n\r\nexport class AIModel {\r\n private router: Router;\r\n private auditor: Auditor;\r\n private config: AIModelConfig;\r\n\r\n constructor(config: AIModelConfig) {\r\n this.config = config;\r\n this.auditor = config.auditor ?? new NoopAuditor();\r\n\r\n const routerConfig: RouterConfig = {\r\n retriesPerProvider: config.retries ?? 2,\r\n auditor: this.auditor,\r\n };\r\n this.router = new Router(routerConfig);\r\n\r\n // Initialize providers in order\r\n for (let i = 0; i < config.providers.length; i++) {\r\n const providerConfig = config.providers[i]!;\r\n const client = this.createClient(providerConfig);\r\n const id = `${this.normalizeType(providerConfig.type)}-${i}`;\r\n\r\n this.router.addProvider({\r\n id,\r\n client,\r\n priority: providerConfig.priority ?? i,\r\n modelOverride: providerConfig.model,\r\n });\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Chat\r\n // ========================================================================\r\n\r\n /** Send a chat request with automatic failover across providers */\r\n async chat(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): Promise<LLMChatResponse> {\r\n return this.router.chat(messages, options);\r\n }\r\n\r\n /** Chat with automatic tool execution (multi-turn loop) */\r\n async chatWithTools(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions & { maxIterations?: number },\r\n ): Promise<LLMChatResponse> {\r\n return this.router.chatWithTools(messages, options);\r\n }\r\n\r\n /** Stream chat response with pluggable decoder strategy */\r\n async *chatStream(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): AsyncGenerator<DecodedEvent, LLMChatResponse | void, unknown> {\r\n return yield* this.router.chatStream(messages, options);\r\n }\r\n\r\n // ========================================================================\r\n // Structured Output\r\n // ========================================================================\r\n\r\n /**\r\n * Generate structured output from the LLM with automatic failover.\r\n * Validates the response against the provided Zod schema.\r\n * Throws StructuredOutputError on validation failure.\r\n *\r\n * @template T The output type\r\n * @param config Schema configuration (JSON Schema + optional validator)\r\n * @param messages Chat messages to send\r\n * @param options Additional options (temperature, maxTokens, etc.)\r\n * @returns Promise resolving to validated structured output\r\n * @throws StructuredOutputError if JSON parsing fails or validation fails\r\n *\r\n * @example\r\n * ```typescript\r\n * import { fromZod } from 'universal-llm-client/zod';\r\n * const UserConfig = fromZod(z.object({\r\n * name: z.string(),\r\n * age: z.number(),\r\n * }));\r\n *\r\n * const user = await model.generateStructured(UserConfig, [\r\n * { role: 'user', content: 'Generate a user profile' },\r\n * ]);\r\n * // user.name: string, user.age: number\r\n * ```\r\n */\r\n async generateStructured<T>(\r\n config: SchemaConfig<T>,\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): Promise<T> {\r\n return this.router.generateStructured(config, messages, options);\r\n }\r\n\r\n /**\r\n * Try to generate structured output, returning a result object instead of throwing.\r\n * Same as generateStructured but returns { ok: true, value } on success\r\n * and { ok: false, error, rawOutput } on failure.\r\n *\r\n * @template T The output type\r\n * @param config Schema configuration (JSON Schema + optional validator)\r\n * @param messages Chat messages to send\r\n * @param options Additional options (temperature, maxTokens, etc.)\r\n * @returns StructuredOutputResult<T> - either success with value or failure with error\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await model.tryParseStructured(config, messages);\r\n *\r\n * if (result.ok) {\r\n * console.log('User:', result.value.name);\r\n * } else {\r\n * console.log('Error:', result.error.message);\r\n * console.log('Raw output:', result.rawOutput);\r\n * }\r\n * ```\r\n */\r\n async tryParseStructured<T>(\r\n config: SchemaConfig<T>,\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): Promise<StructuredOutputResult<T>> {\r\n return this.router.tryParseStructured(config, messages, options);\r\n }\r\n\r\n /**\r\n * Stream structured output with partial validated objects.\r\n *\r\n * Yields partial validated objects as JSON generates, then returns the\r\n * complete validated object on stream completion.\r\n *\r\n * For invalid partial JSON, no yield occurs (partial validation is best-effort).\r\n * On stream completion, if the final JSON fails validation, throws StructuredOutputError.\r\n *\r\n * @template T The output type\r\n * @param config Schema configuration (JSON Schema + optional validator)\r\n * @param messages Chat messages to send\r\n * @param options Additional options (temperature, maxTokens, etc.)\r\n * @yields Partial validated objects as the JSON stream progresses\r\n * @returns Complete validated object on stream completion\r\n * @throws StructuredOutputError if final validation fails\r\n *\r\n * @example\r\n * ```typescript\r\n * import { fromZod } from 'universal-llm-client/zod';\r\n * const UserConfig = fromZod(z.object({\r\n * name: z.string(),\r\n * age: z.number(),\r\n * }));\r\n *\r\n * const stream = model.generateStructuredStream(UserConfig, [\r\n * { role: 'user', content: 'Generate a user' },\r\n * ]);\r\n *\r\n * for await (const partial of stream) {\r\n * console.log('Partial user:', partial);\r\n * }\r\n * ```\r\n */\r\n async *generateStructuredStream<T>(\r\n config: SchemaConfig<T>,\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): AsyncGenerator<T, T, unknown> {\r\n return yield* this.router.generateStructuredStream(config, messages, options);\r\n }\r\n\r\n // ========================================================================\r\n // Embeddings\r\n // ========================================================================\r\n\r\n /** Generate embedding for a single text */\r\n async embed(text: string): Promise<number[]> {\r\n return this.router.embed(text);\r\n }\r\n\r\n /** Generate embeddings for multiple texts */\r\n async embedArray(texts: string[]): Promise<number[][]> {\r\n return this.router.embedArray(texts);\r\n }\r\n\r\n // ========================================================================\r\n // Tool Registration\r\n // ========================================================================\r\n\r\n /** Register a tool callable by the LLM (broadcast to all providers) */\r\n registerTool(\r\n name: string,\r\n description: string,\r\n parameters: LLMFunction['parameters'],\r\n handler: ToolHandler,\r\n ): void {\r\n this.router.registerTool(name, description, parameters, handler);\r\n }\r\n\r\n /** Register multiple tools at once */\r\n registerTools(\r\n tools: Array<{\r\n name: string;\r\n description: string;\r\n parameters: LLMFunction['parameters'];\r\n handler: ToolHandler;\r\n }>,\r\n ): void {\r\n this.router.registerTools(tools);\r\n }\r\n\r\n // ========================================================================\r\n // Model Management\r\n // ========================================================================\r\n\r\n /** Get available models from all configured providers */\r\n async getModels(): Promise<string[]> {\r\n return this.router.getModels();\r\n }\r\n\r\n /** Get metadata about the current model (context length, capabilities) */\r\n async getModelInfo(): Promise<ModelMetadata> {\r\n return this.router.getModelInfo();\r\n }\r\n\r\n /** Switch model at runtime (updates all providers) */\r\n setModel(name: string): void {\r\n this.config.model = name;\r\n // The model name change will be picked up by the providers\r\n // through the router on next request\r\n }\r\n\r\n /** Get the current model name */\r\n get model(): string {\r\n return this.config.model;\r\n }\r\n\r\n // ========================================================================\r\n // Provider Status\r\n // ========================================================================\r\n\r\n /** Get health/status of all configured providers */\r\n getProviderStatus(): ProviderStatus[] {\r\n return this.router.getStatus();\r\n }\r\n\r\n // ========================================================================\r\n // Lifecycle\r\n // ========================================================================\r\n\r\n /** Clean shutdown — flush auditor, disconnect MCP, etc. */\r\n async dispose(): Promise<void> {\r\n await this.auditor.flush?.();\r\n }\r\n\r\n // ========================================================================\r\n // Internal: Provider Factory\r\n // ========================================================================\r\n\r\n private createClient(providerConfig: ProviderConfig): BaseLLMClient {\r\n const type = this.normalizeType(providerConfig.type);\r\n const modelName = providerConfig.model ?? this.config.model;\r\n\r\n const clientOptions: LLMClientOptions = {\r\n model: modelName,\r\n url: providerConfig.url ?? DEFAULT_URLS[type] ?? '',\r\n apiType: type as AIModelApiType,\r\n apiKey: providerConfig.apiKey,\r\n timeout: this.config.timeout ?? 30000,\r\n retries: this.config.retries ?? 2,\r\n debug: this.config.debug ?? false,\r\n defaultParameters: this.config.defaultParameters,\r\n thinking: this.config.thinking ?? false,\r\n region: providerConfig.region,\r\n apiVersion: providerConfig.apiVersion,\r\n };\r\n\r\n switch (type) {\r\n case 'ollama':\r\n return new OllamaClient(clientOptions, this.auditor);\r\n\r\n case 'openai':\r\n case 'llamacpp':\r\n return new OpenAICompatibleClient(clientOptions, this.auditor);\r\n\r\n case 'google':\r\n case 'vertex':\r\n return new GoogleClient(clientOptions, this.auditor);\r\n\r\n case 'anthropic':\r\n return new AnthropicClient(clientOptions, this.auditor);\r\n\r\n default:\r\n throw new Error(`Unknown provider type: ${type}`);\r\n }\r\n }\r\n\r\n private normalizeType(type: string): string {\r\n return type.toLowerCase();\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ai-model.js","sourceRoot":"","sources":["../src/ai-model.ts"],"names":[],"mappings":"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"}
|
package/dist/auditor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditor.js","sourceRoot":"","sources":["../src/auditor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Universal LLM Client v3 — Auditor (Observability)\r\n *\r\n * Every LLM interaction (request, response, tool call, retry, failover)\r\n * is recorded through the Auditor interface. Frameworks inject their own\r\n * Auditor for dashboards, cost tracking, or behavioral scoring.\r\n */\r\n\r\nimport type { TokenUsageInfo, ToolExecutionResult } from './interfaces.js';\r\n\r\n// ============================================================================\r\n// Audit Event\r\n// ============================================================================\r\n\r\nexport type AuditEventType =\r\n | 'request'\r\n | 'response'\r\n | 'stream_start'\r\n | 'stream_end'\r\n | 'tool_call'\r\n | 'tool_result'\r\n | 'error'\r\n | 'retry'\r\n | 'failover'\r\n | 'structured_request'\r\n | 'structured_response'\r\n | 'structured_validation_error';\r\n\r\nexport interface AuditEvent {\r\n /** Unix timestamp in ms */\r\n timestamp: number;\r\n /** Event type */\r\n type: AuditEventType;\r\n /** Provider that generated this event */\r\n provider?: string;\r\n /** Model name */\r\n model?: string;\r\n /** Duration in ms (for request/response pairs) */\r\n duration?: number;\r\n /** Token usage (for response events) */\r\n usage?: TokenUsageInfo;\r\n /** Tool execution details (for tool_call/tool_result events) */\r\n toolExecution?: ToolExecutionResult;\r\n /** Error message (for error/retry events) */\r\n error?: string;\r\n /** Arbitrary metadata for framework-specific data */\r\n metadata?: Record<string, unknown>;\r\n /** Schema name for structured output events */\r\n schemaName?: string;\r\n /** Raw output snippet for validation errors */\r\n rawOutput?: string;\r\n}\r\n\r\n// ============================================================================\r\n// Auditor Interface\r\n// ============================================================================\r\n\r\n/**\r\n * Interface for LLM observability.\r\n *\r\n * Implement this to capture all LLM lifecycle events.\r\n * The library calls `record()` at every interaction point.\r\n */\r\nexport interface Auditor {\r\n /** Record an audit event */\r\n record(event: AuditEvent): void;\r\n /** Flush any buffered events (optional) */\r\n flush?(): Promise<void>;\r\n}\r\n\r\n// ============================================================================\r\n// Built-in Auditors\r\n// ============================================================================\r\n\r\n/**\r\n * Zero-overhead auditor that discards all events.\r\n * Used as the default when no auditor is configured.\r\n */\r\nexport class NoopAuditor implements Auditor {\r\n record(_event: AuditEvent): void {\r\n // Intentionally empty\r\n }\r\n}\r\n\r\n/**\r\n * Structured console logging auditor.\r\n * Useful for development and debugging.\r\n */\r\nexport class ConsoleAuditor implements Auditor {\r\n private prefix: string;\r\n\r\n constructor(prefix: string = '[LLM]') {\r\n this.prefix = prefix;\r\n }\r\n\r\n record(event: AuditEvent): void {\r\n const parts = [\r\n this.prefix,\r\n event.type.toUpperCase(),\r\n event.provider ? `[${event.provider}]` : '',\r\n event.model ? `(${event.model})` : '',\r\n ].filter(Boolean);\r\n\r\n switch (event.type) {\r\n case 'request':\r\n console.log(parts.join(' '), '→');\r\n break;\r\n case 'response':\r\n console.log(\r\n parts.join(' '),\r\n event.duration ? `${event.duration}ms` : '',\r\n event.usage ? `${event.usage.totalTokens} tokens` : '',\r\n );\r\n break;\r\n case 'stream_start':\r\n console.log(parts.join(' '), 'streaming...');\r\n break;\r\n case 'stream_end':\r\n console.log(\r\n parts.join(' '),\r\n 'done',\r\n event.duration ? `${event.duration}ms` : '',\r\n );\r\n break;\r\n case 'tool_call':\r\n console.log(parts.join(' '), event.toolExecution?.tool_call_id ?? '');\r\n break;\r\n case 'tool_result':\r\n console.log(\r\n parts.join(' '),\r\n event.toolExecution?.error ? '❌' : '✅',\r\n event.toolExecution?.duration ? `${event.toolExecution.duration}ms` : '',\r\n );\r\n break;\r\n case 'error':\r\n console.error(parts.join(' '), event.error ?? 'Unknown error');\r\n break;\r\n case 'retry':\r\n console.warn(parts.join(' '), event.error ?? '', event.metadata ?? '');\r\n break;\r\n case 'failover':\r\n console.warn(parts.join(' '), '→', event.metadata?.['nextProvider'] ?? '');\r\n break;\r\n case 'structured_request':\r\n console.log(\r\n parts.join(' '),\r\n `schema=${event.schemaName ?? 'unknown'}`,\r\n '→',\r\n );\r\n break;\r\n case 'structured_response':\r\n console.log(\r\n parts.join(' '),\r\n event.duration ? `${event.duration}ms` : '',\r\n `schema=${event.schemaName ?? 'unknown'}`,\r\n );\r\n break;\r\n case 'structured_validation_error':\r\n console.error(\r\n parts.join(' '),\r\n `schema=${event.schemaName ?? 'unknown'}`,\r\n event.error ?? 'Validation failed',\r\n event.rawOutput ? `raw=${event.rawOutput.slice(0, 50)}...` : '',\r\n );\r\n break;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Buffered auditor that collects events for batch processing.\r\n * Useful for custom sinks (OpenTelemetry, DataDog, databases, etc.)\r\n */\r\nexport class BufferedAuditor implements Auditor {\r\n private events: AuditEvent[] = [];\r\n private maxBufferSize: number;\r\n private onFlush?: (events: AuditEvent[]) => Promise<void>;\r\n\r\n constructor(options: {\r\n maxBufferSize?: number;\r\n onFlush?: (events: AuditEvent[]) => Promise<void>;\r\n } = {}) {\r\n this.maxBufferSize = options.maxBufferSize ?? 1000;\r\n this.onFlush = options.onFlush;\r\n }\r\n\r\n record(event: AuditEvent): void {\r\n this.events.push(event);\r\n if (this.events.length >= this.maxBufferSize) {\r\n // Auto-flush when buffer is full (fire and forget)\r\n this.flush().catch(() => {});\r\n }\r\n }\r\n\r\n /** Get all buffered events */\r\n getEvents(): ReadonlyArray<AuditEvent> {\r\n return this.events;\r\n }\r\n\r\n /** Flush buffered events to the configured sink */\r\n async flush(): Promise<void> {\r\n if (this.events.length === 0) return;\r\n const batch = this.events.splice(0);\r\n if (this.onFlush) {\r\n await this.onFlush(batch);\r\n }\r\n }\r\n\r\n /** Clear all buffered events without flushing */\r\n clear(): void {\r\n this.events.length = 0;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"auditor.js","sourceRoot":"","sources":["../src/auditor.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Universal LLM Client v3 — Base LLM Client\r\n *\r\n * Abstract base class for all LLM providers.\r\n * Handles tool registration, execution, and the autonomous\r\n * multi-turn tool execution loop.\r\n */\r\n\r\nimport type {\r\n LLMClientOptions,\r\n LLMChatMessage,\r\n LLMChatResponse,\r\n LLMToolDefinition,\r\n LLMToolCall,\r\n LLMFunction,\r\n ToolRegistry,\r\n ToolHandler,\r\n ToolExecutionResult,\r\n ChatOptions,\r\n ModelMetadata,\r\n} from './interfaces.js';\r\nimport {\r\n StructuredOutputError,\r\n type StructuredOutputOptions,\r\n type SchemaConfig,\r\n} from './structured-output.js';\r\nimport type { DecodedEvent } from './stream-decoder.js';\r\nimport type { Auditor } from './auditor.js';\r\nimport { NoopAuditor } from './auditor.js';\r\n\r\n// ============================================================================\r\n// Abstract Base Client\r\n// ============================================================================\r\n\r\nexport abstract class BaseLLMClient {\r\n protected options: LLMClientOptions;\r\n protected toolRegistry: ToolRegistry = {};\r\n protected auditor: Auditor;\r\n protected debug: boolean;\r\n\r\n constructor(options: LLMClientOptions, auditor?: Auditor) {\r\n this.options = options;\r\n this.auditor = auditor ?? new NoopAuditor();\r\n this.debug = options.debug ?? false;\r\n }\r\n\r\n // ========================================================================\r\n // Abstract Methods (implemented by providers)\r\n // ========================================================================\r\n\r\n /** Send a chat request and get a response */\r\n abstract chat(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): Promise<LLMChatResponse>;\r\n\r\n /** Stream a chat response as decoded events */\r\n abstract chatStream(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): AsyncGenerator<DecodedEvent, LLMChatResponse | void, unknown>;\r\n\r\n /** Get available models */\r\n abstract getModels(): Promise<string[]>;\r\n\r\n /** Generate embeddings for text */\r\n abstract embed(text: string): Promise<number[]>;\r\n\r\n /** Generate embeddings for multiple texts */\r\n async embedArray(texts: string[]): Promise<number[][]> {\r\n return Promise.all(texts.map(t => this.embed(t)));\r\n }\r\n\r\n /**\r\n * Get metadata about a model (context length, architecture, etc.)\r\n * Override per-provider for accurate data.\r\n */\r\n async getModelInfo(_modelName?: string): Promise<ModelMetadata> {\r\n return { contextLength: 8192 }; // Conservative default\r\n }\r\n\r\n // ========================================================================\r\n // Tool Registration\r\n // ========================================================================\r\n\r\n /**\r\n * Sanitize tool name for LLM compatibility.\r\n * LLM APIs require function names matching [a-zA-Z0-9_-].\r\n * Module-prefixed names like \"@core/computer:list_windows\" are cleaned.\r\n */\r\n private sanitizeToolName(name: string): string {\r\n return name\r\n .replace(/^@[^:]+:/, '') // Strip module prefix\r\n .replace(/[^a-zA-Z0-9_-]/g, '_') // Replace illegal chars\r\n .replace(/_+/g, '_') // Collapse\r\n .replace(/^_|_$/g, ''); // Trim\r\n }\r\n\r\n /** Register a tool/function callable by the model */\r\n registerTool(\r\n name: string,\r\n description: string,\r\n parameters: LLMFunction['parameters'],\r\n handler: ToolHandler,\r\n ): void {\r\n const safeName = this.sanitizeToolName(name);\r\n this.toolRegistry[name] = {\r\n definition: { name: safeName, description, parameters },\r\n handler,\r\n };\r\n // Index by sanitized name for reverse lookup\r\n if (safeName !== name && !this.toolRegistry[safeName]) {\r\n this.toolRegistry[safeName] = this.toolRegistry[name]!;\r\n }\r\n this.debugLog(`Registered tool: ${name} (LLM name: ${safeName})`);\r\n }\r\n\r\n /** Register multiple tools at once */\r\n registerTools(\r\n tools: Array<{\r\n name: string;\r\n description: string;\r\n parameters: LLMFunction['parameters'];\r\n handler: ToolHandler;\r\n }>,\r\n ): void {\r\n for (const tool of tools) {\r\n this.registerTool(tool.name, tool.description, tool.parameters, tool.handler);\r\n }\r\n }\r\n\r\n /** Get all registered tool definitions (deduplicated by sanitized name) */\r\n getToolDefinitions(): LLMToolDefinition[] {\r\n const seen = new Set<string>();\r\n const defs: LLMToolDefinition[] = [];\r\n for (const { definition } of Object.values(this.toolRegistry)) {\r\n if (seen.has(definition.name)) continue;\r\n seen.add(definition.name);\r\n defs.push({ type: 'function' as const, function: definition });\r\n }\r\n return defs;\r\n }\r\n\r\n // ========================================================================\r\n // Tool Execution\r\n // ========================================================================\r\n\r\n /** Execute a single tool call with fuzzy name matching */\r\n async executeTool(toolCall: LLMToolCall): Promise<ToolExecutionResult> {\r\n const toolName = toolCall.function.name;\r\n const start = Date.now();\r\n let tool = this.toolRegistry[toolName];\r\n\r\n // Fuzzy lookup: try suffix match (LLM stripped module prefix)\r\n if (!tool) {\r\n const entries = Object.entries(this.toolRegistry);\r\n const bySuffix = entries.find(([k]) => k.endsWith(`:${toolName}`));\r\n if (bySuffix) {\r\n tool = bySuffix[1];\r\n this.debugLog(`Fuzzy tool match: \"${toolName}\" → \"${bySuffix[0]}\"`);\r\n }\r\n\r\n // Try prefix match: if only one tool in that module, use it\r\n if (!tool) {\r\n const byPrefix = entries.filter(([k]) => k.startsWith(`${toolName}:`));\r\n if (byPrefix.length === 1) {\r\n tool = byPrefix[0]![1];\r\n this.debugLog(`Fuzzy tool match (single): \"${toolName}\" → \"${byPrefix[0]![0]}\"`);\r\n }\r\n }\r\n }\r\n\r\n if (!tool) {\r\n const result: ToolExecutionResult = {\r\n tool_call_id: toolCall.id,\r\n output: null,\r\n error: `Unknown tool: ${toolName}`,\r\n duration: Date.now() - start,\r\n };\r\n this.auditor.record({\r\n timestamp: Date.now(),\r\n type: 'tool_result',\r\n toolExecution: result,\r\n error: result.error,\r\n });\r\n return result;\r\n }\r\n\r\n this.auditor.record({\r\n timestamp: Date.now(),\r\n type: 'tool_call',\r\n metadata: { toolName, arguments: toolCall.function.arguments },\r\n });\r\n\r\n try {\r\n const args = JSON.parse(toolCall.function.arguments);\r\n const output = await tool.handler(args);\r\n const result: ToolExecutionResult = {\r\n tool_call_id: toolCall.id,\r\n output,\r\n duration: Date.now() - start,\r\n };\r\n this.auditor.record({\r\n timestamp: Date.now(),\r\n type: 'tool_result',\r\n toolExecution: result,\r\n });\r\n return result;\r\n } catch (error) {\r\n const result: ToolExecutionResult = {\r\n tool_call_id: toolCall.id,\r\n output: null,\r\n error: error instanceof Error ? error.message : String(error),\r\n duration: Date.now() - start,\r\n };\r\n this.auditor.record({\r\n timestamp: Date.now(),\r\n type: 'tool_result',\r\n toolExecution: result,\r\n error: result.error,\r\n });\r\n return result;\r\n }\r\n }\r\n\r\n /** Execute multiple tool calls in parallel */\r\n async executeTools(toolCalls: LLMToolCall[]): Promise<ToolExecutionResult[]> {\r\n return Promise.all(toolCalls.map(tc => this.executeTool(tc)));\r\n }\r\n\r\n // ========================================================================\r\n // Chat with Tools (multi-turn autonomous loop)\r\n // ========================================================================\r\n\r\n /**\r\n * Chat with automatic tool execution.\r\n * Continues until the model stops calling tools or max iterations reached.\r\n * Returns the complete execution trace in `toolExecutions`.\r\n */\r\n async chatWithTools(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions & { maxIterations?: number },\r\n ): Promise<LLMChatResponse> {\r\n const maxIterations = options?.maxIterations ?? 10;\r\n const conversationMessages = [...messages];\r\n const allToolExecutions: ToolExecutionResult[] = [];\r\n let iterations = 0;\r\n\r\n while (iterations < maxIterations) {\r\n const response = await this.chat(conversationMessages, {\r\n ...options,\r\n tools: this.getToolDefinitions(),\r\n });\r\n\r\n // If no tool calls, return with full trace\r\n if (!response.message.tool_calls?.length) {\r\n return {\r\n ...response,\r\n toolExecutions: allToolExecutions.length > 0 ? allToolExecutions : undefined,\r\n };\r\n }\r\n\r\n // Add assistant message with tool calls\r\n conversationMessages.push(response.message);\r\n\r\n // Execute tools in parallel\r\n const toolResults = await this.executeTools(response.message.tool_calls);\r\n allToolExecutions.push(...toolResults);\r\n\r\n // Add tool results as messages\r\n for (const result of toolResults) {\r\n conversationMessages.push({\r\n role: 'tool',\r\n content: typeof result.output === 'string'\r\n ? result.output\r\n : JSON.stringify(result.output),\r\n tool_call_id: result.tool_call_id,\r\n });\r\n }\r\n\r\n iterations++;\r\n }\r\n\r\n // Max iterations — final call without tools\r\n const finalResponse = await this.chat(conversationMessages);\r\n return {\r\n ...finalResponse,\r\n toolExecutions: allToolExecutions,\r\n };\r\n }\r\n\r\n // ========================================================================\r\n // Helpers\r\n // ========================================================================\r\n\r\n /** Set the model name at runtime */\r\n setModel(modelName: string): void {\r\n this.options.model = modelName;\r\n this.debugLog(`Model switched to: ${modelName}`);\r\n }\r\n\r\n /** Get the current model name */\r\n get model(): string {\r\n return this.options.model;\r\n }\r\n\r\n /** Get the base URL */\r\n get url(): string {\r\n return this.options.url;\r\n }\r\n\r\n /** Set the auditor instance */\r\n setAuditor(auditor: Auditor): void {\r\n this.auditor = auditor;\r\n }\r\n\r\n protected debugLog(message: string, data?: unknown): void {\r\n if (this.debug) {\r\n console.log(`[LLM:${this.options.model}] ${message}`, data ?? '');\r\n }\r\n }\r\n\r\n /**\r\n * Generate a unique ID for tool calls when the provider doesn't provide one.\r\n */\r\n protected generateToolCallId(): string {\r\n return `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\r\n }\r\n\r\n // ========================================================================\r\n // Structured Output Helpers (shared across all providers)\r\n // ========================================================================\r\n\r\n /**\r\n * Extract schema options from ChatOptions.\r\n * Returns null if no schema is provided.\r\n * Returns a SchemaConfig if a schema was found.\r\n */\r\n protected extractSchemaOptions(options?: ChatOptions): (StructuredOutputOptions<unknown> & { schemaConfig: SchemaConfig<unknown> }) | null {\r\n if (!options) return null;\r\n\r\n if (options.schema) {\r\n return {\r\n schemaConfig: options.schema,\r\n name: options.schemaName,\r\n description: options.schemaDescription,\r\n };\r\n }\r\n\r\n if (options.jsonSchema) {\r\n // Raw JSON Schema without validation\r\n const config: SchemaConfig<unknown> = {\r\n jsonSchema: options.jsonSchema,\r\n };\r\n return {\r\n schemaConfig: config,\r\n name: options.schemaName,\r\n description: options.schemaDescription,\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Validate structured response using a SchemaConfig.\r\n * Throws StructuredOutputError on failure.\r\n */\r\n protected validateStructuredResponse(content: string, config: SchemaConfig<unknown>): void {\r\n if (!content) {\r\n throw new StructuredOutputError(\r\n 'Empty response from LLM',\r\n { rawOutput: content },\r\n );\r\n }\r\n\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(content);\r\n } catch (error) {\r\n const syntaxError = error instanceof SyntaxError\r\n ? error\r\n : new SyntaxError(String(error));\r\n throw new StructuredOutputError(\r\n `Failed to parse JSON: ${syntaxError.message}`,\r\n { rawOutput: content, cause: syntaxError },\r\n );\r\n }\r\n\r\n if (config.validate) {\r\n try {\r\n config.validate(parsed);\r\n } catch (error) {\r\n const validationError = error instanceof Error ? error : new Error(String(error));\r\n throw new StructuredOutputError(\r\n `Validation failed: ${validationError.message}`,\r\n { rawOutput: content, cause: validationError },\r\n );\r\n }\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemma 4 can emit its thought channel as text control tokens instead of the
|
|
3
|
+
* generic Ollama `message.thinking` field. Keep that provider quirk isolated so
|
|
4
|
+
* callers receive final-answer text and reasoning separately.
|
|
5
|
+
*/
|
|
6
|
+
export interface GemmaThoughtExtraction {
|
|
7
|
+
readonly content: string;
|
|
8
|
+
readonly reasoning: string;
|
|
9
|
+
readonly found: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const GEMMA_THOUGHT_OPENERS: readonly ["<|channel>thought", "<|thought"];
|
|
12
|
+
export declare function extractGemmaThoughtChannels(input: string): GemmaThoughtExtraction;
|
|
13
|
+
export declare function normalizeGemmaThought(thought: string): string;
|
|
14
|
+
//# sourceMappingURL=gemma-channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemma-channel.d.ts","sourceRoot":"","sources":["../src/gemma-channel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B;AAKD,eAAO,MAAM,qBAAqB,6CAA8C,CAAC;AAEjF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,CAyBjF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemma 4 can emit its thought channel as text control tokens instead of the
|
|
3
|
+
* generic Ollama `message.thinking` field. Keep that provider quirk isolated so
|
|
4
|
+
* callers receive final-answer text and reasoning separately.
|
|
5
|
+
*/
|
|
6
|
+
const GEMMA_THOUGHT_BLOCK = /<\|channel>\s*thought\s*\r?\n?([\s\S]*?)<channel\|>/gi;
|
|
7
|
+
const GEMMA_COMPACT_THOUGHT_BLOCK = /<\|thought\s*\r?\n?([\s\S]*?)\|>/gi;
|
|
8
|
+
export const GEMMA_THOUGHT_OPENERS = ['<|channel>thought', '<|thought'];
|
|
9
|
+
export function extractGemmaThoughtChannels(input) {
|
|
10
|
+
if (!input)
|
|
11
|
+
return { content: input, reasoning: '', found: false };
|
|
12
|
+
const reasoningParts = [];
|
|
13
|
+
let found = false;
|
|
14
|
+
const content = input
|
|
15
|
+
.replace(GEMMA_THOUGHT_BLOCK, (_match, thought) => {
|
|
16
|
+
found = true;
|
|
17
|
+
const normalized = normalizeGemmaThought(thought);
|
|
18
|
+
if (normalized)
|
|
19
|
+
reasoningParts.push(normalized);
|
|
20
|
+
return '';
|
|
21
|
+
})
|
|
22
|
+
.replace(GEMMA_COMPACT_THOUGHT_BLOCK, (_match, thought) => {
|
|
23
|
+
found = true;
|
|
24
|
+
const normalized = normalizeGemmaThought(thought);
|
|
25
|
+
if (normalized)
|
|
26
|
+
reasoningParts.push(normalized);
|
|
27
|
+
return '';
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
content,
|
|
31
|
+
reasoning: reasoningParts.join('\n\n'),
|
|
32
|
+
found,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function normalizeGemmaThought(thought) {
|
|
36
|
+
return thought.replace(/^\s+/, '').replace(/\s+$/, '');
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=gemma-channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemma-channel.js","sourceRoot":"","sources":["../src/gemma-channel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,mBAAmB,GAAG,uDAAuD,CAAC;AACpF,MAAM,2BAA2B,GAAG,oCAAoC,CAAC;AAEzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,mBAAmB,EAAE,WAAW,CAAU,CAAC;AAEjF,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAEnE,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,MAAM,OAAO,GAAG,KAAK;SAChB,OAAO,CAAC,mBAAmB,EAAE,CAAC,MAAM,EAAE,OAAe,EAAE,EAAE;QACtD,KAAK,GAAG,IAAI,CAAC;QACb,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,UAAU;YAAE,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,OAAO,EAAE,CAAC;IACd,CAAC,CAAC;SACD,OAAO,CAAC,2BAA2B,EAAE,CAAC,MAAM,EAAE,OAAe,EAAE,EAAE;QAC9D,KAAK,GAAG,IAAI,CAAC;QACb,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,UAAU;YAAE,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEP,OAAO;QACH,OAAO;QACP,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QACtC,KAAK;KACR,CAAC;AACN,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACjD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiffusionGemma (vLLM) native-protocol adapter.
|
|
3
|
+
*
|
|
4
|
+
* Trimmed vLLM builds that serve DiffusionGemma ship with NO reasoning parser
|
|
5
|
+
* and NO tool-call parser module, and they reject OpenAI-style `tools` unless
|
|
6
|
+
* `--tool-call-parser` is configured. Everything therefore has to be handled
|
|
7
|
+
* client-side, against the model's native channel format (visible only when
|
|
8
|
+
* the request sets `skip_special_tokens: false`):
|
|
9
|
+
*
|
|
10
|
+
* <|channel>thought ...reasoning... <channel|> reasoning channel
|
|
11
|
+
* <|tool_call>call:name{k:<|"|>v<|"|>,n:3}<tool_call|> tool call
|
|
12
|
+
*
|
|
13
|
+
* Tool-call arguments are NOT JSON: keys are bare, strings are wrapped in the
|
|
14
|
+
* <|"|> quote token, numbers/booleans are bare (see the model's
|
|
15
|
+
* chat_template.jinja `format_argument` macro). `gemmaArgsToJson` converts
|
|
16
|
+
* that into a standard JSON string.
|
|
17
|
+
*
|
|
18
|
+
* Request-side protocol (implemented in the OpenAI provider):
|
|
19
|
+
* - always send `skip_special_tokens: false`
|
|
20
|
+
* - send `tools` with `tool_choice: 'none'` — vLLM still renders the
|
|
21
|
+
* declarations into the chat template, it just skips its (absent) parser
|
|
22
|
+
* - send history tool turns structurally (assistant `tool_calls` +
|
|
23
|
+
* `role: 'tool'` messages) — the chat template renders them natively
|
|
24
|
+
*/
|
|
25
|
+
export interface GemmaParsedToolCall {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
/** JSON-encoded arguments object, ready for LLMToolCall.function.arguments */
|
|
28
|
+
readonly argumentsJson: string;
|
|
29
|
+
}
|
|
30
|
+
export interface GemmaDiffusionParsed {
|
|
31
|
+
/** Final answer with reasoning, tool-call blocks and special tokens removed */
|
|
32
|
+
readonly content: string;
|
|
33
|
+
readonly reasoning: string;
|
|
34
|
+
readonly toolCalls: readonly GemmaParsedToolCall[];
|
|
35
|
+
}
|
|
36
|
+
/** Models that speak this native protocol when served by vLLM. */
|
|
37
|
+
export declare function isGemmaDiffusionModel(model: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Convert the Gemma template's pseudo-JSON argument syntax to a JSON string.
|
|
40
|
+
* Lenient by design: bare words that aren't numbers/booleans become strings,
|
|
41
|
+
* since the model occasionally omits the quote token.
|
|
42
|
+
*/
|
|
43
|
+
export declare function gemmaArgsToJson(body: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Parse a complete raw DiffusionGemma output into reasoning, tool calls and
|
|
46
|
+
* clean answer text.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseGemmaDiffusionOutput(raw: string): GemmaDiffusionParsed;
|
|
49
|
+
//# sourceMappingURL=gemma-diffusion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemma-diffusion.d.ts","sourceRoot":"","sources":["../src/gemma-diffusion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACtD;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAaD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwEpD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CA2B3E"}
|