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
JavaScript
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
};