@moikapy/origen 0.4.1 → 0.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/README.md +170 -25
- package/dist/adapter-DXIT3O2f.d.ts +209 -0
- package/dist/adapter.d.ts +5 -204
- package/dist/adapter.js +3 -1
- package/dist/chunk-GK5KZOHB.js +201 -0
- package/dist/chunk-GK5KZOHB.js.map +1 -0
- package/dist/{chunk-TECUAB3E.js → chunk-K3FE63XL.js} +60 -8
- package/dist/chunk-K3FE63XL.js.map +1 -0
- package/dist/chunk-QF3XSUMT.js +333 -0
- package/dist/chunk-QF3XSUMT.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +41 -9
- package/dist/models.js +7 -1
- package/dist/soul.js +4 -327
- package/dist/soul.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-ECRY7XDR.js +0 -109
- package/dist/chunk-ECRY7XDR.js.map +0 -1
- package/dist/chunk-TECUAB3E.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,18 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
> Multi-Provider Agent Engine — an agent harness, not a chatbot.
|
|
4
4
|
|
|
5
|
-
Named after **Origen of Alexandria** (c. 185–254 AD) — the early church's greatest scholar. This package is
|
|
5
|
+
Named after **Origen of Alexandria** (c. 185–254 AD) — the early church's greatest scholar. This package is a **generic** agent harness that wraps any LLM provider with tool calling, streaming, Soul.md personas, and Cloudflare D1 integration.
|
|
6
6
|
|
|
7
7
|
**Domain-specific tools live in separate packages.** For Bible study, see `@moikapy/scholar-tools`.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Multi-provider**: OpenRouter, Ollama, Anthropic, Google, OpenAI, DeepSeek, Groq, xAI via `@mariozechner/pi-ai`
|
|
12
|
+
- **Streaming first**: `streamOrigen()` yields typed events (reasoning, tool calls, text deltas, citations)
|
|
13
|
+
- **Parallel tool execution**: Tools run concurrently by default; sequential mode available
|
|
14
|
+
- **Soul.md personas**: Declarative persona definitions with profiles, moods, and voice tuning
|
|
15
|
+
- **D1 integration**: Tools receive a `D1Provider` for Cloudflare D1 database access
|
|
16
|
+
- **Provider-aware auth**: `getApiKey(provider)` resolves keys per-provider (OAuth PKCE, local Ollama, etc.)
|
|
17
|
+
- **Abort support**: Pass `signal: AbortSignal` to cancel streaming mid-flight
|
|
18
|
+
- **Citation extraction**: Pluggable `extractCitations` for domain-specific parsing
|
|
19
|
+
- **Thinking models**: Automatic extended reasoning for DeepSeek R1, Claude Sonnet 4, Gemini 2.5 Flash
|
|
10
20
|
|
|
11
|
-
|
|
21
|
+
## Providers
|
|
12
22
|
|
|
13
23
|
| Provider | Models | Auth |
|
|
14
24
|
|---|---|---|
|
|
15
25
|
| **OpenRouter** | 275+ models, free tier available | OAuth PKCE / API key |
|
|
16
|
-
| **Ollama** | Llama 3, Gemma 3, Mistral, Qwen 3, DeepSeek R1 | Local (no key needed) |
|
|
26
|
+
| **Ollama** | Llama 3, Gemma 3, Mistral, Qwen 3, DeepSeek R1, + any custom model | Local (no key needed) |
|
|
17
27
|
| **Anthropic** | Claude Sonnet 4, etc. | API key |
|
|
18
28
|
| **Google** | Gemini 2.5 Flash, etc. | API key |
|
|
19
29
|
| **OpenAI** | GPT-4o, etc. | API key |
|
|
@@ -52,7 +62,6 @@ const config: AgentConfig = {
|
|
|
52
62
|
tools: [myTool],
|
|
53
63
|
getD1: async () => myD1Database,
|
|
54
64
|
model: "openrouter/free",
|
|
55
|
-
// Provider-aware key resolution
|
|
56
65
|
getApiKey: async (provider) => {
|
|
57
66
|
if (provider === "ollama") return "ollama";
|
|
58
67
|
return getOpenRouterKey();
|
|
@@ -73,14 +82,44 @@ for await (const event of streamOrigen(messages, context, config)) {
|
|
|
73
82
|
|
|
74
83
|
## Ollama Support
|
|
75
84
|
|
|
85
|
+
### Static Model List
|
|
86
|
+
|
|
87
|
+
Origen ships with hardcoded entries for popular Ollama models (Llama 3, Gemma 3, DeepSeek R1, etc.). These serve as fallbacks when Ollama isn't running.
|
|
88
|
+
|
|
89
|
+
### Dynamic Discovery
|
|
90
|
+
|
|
91
|
+
When Ollama is running, Origen can pull the full list of available models — including cloud models (`:cloud` suffix) — via `fetchOllamaModels()`:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { discoverOllamaModels, getModelsForUI } from "@moikapy/origen/models";
|
|
95
|
+
|
|
96
|
+
// Fetch from Ollama, merge into MODELS registry, return combined map
|
|
97
|
+
const allModels = await discoverOllamaModels("http://localhost:11434");
|
|
98
|
+
console.log(allModels["ollama/llama3.2"]); // { name: "llama3.2 (3.2B)", description: "Local — 3.2B (Q4_K_M) requires Ollama", free: true }
|
|
99
|
+
|
|
100
|
+
// Or do it in two steps for more control:
|
|
101
|
+
import { fetchOllamaModels, mergeOllamaModels } from "@moikapy/origen/models";
|
|
102
|
+
|
|
103
|
+
const discovered = await fetchOllamaModels("http://localhost:11434");
|
|
104
|
+
// Filter, transform, or inspect before merging
|
|
105
|
+
mergeOllamaModels(discovered);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Key behaviors:**
|
|
109
|
+
- Embedding models (e.g., `nomic-embed-text`) are automatically filtered out
|
|
110
|
+
- Cloud models (tagged `:cloud`) are tagged as "Cloud" in their description
|
|
111
|
+
- Reasoning model families (DeepSeek R1, Qwen3, etc.) are auto-detected
|
|
112
|
+
- Network errors return empty results — no crash, just static fallbacks
|
|
113
|
+
- 5-second timeout — won't block startup if Ollama is slow
|
|
114
|
+
|
|
115
|
+
### Custom Models
|
|
116
|
+
|
|
117
|
+
Use `ollama/<model-name>` and Origen constructs a generic OpenAI-compatible config pointing at your Ollama server:
|
|
118
|
+
|
|
76
119
|
```typescript
|
|
77
120
|
const config: AgentConfig = {
|
|
78
|
-
model: "ollama/
|
|
121
|
+
model: "ollama/my-custom-finetune",
|
|
79
122
|
ollamaBaseUrl: "http://localhost:11434/v1",
|
|
80
|
-
getApiKey: async (provider) => {
|
|
81
|
-
if (provider === "ollama") return "ollama"; // Ollama doesn't need a real key
|
|
82
|
-
return undefined;
|
|
83
|
-
},
|
|
84
123
|
// ...
|
|
85
124
|
};
|
|
86
125
|
```
|
|
@@ -100,21 +139,24 @@ console.log(concise.buildPrompt()); // Concise version
|
|
|
100
139
|
|
|
101
140
|
### Supported Soul.md Fields
|
|
102
141
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
142
|
+
| Section | Fields |
|
|
143
|
+
|---|---|
|
|
144
|
+
| **identity** | role, archetype, domain_focus, non_goals |
|
|
145
|
+
| **relationship** | stance, user_model_default, trust_baseline |
|
|
146
|
+
| **voice** | formality, warmth, verbosity, jargon, formatting, banned_phrases, preferred_phrases, emoji_policy |
|
|
147
|
+
| **interaction** | clarifying_questions, uncertainty, disagreement, confirmations |
|
|
148
|
+
| **cognition** | mode, depth, verification (fact_checking, cross_validation) |
|
|
149
|
+
| **safety** | refusal_style, privacy, speculation, no_fabrication, no_false_certainty |
|
|
150
|
+
| **actions** | when_to_use_tools, explain_actions, failover |
|
|
151
|
+
| **state** | dynamic moods with trigger-based transitions |
|
|
152
|
+
| **profiles** | named overlays (concise, scholarly, friendly, etc.) |
|
|
153
|
+
| **composition** | extends, mixins, merge_policy |
|
|
154
|
+
|
|
155
|
+
## API Reference
|
|
114
156
|
|
|
115
157
|
### `streamOrigen(messages, context, config, apiKey?)`
|
|
116
158
|
|
|
117
|
-
Async generator yielding `StreamEvent`s. Handles the full agent loop with parallel tool execution.
|
|
159
|
+
Async generator yielding `StreamEvent`s. Handles the full agent loop with parallel tool execution. Events: `reasoning`, `tool_call`, `tool_result`, `text`, `done`, `error`.
|
|
118
160
|
|
|
119
161
|
### `callOrigen(messages, context, config, apiKey?)`
|
|
120
162
|
|
|
@@ -122,12 +164,20 @@ Non-streaming wrapper. Returns `{ message, citations, usage }`.
|
|
|
122
164
|
|
|
123
165
|
### `checkAuth(getApiKey)`
|
|
124
166
|
|
|
125
|
-
Provider-aware auth check. Returns `{ authenticated, apiKey, provider, error? }`.
|
|
167
|
+
Provider-aware auth check. Tries OpenRouter → Ollama → Anthropic. Returns `{ authenticated, apiKey, provider, error? }`.
|
|
126
168
|
|
|
127
169
|
### `checkOpenRouterAuth(getApiKey)`
|
|
128
170
|
|
|
129
171
|
OpenRouter-only auth check (backward compat).
|
|
130
172
|
|
|
173
|
+
### `resolveModel(modelId, options?)`
|
|
174
|
+
|
|
175
|
+
Resolves a model ID string to a pi-ai `Model` object. Handles Ollama models, pi-ai registry lookups, and generic fallbacks.
|
|
176
|
+
|
|
177
|
+
### `createEventStream(agent, extractCitations?)`
|
|
178
|
+
|
|
179
|
+
Eagerly subscribes to an Agent and returns `{ stream, unsubscribe }`. Subscribes synchronously before `prompt()` to avoid race conditions.
|
|
180
|
+
|
|
131
181
|
## Configuration
|
|
132
182
|
|
|
133
183
|
```typescript
|
|
@@ -150,16 +200,111 @@ interface AgentConfig {
|
|
|
150
200
|
## Models
|
|
151
201
|
|
|
152
202
|
```typescript
|
|
153
|
-
import {
|
|
203
|
+
import {
|
|
204
|
+
MODELS, DEFAULT_MODEL, THINKING_MODELS,
|
|
205
|
+
supportsThinking, isOllamaModel,
|
|
206
|
+
getModelsByProvider, getModelsForUI,
|
|
207
|
+
fetchOllamaModels, mergeOllamaModels, discoverOllamaModels,
|
|
208
|
+
} from "@moikapy/origen/models";
|
|
154
209
|
```
|
|
155
210
|
|
|
156
|
-
|
|
211
|
+
### Built-in Model IDs
|
|
212
|
+
|
|
213
|
+
| ID | Name | Free? |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| `openrouter/free` | Free (Auto) | ✅ |
|
|
216
|
+
| `google/gemma-4-31b-it:free` | Gemma 4 31B | ✅ |
|
|
217
|
+
| `nvidia/nemotron-3-super-120b-a12b:free` | Nemotron 3 Super | ✅ |
|
|
218
|
+
| `deepseek/deepseek-r1:free` | DeepSeek R1 (Free) | ✅ |
|
|
219
|
+
| `qwen/qwen3-coder:free` | Qwen3 Coder | ✅ |
|
|
220
|
+
| `ollama/llama3` | Llama 3 (Ollama) | ✅ |
|
|
221
|
+
| `ollama/llama3.1` | Llama 3.1 8B (Ollama) | ✅ |
|
|
222
|
+
| `ollama/gemma3` | Gemma 3 (Ollama) | ✅ |
|
|
223
|
+
| `ollama/mistral` | Mistral 7B (Ollama) | ✅ |
|
|
224
|
+
| `ollama/qwen3` | Qwen 3 (Ollama) | ✅ |
|
|
225
|
+
| `ollama/deepseek-r1` | DeepSeek R1 (Ollama) | ✅ |
|
|
226
|
+
| `ollama/codellama` | Code Llama (Ollama) | ✅ |
|
|
227
|
+
| `ollama/phi3` | Phi-3 (Ollama) | ✅ |
|
|
228
|
+
| `openrouter/auto` | Auto (All) | ❌ |
|
|
229
|
+
| `anthropic/claude-sonnet-4` | Claude Sonnet 4 | ❌ |
|
|
230
|
+
| `google/gemini-2.5-flash-preview` | Gemini 2.5 Flash | ❌ |
|
|
231
|
+
|
|
232
|
+
### Thinking Models
|
|
233
|
+
|
|
234
|
+
Extended reasoning support for: `anthropic/claude-sonnet-4`, `deepseek/deepseek-r1:free`, `google/gemini-2.5-flash-preview`, `ollama/deepseek-r1`.
|
|
235
|
+
|
|
236
|
+
### Dynamic Ollama Discovery
|
|
237
|
+
|
|
238
|
+
Ollama models can be discovered at runtime from a running server:
|
|
239
|
+
|
|
240
|
+
| Function | Description |
|
|
241
|
+
|---|---|
|
|
242
|
+
| `fetchOllamaModels(baseUrl?)` | Query Ollama `/api/tags`, return `Record<string, ModelConfig>` |
|
|
243
|
+
| `mergeOllamaModels(models)` | Merge discovered models into the static `MODELS` registry |
|
|
244
|
+
| `discoverOllamaModels(baseUrl?)` | One-shot: fetch + merge + return combined map |
|
|
245
|
+
|
|
246
|
+
## Exports Map
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
".": "Main entry — streamOrigen, callOrigen, checkAuth, MODELS, Soul, etc.",
|
|
251
|
+
"./models": "MODELS registry, supportsThinking, isOllamaModel, getModelsByProvider",
|
|
252
|
+
"./soul": "Soul class, loadSoul, SoulConfig types",
|
|
253
|
+
"./adapter": "resolveModel, createEventStream, adaptTools, convertMessages"
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Architecture
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
┌─────────────────────────────────────────────────────┐
|
|
261
|
+
│ Your App │
|
|
262
|
+
│ streamOrigen(messages, context, config) │
|
|
263
|
+
└────────┬──────────────┬─────────────────────────────┘
|
|
264
|
+
│ │
|
|
265
|
+
┌────▼────┐ ┌─────▼──────┐
|
|
266
|
+
│ agent.ts│ │ adapter.ts │
|
|
267
|
+
│ Agent │ │ Tool adapt │
|
|
268
|
+
│ loop │ │ Model res. │
|
|
269
|
+
│ Auth │ │ Event xlate│
|
|
270
|
+
└────┬────┘ └─────┬──────┘
|
|
271
|
+
│ │
|
|
272
|
+
┌────▼──────────────▼────┐
|
|
273
|
+
│ pi-ai + pi-agent-core│
|
|
274
|
+
│ (LLM providers, │
|
|
275
|
+
│ streaming, tools) │
|
|
276
|
+
└───────────────────────┘
|
|
277
|
+
```
|
|
157
278
|
|
|
279
|
+
- **agent.ts** — Agent loop, auth checks, event types. Orchestrates `Agent` from pi-agent-core.
|
|
280
|
+
- **adapter.ts** — Bridges Origen's simple types to pi-ai/pi-agent-core. Tool adaptation, model resolution, event translation, eager event stream.
|
|
281
|
+
- **models.ts** — Model registry with UI-safe configs, thinking model detection, provider filtering.
|
|
282
|
+
- **soul.ts** — Soul.md RFC-1 parser with YAML front matter, profile overlays, prompt generation.
|
|
283
|
+
- **types.ts** — Zero-dependency types (D1Like, Citation, UsageInfo, ReadingContext).
|
|
284
|
+
|
|
285
|
+
## Changelog
|
|
286
|
+
|
|
287
|
+
### v0.5 (current)
|
|
288
|
+
- **Dynamic Ollama discovery**: `fetchOllamaModels()`, `mergeOllamaModels()`, `discoverOllamaModels()` pull live models from Ollama's `/api/tags` endpoint
|
|
289
|
+
- **Improved Ollama model catalog**: Added Llama 3.1, Mistral Nemo, Code Llama, Phi-3; updated context windows
|
|
290
|
+
- **Ollama provider in resolveModel**: Now tries `ollama` in the pi-ai registry loop
|
|
291
|
+
- **Exported `defaultCitationExtractor`**: Now importable for custom citation pipelines
|
|
292
|
+
- **Reduced `as any` casts**: Replaced with documented type assertions where pi-ai generics are too narrow
|
|
293
|
+
|
|
294
|
+
### v0.4
|
|
295
|
+
- **Zod validation**: Optional `inputSchema` on `OrigenTool` for runtime parameter validation
|
|
296
|
+
- **Qwen3 Coder**: Added `qwen/qwen3-coder:free` to model registry
|
|
297
|
+
- **getModelsForUI()**: UI-safe model configs without internal fields
|
|
298
|
+
- **getModelsByProvider()**: Filter models by provider prefix
|
|
299
|
+
- **UIModelConfig type**: Stripped model config safe for client-side use
|
|
300
|
+
|
|
301
|
+
### v0.3
|
|
158
302
|
- **Multi-provider**: OpenRouter, Ollama, Anthropic, Google, DeepSeek, Groq, xAI via pi-ai
|
|
159
303
|
- **Parallel tool execution**: Tools run concurrently by default
|
|
160
304
|
- **Abort support**: Pass `signal: AbortSignal` to cancel streaming
|
|
161
305
|
- **Soul.md personas**: Declarative persona definitions with profiles and moods
|
|
162
306
|
- **Provider-aware auth**: `getApiKey(provider)` resolves keys per-provider
|
|
307
|
+
- **Eager event stream**: `createEventStream()` subscribes before prompt to avoid race conditions
|
|
163
308
|
- **No more hardcoded SSE parser**: Delegate to pi-ai + pi-agent-core
|
|
164
309
|
|
|
165
310
|
## License
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { Model, Api, Message, Context } from '@mariozechner/pi-ai';
|
|
2
|
+
import { AgentTool, AgentEvent } from '@mariozechner/pi-agent-core';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { ModelId } from './models.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Origen types — no runtime deps, safe for client + server.
|
|
8
|
+
*/
|
|
9
|
+
/** D1-compatible database interface for tool execution */
|
|
10
|
+
interface D1Like {
|
|
11
|
+
prepare(sql: string): {
|
|
12
|
+
bind(...params: unknown[]): {
|
|
13
|
+
all(): Promise<{
|
|
14
|
+
results?: Record<string, unknown>[];
|
|
15
|
+
}>;
|
|
16
|
+
first(): Promise<Record<string, unknown> | null>;
|
|
17
|
+
run(): Promise<{
|
|
18
|
+
meta?: {
|
|
19
|
+
changes: number;
|
|
20
|
+
last_row_id: number;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Function that provides a D1 instance to tool executors */
|
|
27
|
+
type D1Provider = () => Promise<D1Like>;
|
|
28
|
+
/** Chat context passed from the UI (what the user is reading) */
|
|
29
|
+
interface ReadingContext {
|
|
30
|
+
translation: string;
|
|
31
|
+
bookCode: string;
|
|
32
|
+
chapter: number;
|
|
33
|
+
selectedVerses?: number[];
|
|
34
|
+
}
|
|
35
|
+
interface Citation {
|
|
36
|
+
book: string;
|
|
37
|
+
chapter: number;
|
|
38
|
+
verse: number;
|
|
39
|
+
}
|
|
40
|
+
interface UsageInfo {
|
|
41
|
+
promptTokens?: number;
|
|
42
|
+
completionTokens?: number;
|
|
43
|
+
totalCost?: number;
|
|
44
|
+
}
|
|
45
|
+
/** Model configuration entry */
|
|
46
|
+
interface ModelConfig {
|
|
47
|
+
name: string;
|
|
48
|
+
description: string;
|
|
49
|
+
free: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Origen — Agent Engine (v0.3)
|
|
54
|
+
*
|
|
55
|
+
* Multi-provider agent harness built on pi-ai + pi-agent-core.
|
|
56
|
+
* Supports OpenRouter, Ollama, Anthropic, Google, and any OpenAI-compatible API.
|
|
57
|
+
* Soul.md personas, streaming, parallel tool execution, abort support.
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A tool that the host app registers with Origen.
|
|
62
|
+
* Simple interface: name, description, JSON schema, and an execute function
|
|
63
|
+
* that receives (args, getD1). The adapter wraps this into pi-agent-core's AgentTool.
|
|
64
|
+
*/
|
|
65
|
+
interface OrigenTool {
|
|
66
|
+
name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
/** OpenAI function-calling parameter schema (JSON) */
|
|
69
|
+
parameters: Record<string, unknown>;
|
|
70
|
+
/** Zod schema for runtime validation (optional) */
|
|
71
|
+
inputSchema?: z.ZodType;
|
|
72
|
+
execute: (args: Record<string, unknown>, getD1: D1Provider) => Promise<string>;
|
|
73
|
+
}
|
|
74
|
+
interface AgentConfig {
|
|
75
|
+
appName?: string;
|
|
76
|
+
systemPrompt?: string;
|
|
77
|
+
tools: OrigenTool[];
|
|
78
|
+
getD1: D1Provider;
|
|
79
|
+
model?: ModelId;
|
|
80
|
+
maxSteps?: number;
|
|
81
|
+
/** Custom citation extractor */
|
|
82
|
+
extractCitations?: (text: string) => Citation[];
|
|
83
|
+
/** Dynamic API key resolution per provider (e.g., for expiring OAuth tokens) */
|
|
84
|
+
getApiKey?: (provider: string) => Promise<string | undefined>;
|
|
85
|
+
/** Ollama base URL override (default: http://localhost:11434/v1) */
|
|
86
|
+
ollamaBaseUrl?: string;
|
|
87
|
+
/** Tool execution mode: "parallel" (default) or "sequential" */
|
|
88
|
+
toolExecution?: "sequential" | "parallel";
|
|
89
|
+
/** Abort signal for cancellation */
|
|
90
|
+
signal?: AbortSignal;
|
|
91
|
+
/** Reasoning/thinking level for models that support it */
|
|
92
|
+
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high";
|
|
93
|
+
}
|
|
94
|
+
interface AuthCheckResult {
|
|
95
|
+
authenticated: boolean;
|
|
96
|
+
apiKey: string | null;
|
|
97
|
+
provider?: string;
|
|
98
|
+
error?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Provider-aware auth check. Tests key availability for each provider.
|
|
102
|
+
* If no provider argument, checks OpenRouter + Ollama availability.
|
|
103
|
+
*/
|
|
104
|
+
declare function checkAuth(getApiKey: ((provider: string) => Promise<string | undefined>) | (() => Promise<string | null>)): Promise<AuthCheckResult>;
|
|
105
|
+
/** Convenience: check OpenRouter auth only (backward compat). */
|
|
106
|
+
declare function checkOpenRouterAuth(getApiKey: () => Promise<string | null>): Promise<AuthCheckResult>;
|
|
107
|
+
type StreamEvent = {
|
|
108
|
+
type: "reasoning";
|
|
109
|
+
content: string;
|
|
110
|
+
} | {
|
|
111
|
+
type: "tool_call";
|
|
112
|
+
name: string;
|
|
113
|
+
args: Record<string, unknown>;
|
|
114
|
+
} | {
|
|
115
|
+
type: "tool_result";
|
|
116
|
+
name: string;
|
|
117
|
+
result: string;
|
|
118
|
+
} | {
|
|
119
|
+
type: "text";
|
|
120
|
+
content: string;
|
|
121
|
+
} | {
|
|
122
|
+
type: "done";
|
|
123
|
+
message: string;
|
|
124
|
+
citations: Citation[];
|
|
125
|
+
usage?: UsageInfo;
|
|
126
|
+
} | {
|
|
127
|
+
type: "error";
|
|
128
|
+
message: string;
|
|
129
|
+
};
|
|
130
|
+
declare function streamOrigen(messages: Array<{
|
|
131
|
+
role: "user" | "assistant";
|
|
132
|
+
content: string;
|
|
133
|
+
}>, context: Record<string, unknown> | undefined, config: AgentConfig, apiKey?: string): AsyncGenerator<StreamEvent>;
|
|
134
|
+
interface AgentResponse {
|
|
135
|
+
message: string;
|
|
136
|
+
citations: Citation[];
|
|
137
|
+
usage?: UsageInfo;
|
|
138
|
+
}
|
|
139
|
+
declare function callOrigen(messages: Array<{
|
|
140
|
+
role: "user" | "assistant";
|
|
141
|
+
content: string;
|
|
142
|
+
}>, context: Record<string, unknown> | undefined, config: AgentConfig, apiKey?: string): Promise<AgentResponse>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Adapter: bridges Origen's simple types to pi-agent-core/pi-ai types.
|
|
146
|
+
*
|
|
147
|
+
* - OrigenTool → AgentTool (injects D1Provider)
|
|
148
|
+
* - pi-ai Model resolution (OpenRouter, Ollama, Anthropic, Google)
|
|
149
|
+
* - StreamEvent translation (AgentEvent → Origen's StreamEvent)
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Convert an OrigenTool into a pi-agent-core AgentTool.
|
|
154
|
+
* The D1Provider is captured in closure so the tool's execute gets it.
|
|
155
|
+
*/
|
|
156
|
+
declare function adaptTool(tool: OrigenTool, getD1: D1Provider): AgentTool;
|
|
157
|
+
/** Adapt all OrigenTools for an Agent instance. */
|
|
158
|
+
declare function adaptTools(tools: OrigenTool[], getD1: D1Provider): AgentTool[];
|
|
159
|
+
interface ModelResolutionOptions {
|
|
160
|
+
/** Ollama base URL, e.g. "http://localhost:11434/v1" */
|
|
161
|
+
ollamaBaseUrl?: string;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Resolve a model ID string to a pi-ai Model object.
|
|
165
|
+
* Tries pi-ai's registry first, then falls back to built-in Ollama definitions.
|
|
166
|
+
*/
|
|
167
|
+
declare function resolveModel(modelId: string, options?: ModelResolutionOptions): Model<Api>;
|
|
168
|
+
/** Convert Origen's simple messages to pi-ai Message format. */
|
|
169
|
+
declare function convertMessages(messages: Array<{
|
|
170
|
+
role: "user" | "assistant";
|
|
171
|
+
content: string;
|
|
172
|
+
}>): Message[];
|
|
173
|
+
/** Build a pi-ai Context from Origen's config. */
|
|
174
|
+
declare function buildContext(systemPrompt: string, messages: Message[], adaptedTools: AgentTool[]): Context;
|
|
175
|
+
/** Default citation extractor — [BOOK CHAPTER:VERSE] patterns (e.g., [GEN 1:1]).
|
|
176
|
+
* Bible-specific pattern. Consumers should provide their own extractCitations
|
|
177
|
+
* for non-biblical citation formats. Exported for reuse and testing.
|
|
178
|
+
*/
|
|
179
|
+
declare function defaultCitationExtractor(text: string): Citation[];
|
|
180
|
+
/** Translate a pi-agent-core AgentEvent into an Origen StreamEvent. */
|
|
181
|
+
declare function translateEvent(event: AgentEvent, extractCitations?: (text: string) => Citation[]): StreamEvent | null;
|
|
182
|
+
/**
|
|
183
|
+
* Eagerly subscribe to an Agent and return an async iterable of Origen StreamEvents.
|
|
184
|
+
*
|
|
185
|
+
* CRITICAL: The subscription is created synchronously when this function is called,
|
|
186
|
+
* BEFORE agent.prompt() starts. This avoids the race condition where events
|
|
187
|
+
* emitted during prompt() are missed if subscription happens after.
|
|
188
|
+
*
|
|
189
|
+
* Usage:
|
|
190
|
+
* const { stream, unsubscribe } = createEventStream(agent, extractCitations);
|
|
191
|
+
* agent.prompt(messages); // events flow into stream via active subscription
|
|
192
|
+
* for await (const event of stream) { ... }
|
|
193
|
+
*/
|
|
194
|
+
declare function createEventStream(agent: any, // Agent from pi-agent-core
|
|
195
|
+
extractCitations?: (text: string) => Citation[]): {
|
|
196
|
+
stream: AsyncGenerator<StreamEvent>;
|
|
197
|
+
unsubscribe: () => void;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Subscribe to an Agent and yield Origen StreamEvents.
|
|
201
|
+
* Handles the full lifecycle from agent_start to agent_end.
|
|
202
|
+
*
|
|
203
|
+
* @deprecated Use createEventStream() instead to avoid race conditions.
|
|
204
|
+
* This function subscribes lazily (on first iteration) which can miss events
|
|
205
|
+
* if the agent has already started emitting.
|
|
206
|
+
*/
|
|
207
|
+
declare function agentToStreamEvents(agent: any, extractCitations?: (text: string) => Citation[]): AsyncGenerator<StreamEvent>;
|
|
208
|
+
|
|
209
|
+
export { type AgentConfig as A, type Citation as C, type D1Like as D, type ModelResolutionOptions as M, type OrigenTool as O, type ReadingContext as R, type StreamEvent as S, type UsageInfo as U, type AgentResponse as a, type AuthCheckResult as b, type D1Provider as c, type ModelConfig as d, callOrigen as e, checkAuth as f, checkOpenRouterAuth as g, createEventStream as h, defaultCitationExtractor as i, adaptTool as j, adaptTools as k, agentToStreamEvents as l, buildContext as m, convertMessages as n, resolveModel as r, streamOrigen as s, translateEvent as t };
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,204 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Origen types — no runtime deps, safe for client + server.
|
|
8
|
-
*/
|
|
9
|
-
/** D1-compatible database interface for tool execution */
|
|
10
|
-
interface D1Like {
|
|
11
|
-
prepare(sql: string): {
|
|
12
|
-
bind(...params: unknown[]): {
|
|
13
|
-
all(): Promise<{
|
|
14
|
-
results?: Record<string, unknown>[];
|
|
15
|
-
}>;
|
|
16
|
-
first(): Promise<Record<string, unknown> | null>;
|
|
17
|
-
run(): Promise<{
|
|
18
|
-
meta?: {
|
|
19
|
-
changes: number;
|
|
20
|
-
last_row_id: number;
|
|
21
|
-
};
|
|
22
|
-
}>;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
/** Function that provides a D1 instance to tool executors */
|
|
27
|
-
type D1Provider = () => Promise<D1Like>;
|
|
28
|
-
/** Chat context passed from the UI (what the user is reading) */
|
|
29
|
-
interface ReadingContext {
|
|
30
|
-
translation: string;
|
|
31
|
-
bookCode: string;
|
|
32
|
-
chapter: number;
|
|
33
|
-
selectedVerses?: number[];
|
|
34
|
-
}
|
|
35
|
-
interface Citation {
|
|
36
|
-
book: string;
|
|
37
|
-
chapter: number;
|
|
38
|
-
verse: number;
|
|
39
|
-
}
|
|
40
|
-
interface UsageInfo {
|
|
41
|
-
promptTokens?: number;
|
|
42
|
-
completionTokens?: number;
|
|
43
|
-
totalCost?: number;
|
|
44
|
-
}
|
|
45
|
-
/** Model configuration entry */
|
|
46
|
-
interface ModelConfig {
|
|
47
|
-
name: string;
|
|
48
|
-
description: string;
|
|
49
|
-
free: boolean;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Origen — Agent Engine (v0.3)
|
|
54
|
-
*
|
|
55
|
-
* Multi-provider agent harness built on pi-ai + pi-agent-core.
|
|
56
|
-
* Supports OpenRouter, Ollama, Anthropic, Google, and any OpenAI-compatible API.
|
|
57
|
-
* Soul.md personas, streaming, parallel tool execution, abort support.
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* A tool that the host app registers with Origen.
|
|
62
|
-
* Simple interface: name, description, JSON schema, and an execute function
|
|
63
|
-
* that receives (args, getD1). The adapter wraps this into pi-agent-core's AgentTool.
|
|
64
|
-
*/
|
|
65
|
-
interface OrigenTool {
|
|
66
|
-
name: string;
|
|
67
|
-
description: string;
|
|
68
|
-
/** OpenAI function-calling parameter schema (JSON) */
|
|
69
|
-
parameters: Record<string, unknown>;
|
|
70
|
-
/** Zod schema for runtime validation (optional) */
|
|
71
|
-
inputSchema?: z.ZodType;
|
|
72
|
-
execute: (args: Record<string, unknown>, getD1: D1Provider) => Promise<string>;
|
|
73
|
-
}
|
|
74
|
-
interface AgentConfig {
|
|
75
|
-
appName?: string;
|
|
76
|
-
systemPrompt?: string;
|
|
77
|
-
tools: OrigenTool[];
|
|
78
|
-
getD1: D1Provider;
|
|
79
|
-
model?: ModelId;
|
|
80
|
-
maxSteps?: number;
|
|
81
|
-
/** Custom citation extractor */
|
|
82
|
-
extractCitations?: (text: string) => Citation[];
|
|
83
|
-
/** Dynamic API key resolution per provider (e.g., for expiring OAuth tokens) */
|
|
84
|
-
getApiKey?: (provider: string) => Promise<string | undefined>;
|
|
85
|
-
/** Ollama base URL override (default: http://localhost:11434/v1) */
|
|
86
|
-
ollamaBaseUrl?: string;
|
|
87
|
-
/** Tool execution mode: "parallel" (default) or "sequential" */
|
|
88
|
-
toolExecution?: "sequential" | "parallel";
|
|
89
|
-
/** Abort signal for cancellation */
|
|
90
|
-
signal?: AbortSignal;
|
|
91
|
-
/** Reasoning/thinking level for models that support it */
|
|
92
|
-
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high";
|
|
93
|
-
}
|
|
94
|
-
interface AuthCheckResult {
|
|
95
|
-
authenticated: boolean;
|
|
96
|
-
apiKey: string | null;
|
|
97
|
-
provider?: string;
|
|
98
|
-
error?: string;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Provider-aware auth check. Tests key availability for each provider.
|
|
102
|
-
* If no provider argument, checks OpenRouter + Ollama availability.
|
|
103
|
-
*/
|
|
104
|
-
declare function checkAuth(getApiKey: ((provider: string) => Promise<string | undefined>) | (() => Promise<string | null>)): Promise<AuthCheckResult>;
|
|
105
|
-
/** Convenience: check OpenRouter auth only (backward compat). */
|
|
106
|
-
declare function checkOpenRouterAuth(getApiKey: () => Promise<string | null>): Promise<AuthCheckResult>;
|
|
107
|
-
type StreamEvent = {
|
|
108
|
-
type: "reasoning";
|
|
109
|
-
content: string;
|
|
110
|
-
} | {
|
|
111
|
-
type: "tool_call";
|
|
112
|
-
name: string;
|
|
113
|
-
args: Record<string, unknown>;
|
|
114
|
-
} | {
|
|
115
|
-
type: "tool_result";
|
|
116
|
-
name: string;
|
|
117
|
-
result: string;
|
|
118
|
-
} | {
|
|
119
|
-
type: "text";
|
|
120
|
-
content: string;
|
|
121
|
-
} | {
|
|
122
|
-
type: "done";
|
|
123
|
-
message: string;
|
|
124
|
-
citations: Citation[];
|
|
125
|
-
usage?: UsageInfo;
|
|
126
|
-
} | {
|
|
127
|
-
type: "error";
|
|
128
|
-
message: string;
|
|
129
|
-
};
|
|
130
|
-
declare function streamOrigen(messages: Array<{
|
|
131
|
-
role: "user" | "assistant";
|
|
132
|
-
content: string;
|
|
133
|
-
}>, context: Record<string, unknown> | undefined, config: AgentConfig, apiKey?: string): AsyncGenerator<StreamEvent>;
|
|
134
|
-
interface AgentResponse {
|
|
135
|
-
message: string;
|
|
136
|
-
citations: Citation[];
|
|
137
|
-
usage?: UsageInfo;
|
|
138
|
-
}
|
|
139
|
-
declare function callOrigen(messages: Array<{
|
|
140
|
-
role: "user" | "assistant";
|
|
141
|
-
content: string;
|
|
142
|
-
}>, context: Record<string, unknown> | undefined, config: AgentConfig, apiKey?: string): Promise<AgentResponse>;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Adapter: bridges Origen's simple types to pi-agent-core/pi-ai types.
|
|
146
|
-
*
|
|
147
|
-
* - OrigenTool → AgentTool (injects D1Provider)
|
|
148
|
-
* - pi-ai Model resolution (OpenRouter, Ollama, Anthropic, Google)
|
|
149
|
-
* - StreamEvent translation (AgentEvent → Origen's StreamEvent)
|
|
150
|
-
*/
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Convert an OrigenTool into a pi-agent-core AgentTool.
|
|
154
|
-
* The D1Provider is captured in closure so the tool's execute gets it.
|
|
155
|
-
*/
|
|
156
|
-
declare function adaptTool(tool: OrigenTool, getD1: D1Provider): AgentTool;
|
|
157
|
-
/** Adapt all OrigenTools for an Agent instance. */
|
|
158
|
-
declare function adaptTools(tools: OrigenTool[], getD1: D1Provider): AgentTool[];
|
|
159
|
-
interface ModelResolutionOptions {
|
|
160
|
-
/** Ollama base URL, e.g. "http://localhost:11434/v1" */
|
|
161
|
-
ollamaBaseUrl?: string;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Resolve a model ID string to a pi-ai Model object.
|
|
165
|
-
* Tries pi-ai's registry first, then falls back to built-in Ollama definitions.
|
|
166
|
-
*/
|
|
167
|
-
declare function resolveModel(modelId: string, options?: ModelResolutionOptions): Model<Api>;
|
|
168
|
-
/** Convert Origen's simple messages to pi-ai Message format. */
|
|
169
|
-
declare function convertMessages(messages: Array<{
|
|
170
|
-
role: "user" | "assistant";
|
|
171
|
-
content: string;
|
|
172
|
-
}>): Message[];
|
|
173
|
-
/** Build a pi-ai Context from Origen's config. */
|
|
174
|
-
declare function buildContext(systemPrompt: string, messages: Message[], adaptedTools: AgentTool[]): Context;
|
|
175
|
-
/** Translate a pi-agent-core AgentEvent into an Origen StreamEvent. */
|
|
176
|
-
declare function translateEvent(event: AgentEvent, extractCitations?: (text: string) => Citation[]): StreamEvent | null;
|
|
177
|
-
/**
|
|
178
|
-
* Eagerly subscribe to an Agent and return an async iterable of Origen StreamEvents.
|
|
179
|
-
*
|
|
180
|
-
* CRITICAL: The subscription is created synchronously when this function is called,
|
|
181
|
-
* BEFORE agent.prompt() starts. This avoids the race condition where events
|
|
182
|
-
* emitted during prompt() are missed if subscription happens after.
|
|
183
|
-
*
|
|
184
|
-
* Usage:
|
|
185
|
-
* const { stream, unsubscribe } = createEventStream(agent, extractCitations);
|
|
186
|
-
* agent.prompt(messages); // events flow into stream via active subscription
|
|
187
|
-
* for await (const event of stream) { ... }
|
|
188
|
-
*/
|
|
189
|
-
declare function createEventStream(agent: any, // Agent from pi-agent-core
|
|
190
|
-
extractCitations?: (text: string) => Citation[]): {
|
|
191
|
-
stream: AsyncGenerator<StreamEvent>;
|
|
192
|
-
unsubscribe: () => void;
|
|
193
|
-
};
|
|
194
|
-
/**
|
|
195
|
-
* Subscribe to an Agent and yield Origen StreamEvents.
|
|
196
|
-
* Handles the full lifecycle from agent_start to agent_end.
|
|
197
|
-
*
|
|
198
|
-
* @deprecated Use createEventStream() instead to avoid race conditions.
|
|
199
|
-
* This function subscribes lazily (on first iteration) which can miss events
|
|
200
|
-
* if the agent has already started emitting.
|
|
201
|
-
*/
|
|
202
|
-
declare function agentToStreamEvents(agent: any, extractCitations?: (text: string) => Citation[]): AsyncGenerator<StreamEvent>;
|
|
203
|
-
|
|
204
|
-
export { type AgentConfig as A, type Citation as C, type D1Like as D, type ModelConfig as M, type ModelResolutionOptions, type OrigenTool as O, type ReadingContext as R, type StreamEvent as S, type UsageInfo as U, type AgentResponse as a, adaptTool, adaptTools, agentToStreamEvents, type AuthCheckResult as b, buildContext, type D1Provider as c, convertMessages, createEventStream, callOrigen as d, checkAuth as e, checkOpenRouterAuth as f, resolveModel, streamOrigen as s, translateEvent };
|
|
1
|
+
import '@mariozechner/pi-ai';
|
|
2
|
+
import '@mariozechner/pi-agent-core';
|
|
3
|
+
export { M as ModelResolutionOptions, j as adaptTool, k as adaptTools, l as agentToStreamEvents, m as buildContext, n as convertMessages, h as createEventStream, i as defaultCitationExtractor, r as resolveModel, t as translateEvent } from './adapter-DXIT3O2f.js';
|
|
4
|
+
import 'zod';
|
|
5
|
+
import './models.js';
|