@sschepis/oboto-agent 0.1.0 → 0.1.1
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/dist/index.d.ts +21 -6
- package/dist/index.js +152 -64
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Session, ConversationMessage } from '@sschepis/as-agent';
|
|
2
|
-
import {
|
|
2
|
+
import { BaseProvider } from '@sschepis/llm-wrapper';
|
|
3
3
|
import { Router, BranchNode } from '@sschepis/swiss-army-tool';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
+
import { ToolDefinition, ChatMessage, LLMProvider, LScriptRuntime, LScriptFunction } from '@sschepis/lmscript';
|
|
5
6
|
|
|
6
7
|
interface ObotoAgentConfig {
|
|
7
8
|
/** Small, fast model for triage and summarization (e.g. Ollama, LMStudio) */
|
|
8
|
-
localModel:
|
|
9
|
+
localModel: BaseProvider;
|
|
9
10
|
/** Powerful model for complex reasoning (e.g. Anthropic, OpenAI, Gemini) */
|
|
10
|
-
remoteModel:
|
|
11
|
+
remoteModel: BaseProvider;
|
|
11
12
|
/** Model identifier for the local provider (e.g. "llama3:8b") */
|
|
12
13
|
localModelName: string;
|
|
13
14
|
/** Model identifier for the remote provider (e.g. "claude-sonnet-4-20250514") */
|
|
@@ -50,7 +51,8 @@ type EventHandler$1 = (event: AgentEvent) => void;
|
|
|
50
51
|
* ObotoAgent is the central orchestrator for dual-LLM agent execution.
|
|
51
52
|
*
|
|
52
53
|
* It binds together:
|
|
53
|
-
* -
|
|
54
|
+
* - llm-wrapper (LLM communication via local and remote providers)
|
|
55
|
+
* - lmscript (structured/schema-validated calls for triage)
|
|
54
56
|
* - swiss-army-tool (tool execution via Router)
|
|
55
57
|
* - as-agent (session state and conversation history)
|
|
56
58
|
*
|
|
@@ -59,7 +61,8 @@ type EventHandler$1 = (event: AgentEvent) => void;
|
|
|
59
61
|
declare class ObotoAgent {
|
|
60
62
|
private bus;
|
|
61
63
|
private localRuntime;
|
|
62
|
-
private
|
|
64
|
+
private localProvider;
|
|
65
|
+
private remoteProvider;
|
|
63
66
|
private contextManager;
|
|
64
67
|
private routerTool;
|
|
65
68
|
private triageFn;
|
|
@@ -89,6 +92,10 @@ declare class ObotoAgent {
|
|
|
89
92
|
removeAllListeners(): void;
|
|
90
93
|
private executionLoop;
|
|
91
94
|
private triage;
|
|
95
|
+
/**
|
|
96
|
+
* Execute the agent loop using llm-wrapper directly.
|
|
97
|
+
* No JSON mode, no schema enforcement — just natural chat with tool calling.
|
|
98
|
+
*/
|
|
92
99
|
private executeWithModel;
|
|
93
100
|
}
|
|
94
101
|
|
|
@@ -139,6 +146,14 @@ declare function sessionToHistory(session: Session): ChatMessage[];
|
|
|
139
146
|
/** Create an empty as-agent Session. */
|
|
140
147
|
declare function createEmptySession(): Session;
|
|
141
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Adapt a llm-wrapper BaseProvider into lmscript's LLMProvider interface.
|
|
151
|
+
*
|
|
152
|
+
* This allows lmscript's LScriptRuntime to use llm-wrapper providers for
|
|
153
|
+
* structured calls (e.g. triage) that need schema validation.
|
|
154
|
+
*/
|
|
155
|
+
declare function toLmscriptProvider(provider: BaseProvider, name?: string): LLMProvider;
|
|
156
|
+
|
|
142
157
|
/**
|
|
143
158
|
* Manages the sliding context window with automatic summarization.
|
|
144
159
|
* Wraps lmscript's ContextStack and uses the local LLM for compression.
|
|
@@ -185,4 +200,4 @@ type TriageInput = {
|
|
|
185
200
|
*/
|
|
186
201
|
declare function createTriageFunction(modelName: string): LScriptFunction<TriageInput, typeof TriageSchema>;
|
|
187
202
|
|
|
188
|
-
export { type AgentEvent, AgentEventBus, type AgentEventType, ContextManager, ObotoAgent, type ObotoAgentConfig, type ToolExecutionEvent, type TriageResult, TriageSchema, createEmptySession, createRouterTool, createTriageFunction, fromChat, sessionToHistory, toChat };
|
|
203
|
+
export { type AgentEvent, AgentEventBus, type AgentEventType, ContextManager, ObotoAgent, type ObotoAgentConfig, type ToolExecutionEvent, type TriageResult, TriageSchema, createEmptySession, createRouterTool, createTriageFunction, fromChat, sessionToHistory, toChat, toLmscriptProvider };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
// src/oboto-agent.ts
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
LScriptRuntime,
|
|
5
|
-
AgentLoop
|
|
6
|
-
} from "@sschepis/lmscript";
|
|
2
|
+
import { LScriptRuntime } from "@sschepis/lmscript";
|
|
7
3
|
import { MessageRole as MessageRole2 } from "@sschepis/as-agent";
|
|
8
4
|
|
|
9
5
|
// src/event-bus.ts
|
|
@@ -164,6 +160,56 @@ function createRouterTool(router, root) {
|
|
|
164
160
|
};
|
|
165
161
|
}
|
|
166
162
|
|
|
163
|
+
// src/adapters/llm-wrapper.ts
|
|
164
|
+
function toLmscriptProvider(provider, name) {
|
|
165
|
+
return {
|
|
166
|
+
name: name ?? provider.providerName,
|
|
167
|
+
async chat(request) {
|
|
168
|
+
const messages = request.messages.map((m) => ({
|
|
169
|
+
role: m.role,
|
|
170
|
+
content: typeof m.content === "string" ? m.content : m.content.filter((b) => b.type === "text").map((b) => b.text).join("\n")
|
|
171
|
+
}));
|
|
172
|
+
let tools;
|
|
173
|
+
if (request.tools && request.tools.length > 0) {
|
|
174
|
+
tools = request.tools.map((t) => ({
|
|
175
|
+
type: "function",
|
|
176
|
+
function: {
|
|
177
|
+
name: t.name,
|
|
178
|
+
description: t.description,
|
|
179
|
+
parameters: t.parameters
|
|
180
|
+
}
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
const params = {
|
|
184
|
+
model: request.model,
|
|
185
|
+
messages,
|
|
186
|
+
temperature: request.temperature,
|
|
187
|
+
...tools ? { tools } : {},
|
|
188
|
+
...request.jsonMode ? { response_format: { type: "json_object" } } : {}
|
|
189
|
+
};
|
|
190
|
+
const response = await provider.chat(params);
|
|
191
|
+
const choice = response.choices[0];
|
|
192
|
+
let toolCalls;
|
|
193
|
+
if (choice?.message?.tool_calls) {
|
|
194
|
+
toolCalls = choice.message.tool_calls.map((tc) => ({
|
|
195
|
+
id: tc.id,
|
|
196
|
+
name: tc.function.name,
|
|
197
|
+
arguments: tc.function.arguments
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
content: choice?.message?.content ?? "",
|
|
202
|
+
usage: response.usage ? {
|
|
203
|
+
promptTokens: response.usage.prompt_tokens,
|
|
204
|
+
completionTokens: response.usage.completion_tokens,
|
|
205
|
+
totalTokens: response.usage.total_tokens
|
|
206
|
+
} : void 0,
|
|
207
|
+
toolCalls
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
167
213
|
// src/adapters/memory.ts
|
|
168
214
|
import {
|
|
169
215
|
MessageRole
|
|
@@ -212,13 +258,11 @@ function createEmptySession() {
|
|
|
212
258
|
}
|
|
213
259
|
|
|
214
260
|
// src/oboto-agent.ts
|
|
215
|
-
var AgentResponseSchema = z4.object({
|
|
216
|
-
response: z4.string().describe("The agent's response to the user")
|
|
217
|
-
});
|
|
218
261
|
var ObotoAgent = class {
|
|
219
262
|
bus = new AgentEventBus();
|
|
220
263
|
localRuntime;
|
|
221
|
-
|
|
264
|
+
localProvider;
|
|
265
|
+
remoteProvider;
|
|
222
266
|
contextManager;
|
|
223
267
|
routerTool;
|
|
224
268
|
triageFn;
|
|
@@ -230,8 +274,10 @@ var ObotoAgent = class {
|
|
|
230
274
|
config;
|
|
231
275
|
constructor(config) {
|
|
232
276
|
this.config = config;
|
|
233
|
-
this.
|
|
234
|
-
this.
|
|
277
|
+
this.localProvider = config.localModel;
|
|
278
|
+
this.remoteProvider = config.remoteModel;
|
|
279
|
+
const localLmscript = toLmscriptProvider(config.localModel, "local");
|
|
280
|
+
this.localRuntime = new LScriptRuntime({ provider: localLmscript });
|
|
235
281
|
this.session = config.session ?? createEmptySession();
|
|
236
282
|
this.systemPrompt = config.systemPrompt ?? "You are a helpful AI assistant with access to tools.";
|
|
237
283
|
this.maxIterations = config.maxIterations ?? 10;
|
|
@@ -330,7 +376,7 @@ var ObotoAgent = class {
|
|
|
330
376
|
this.bus.emit("turn_complete", { model: "local", escalated: false });
|
|
331
377
|
return;
|
|
332
378
|
}
|
|
333
|
-
const
|
|
379
|
+
const provider = triageResult.escalate ? this.remoteProvider : this.localProvider;
|
|
334
380
|
const modelName = triageResult.escalate ? this.config.remoteModelName : this.config.localModelName;
|
|
335
381
|
if (triageResult.escalate) {
|
|
336
382
|
this.bus.emit("agent_thought", {
|
|
@@ -339,7 +385,7 @@ var ObotoAgent = class {
|
|
|
339
385
|
escalating: true
|
|
340
386
|
});
|
|
341
387
|
}
|
|
342
|
-
await this.executeWithModel(
|
|
388
|
+
await this.executeWithModel(provider, modelName, userInput);
|
|
343
389
|
}
|
|
344
390
|
async triage(userInput) {
|
|
345
391
|
const recentMessages = this.contextManager.getMessages().slice(-5);
|
|
@@ -354,65 +400,106 @@ var ObotoAgent = class {
|
|
|
354
400
|
});
|
|
355
401
|
return result.data;
|
|
356
402
|
}
|
|
357
|
-
|
|
403
|
+
/**
|
|
404
|
+
* Execute the agent loop using llm-wrapper directly.
|
|
405
|
+
* No JSON mode, no schema enforcement — just natural chat with tool calling.
|
|
406
|
+
*/
|
|
407
|
+
async executeWithModel(provider, modelName, _userInput) {
|
|
358
408
|
const contextMessages = this.contextManager.getMessages();
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
})
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
409
|
+
const messages = contextMessages.map((m) => ({
|
|
410
|
+
role: m.role,
|
|
411
|
+
content: typeof m.content === "string" ? m.content : m.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n")
|
|
412
|
+
}));
|
|
413
|
+
const tool = this.routerTool;
|
|
414
|
+
const tools = [
|
|
415
|
+
{
|
|
416
|
+
type: "function",
|
|
417
|
+
function: {
|
|
418
|
+
name: tool.name,
|
|
419
|
+
description: tool.description,
|
|
420
|
+
parameters: tool.parameters ? JSON.parse(JSON.stringify(tool.parameters)) : { type: "object", properties: {} }
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
];
|
|
424
|
+
let totalToolCalls = 0;
|
|
425
|
+
for (let iteration = 1; iteration <= this.maxIterations; iteration++) {
|
|
426
|
+
if (this.interrupted) break;
|
|
427
|
+
const params = {
|
|
428
|
+
model: modelName,
|
|
429
|
+
messages: [...messages],
|
|
430
|
+
temperature: 0.7,
|
|
431
|
+
tools,
|
|
432
|
+
tool_choice: "auto"
|
|
433
|
+
};
|
|
434
|
+
const response = await provider.chat(params);
|
|
435
|
+
const choice = response.choices[0];
|
|
436
|
+
const content = choice?.message?.content ?? "";
|
|
437
|
+
this.bus.emit("agent_thought", {
|
|
438
|
+
text: content,
|
|
439
|
+
model: modelName,
|
|
440
|
+
iteration
|
|
441
|
+
});
|
|
442
|
+
const toolCalls = choice?.message?.tool_calls;
|
|
443
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
444
|
+
const responseText = content;
|
|
445
|
+
const assistantMsg = {
|
|
446
|
+
role: MessageRole2.Assistant,
|
|
447
|
+
blocks: [{ kind: "text", text: responseText }]
|
|
448
|
+
};
|
|
449
|
+
this.session.messages.push(assistantMsg);
|
|
450
|
+
await this.contextManager.push(toChat(assistantMsg));
|
|
451
|
+
this.bus.emit("state_updated", { reason: "assistant_response" });
|
|
452
|
+
this.bus.emit("turn_complete", {
|
|
393
453
|
model: modelName,
|
|
394
|
-
|
|
454
|
+
escalated: true,
|
|
455
|
+
iterations: iteration,
|
|
456
|
+
toolCalls: totalToolCalls
|
|
395
457
|
});
|
|
396
|
-
|
|
458
|
+
return;
|
|
397
459
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
460
|
+
messages.push({
|
|
461
|
+
role: "assistant",
|
|
462
|
+
content: content || null,
|
|
463
|
+
tool_calls: toolCalls
|
|
464
|
+
});
|
|
465
|
+
for (const tc of toolCalls) {
|
|
466
|
+
if (this.interrupted) break;
|
|
467
|
+
let args;
|
|
468
|
+
try {
|
|
469
|
+
args = JSON.parse(tc.function.arguments);
|
|
470
|
+
} catch {
|
|
471
|
+
args = {};
|
|
472
|
+
}
|
|
473
|
+
const command = args.command ?? tc.function.name;
|
|
474
|
+
const kwargs = args.kwargs ?? {};
|
|
475
|
+
this.bus.emit("tool_execution_start", { command, kwargs });
|
|
476
|
+
let result;
|
|
477
|
+
try {
|
|
478
|
+
result = await tool.execute(args);
|
|
479
|
+
} catch (err) {
|
|
480
|
+
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
481
|
+
}
|
|
482
|
+
this.bus.emit("tool_execution_complete", { command, kwargs, result });
|
|
483
|
+
totalToolCalls++;
|
|
484
|
+
messages.push({
|
|
485
|
+
role: "tool",
|
|
486
|
+
tool_call_id: tc.id,
|
|
487
|
+
content: typeof result === "string" ? result : JSON.stringify(result)
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const fallbackMsg = {
|
|
405
492
|
role: MessageRole2.Assistant,
|
|
406
|
-
blocks: [{ kind: "text", text:
|
|
493
|
+
blocks: [{ kind: "text", text: "I reached the maximum number of iterations. Here is what I have so far." }]
|
|
407
494
|
};
|
|
408
|
-
this.session.messages.push(
|
|
409
|
-
await this.contextManager.push(toChat(
|
|
410
|
-
this.bus.emit("state_updated", { reason: "
|
|
495
|
+
this.session.messages.push(fallbackMsg);
|
|
496
|
+
await this.contextManager.push(toChat(fallbackMsg));
|
|
497
|
+
this.bus.emit("state_updated", { reason: "max_iterations" });
|
|
411
498
|
this.bus.emit("turn_complete", {
|
|
412
499
|
model: modelName,
|
|
413
500
|
escalated: true,
|
|
414
|
-
iterations:
|
|
415
|
-
toolCalls:
|
|
501
|
+
iterations: this.maxIterations,
|
|
502
|
+
toolCalls: totalToolCalls
|
|
416
503
|
});
|
|
417
504
|
}
|
|
418
505
|
};
|
|
@@ -426,6 +513,7 @@ export {
|
|
|
426
513
|
createTriageFunction,
|
|
427
514
|
fromChat,
|
|
428
515
|
sessionToHistory,
|
|
429
|
-
toChat
|
|
516
|
+
toChat,
|
|
517
|
+
toLmscriptProvider
|
|
430
518
|
};
|
|
431
519
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/oboto-agent.ts","../src/event-bus.ts","../src/context-manager.ts","../src/triage.ts","../src/adapters/tools.ts","../src/adapters/memory.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n LScriptRuntime,\n AgentLoop,\n type LScriptFunction,\n type ToolDefinition,\n type ChatMessage,\n type ToolCall,\n} from \"@sschepis/lmscript\";\nimport type { Session, ConversationMessage } from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\nimport type { ObotoAgentConfig, AgentEventType, AgentEvent, TriageResult } from \"./types.js\";\nimport { AgentEventBus } from \"./event-bus.js\";\nimport { ContextManager } from \"./context-manager.js\";\nimport { createTriageFunction, type TriageInput } from \"./triage.js\";\nimport { createRouterTool } from \"./adapters/tools.js\";\nimport { toChat, fromChat, createEmptySession } from \"./adapters/memory.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/** Free-form response schema for the main agent loop. */\nconst AgentResponseSchema = z.object({\n response: z.string().describe(\"The agent's response to the user\"),\n});\n\ntype AgentInput = { userInput: string; context: string };\n\n/**\n * ObotoAgent is the central orchestrator for dual-LLM agent execution.\n *\n * It binds together:\n * - lmscript (LLM I/O via local and remote providers)\n * - swiss-army-tool (tool execution via Router)\n * - as-agent (session state and conversation history)\n *\n * All interaction flows through an event-driven architecture.\n */\nexport class ObotoAgent {\n private bus = new AgentEventBus();\n private localRuntime: LScriptRuntime;\n private remoteRuntime: LScriptRuntime;\n private contextManager: ContextManager;\n private routerTool: ToolDefinition<any, any>;\n private triageFn: ReturnType<typeof createTriageFunction>;\n private session: Session;\n private isProcessing = false;\n private interrupted = false;\n private systemPrompt: string;\n private maxIterations: number;\n private config: ObotoAgentConfig;\n\n constructor(config: ObotoAgentConfig) {\n this.config = config;\n this.localRuntime = new LScriptRuntime({ provider: config.localModel });\n this.remoteRuntime = new LScriptRuntime({ provider: config.remoteModel });\n this.session = config.session ?? createEmptySession();\n this.systemPrompt = config.systemPrompt ?? \"You are a helpful AI assistant with access to tools.\";\n this.maxIterations = config.maxIterations ?? 10;\n\n this.contextManager = new ContextManager(\n this.localRuntime,\n config.localModelName,\n config.maxContextTokens ?? 8192\n );\n\n this.routerTool = createRouterTool(config.router);\n this.triageFn = createTriageFunction(config.localModelName);\n\n // Push system prompt into context\n this.contextManager.push({\n role: \"system\",\n content: this.systemPrompt,\n });\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n /** Subscribe to agent events. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.on(type, handler);\n }\n\n /** Subscribe to an event for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.once(type, handler);\n }\n\n /** Submit user input to the agent. Triggers the execution loop. */\n async submitInput(text: string): Promise<void> {\n if (this.isProcessing) {\n this.interrupt(text);\n return;\n }\n\n this.isProcessing = true;\n this.interrupted = false;\n\n try {\n await this.executionLoop(text);\n } catch (err) {\n this.bus.emit(\"error\", {\n message: err instanceof Error ? err.message : String(err),\n error: err,\n });\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Interrupt the current execution loop.\n * Optionally inject new directives into the context.\n */\n interrupt(newDirectives?: string): void {\n this.interrupted = true;\n this.bus.emit(\"interruption\", { newDirectives });\n\n if (newDirectives) {\n const msg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: `[INTERRUPTION] ${newDirectives}` }],\n };\n this.session.messages.push(msg);\n this.contextManager.push(toChat(msg));\n this.bus.emit(\"state_updated\", { reason: \"interruption\" });\n }\n }\n\n /** Get the current session state. */\n getSession(): Session {\n return this.session;\n }\n\n /** Whether the agent is currently processing input. */\n get processing(): boolean {\n return this.isProcessing;\n }\n\n /** Remove all event listeners. */\n removeAllListeners(): void {\n this.bus.removeAllListeners();\n }\n\n // ── Internal ───────────────────────────────────────────────────────\n\n private async executionLoop(userInput: string): Promise<void> {\n // 1. Emit user_input and record in session + context\n this.bus.emit(\"user_input\", { text: userInput });\n\n const userMsg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: userInput }],\n };\n this.session.messages.push(userMsg);\n await this.contextManager.push(toChat(userMsg));\n this.bus.emit(\"state_updated\", { reason: \"user_input\" });\n\n // 2. Triage via local LLM\n const triageResult = await this.triage(userInput);\n this.bus.emit(\"triage_result\", triageResult);\n\n if (this.interrupted) return;\n\n // 3. If local can handle directly, emit and return\n if (!triageResult.escalate && triageResult.directResponse) {\n const response = triageResult.directResponse;\n this.bus.emit(\"agent_thought\", { text: response, model: \"local\" });\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: response }],\n };\n this.session.messages.push(assistantMsg);\n await this.contextManager.push(toChat(assistantMsg));\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n this.bus.emit(\"turn_complete\", { model: \"local\", escalated: false });\n return;\n }\n\n // 4. Escalate to remote model with tool access\n const runtime = triageResult.escalate ? this.remoteRuntime : this.localRuntime;\n const modelName = triageResult.escalate\n ? this.config.remoteModelName\n : this.config.localModelName;\n\n if (triageResult.escalate) {\n this.bus.emit(\"agent_thought\", {\n text: triageResult.reasoning,\n model: \"local\",\n escalating: true,\n });\n }\n\n await this.executeWithModel(runtime, modelName, userInput);\n }\n\n private async triage(userInput: string): Promise<TriageResult> {\n const recentMessages = this.contextManager.getMessages().slice(-5);\n const recentContext = recentMessages\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const result = await this.localRuntime.execute(this.triageFn, {\n userInput,\n recentContext,\n availableTools: this.routerTool.description,\n });\n\n return result.data;\n }\n\n private async executeWithModel(\n runtime: LScriptRuntime,\n modelName: string,\n userInput: string\n ): Promise<void> {\n const contextMessages = this.contextManager.getMessages();\n const contextStr = contextMessages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const agentFn: LScriptFunction<AgentInput, typeof AgentResponseSchema> = {\n name: \"agent_execute\",\n model: modelName,\n system: this.systemPrompt,\n prompt: ({ context }) =>\n context\n ? `Conversation so far:\\n${context}\\n\\nRespond to the user's latest message. Use tools when needed.`\n : `Respond to the user.`,\n schema: AgentResponseSchema,\n temperature: 0.7,\n tools: [this.routerTool],\n };\n\n const agent = new AgentLoop(runtime, {\n maxIterations: this.maxIterations,\n onToolCall: (toolCall: ToolCall) => {\n const args = toolCall.arguments as { command?: string; kwargs?: Record<string, unknown> } | undefined;\n this.bus.emit(\"tool_execution_start\", {\n command: args?.command ?? toolCall.name,\n kwargs: args?.kwargs ?? {},\n });\n this.bus.emit(\"tool_execution_complete\", {\n command: args?.command ?? toolCall.name,\n kwargs: args?.kwargs ?? {},\n result: toolCall.result,\n });\n\n // Check for interruption\n if (this.interrupted) return false;\n },\n onIteration: (_iteration: number, response: string) => {\n this.bus.emit(\"agent_thought\", {\n text: response,\n model: modelName,\n iteration: _iteration,\n });\n if (this.interrupted) return false;\n },\n });\n\n const result = await agent.run(agentFn, {\n userInput,\n context: contextStr,\n });\n\n // Record final response in session and context\n const responseText = result.data.response;\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: responseText }],\n };\n this.session.messages.push(assistantMsg);\n await this.contextManager.push(toChat(assistantMsg));\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: result.iterations,\n toolCalls: result.toolCalls.length,\n });\n }\n}\n","import type { AgentEventType, AgentEvent } from \"./types.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * Platform-agnostic typed event bus.\n * Uses a plain Map instead of Node.js EventEmitter for browser/Deno/Bun compatibility.\n */\nexport class AgentEventBus {\n private listeners = new Map<AgentEventType, Set<EventHandler>>();\n\n /** Subscribe to an event type. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(handler);\n return () => this.off(type, handler);\n }\n\n /** Unsubscribe a handler from an event type. */\n off(type: AgentEventType, handler: EventHandler): void {\n this.listeners.get(type)?.delete(handler);\n }\n\n /** Subscribe to an event type for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n const wrapper: EventHandler = (event) => {\n this.off(type, wrapper);\n handler(event);\n };\n return this.on(type, wrapper);\n }\n\n /** Emit an event to all subscribers. */\n emit(type: AgentEventType, payload: unknown): void {\n const event: AgentEvent = {\n type,\n payload,\n timestamp: Date.now(),\n };\n const handlers = this.listeners.get(type);\n if (handlers) {\n for (const handler of handlers) {\n handler(event);\n }\n }\n }\n\n /** Remove all listeners for all event types. */\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import { z } from \"zod\";\nimport { ContextStack, type LScriptRuntime, type ChatMessage, type LScriptFunction } from \"@sschepis/lmscript\";\n\nconst SummarySchema = z.object({\n summary: z.string().describe(\"A dense summary of the conversation so far\"),\n});\n\ntype SummaryInput = { conversation: string };\n\n/**\n * Manages the sliding context window with automatic summarization.\n * Wraps lmscript's ContextStack and uses the local LLM for compression.\n */\nexport class ContextManager {\n private stack: ContextStack;\n private summarizeFn: LScriptFunction<SummaryInput, typeof SummarySchema>;\n\n constructor(\n private localRuntime: LScriptRuntime,\n localModelName: string,\n maxTokens: number\n ) {\n this.stack = new ContextStack({\n maxTokens,\n pruneStrategy: \"summarize\",\n });\n\n this.summarizeFn = {\n name: \"summarize_context\",\n model: localModelName,\n system:\n \"You are a summarization engine. Compress the given conversation into a dense, factual summary that preserves all key information, decisions, and context needed for continued operation. Be concise but thorough.\",\n prompt: ({ conversation }) => conversation,\n schema: SummarySchema,\n temperature: 0.2,\n maxRetries: 1,\n };\n\n this.stack.setSummarizer(async (messages: ChatMessage[]) => {\n const conversation = messages\n .map((m) => {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\" \");\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const result = await this.localRuntime.execute(this.summarizeFn, {\n conversation,\n });\n return result.data.summary;\n });\n }\n\n /** Append a message to the context. Triggers pruning if over budget. */\n async push(message: ChatMessage): Promise<void> {\n await this.stack.push(message);\n }\n\n /** Append multiple messages. */\n async pushAll(messages: ChatMessage[]): Promise<void> {\n await this.stack.pushAll(messages);\n }\n\n /** Get all messages in the current context window. */\n getMessages(): ChatMessage[] {\n return this.stack.getMessages();\n }\n\n /** Get estimated token count. */\n getTokenCount(): number {\n return this.stack.getTokenCount();\n }\n\n /** Clear all context. */\n clear(): void {\n this.stack.clear();\n }\n}\n","import { z } from \"zod\";\nimport type { LScriptFunction } from \"@sschepis/lmscript\";\n\n/** Zod schema for structured triage output. */\nexport const TriageSchema = z.object({\n escalate: z\n .boolean()\n .describe(\"True if the request needs a powerful model, false if answerable directly\"),\n reasoning: z\n .string()\n .describe(\"Brief explanation of the triage decision\"),\n directResponse: z\n .string()\n .optional()\n .describe(\"Direct answer if the request can be handled without escalation\"),\n});\n\nexport type TriageInput = {\n userInput: string;\n recentContext: string;\n availableTools: string;\n};\n\nconst TRIAGE_SYSTEM = `You are a fast triage classifier for an AI agent system.\nYour job is to decide whether a user's request can be answered directly (simple queries,\ncasual chat, short lookups) or needs to be escalated to a more powerful model\n(complex reasoning, multi-step tool usage, code generation, analysis).\n\nRules:\n- If the request is a greeting, simple question, or casual conversation: respond directly.\n- If the request needs tool calls, code analysis, or multi-step reasoning: escalate.\n- If unsure, escalate. It's better to over-escalate than to give a poor direct answer.\n- Keep directResponse under 200 words when answering directly.\n\nRespond with JSON matching the schema.`;\n\n/**\n * Create an LScriptFunction for local-LLM triage classification.\n * The local model evaluates whether input needs escalation to the remote model.\n */\nexport function createTriageFunction(\n modelName: string\n): LScriptFunction<TriageInput, typeof TriageSchema> {\n return {\n name: \"triage\",\n model: modelName,\n system: TRIAGE_SYSTEM,\n prompt: ({ userInput, recentContext, availableTools }) =>\n `Recent context:\\n${recentContext}\\n\\nAvailable tools: ${availableTools}\\n\\nUser: ${userInput}`,\n schema: TriageSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n}\n","import { z } from \"zod\";\nimport type { Router } from \"@sschepis/swiss-army-tool\";\nimport { generateToolSchema } from \"@sschepis/swiss-army-tool\";\nimport type { ToolDefinition } from \"@sschepis/lmscript\";\nimport type { BranchNode } from \"@sschepis/swiss-army-tool\";\n\n/** Parameter schema for the omni-tool bridge. */\nconst RouterToolParams = z.object({\n command: z.string().describe(\n \"The command or menu path (e.g., 'help', 'filesystem read', 'db query')\"\n ),\n kwargs: z\n .record(z.unknown())\n .optional()\n .default({})\n .describe(\"Key-value arguments for the command\"),\n});\n\n/**\n * Bridge a swiss-army-tool Router into an lmscript ToolDefinition.\n *\n * The LLM sees a single tool (\"terminal_interface\") with `command` and `kwargs`\n * parameters. When called, it routes through the swiss-army-tool command tree.\n */\nexport function createRouterTool(\n router: Router,\n root?: BranchNode\n): ToolDefinition<typeof RouterToolParams, string> {\n const schema = generateToolSchema({ root });\n\n return {\n name: schema.name,\n description: schema.description,\n parameters: RouterToolParams,\n execute: async (params) => {\n return router.execute(params.command, params.kwargs ?? {});\n },\n };\n}\n","import {\n MessageRole,\n type ConversationMessage,\n type ContentBlock as AsContentBlock,\n type Session,\n} from \"@sschepis/as-agent\";\nimport type { ChatMessage, Role } from \"@sschepis/lmscript\";\n\nconst ROLE_TO_STRING: Record<MessageRole, Role> = {\n [MessageRole.System]: \"system\",\n [MessageRole.User]: \"user\",\n [MessageRole.Assistant]: \"assistant\",\n [MessageRole.Tool]: \"user\",\n};\n\nconst STRING_TO_ROLE: Record<Role, MessageRole> = {\n system: MessageRole.System,\n user: MessageRole.User,\n assistant: MessageRole.Assistant,\n};\n\n/** Extract plain text from as-agent content blocks. */\nfunction blocksToText(blocks: AsContentBlock[]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool call: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Tool error (${b.toolName}): ${b.output}]`\n : `[Tool result (${b.toolName}): ${b.output}]`;\n }\n })\n .join(\"\\n\");\n}\n\n/** Convert an as-agent ConversationMessage to an lmscript ChatMessage. */\nexport function toChat(msg: ConversationMessage): ChatMessage {\n return {\n role: ROLE_TO_STRING[msg.role] ?? \"user\",\n content: blocksToText(msg.blocks),\n };\n}\n\n/** Convert an lmscript ChatMessage to an as-agent ConversationMessage. */\nexport function fromChat(msg: ChatMessage): ConversationMessage {\n const text = typeof msg.content === \"string\"\n ? msg.content\n : msg.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\"\\n\");\n\n return {\n role: STRING_TO_ROLE[msg.role] ?? MessageRole.User,\n blocks: [{ kind: \"text\", text }],\n };\n}\n\n/** Convert an entire as-agent Session to an array of lmscript ChatMessages. */\nexport function sessionToHistory(session: Session): ChatMessage[] {\n return session.messages.map(toChat);\n}\n\n/** Create an empty as-agent Session. */\nexport function createEmptySession(): Session {\n return { version: 1, messages: [] };\n}\n"],"mappings":"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","names":["z","MessageRole","z","z","z","MessageRole"]}
|
|
1
|
+
{"version":3,"sources":["../src/oboto-agent.ts","../src/event-bus.ts","../src/context-manager.ts","../src/triage.ts","../src/adapters/tools.ts","../src/adapters/llm-wrapper.ts","../src/adapters/memory.ts"],"sourcesContent":["import { LScriptRuntime, type ToolDefinition, type ChatMessage } from \"@sschepis/lmscript\";\nimport type {\n BaseProvider,\n StandardChatParams,\n Message as WrapperMessage,\n ToolDefinition as WrapperToolDef,\n StandardChatResponse,\n} from \"@sschepis/llm-wrapper\";\nimport type { Session, ConversationMessage } from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\nimport type { ObotoAgentConfig, AgentEventType, AgentEvent, TriageResult } from \"./types.js\";\nimport { AgentEventBus } from \"./event-bus.js\";\nimport { ContextManager } from \"./context-manager.js\";\nimport { createTriageFunction } from \"./triage.js\";\nimport { createRouterTool } from \"./adapters/tools.js\";\nimport { toLmscriptProvider } from \"./adapters/llm-wrapper.js\";\nimport { toChat, createEmptySession } from \"./adapters/memory.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * ObotoAgent is the central orchestrator for dual-LLM agent execution.\n *\n * It binds together:\n * - llm-wrapper (LLM communication via local and remote providers)\n * - lmscript (structured/schema-validated calls for triage)\n * - swiss-army-tool (tool execution via Router)\n * - as-agent (session state and conversation history)\n *\n * All interaction flows through an event-driven architecture.\n */\nexport class ObotoAgent {\n private bus = new AgentEventBus();\n private localRuntime: LScriptRuntime;\n private localProvider: BaseProvider;\n private remoteProvider: BaseProvider;\n private contextManager: ContextManager;\n private routerTool: ToolDefinition<any, any>;\n private triageFn: ReturnType<typeof createTriageFunction>;\n private session: Session;\n private isProcessing = false;\n private interrupted = false;\n private systemPrompt: string;\n private maxIterations: number;\n private config: ObotoAgentConfig;\n\n constructor(config: ObotoAgentConfig) {\n this.config = config;\n this.localProvider = config.localModel;\n this.remoteProvider = config.remoteModel;\n\n // Wrap llm-wrapper providers into lmscript LLMProvider for structured calls (triage)\n const localLmscript = toLmscriptProvider(config.localModel, \"local\");\n this.localRuntime = new LScriptRuntime({ provider: localLmscript });\n\n this.session = config.session ?? createEmptySession();\n this.systemPrompt = config.systemPrompt ?? \"You are a helpful AI assistant with access to tools.\";\n this.maxIterations = config.maxIterations ?? 10;\n\n this.contextManager = new ContextManager(\n this.localRuntime,\n config.localModelName,\n config.maxContextTokens ?? 8192\n );\n\n this.routerTool = createRouterTool(config.router);\n this.triageFn = createTriageFunction(config.localModelName);\n\n // Push system prompt into context\n this.contextManager.push({\n role: \"system\",\n content: this.systemPrompt,\n });\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n /** Subscribe to agent events. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.on(type, handler);\n }\n\n /** Subscribe to an event for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.once(type, handler);\n }\n\n /** Submit user input to the agent. Triggers the execution loop. */\n async submitInput(text: string): Promise<void> {\n if (this.isProcessing) {\n this.interrupt(text);\n return;\n }\n\n this.isProcessing = true;\n this.interrupted = false;\n\n try {\n await this.executionLoop(text);\n } catch (err) {\n this.bus.emit(\"error\", {\n message: err instanceof Error ? err.message : String(err),\n error: err,\n });\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Interrupt the current execution loop.\n * Optionally inject new directives into the context.\n */\n interrupt(newDirectives?: string): void {\n this.interrupted = true;\n this.bus.emit(\"interruption\", { newDirectives });\n\n if (newDirectives) {\n const msg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: `[INTERRUPTION] ${newDirectives}` }],\n };\n this.session.messages.push(msg);\n this.contextManager.push(toChat(msg));\n this.bus.emit(\"state_updated\", { reason: \"interruption\" });\n }\n }\n\n /** Get the current session state. */\n getSession(): Session {\n return this.session;\n }\n\n /** Whether the agent is currently processing input. */\n get processing(): boolean {\n return this.isProcessing;\n }\n\n /** Remove all event listeners. */\n removeAllListeners(): void {\n this.bus.removeAllListeners();\n }\n\n // ── Internal ───────────────────────────────────────────────────────\n\n private async executionLoop(userInput: string): Promise<void> {\n // 1. Emit user_input and record in session + context\n this.bus.emit(\"user_input\", { text: userInput });\n\n const userMsg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: userInput }],\n };\n this.session.messages.push(userMsg);\n await this.contextManager.push(toChat(userMsg));\n this.bus.emit(\"state_updated\", { reason: \"user_input\" });\n\n // 2. Triage via local LLM (uses lmscript for structured output)\n const triageResult = await this.triage(userInput);\n this.bus.emit(\"triage_result\", triageResult);\n\n if (this.interrupted) return;\n\n // 3. If local can handle directly, emit and return\n if (!triageResult.escalate && triageResult.directResponse) {\n const response = triageResult.directResponse;\n this.bus.emit(\"agent_thought\", { text: response, model: \"local\" });\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: response }],\n };\n this.session.messages.push(assistantMsg);\n await this.contextManager.push(toChat(assistantMsg));\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n this.bus.emit(\"turn_complete\", { model: \"local\", escalated: false });\n return;\n }\n\n // 4. Escalate to remote model with tool access\n const provider = triageResult.escalate ? this.remoteProvider : this.localProvider;\n const modelName = triageResult.escalate\n ? this.config.remoteModelName\n : this.config.localModelName;\n\n if (triageResult.escalate) {\n this.bus.emit(\"agent_thought\", {\n text: triageResult.reasoning,\n model: \"local\",\n escalating: true,\n });\n }\n\n await this.executeWithModel(provider, modelName, userInput);\n }\n\n private async triage(userInput: string): Promise<TriageResult> {\n const recentMessages = this.contextManager.getMessages().slice(-5);\n const recentContext = recentMessages\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const result = await this.localRuntime.execute(this.triageFn, {\n userInput,\n recentContext,\n availableTools: this.routerTool.description,\n });\n\n return result.data;\n }\n\n /**\n * Execute the agent loop using llm-wrapper directly.\n * No JSON mode, no schema enforcement — just natural chat with tool calling.\n */\n private async executeWithModel(\n provider: BaseProvider,\n modelName: string,\n _userInput: string\n ): Promise<void> {\n // Build messages from context manager (includes system prompt + history)\n const contextMessages = this.contextManager.getMessages();\n\n // Convert lmscript ChatMessages → llm-wrapper Messages\n const messages: WrapperMessage[] = contextMessages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : (m.content as Array<{ type: string; text?: string }>)\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\\n\"),\n }));\n\n // Build llm-wrapper tool definitions from the router tool\n const tool = this.routerTool;\n const tools: WrapperToolDef[] = [\n {\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n ? JSON.parse(JSON.stringify(tool.parameters))\n : { type: \"object\", properties: {} },\n },\n },\n ];\n\n let totalToolCalls = 0;\n\n for (let iteration = 1; iteration <= this.maxIterations; iteration++) {\n if (this.interrupted) break;\n\n const params: StandardChatParams = {\n model: modelName,\n messages: [...messages],\n temperature: 0.7,\n tools,\n tool_choice: \"auto\",\n };\n\n const response: StandardChatResponse = await provider.chat(params);\n const choice = response.choices[0];\n const content = (choice?.message?.content as string) ?? \"\";\n\n // Emit thought for each iteration\n this.bus.emit(\"agent_thought\", {\n text: content,\n model: modelName,\n iteration,\n });\n\n // If no tool calls, this is the final response\n const toolCalls = choice?.message?.tool_calls;\n if (!toolCalls || toolCalls.length === 0) {\n const responseText = content;\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: responseText }],\n };\n this.session.messages.push(assistantMsg);\n await this.contextManager.push(toChat(assistantMsg));\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: iteration,\n toolCalls: totalToolCalls,\n });\n return;\n }\n\n // Append assistant message (with tool_calls) to conversation\n messages.push({\n role: \"assistant\",\n content: content || null,\n tool_calls: toolCalls,\n });\n\n // Execute each tool call and feed results back\n for (const tc of toolCalls) {\n if (this.interrupted) break;\n\n let args: Record<string, unknown>;\n try {\n args = JSON.parse(tc.function.arguments);\n } catch {\n args = {};\n }\n\n const command = (args.command as string) ?? tc.function.name;\n const kwargs = (args.kwargs as Record<string, unknown>) ?? {};\n\n this.bus.emit(\"tool_execution_start\", { command, kwargs });\n\n let result: string;\n try {\n result = await tool.execute(args);\n } catch (err) {\n result = `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n\n this.bus.emit(\"tool_execution_complete\", { command, kwargs, result });\n totalToolCalls++;\n\n // Feed tool result back as a tool message (OpenAI format)\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: typeof result === \"string\" ? result : JSON.stringify(result),\n });\n }\n }\n\n // Exhausted iterations\n const fallbackMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: \"I reached the maximum number of iterations. Here is what I have so far.\" }],\n };\n this.session.messages.push(fallbackMsg);\n await this.contextManager.push(toChat(fallbackMsg));\n this.bus.emit(\"state_updated\", { reason: \"max_iterations\" });\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: this.maxIterations,\n toolCalls: totalToolCalls,\n });\n }\n}\n","import type { AgentEventType, AgentEvent } from \"./types.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * Platform-agnostic typed event bus.\n * Uses a plain Map instead of Node.js EventEmitter for browser/Deno/Bun compatibility.\n */\nexport class AgentEventBus {\n private listeners = new Map<AgentEventType, Set<EventHandler>>();\n\n /** Subscribe to an event type. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(handler);\n return () => this.off(type, handler);\n }\n\n /** Unsubscribe a handler from an event type. */\n off(type: AgentEventType, handler: EventHandler): void {\n this.listeners.get(type)?.delete(handler);\n }\n\n /** Subscribe to an event type for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n const wrapper: EventHandler = (event) => {\n this.off(type, wrapper);\n handler(event);\n };\n return this.on(type, wrapper);\n }\n\n /** Emit an event to all subscribers. */\n emit(type: AgentEventType, payload: unknown): void {\n const event: AgentEvent = {\n type,\n payload,\n timestamp: Date.now(),\n };\n const handlers = this.listeners.get(type);\n if (handlers) {\n for (const handler of handlers) {\n handler(event);\n }\n }\n }\n\n /** Remove all listeners for all event types. */\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import { z } from \"zod\";\nimport { ContextStack, type LScriptRuntime, type ChatMessage, type LScriptFunction } from \"@sschepis/lmscript\";\n\nconst SummarySchema = z.object({\n summary: z.string().describe(\"A dense summary of the conversation so far\"),\n});\n\ntype SummaryInput = { conversation: string };\n\n/**\n * Manages the sliding context window with automatic summarization.\n * Wraps lmscript's ContextStack and uses the local LLM for compression.\n */\nexport class ContextManager {\n private stack: ContextStack;\n private summarizeFn: LScriptFunction<SummaryInput, typeof SummarySchema>;\n\n constructor(\n private localRuntime: LScriptRuntime,\n localModelName: string,\n maxTokens: number\n ) {\n this.stack = new ContextStack({\n maxTokens,\n pruneStrategy: \"summarize\",\n });\n\n this.summarizeFn = {\n name: \"summarize_context\",\n model: localModelName,\n system:\n \"You are a summarization engine. Compress the given conversation into a dense, factual summary that preserves all key information, decisions, and context needed for continued operation. Be concise but thorough.\",\n prompt: ({ conversation }) => conversation,\n schema: SummarySchema,\n temperature: 0.2,\n maxRetries: 1,\n };\n\n this.stack.setSummarizer(async (messages: ChatMessage[]) => {\n const conversation = messages\n .map((m) => {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\" \");\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const result = await this.localRuntime.execute(this.summarizeFn, {\n conversation,\n });\n return result.data.summary;\n });\n }\n\n /** Append a message to the context. Triggers pruning if over budget. */\n async push(message: ChatMessage): Promise<void> {\n await this.stack.push(message);\n }\n\n /** Append multiple messages. */\n async pushAll(messages: ChatMessage[]): Promise<void> {\n await this.stack.pushAll(messages);\n }\n\n /** Get all messages in the current context window. */\n getMessages(): ChatMessage[] {\n return this.stack.getMessages();\n }\n\n /** Get estimated token count. */\n getTokenCount(): number {\n return this.stack.getTokenCount();\n }\n\n /** Clear all context. */\n clear(): void {\n this.stack.clear();\n }\n}\n","import { z } from \"zod\";\nimport type { LScriptFunction } from \"@sschepis/lmscript\";\n\n/** Zod schema for structured triage output. */\nexport const TriageSchema = z.object({\n escalate: z\n .boolean()\n .describe(\"True if the request needs a powerful model, false if answerable directly\"),\n reasoning: z\n .string()\n .describe(\"Brief explanation of the triage decision\"),\n directResponse: z\n .string()\n .optional()\n .describe(\"Direct answer if the request can be handled without escalation\"),\n});\n\nexport type TriageInput = {\n userInput: string;\n recentContext: string;\n availableTools: string;\n};\n\nconst TRIAGE_SYSTEM = `You are a fast triage classifier for an AI agent system.\nYour job is to decide whether a user's request can be answered directly (simple queries,\ncasual chat, short lookups) or needs to be escalated to a more powerful model\n(complex reasoning, multi-step tool usage, code generation, analysis).\n\nRules:\n- If the request is a greeting, simple question, or casual conversation: respond directly.\n- If the request needs tool calls, code analysis, or multi-step reasoning: escalate.\n- If unsure, escalate. It's better to over-escalate than to give a poor direct answer.\n- Keep directResponse under 200 words when answering directly.\n\nRespond with JSON matching the schema.`;\n\n/**\n * Create an LScriptFunction for local-LLM triage classification.\n * The local model evaluates whether input needs escalation to the remote model.\n */\nexport function createTriageFunction(\n modelName: string\n): LScriptFunction<TriageInput, typeof TriageSchema> {\n return {\n name: \"triage\",\n model: modelName,\n system: TRIAGE_SYSTEM,\n prompt: ({ userInput, recentContext, availableTools }) =>\n `Recent context:\\n${recentContext}\\n\\nAvailable tools: ${availableTools}\\n\\nUser: ${userInput}`,\n schema: TriageSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n}\n","import { z } from \"zod\";\nimport type { Router } from \"@sschepis/swiss-army-tool\";\nimport { generateToolSchema } from \"@sschepis/swiss-army-tool\";\nimport type { ToolDefinition } from \"@sschepis/lmscript\";\nimport type { BranchNode } from \"@sschepis/swiss-army-tool\";\n\n/** Parameter schema for the omni-tool bridge. */\nconst RouterToolParams = z.object({\n command: z.string().describe(\n \"The command or menu path (e.g., 'help', 'filesystem read', 'db query')\"\n ),\n kwargs: z\n .record(z.unknown())\n .optional()\n .default({})\n .describe(\"Key-value arguments for the command\"),\n});\n\n/**\n * Bridge a swiss-army-tool Router into an lmscript ToolDefinition.\n *\n * The LLM sees a single tool (\"terminal_interface\") with `command` and `kwargs`\n * parameters. When called, it routes through the swiss-army-tool command tree.\n */\nexport function createRouterTool(\n router: Router,\n root?: BranchNode\n): ToolDefinition<typeof RouterToolParams, string> {\n const schema = generateToolSchema({ root });\n\n return {\n name: schema.name,\n description: schema.description,\n parameters: RouterToolParams,\n execute: async (params) => {\n return router.execute(params.command, params.kwargs ?? {});\n },\n };\n}\n","import type { LLMProvider, LLMRequest, LLMResponse } from \"@sschepis/lmscript\";\nimport type {\n BaseProvider,\n StandardChatParams,\n Message,\n ToolDefinition as WrapperToolDef,\n} from \"@sschepis/llm-wrapper\";\n\n/**\n * Adapt a llm-wrapper BaseProvider into lmscript's LLMProvider interface.\n *\n * This allows lmscript's LScriptRuntime to use llm-wrapper providers for\n * structured calls (e.g. triage) that need schema validation.\n */\nexport function toLmscriptProvider(\n provider: BaseProvider,\n name?: string\n): LLMProvider {\n return {\n name: name ?? provider.providerName,\n\n async chat(request: LLMRequest): Promise<LLMResponse> {\n // Convert lmscript messages → llm-wrapper messages\n const messages: Message[] = request.messages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { type: \"text\"; text: string }).text)\n .join(\"\\n\"),\n }));\n\n // Convert lmscript tools → llm-wrapper tool definitions\n let tools: WrapperToolDef[] | undefined;\n if (request.tools && request.tools.length > 0) {\n tools = request.tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters as Record<string, unknown>,\n },\n }));\n }\n\n const params: StandardChatParams = {\n model: request.model,\n messages,\n temperature: request.temperature,\n ...(tools ? { tools } : {}),\n ...(request.jsonMode\n ? { response_format: { type: \"json_object\" as const } }\n : {}),\n };\n\n const response = await provider.chat(params);\n const choice = response.choices[0];\n\n // Convert tool calls back to lmscript format\n let toolCalls: LLMResponse[\"toolCalls\"];\n if (choice?.message?.tool_calls) {\n toolCalls = choice.message.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }));\n }\n\n return {\n content: (choice?.message?.content as string) ?? \"\",\n usage: response.usage\n ? {\n promptTokens: response.usage.prompt_tokens,\n completionTokens: response.usage.completion_tokens,\n totalTokens: response.usage.total_tokens,\n }\n : undefined,\n toolCalls,\n };\n },\n };\n}\n","import {\n MessageRole,\n type ConversationMessage,\n type ContentBlock as AsContentBlock,\n type Session,\n} from \"@sschepis/as-agent\";\nimport type { ChatMessage, Role } from \"@sschepis/lmscript\";\n\nconst ROLE_TO_STRING: Record<MessageRole, Role> = {\n [MessageRole.System]: \"system\",\n [MessageRole.User]: \"user\",\n [MessageRole.Assistant]: \"assistant\",\n [MessageRole.Tool]: \"user\",\n};\n\nconst STRING_TO_ROLE: Record<Role, MessageRole> = {\n system: MessageRole.System,\n user: MessageRole.User,\n assistant: MessageRole.Assistant,\n};\n\n/** Extract plain text from as-agent content blocks. */\nfunction blocksToText(blocks: AsContentBlock[]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool call: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Tool error (${b.toolName}): ${b.output}]`\n : `[Tool result (${b.toolName}): ${b.output}]`;\n }\n })\n .join(\"\\n\");\n}\n\n/** Convert an as-agent ConversationMessage to an lmscript ChatMessage. */\nexport function toChat(msg: ConversationMessage): ChatMessage {\n return {\n role: ROLE_TO_STRING[msg.role] ?? \"user\",\n content: blocksToText(msg.blocks),\n };\n}\n\n/** Convert an lmscript ChatMessage to an as-agent ConversationMessage. */\nexport function fromChat(msg: ChatMessage): ConversationMessage {\n const text = typeof msg.content === \"string\"\n ? msg.content\n : msg.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\"\\n\");\n\n return {\n role: STRING_TO_ROLE[msg.role] ?? MessageRole.User,\n blocks: [{ kind: \"text\", text }],\n };\n}\n\n/** Convert an entire as-agent Session to an array of lmscript ChatMessages. */\nexport function sessionToHistory(session: Session): ChatMessage[] {\n return session.messages.map(toChat);\n}\n\n/** Create an empty as-agent Session. */\nexport function createEmptySession(): Session {\n return { version: 1, messages: [] };\n}\n"],"mappings":";AAAA,SAAS,sBAA6D;AAStE,SAAS,eAAAA,oBAAmB;;;ACDrB,IAAM,gBAAN,MAAoB;AAAA,EACjB,YAAY,oBAAI,IAAuC;AAAA;AAAA,EAG/D,GAAG,MAAsB,SAAmC;AAC1D,QAAI,CAAC,KAAK,UAAU,IAAI,IAAI,GAAG;AAC7B,WAAK,UAAU,IAAI,MAAM,oBAAI,IAAI,CAAC;AAAA,IACpC;AACA,SAAK,UAAU,IAAI,IAAI,EAAG,IAAI,OAAO;AACrC,WAAO,MAAM,KAAK,IAAI,MAAM,OAAO;AAAA,EACrC;AAAA;AAAA,EAGA,IAAI,MAAsB,SAA6B;AACrD,SAAK,UAAU,IAAI,IAAI,GAAG,OAAO,OAAO;AAAA,EAC1C;AAAA;AAAA,EAGA,KAAK,MAAsB,SAAmC;AAC5D,UAAM,UAAwB,CAAC,UAAU;AACvC,WAAK,IAAI,MAAM,OAAO;AACtB,cAAQ,KAAK;AAAA,IACf;AACA,WAAO,KAAK,GAAG,MAAM,OAAO;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAK,MAAsB,SAAwB;AACjD,UAAM,QAAoB;AAAA,MACxB;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,IACtB;AACA,UAAM,WAAW,KAAK,UAAU,IAAI,IAAI;AACxC,QAAI,UAAU;AACZ,iBAAW,WAAW,UAAU;AAC9B,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,qBAA2B;AACzB,SAAK,UAAU,MAAM;AAAA,EACvB;AACF;;;ACrDA,SAAS,SAAS;AAClB,SAAS,oBAAiF;AAE1F,IAAM,gBAAgB,EAAE,OAAO;AAAA,EAC7B,SAAS,EAAE,OAAO,EAAE,SAAS,4CAA4C;AAC3E,CAAC;AAQM,IAAM,iBAAN,MAAqB;AAAA,EAI1B,YACU,cACR,gBACA,WACA;AAHQ;AAIR,SAAK,QAAQ,IAAI,aAAa;AAAA,MAC5B;AAAA,MACA,eAAe;AAAA,IACjB,CAAC;AAED,SAAK,cAAc;AAAA,MACjB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QACE;AAAA,MACF,QAAQ,CAAC,EAAE,aAAa,MAAM;AAAA,MAC9B,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,YAAY;AAAA,IACd;AAEA,SAAK,MAAM,cAAc,OAAO,aAA4B;AAC1D,YAAM,eAAe,SAClB,IAAI,CAAC,MAAM;AACV,cAAM,OACJ,OAAO,EAAE,YAAY,WACjB,EAAE,UACF,EAAE,QACC,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAO,EAAuB,IAAI,EACvC,KAAK,GAAG;AACjB,eAAO,GAAG,EAAE,IAAI,KAAK,IAAI;AAAA,MAC3B,CAAC,EACA,KAAK,IAAI;AAEZ,YAAM,SAAS,MAAM,KAAK,aAAa,QAAQ,KAAK,aAAa;AAAA,QAC/D;AAAA,MACF,CAAC;AACD,aAAO,OAAO,KAAK;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAvCU;AAAA,EAJF;AAAA,EACA;AAAA;AAAA,EA6CR,MAAM,KAAK,SAAqC;AAC9C,UAAM,KAAK,MAAM,KAAK,OAAO;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,QAAQ,UAAwC;AACpD,UAAM,KAAK,MAAM,QAAQ,QAAQ;AAAA,EACnC;AAAA;AAAA,EAGA,cAA6B;AAC3B,WAAO,KAAK,MAAM,YAAY;AAAA,EAChC;AAAA;AAAA,EAGA,gBAAwB;AACtB,WAAO,KAAK,MAAM,cAAc;AAAA,EAClC;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AACF;;;ACnFA,SAAS,KAAAC,UAAS;AAIX,IAAM,eAAeA,GAAE,OAAO;AAAA,EACnC,UAAUA,GACP,QAAQ,EACR,SAAS,0EAA0E;AAAA,EACtF,WAAWA,GACR,OAAO,EACP,SAAS,0CAA0C;AAAA,EACtD,gBAAgBA,GACb,OAAO,EACP,SAAS,EACT,SAAS,gEAAgE;AAC9E,CAAC;AAQD,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBf,SAAS,qBACd,WACmD;AACnD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ,CAAC,EAAE,WAAW,eAAe,eAAe,MAClD;AAAA,EAAoB,aAAa;AAAA;AAAA,mBAAwB,cAAc;AAAA;AAAA,QAAa,SAAS;AAAA,IAC/F,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AACF;;;ACrDA,SAAS,KAAAC,UAAS;AAElB,SAAS,0BAA0B;AAKnC,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EAChC,SAASA,GAAE,OAAO,EAAE;AAAA,IAClB;AAAA,EACF;AAAA,EACA,QAAQA,GACL,OAAOA,GAAE,QAAQ,CAAC,EAClB,SAAS,EACT,QAAQ,CAAC,CAAC,EACV,SAAS,qCAAqC;AACnD,CAAC;AAQM,SAAS,iBACd,QACA,MACiD;AACjD,QAAM,SAAS,mBAAmB,EAAE,KAAK,CAAC;AAE1C,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,aAAa,OAAO;AAAA,IACpB,YAAY;AAAA,IACZ,SAAS,OAAO,WAAW;AACzB,aAAO,OAAO,QAAQ,OAAO,SAAS,OAAO,UAAU,CAAC,CAAC;AAAA,IAC3D;AAAA,EACF;AACF;;;ACxBO,SAAS,mBACd,UACA,MACa;AACb,SAAO;AAAA,IACL,MAAM,QAAQ,SAAS;AAAA,IAEvB,MAAM,KAAK,SAA2C;AAEpD,YAAM,WAAsB,QAAQ,SAAS,IAAI,CAAC,OAAO;AAAA,QACvD,MAAM,EAAE;AAAA,QACR,SACE,OAAO,EAAE,YAAY,WACjB,EAAE,UACF,EAAE,QACC,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAO,EAAqC,IAAI,EACrD,KAAK,IAAI;AAAA,MACpB,EAAE;AAGF,UAAI;AACJ,UAAI,QAAQ,SAAS,QAAQ,MAAM,SAAS,GAAG;AAC7C,gBAAQ,QAAQ,MAAM,IAAI,CAAC,OAAO;AAAA,UAChC,MAAM;AAAA,UACN,UAAU;AAAA,YACR,MAAM,EAAE;AAAA,YACR,aAAa,EAAE;AAAA,YACf,YAAY,EAAE;AAAA,UAChB;AAAA,QACF,EAAE;AAAA,MACJ;AAEA,YAAM,SAA6B;AAAA,QACjC,OAAO,QAAQ;AAAA,QACf;AAAA,QACA,aAAa,QAAQ;AAAA,QACrB,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QACzB,GAAI,QAAQ,WACR,EAAE,iBAAiB,EAAE,MAAM,cAAuB,EAAE,IACpD,CAAC;AAAA,MACP;AAEA,YAAM,WAAW,MAAM,SAAS,KAAK,MAAM;AAC3C,YAAM,SAAS,SAAS,QAAQ,CAAC;AAGjC,UAAI;AACJ,UAAI,QAAQ,SAAS,YAAY;AAC/B,oBAAY,OAAO,QAAQ,WAAW,IAAI,CAAC,QAAQ;AAAA,UACjD,IAAI,GAAG;AAAA,UACP,MAAM,GAAG,SAAS;AAAA,UAClB,WAAW,GAAG,SAAS;AAAA,QACzB,EAAE;AAAA,MACJ;AAEA,aAAO;AAAA,QACL,SAAU,QAAQ,SAAS,WAAsB;AAAA,QACjD,OAAO,SAAS,QACZ;AAAA,UACE,cAAc,SAAS,MAAM;AAAA,UAC7B,kBAAkB,SAAS,MAAM;AAAA,UACjC,aAAa,SAAS,MAAM;AAAA,QAC9B,IACA;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACnFA;AAAA,EACE;AAAA,OAIK;AAGP,IAAM,iBAA4C;AAAA,EAChD,CAAC,YAAY,MAAM,GAAG;AAAA,EACtB,CAAC,YAAY,IAAI,GAAG;AAAA,EACpB,CAAC,YAAY,SAAS,GAAG;AAAA,EACzB,CAAC,YAAY,IAAI,GAAG;AACtB;AAEA,IAAM,iBAA4C;AAAA,EAChD,QAAQ,YAAY;AAAA,EACpB,MAAM,YAAY;AAAA,EAClB,WAAW,YAAY;AACzB;AAGA,SAAS,aAAa,QAAkC;AACtD,SAAO,OACJ,IAAI,CAAC,MAAM;AACV,YAAQ,EAAE,MAAM;AAAA,MACd,KAAK;AACH,eAAO,EAAE;AAAA,MACX,KAAK;AACH,eAAO,eAAe,EAAE,IAAI,IAAI,EAAE,KAAK;AAAA,MACzC,KAAK;AACH,eAAO,EAAE,UACL,gBAAgB,EAAE,QAAQ,MAAM,EAAE,MAAM,MACxC,iBAAiB,EAAE,QAAQ,MAAM,EAAE,MAAM;AAAA,IACjD;AAAA,EACF,CAAC,EACA,KAAK,IAAI;AACd;AAGO,SAAS,OAAO,KAAuC;AAC5D,SAAO;AAAA,IACL,MAAM,eAAe,IAAI,IAAI,KAAK;AAAA,IAClC,SAAS,aAAa,IAAI,MAAM;AAAA,EAClC;AACF;AAGO,SAAS,SAAS,KAAuC;AAC9D,QAAM,OAAO,OAAO,IAAI,YAAY,WAChC,IAAI,UACJ,IAAI,QACD,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAO,EAAuB,IAAI,EACvC,KAAK,IAAI;AAEhB,SAAO;AAAA,IACL,MAAM,eAAe,IAAI,IAAI,KAAK,YAAY;AAAA,IAC9C,QAAQ,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,EACjC;AACF;AAGO,SAAS,iBAAiB,SAAiC;AAChE,SAAO,QAAQ,SAAS,IAAI,MAAM;AACpC;AAGO,SAAS,qBAA8B;AAC5C,SAAO,EAAE,SAAS,GAAG,UAAU,CAAC,EAAE;AACpC;;;ANvCO,IAAM,aAAN,MAAiB;AAAA,EACd,MAAM,IAAI,cAAc;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAA0B;AACpC,SAAK,SAAS;AACd,SAAK,gBAAgB,OAAO;AAC5B,SAAK,iBAAiB,OAAO;AAG7B,UAAM,gBAAgB,mBAAmB,OAAO,YAAY,OAAO;AACnE,SAAK,eAAe,IAAI,eAAe,EAAE,UAAU,cAAc,CAAC;AAElE,SAAK,UAAU,OAAO,WAAW,mBAAmB;AACpD,SAAK,eAAe,OAAO,gBAAgB;AAC3C,SAAK,gBAAgB,OAAO,iBAAiB;AAE7C,SAAK,iBAAiB,IAAI;AAAA,MACxB,KAAK;AAAA,MACL,OAAO;AAAA,MACP,OAAO,oBAAoB;AAAA,IAC7B;AAEA,SAAK,aAAa,iBAAiB,OAAO,MAAM;AAChD,SAAK,WAAW,qBAAqB,OAAO,cAAc;AAG1D,SAAK,eAAe,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAKA,GAAG,MAAsB,SAAmC;AAC1D,WAAO,KAAK,IAAI,GAAG,MAAM,OAAO;AAAA,EAClC;AAAA;AAAA,EAGA,KAAK,MAAsB,SAAmC;AAC5D,WAAO,KAAK,IAAI,KAAK,MAAM,OAAO;AAAA,EACpC;AAAA;AAAA,EAGA,MAAM,YAAY,MAA6B;AAC7C,QAAI,KAAK,cAAc;AACrB,WAAK,UAAU,IAAI;AACnB;AAAA,IACF;AAEA,SAAK,eAAe;AACpB,SAAK,cAAc;AAEnB,QAAI;AACF,YAAM,KAAK,cAAc,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,WAAK,IAAI,KAAK,SAAS;AAAA,QACrB,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACxD,OAAO;AAAA,MACT,CAAC;AAAA,IACH,UAAE;AACA,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,eAA8B;AACtC,SAAK,cAAc;AACnB,SAAK,IAAI,KAAK,gBAAgB,EAAE,cAAc,CAAC;AAE/C,QAAI,eAAe;AACjB,YAAM,MAA2B;AAAA,QAC/B,MAAMC,aAAY;AAAA,QAClB,QAAQ,CAAC,EAAE,MAAM,QAAQ,MAAM,kBAAkB,aAAa,GAAG,CAAC;AAAA,MACpE;AACA,WAAK,QAAQ,SAAS,KAAK,GAAG;AAC9B,WAAK,eAAe,KAAK,OAAO,GAAG,CAAC;AACpC,WAAK,IAAI,KAAK,iBAAiB,EAAE,QAAQ,eAAe,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA;AAAA,EAGA,aAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,aAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,qBAA2B;AACzB,SAAK,IAAI,mBAAmB;AAAA,EAC9B;AAAA;AAAA,EAIA,MAAc,cAAc,WAAkC;AAE5D,SAAK,IAAI,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,UAAM,UAA+B;AAAA,MACnC,MAAMA,aAAY;AAAA,MAClB,QAAQ,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,CAAC;AAAA,IAC5C;AACA,SAAK,QAAQ,SAAS,KAAK,OAAO;AAClC,UAAM,KAAK,eAAe,KAAK,OAAO,OAAO,CAAC;AAC9C,SAAK,IAAI,KAAK,iBAAiB,EAAE,QAAQ,aAAa,CAAC;AAGvD,UAAM,eAAe,MAAM,KAAK,OAAO,SAAS;AAChD,SAAK,IAAI,KAAK,iBAAiB,YAAY;AAE3C,QAAI,KAAK,YAAa;AAGtB,QAAI,CAAC,aAAa,YAAY,aAAa,gBAAgB;AACzD,YAAM,WAAW,aAAa;AAC9B,WAAK,IAAI,KAAK,iBAAiB,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAEjE,YAAM,eAAoC;AAAA,QACxC,MAAMA,aAAY;AAAA,QAClB,QAAQ,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,MAC3C;AACA,WAAK,QAAQ,SAAS,KAAK,YAAY;AACvC,YAAM,KAAK,eAAe,KAAK,OAAO,YAAY,CAAC;AACnD,WAAK,IAAI,KAAK,iBAAiB,EAAE,QAAQ,qBAAqB,CAAC;AAC/D,WAAK,IAAI,KAAK,iBAAiB,EAAE,OAAO,SAAS,WAAW,MAAM,CAAC;AACnE;AAAA,IACF;AAGA,UAAM,WAAW,aAAa,WAAW,KAAK,iBAAiB,KAAK;AACpE,UAAM,YAAY,aAAa,WAC3B,KAAK,OAAO,kBACZ,KAAK,OAAO;AAEhB,QAAI,aAAa,UAAU;AACzB,WAAK,IAAI,KAAK,iBAAiB;AAAA,QAC7B,MAAM,aAAa;AAAA,QACnB,OAAO;AAAA,QACP,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,UAAM,KAAK,iBAAiB,UAAU,WAAW,SAAS;AAAA,EAC5D;AAAA,EAEA,MAAc,OAAO,WAA0C;AAC7D,UAAM,iBAAiB,KAAK,eAAe,YAAY,EAAE,MAAM,EAAE;AACjE,UAAM,gBAAgB,eACnB,IAAI,CAAC,MAAM;AACV,YAAM,OAAO,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AACzD,aAAO,GAAG,EAAE,IAAI,KAAK,IAAI;AAAA,IAC3B,CAAC,EACA,KAAK,IAAI;AAEZ,UAAM,SAAS,MAAM,KAAK,aAAa,QAAQ,KAAK,UAAU;AAAA,MAC5D;AAAA,MACA;AAAA,MACA,gBAAgB,KAAK,WAAW;AAAA,IAClC,CAAC;AAED,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,iBACZ,UACA,WACA,YACe;AAEf,UAAM,kBAAkB,KAAK,eAAe,YAAY;AAGxD,UAAM,WAA6B,gBAAgB,IAAI,CAAC,OAAO;AAAA,MAC7D,MAAM,EAAE;AAAA,MACR,SACE,OAAO,EAAE,YAAY,WACjB,EAAE,UACD,EAAE,QACA,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,KAAK,IAAI;AAAA,IACpB,EAAE;AAGF,UAAM,OAAO,KAAK;AAClB,UAAM,QAA0B;AAAA,MAC9B;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,UACR,MAAM,KAAK;AAAA,UACX,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK,aACb,KAAK,MAAM,KAAK,UAAU,KAAK,UAAU,CAAC,IAC1C,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,iBAAiB;AAErB,aAAS,YAAY,GAAG,aAAa,KAAK,eAAe,aAAa;AACpE,UAAI,KAAK,YAAa;AAEtB,YAAM,SAA6B;AAAA,QACjC,OAAO;AAAA,QACP,UAAU,CAAC,GAAG,QAAQ;AAAA,QACtB,aAAa;AAAA,QACb;AAAA,QACA,aAAa;AAAA,MACf;AAEA,YAAM,WAAiC,MAAM,SAAS,KAAK,MAAM;AACjE,YAAM,SAAS,SAAS,QAAQ,CAAC;AACjC,YAAM,UAAW,QAAQ,SAAS,WAAsB;AAGxD,WAAK,IAAI,KAAK,iBAAiB;AAAA,QAC7B,MAAM;AAAA,QACN,OAAO;AAAA,QACP;AAAA,MACF,CAAC;AAGD,YAAM,YAAY,QAAQ,SAAS;AACnC,UAAI,CAAC,aAAa,UAAU,WAAW,GAAG;AACxC,cAAM,eAAe;AAErB,cAAM,eAAoC;AAAA,UACxC,MAAMA,aAAY;AAAA,UAClB,QAAQ,CAAC,EAAE,MAAM,QAAQ,MAAM,aAAa,CAAC;AAAA,QAC/C;AACA,aAAK,QAAQ,SAAS,KAAK,YAAY;AACvC,cAAM,KAAK,eAAe,KAAK,OAAO,YAAY,CAAC;AACnD,aAAK,IAAI,KAAK,iBAAiB,EAAE,QAAQ,qBAAqB,CAAC;AAC/D,aAAK,IAAI,KAAK,iBAAiB;AAAA,UAC7B,OAAO;AAAA,UACP,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,WAAW;AAAA,QACb,CAAC;AACD;AAAA,MACF;AAGA,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,WAAW;AAAA,QACpB,YAAY;AAAA,MACd,CAAC;AAGD,iBAAW,MAAM,WAAW;AAC1B,YAAI,KAAK,YAAa;AAEtB,YAAI;AACJ,YAAI;AACF,iBAAO,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,QACzC,QAAQ;AACN,iBAAO,CAAC;AAAA,QACV;AAEA,cAAM,UAAW,KAAK,WAAsB,GAAG,SAAS;AACxD,cAAM,SAAU,KAAK,UAAsC,CAAC;AAE5D,aAAK,IAAI,KAAK,wBAAwB,EAAE,SAAS,OAAO,CAAC;AAEzD,YAAI;AACJ,YAAI;AACF,mBAAS,MAAM,KAAK,QAAQ,IAAI;AAAA,QAClC,SAAS,KAAK;AACZ,mBAAS,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACrE;AAEA,aAAK,IAAI,KAAK,2BAA2B,EAAE,SAAS,QAAQ,OAAO,CAAC;AACpE;AAGA,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,cAAc,GAAG;AAAA,UACjB,SAAS,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,MAAM;AAAA,QACtE,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,cAAmC;AAAA,MACvC,MAAMA,aAAY;AAAA,MAClB,QAAQ,CAAC,EAAE,MAAM,QAAQ,MAAM,0EAA0E,CAAC;AAAA,IAC5G;AACA,SAAK,QAAQ,SAAS,KAAK,WAAW;AACtC,UAAM,KAAK,eAAe,KAAK,OAAO,WAAW,CAAC;AAClD,SAAK,IAAI,KAAK,iBAAiB,EAAE,QAAQ,iBAAiB,CAAC;AAC3D,SAAK,IAAI,KAAK,iBAAiB;AAAA,MAC7B,OAAO;AAAA,MACP,WAAW;AAAA,MACX,YAAY,KAAK;AAAA,MACjB,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;","names":["MessageRole","z","z","MessageRole"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sschepis/oboto-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Event-driven dual-LLM orchestration library for autonomous AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"zod": "^3.23.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
+
"@sschepis/llm-wrapper": "^0.1.0",
|
|
46
47
|
"@sschepis/lmscript": "^0.1.0",
|
|
47
48
|
"@sschepis/swiss-army-tool": "^0.1.0",
|
|
48
49
|
"@sschepis/as-agent": "^0.1.0"
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"@sschepis/resolang": "^0.5.0"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
56
|
+
"@sschepis/llm-wrapper": "file:../llm-wrapper",
|
|
55
57
|
"@sschepis/lmscript": "file:../lmscript",
|
|
56
58
|
"@sschepis/swiss-army-tool": "file:../swiss-army-tool",
|
|
57
59
|
"@sschepis/as-agent": "file:../claw-code/assembly",
|