UNPKG

trellis

Version:

Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications

201 lines (197 loc) 6.34 kB
import { PROVENANCE, init_canonical_op } from "../../chunk-RUMOVKR4.js"; import "../../chunk-2ESYSVXG.js"; // src/plugins/proactive-watcher/ontology.ts var proactiveWatcherOntology = { id: "trellis:proactive-watcher", name: "Proactive Watcher Schema", description: "Schema for proactive agent suggestions", version: "1.0.0", entities: [ { name: "AgentSuggestion", description: "A proactive suggestion generated by an agent observing the graph", attributes: [ { name: "title", type: "string", required: true }, { name: "description", type: "string", required: true }, { name: "status", type: "string", enum: ["pending", "accepted", "rejected", "dismissed"], required: true }, { name: "type", type: "string", description: "Category of suggestion (e.g. task_proposal, documentation, refactor, config)", required: true }, { name: "confidence", type: "number", description: "Confidence score from 0.0 to 1.0" }, { name: "proposedAction", type: "string", description: "JSON serialized action payload representing what to do if accepted" }, { name: "createdAt", type: "string", required: true } ] } ], relations: [ { name: "suggestsFor", sourceTypes: ["AgentSuggestion"], targetTypes: ["Any"], // Can point to any entity that triggered the suggestion description: "The entity this suggestion is about" }, { name: "generatedByRule", sourceTypes: ["AgentSuggestion"], targetTypes: ["Any"], description: "The rule or agent definition that triggered this suggestion" } ] }; // src/plugins/proactive-watcher/watcher-manager.ts init_canonical_op(); var WATCHER_CTX = { provenance: PROVENANCE.sdk }; var WatcherManager = class { kernel; harness; ctx = null; rules = []; suggestionCounter = 0; constructor(kernel, harness) { this.kernel = kernel; this.harness = harness; } setContext(ctx) { this.ctx = ctx; } addRule(rule) { this.rules.push(rule); } /** * Called by the event handler on `op:applied`. */ async processOperation(data) { if (!data || typeof data !== "object") return; const op = data; if (!op.kind || !op.hash) return; if (op.facts?.some((f) => f.a === "type" && f.v === "AgentSuggestion")) { return; } const matchedRules = this.rules.filter((rule) => { try { return rule.condition(op, this.kernel); } catch { return false; } }); if (matchedRules.length === 0) return; for (const rule of matchedRules) { this.ctx?.log(`Rule "${rule.id}" matched op ${op.hash}. Spawning agent "${rule.agentId}"...`); this._evaluateRule(rule, op).catch((err) => { this.ctx?.log(`Error evaluating rule "${rule.id}": ${err}`); }); } } async _evaluateRule(rule, op) { let agent = this.harness.getAgent(rule.agentId); if (!agent) { agent = await this.harness.createAgent({ id: rule.agentId, name: "Proactive Watcher Agent", description: "Analyzes graph changes and proposes proactive suggestions", model: "claude-3-5-sonnet-latest", systemPrompt: `You are a proactive monitoring agent. Your job is to look at recent changes to the system graph and generate helpful suggestions (AgentSuggestion) for the user. If you decide a suggestion is warranted, use the 'createSuggestion' tool to submit it. If no suggestion is needed, simply respond that no action is necessary.`, tools: ["createSuggestion"], status: "active" }); } if (!this.harness.getToolHandler("createSuggestion")) { await this.harness.registerTool( { id: "createSuggestion", name: "createSuggestion", description: "Create an AgentSuggestion entity in the graph.", schema: JSON.stringify({ type: "object", properties: { title: { type: "string" }, description: { type: "string" }, type: { type: "string" }, confidence: { type: "number" }, relatedEntityId: { type: "string" } }, required: ["title", "description", "type"] }) }, async (input) => { const { title, description, type, confidence, relatedEntityId } = input; const suggestionId = `suggestion:${Date.now()}:${++this.suggestionCounter}`; await this.kernel.createEntity(suggestionId, "AgentSuggestion", { title, description, type, status: "pending", ...confidence !== void 0 ? { confidence } : {} }, void 0, WATCHER_CTX); if (relatedEntityId) { await this.kernel.addLink(suggestionId, "suggestsFor", relatedEntityId, WATCHER_CTX); } await this.kernel.addLink(suggestionId, "generatedByRule", rule.id, WATCHER_CTX); return { success: true, output: { suggestionId } }; } ); } const prompt = rule.promptFactory(op); try { await this.harness.runAgentTask(agent.id, prompt); } catch (err) { this.ctx?.log(`Agent task failed for rule "${rule.id}": ${err.message}`); } } }; // src/plugins/proactive-watcher/plugin.ts function createProactiveWatcherPlugin(kernel, harness) { const manager = new WatcherManager(kernel, harness); return { id: "trellis:proactive-watcher", name: "Proactive Watcher", version: "1.0.0", description: "Watches the graph for changes and proactively generates suggestions", ontologies: [proactiveWatcherOntology], eventHandlers: [ { event: "op:applied", handler: async (data) => { await manager.processOperation(data); } } ], onLoad: async (ctx) => { ctx.log("Proactive Watcher loaded"); manager.setContext(ctx); }, onUnload: async (ctx) => { ctx.log("Proactive Watcher unloaded"); manager.setContext(null); }, manager }; } export { WatcherManager, createProactiveWatcherPlugin, proactiveWatcherOntology };