trellis
Version:
Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications
104 lines • 3.96 kB
TypeScript
/**
* Plan Manager — Coordinates multi-turn planning with buffered mutations.
*
* When plan mode is active, the PlanManager buffers intended graph operations
* as structured data instead of executing them. On approval, it replays them
* as real kernel calls. On rejection, the plan is preserved as an entity for
* the Idea Garden.
*
* @module trellis/plugins/plan-approval
*/
import type { TrellisKernel, MutateResult } from '../../core/kernel/trellis-kernel.js';
import type { Atom } from '../../core/store/eav-store.js';
export type OperationKind = 'createEntity' | 'updateEntity' | 'deleteEntity' | 'addLink' | 'removeLink';
export interface PlannedOperation {
id: string;
kind: OperationKind;
entityId?: string;
entityType?: string;
attributes?: Record<string, Atom>;
sourceId?: string;
targetId?: string;
linkAttribute?: string;
description?: string;
sequence: number;
}
export type PlanStatus = 'drafting' | 'submitted' | 'approved' | 'rejected';
export interface PendingPlan {
id: string;
status: PlanStatus;
title: string;
description?: string;
operations: PlannedOperation[];
createdAt: string;
submittedAt?: string;
resolvedAt?: string;
resolvedBy?: string;
rejectionReason?: string;
}
export interface ApprovalResult {
planId: string;
operationsExecuted: number;
results: MutateResult[];
}
export declare class PlanManager {
private kernel;
private activePlan;
constructor(kernel: TrellisKernel);
/**
* Enter plan mode. Creates a PendingPlan entity in the graph and sets it
* as the active plan. All subsequent `addOperation()` calls buffer into it.
*/
enterPlanMode(title: string, description?: string): Promise<string>;
/**
* Whether a plan is currently being drafted.
*/
isInPlanMode(): boolean;
/**
* Get the active plan (if any).
*/
getActivePlan(): PendingPlan | null;
/**
* Buffer a planned graph operation. Only valid in plan mode.
* Returns the operation ID.
*/
addOperation(op: Omit<PlannedOperation, 'id' | 'sequence'>): Promise<string>;
planCreateEntity(entityId: string, entityType: string, attributes?: Record<string, Atom>, description?: string): Promise<string>;
planUpdateEntity(entityId: string, attributes: Record<string, Atom>, description?: string): Promise<string>;
planDeleteEntity(entityId: string, description?: string): Promise<string>;
planAddLink(sourceId: string, linkAttribute: string, targetId: string, description?: string): Promise<string>;
planRemoveLink(sourceId: string, linkAttribute: string, targetId: string, description?: string): Promise<string>;
/**
* Submit the active plan for review. Marks it as submitted and returns
* the plan for the caller to present to the user.
*/
submitPlan(): Promise<PendingPlan>;
/**
* Approve a submitted plan. Replays all buffered operations against the
* real kernel in sequence order. Returns the results of each operation.
*/
approvePlan(resolvedBy?: string): Promise<ApprovalResult>;
/**
* Reject a submitted plan. The plan and its operations remain in the graph
* as entities, preserving them as substrate for the Idea Garden (Phase 6).
*/
rejectPlan(reason?: string, resolvedBy?: string): Promise<void>;
/**
* Cancel a drafting plan without submitting. Like rejection but for
* plans that were never submitted.
*/
cancelPlan(): Promise<void>;
/**
* Load a plan from the graph by ID, including its operations.
*/
loadPlan(planId: string): PendingPlan | null;
/**
* List all plans, optionally filtered by status.
*/
listPlans(status?: PlanStatus): PendingPlan[];
/**
* Execute a single planned operation against the real kernel.
*/
private _executeOperation;
}
//# sourceMappingURL=plan-manager.d.ts.map