@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 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