@moikapy/origen 0.3.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 +167 -0
- package/bun.lock +561 -0
- package/package.json +27 -0
- package/src/adapter.ts +364 -0
- package/src/agent.ts +219 -0
- package/src/index.ts +58 -0
- package/src/models.ts +143 -0
- package/src/soul.ts +508 -0
- package/src/types.ts +59 -0
- package/test/origen.test.ts +171 -0
- package/tsconfig.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# @moikapy/origen
|
|
2
|
+
|
|
3
|
+
> Multi-Provider Agent Engine — an agent harness, not a chatbot.
|
|
4
|
+
|
|
5
|
+
Named after **Origen of Alexandria** (c. 185–254 AD) — the early church's greatest scholar. This package is the **generic** agent harness that wraps any LLM provider with tool calling, streaming, and Soul.md personas.
|
|
6
|
+
|
|
7
|
+
**Domain-specific tools live in separate packages.** For Bible study, see `@moikapy/scholar-tools`.
|
|
8
|
+
|
|
9
|
+
## Providers
|
|
10
|
+
|
|
11
|
+
Origen supports multiple LLM providers via `@mariozechner/pi-ai`:
|
|
12
|
+
|
|
13
|
+
| Provider | Models | Auth |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **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) |
|
|
17
|
+
| **Anthropic** | Claude Sonnet 4, etc. | API key |
|
|
18
|
+
| **Google** | Gemini 2.5 Flash, etc. | API key |
|
|
19
|
+
| **OpenAI** | GPT-4o, etc. | API key |
|
|
20
|
+
| **DeepSeek, Groq, xAI** | Various | API key |
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bun add @moikapy/origen
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { streamOrigen, MODELS } from "@moikapy/origen";
|
|
32
|
+
import type { OrigenTool, AgentConfig, ModelId } from "@moikapy/origen";
|
|
33
|
+
|
|
34
|
+
// Define your own tools
|
|
35
|
+
const myTool: OrigenTool = {
|
|
36
|
+
name: "lookup",
|
|
37
|
+
description: "Look up information",
|
|
38
|
+
parameters: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: { query: { type: "string", description: "Search query" } },
|
|
41
|
+
required: ["query"],
|
|
42
|
+
},
|
|
43
|
+
execute: async (args, getD1) => {
|
|
44
|
+
const d1 = await getD1();
|
|
45
|
+
const result = await d1.prepare("SELECT * FROM data WHERE content LIKE ?").bind(`%${args.query}%`).all();
|
|
46
|
+
return JSON.stringify(result.results);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const config: AgentConfig = {
|
|
51
|
+
appName: "MyApp",
|
|
52
|
+
tools: [myTool],
|
|
53
|
+
getD1: async () => myD1Database,
|
|
54
|
+
model: "openrouter/free",
|
|
55
|
+
// Provider-aware key resolution
|
|
56
|
+
getApiKey: async (provider) => {
|
|
57
|
+
if (provider === "ollama") return "ollama";
|
|
58
|
+
return getOpenRouterKey();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
for await (const event of streamOrigen(messages, context, config)) {
|
|
63
|
+
switch (event.type) {
|
|
64
|
+
case "reasoning": // thinking tokens (DeepSeek R1, etc.)
|
|
65
|
+
case "tool_call": // tool name + args
|
|
66
|
+
case "tool_result": // tool execution result
|
|
67
|
+
case "text": // response text delta
|
|
68
|
+
case "done": // final message + citations + usage
|
|
69
|
+
case "error": // auth/rate-limit/network errors
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Ollama Support
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const config: AgentConfig = {
|
|
78
|
+
model: "ollama/llama3",
|
|
79
|
+
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
|
+
// ...
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Soul.md — Persona as Code
|
|
89
|
+
|
|
90
|
+
Origen supports [Soul.md (RFC-1)](https://github.com/rokoss21/soul.md) — a portable specification for AI agent personas:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { loadSoul } from "@moikapy/origen/soul";
|
|
94
|
+
|
|
95
|
+
const soul = loadSoul(soulMdContent);
|
|
96
|
+
const prompt = soul.buildPrompt(); // Generate system prompt
|
|
97
|
+
const concise = soul.selectProfile("concise"); // Switch profile
|
|
98
|
+
console.log(concise.buildPrompt()); // Concise version
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Supported Soul.md Fields
|
|
102
|
+
|
|
103
|
+
- **identity**: role, archetype, domain_focus, non_goals
|
|
104
|
+
- **relationship**: stance, user_model_default, trust_baseline
|
|
105
|
+
- **voice**: formality, warmth, verbosity, jargon, formatting, banned_phrases, preferred_phrases, emoji_policy
|
|
106
|
+
- **interaction**: clarifying_questions, uncertainty, disagreement, confirmations
|
|
107
|
+
- **cognition**: mode, depth, verification (fact_checking, cross_validation)
|
|
108
|
+
- **safety**: refusal_style, privacy, speculation, no_fabrication, no_false_certainty
|
|
109
|
+
- **actions**: when_to_use_tools, explain_actions, failover
|
|
110
|
+
- **state**: dynamic moods with trigger-based transitions
|
|
111
|
+
- **profiles**: named overlays (concise, scholarly, friendly, etc.)
|
|
112
|
+
|
|
113
|
+
## API
|
|
114
|
+
|
|
115
|
+
### `streamOrigen(messages, context, config, apiKey?)`
|
|
116
|
+
|
|
117
|
+
Async generator yielding `StreamEvent`s. Handles the full agent loop with parallel tool execution.
|
|
118
|
+
|
|
119
|
+
### `callOrigen(messages, context, config, apiKey?)`
|
|
120
|
+
|
|
121
|
+
Non-streaming wrapper. Returns `{ message, citations, usage }`.
|
|
122
|
+
|
|
123
|
+
### `checkAuth(getApiKey)`
|
|
124
|
+
|
|
125
|
+
Provider-aware auth check. Returns `{ authenticated, apiKey, provider, error? }`.
|
|
126
|
+
|
|
127
|
+
### `checkOpenRouterAuth(getApiKey)`
|
|
128
|
+
|
|
129
|
+
OpenRouter-only auth check (backward compat).
|
|
130
|
+
|
|
131
|
+
## Configuration
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
interface AgentConfig {
|
|
135
|
+
appName?: string; // Used in default system prompt if no systemPrompt
|
|
136
|
+
systemPrompt?: string; // Override the default prompt entirely
|
|
137
|
+
tools: OrigenTool[]; // Tools available to the agent
|
|
138
|
+
getD1: D1Provider; // () => Promise<D1Like> — database access
|
|
139
|
+
model?: ModelId; // Default: "openrouter/free"
|
|
140
|
+
maxSteps?: number; // Default: 5, max tool-call loops
|
|
141
|
+
extractCitations?: (text: string) => Citation[]; // Custom citation parser
|
|
142
|
+
getApiKey?: (provider: string) => Promise<string | undefined>; // Per-provider key
|
|
143
|
+
ollamaBaseUrl?: string; // Default: "http://localhost:11434/v1"
|
|
144
|
+
toolExecution?: "sequential" | "parallel"; // Default: "parallel"
|
|
145
|
+
signal?: AbortSignal; // Cancellation support
|
|
146
|
+
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high"; // Reasoning
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Models
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { MODELS, DEFAULT_MODEL, THINKING_MODELS, supportsThinking, isOllamaModel } from "@moikapy/origen/models";
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## What Changed (v0.3)
|
|
157
|
+
|
|
158
|
+
- **Multi-provider**: OpenRouter, Ollama, Anthropic, Google, DeepSeek, Groq, xAI via pi-ai
|
|
159
|
+
- **Parallel tool execution**: Tools run concurrently by default
|
|
160
|
+
- **Abort support**: Pass `signal: AbortSignal` to cancel streaming
|
|
161
|
+
- **Soul.md personas**: Declarative persona definitions with profiles and moods
|
|
162
|
+
- **Provider-aware auth**: `getApiKey(provider)` resolves keys per-provider
|
|
163
|
+
- **No more hardcoded SSE parser**: Delegate to pi-ai + pi-agent-core
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|