@soulcraft/sdk 1.6.2 → 2.0.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/dist/client/create-client-sdk.d.ts +16 -2
- package/dist/client/create-client-sdk.d.ts.map +1 -1
- package/dist/client/create-client-sdk.js +2 -7
- package/dist/client/create-client-sdk.js.map +1 -1
- package/dist/client/index.d.ts +48 -37
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +61 -42
- package/dist/client/index.js.map +1 -1
- package/dist/client/namespace-proxy.d.ts +108 -0
- package/dist/client/namespace-proxy.d.ts.map +1 -0
- package/dist/client/namespace-proxy.js +151 -0
- package/dist/client/namespace-proxy.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/app-context/index.d.ts +214 -0
- package/dist/modules/app-context/index.d.ts.map +1 -0
- package/dist/modules/app-context/index.js +569 -0
- package/dist/modules/app-context/index.js.map +1 -0
- package/dist/modules/auth/products.d.ts +208 -0
- package/dist/modules/auth/products.d.ts.map +1 -0
- package/dist/modules/auth/products.js +165 -0
- package/dist/modules/auth/products.js.map +1 -0
- package/dist/namespaces.d.ts +2942 -0
- package/dist/namespaces.d.ts.map +1 -0
- package/dist/namespaces.js +37 -0
- package/dist/namespaces.js.map +1 -0
- package/dist/rpc.d.ts +156 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +26 -0
- package/dist/rpc.js.map +1 -0
- package/dist/server/create-sdk.d.ts.map +1 -1
- package/dist/server/create-sdk.js +3 -13
- package/dist/server/create-sdk.js.map +1 -1
- package/dist/server/handlers/annotations.d.ts +52 -0
- package/dist/server/handlers/annotations.d.ts.map +1 -0
- package/dist/server/handlers/annotations.js +204 -0
- package/dist/server/handlers/annotations.js.map +1 -0
- package/dist/server/handlers/auth.d.ts +53 -0
- package/dist/server/handlers/auth.d.ts.map +1 -0
- package/dist/server/handlers/auth.js +66 -0
- package/dist/server/handlers/auth.js.map +1 -0
- package/dist/server/handlers/certification.d.ts +32 -0
- package/dist/server/handlers/certification.d.ts.map +1 -0
- package/dist/server/handlers/certification.js +253 -0
- package/dist/server/handlers/certification.js.map +1 -0
- package/dist/server/handlers/chat/conversations.d.ts +91 -0
- package/dist/server/handlers/chat/conversations.d.ts.map +1 -0
- package/dist/server/handlers/chat/conversations.js +314 -0
- package/dist/server/handlers/chat/conversations.js.map +1 -0
- package/dist/server/handlers/chat/delegator.d.ts +144 -0
- package/dist/server/handlers/chat/delegator.d.ts.map +1 -0
- package/dist/server/handlers/chat/delegator.js +431 -0
- package/dist/server/handlers/chat/delegator.js.map +1 -0
- package/dist/server/handlers/chat/engine.d.ts +81 -0
- package/dist/server/handlers/chat/engine.d.ts.map +1 -0
- package/dist/server/handlers/chat/engine.js +442 -0
- package/dist/server/handlers/chat/engine.js.map +1 -0
- package/dist/server/handlers/chat/executor.d.ts +65 -0
- package/dist/server/handlers/chat/executor.d.ts.map +1 -0
- package/dist/server/handlers/chat/executor.js +375 -0
- package/dist/server/handlers/chat/executor.js.map +1 -0
- package/dist/server/handlers/chat/index.d.ts +62 -0
- package/dist/server/handlers/chat/index.d.ts.map +1 -0
- package/dist/server/handlers/chat/index.js +182 -0
- package/dist/server/handlers/chat/index.js.map +1 -0
- package/dist/server/handlers/chat/memory.d.ts +91 -0
- package/dist/server/handlers/chat/memory.d.ts.map +1 -0
- package/dist/server/handlers/chat/memory.js +293 -0
- package/dist/server/handlers/chat/memory.js.map +1 -0
- package/dist/server/handlers/chat/models.d.ts +180 -0
- package/dist/server/handlers/chat/models.d.ts.map +1 -0
- package/dist/server/handlers/chat/models.js +304 -0
- package/dist/server/handlers/chat/models.js.map +1 -0
- package/dist/server/handlers/chat/planner.d.ts +116 -0
- package/dist/server/handlers/chat/planner.d.ts.map +1 -0
- package/dist/server/handlers/chat/planner.js +344 -0
- package/dist/server/handlers/chat/planner.js.map +1 -0
- package/dist/server/handlers/chat/types.d.ts +500 -0
- package/dist/server/handlers/chat/types.d.ts.map +1 -0
- package/dist/server/handlers/chat/types.js +11 -0
- package/dist/server/handlers/chat/types.js.map +1 -0
- package/dist/server/handlers/collections.d.ts +67 -0
- package/dist/server/handlers/collections.d.ts.map +1 -0
- package/dist/server/handlers/collections.js +484 -0
- package/dist/server/handlers/collections.js.map +1 -0
- package/dist/server/handlers/commerce.d.ts +106 -0
- package/dist/server/handlers/commerce.d.ts.map +1 -0
- package/dist/server/handlers/commerce.js +62 -0
- package/dist/server/handlers/commerce.js.map +1 -0
- package/dist/server/handlers/config.d.ts +112 -0
- package/dist/server/handlers/config.d.ts.map +1 -0
- package/dist/server/handlers/config.js +122 -0
- package/dist/server/handlers/config.js.map +1 -0
- package/dist/server/handlers/export.d.ts +72 -0
- package/dist/server/handlers/export.d.ts.map +1 -0
- package/dist/server/handlers/export.js +175 -0
- package/dist/server/handlers/export.js.map +1 -0
- package/dist/server/handlers/formats.d.ts +77 -0
- package/dist/server/handlers/formats.d.ts.map +1 -0
- package/dist/server/handlers/formats.js +65 -0
- package/dist/server/handlers/formats.js.map +1 -0
- package/dist/server/handlers/graph.d.ts +31 -0
- package/dist/server/handlers/graph.d.ts.map +1 -0
- package/dist/server/handlers/graph.js +490 -0
- package/dist/server/handlers/graph.js.map +1 -0
- package/dist/server/handlers/import.d.ts +96 -0
- package/dist/server/handlers/import.d.ts.map +1 -0
- package/dist/server/handlers/import.js +108 -0
- package/dist/server/handlers/import.js.map +1 -0
- package/dist/server/handlers/index.d.ts +68 -0
- package/dist/server/handlers/index.d.ts.map +1 -0
- package/dist/server/handlers/index.js +71 -0
- package/dist/server/handlers/index.js.map +1 -0
- package/dist/server/handlers/media.d.ts +76 -0
- package/dist/server/handlers/media.d.ts.map +1 -0
- package/dist/server/handlers/media.js +53 -0
- package/dist/server/handlers/media.js.map +1 -0
- package/dist/server/handlers/project.d.ts +45 -0
- package/dist/server/handlers/project.d.ts.map +1 -0
- package/dist/server/handlers/project.js +181 -0
- package/dist/server/handlers/project.js.map +1 -0
- package/dist/server/handlers/publish.d.ts +102 -0
- package/dist/server/handlers/publish.d.ts.map +1 -0
- package/dist/server/handlers/publish.js +130 -0
- package/dist/server/handlers/publish.js.map +1 -0
- package/dist/server/handlers/pulse.d.ts +39 -0
- package/dist/server/handlers/pulse.d.ts.map +1 -0
- package/dist/server/handlers/pulse.js +78 -0
- package/dist/server/handlers/pulse.js.map +1 -0
- package/dist/server/handlers/realtime.d.ts +55 -0
- package/dist/server/handlers/realtime.d.ts.map +1 -0
- package/dist/server/handlers/realtime.js +49 -0
- package/dist/server/handlers/realtime.js.map +1 -0
- package/dist/server/handlers/search.d.ts +21 -0
- package/dist/server/handlers/search.d.ts.map +1 -0
- package/dist/server/handlers/search.js +237 -0
- package/dist/server/handlers/search.js.map +1 -0
- package/dist/server/handlers/session.d.ts +47 -0
- package/dist/server/handlers/session.d.ts.map +1 -0
- package/dist/server/handlers/session.js +286 -0
- package/dist/server/handlers/session.js.map +1 -0
- package/dist/server/handlers/settings.d.ts +97 -0
- package/dist/server/handlers/settings.d.ts.map +1 -0
- package/dist/server/handlers/settings.js +131 -0
- package/dist/server/handlers/settings.js.map +1 -0
- package/dist/server/handlers/workspace.d.ts +78 -0
- package/dist/server/handlers/workspace.d.ts.map +1 -0
- package/dist/server/handlers/workspace.js +270 -0
- package/dist/server/handlers/workspace.js.map +1 -0
- package/dist/server/hono-router.d.ts +66 -0
- package/dist/server/hono-router.d.ts.map +1 -0
- package/dist/server/hono-router.js +203 -0
- package/dist/server/hono-router.js.map +1 -0
- package/dist/server/index.d.ts +29 -19
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +33 -19
- package/dist/server/index.js.map +1 -1
- package/dist/server/namespace-router.d.ts +204 -0
- package/dist/server/namespace-router.d.ts.map +1 -0
- package/dist/server/namespace-router.js +262 -0
- package/dist/server/namespace-router.js.map +1 -0
- package/dist/transports/http-namespace.d.ts +210 -0
- package/dist/transports/http-namespace.d.ts.map +1 -0
- package/dist/transports/http-namespace.js +514 -0
- package/dist/transports/http-namespace.js.map +1 -0
- package/dist/transports/workshop.d.ts +173 -0
- package/dist/transports/workshop.d.ts.map +1 -0
- package/dist/transports/workshop.js +307 -0
- package/dist/transports/workshop.js.map +1 -0
- package/dist/types.d.ts +65 -67
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -3
- package/dist/types.js.map +1 -1
- package/docs/ADR-004-product-registry.md +108 -0
- package/package.json +1 -1
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module server/handlers/chat/planner
|
|
3
|
+
* @description Plan generation, storage, approval, and modification.
|
|
4
|
+
*
|
|
5
|
+
* When Plan Mode is enabled, the planner uses a smart model (Opus) to:
|
|
6
|
+
* 1. Analyze the user's request and identify the high-level strategy
|
|
7
|
+
* 2. Break it into discrete, dependency-ordered steps
|
|
8
|
+
* 3. Identify required tools, files, entities, and skills
|
|
9
|
+
* 4. Estimate execution cost
|
|
10
|
+
*
|
|
11
|
+
* Plans are stored as Brainy `collection` entities with `_aiDataType: 'plan'`,
|
|
12
|
+
* linked to their conversation via `contains` edges. Plans must be approved
|
|
13
|
+
* before the executor runs them.
|
|
14
|
+
*/
|
|
15
|
+
import { DEFAULT_MODEL_TIERS, estimateCost } from './models.js';
|
|
16
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
17
|
+
// Plan Generation
|
|
18
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
19
|
+
/** System prompt for the planning model. */
|
|
20
|
+
const PLANNING_SYSTEM_PROMPT = `You are an AI planning assistant. Your role is to analyze user requests and create detailed execution plans.
|
|
21
|
+
|
|
22
|
+
When given a request, you must:
|
|
23
|
+
1. Analyze what the user wants to accomplish
|
|
24
|
+
2. Break it down into discrete, actionable steps
|
|
25
|
+
3. Identify what tools and context each step needs
|
|
26
|
+
4. Order steps by dependencies
|
|
27
|
+
|
|
28
|
+
Output your plan in the following JSON format:
|
|
29
|
+
{
|
|
30
|
+
"analysis": "Your understanding of what the user wants",
|
|
31
|
+
"approach": "Your high-level strategy for accomplishing it",
|
|
32
|
+
"steps": [
|
|
33
|
+
{
|
|
34
|
+
"id": "step_1",
|
|
35
|
+
"description": "What this step does (imperative form)",
|
|
36
|
+
"activeDescription": "What this step is doing (present continuous)",
|
|
37
|
+
"tools": ["tool_name_1", "tool_name_2"],
|
|
38
|
+
"dependencies": []
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "step_2",
|
|
42
|
+
"description": "Second step description",
|
|
43
|
+
"activeDescription": "Second step active description",
|
|
44
|
+
"tools": ["tool_name"],
|
|
45
|
+
"dependencies": ["step_1"]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"executionContext": {
|
|
49
|
+
"relevantFiles": ["file paths that might be needed"],
|
|
50
|
+
"relevantEntities": ["entity IDs or names"],
|
|
51
|
+
"toolsNeeded": ["list of all tools needed"],
|
|
52
|
+
"skillsNeeded": ["list of skills that might help"]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Guidelines:
|
|
57
|
+
- Keep steps atomic and focused
|
|
58
|
+
- Include all necessary tools for each step
|
|
59
|
+
- Use dependencies to ensure correct ordering
|
|
60
|
+
- Be specific in descriptions
|
|
61
|
+
- Consider error cases and validation steps where appropriate`;
|
|
62
|
+
/**
|
|
63
|
+
* Generate an execution plan from a user message.
|
|
64
|
+
*
|
|
65
|
+
* Uses the planning model (Opus by default) to analyze the request and
|
|
66
|
+
* produce a structured, dependency-ordered plan.
|
|
67
|
+
*
|
|
68
|
+
* @param options - Plan generation configuration.
|
|
69
|
+
* @returns The generated plan with cost estimates.
|
|
70
|
+
*/
|
|
71
|
+
export async function generatePlan(options) {
|
|
72
|
+
const { userMessage, conversationId, aiClient, tools, productContext, planModel = DEFAULT_MODEL_TIERS.planner, executeModel = DEFAULT_MODEL_TIERS.executor, } = options;
|
|
73
|
+
const planId = `plan_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
74
|
+
// Build context string from product context
|
|
75
|
+
let contextStr = '';
|
|
76
|
+
if (productContext) {
|
|
77
|
+
const ctx = productContext;
|
|
78
|
+
if (ctx.type && ctx.type !== 'none') {
|
|
79
|
+
contextStr += `\nContext type: ${ctx.type}`;
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(ctx.conceptIds) && ctx.conceptIds.length > 0) {
|
|
82
|
+
contextStr += `\nSelected concepts: ${ctx.conceptIds.join(', ')}`;
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(ctx.fileIds) && ctx.fileIds.length > 0) {
|
|
85
|
+
contextStr += `\nSelected files: ${ctx.fileIds.join(', ')}`;
|
|
86
|
+
}
|
|
87
|
+
if (typeof ctx.path === 'string') {
|
|
88
|
+
contextStr += `\nCurrent path: ${ctx.path}`;
|
|
89
|
+
}
|
|
90
|
+
if (typeof ctx.kitName === 'string') {
|
|
91
|
+
contextStr += `\nActive kit: ${ctx.kitName}`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Append tool list to the planning prompt
|
|
95
|
+
const toolSummary = tools.map(t => `- ${t.name}: ${t.description}`).join('\n');
|
|
96
|
+
const fullSystemPrompt = PLANNING_SYSTEM_PROMPT + `\n\nAvailable tools:\n${toolSummary}`;
|
|
97
|
+
const userPrompt = `${contextStr ? `Context:${contextStr}\n\n` : ''}User request: ${userMessage}
|
|
98
|
+
|
|
99
|
+
Please analyze this request and create a detailed execution plan.`;
|
|
100
|
+
const response = await aiClient.create({
|
|
101
|
+
model: planModel,
|
|
102
|
+
maxTokens: 4096,
|
|
103
|
+
system: fullSystemPrompt,
|
|
104
|
+
messages: [{ role: 'user', content: userPrompt }],
|
|
105
|
+
});
|
|
106
|
+
// Extract text
|
|
107
|
+
let planJson = '';
|
|
108
|
+
for (const block of response.content) {
|
|
109
|
+
if (block.type === 'text' && block.text) {
|
|
110
|
+
planJson += block.text;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Parse the JSON (handle markdown code blocks)
|
|
114
|
+
let parsedPlan;
|
|
115
|
+
try {
|
|
116
|
+
const jsonMatch = planJson.match(/```(?:json)?\s*([\s\S]*?)```/) || [null, planJson];
|
|
117
|
+
const cleanJson = jsonMatch[1] || planJson;
|
|
118
|
+
parsedPlan = JSON.parse(cleanJson.trim());
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Fallback: single-step plan
|
|
122
|
+
parsedPlan = {
|
|
123
|
+
analysis: 'Could not parse detailed plan',
|
|
124
|
+
approach: 'Execute request directly',
|
|
125
|
+
steps: [{
|
|
126
|
+
id: 'step_1',
|
|
127
|
+
description: userMessage,
|
|
128
|
+
activeDescription: `Executing: ${userMessage}`,
|
|
129
|
+
tools: [],
|
|
130
|
+
dependencies: [],
|
|
131
|
+
}],
|
|
132
|
+
executionContext: {
|
|
133
|
+
relevantFiles: [],
|
|
134
|
+
relevantEntities: [],
|
|
135
|
+
toolsNeeded: [],
|
|
136
|
+
skillsNeeded: [],
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// Cost estimation
|
|
141
|
+
const planInputTokens = response.usage?.input_tokens || 0;
|
|
142
|
+
const planOutputTokens = response.usage?.output_tokens || 0;
|
|
143
|
+
const estimatedExecuteInput = parsedPlan.steps.length * 2000;
|
|
144
|
+
const estimatedExecuteOutput = parsedPlan.steps.length * 500;
|
|
145
|
+
const costEstimate = estimateCost(planInputTokens, planOutputTokens, estimatedExecuteInput, estimatedExecuteOutput, planModel, executeModel);
|
|
146
|
+
return {
|
|
147
|
+
id: planId,
|
|
148
|
+
conversationId,
|
|
149
|
+
userMessage,
|
|
150
|
+
status: 'pending',
|
|
151
|
+
analysis: parsedPlan.analysis,
|
|
152
|
+
approach: parsedPlan.approach,
|
|
153
|
+
steps: parsedPlan.steps.map(step => ({
|
|
154
|
+
...step,
|
|
155
|
+
status: 'pending',
|
|
156
|
+
})),
|
|
157
|
+
executionContext: {
|
|
158
|
+
relevantFiles: parsedPlan.executionContext.relevantFiles,
|
|
159
|
+
entities: parsedPlan.executionContext.relevantEntities,
|
|
160
|
+
tools: parsedPlan.executionContext.toolsNeeded,
|
|
161
|
+
skills: parsedPlan.executionContext.skillsNeeded,
|
|
162
|
+
},
|
|
163
|
+
planModel,
|
|
164
|
+
executeModel,
|
|
165
|
+
createdAt: new Date().toISOString(),
|
|
166
|
+
estimatedCost: {
|
|
167
|
+
planTokens: planInputTokens + planOutputTokens,
|
|
168
|
+
executeTokens: estimatedExecuteInput + estimatedExecuteOutput,
|
|
169
|
+
totalUSD: costEstimate.totalUSD,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
174
|
+
// Plan Storage (Brainy)
|
|
175
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
176
|
+
/**
|
|
177
|
+
* Store a plan as a Brainy collection entity.
|
|
178
|
+
*
|
|
179
|
+
* Creates the entity and links it to the conversation via `contains`.
|
|
180
|
+
*
|
|
181
|
+
* @param brain - Brainy instance.
|
|
182
|
+
* @param plan - The plan to store.
|
|
183
|
+
* @returns The Brainy entity ID.
|
|
184
|
+
*/
|
|
185
|
+
export async function storePlan(brain, plan) {
|
|
186
|
+
const title = `Plan: ${plan.userMessage.slice(0, 50)}${plan.userMessage.length > 50 ? '...' : ''}`;
|
|
187
|
+
const planEntityId = await brain.add({
|
|
188
|
+
type: 'collection',
|
|
189
|
+
data: { title, plan },
|
|
190
|
+
metadata: {
|
|
191
|
+
name: title,
|
|
192
|
+
isAIManaged: true,
|
|
193
|
+
_aiDataType: 'plan',
|
|
194
|
+
conversationId: plan.conversationId,
|
|
195
|
+
status: plan.status,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
// Link to conversation
|
|
199
|
+
await brain.relate({
|
|
200
|
+
from: plan.conversationId,
|
|
201
|
+
to: planEntityId,
|
|
202
|
+
type: 'contains',
|
|
203
|
+
});
|
|
204
|
+
return planEntityId;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Load a plan from Brainy by entity ID.
|
|
208
|
+
*
|
|
209
|
+
* @param brain - Brainy instance.
|
|
210
|
+
* @param planId - Brainy entity ID.
|
|
211
|
+
* @returns The plan, or null if not found.
|
|
212
|
+
*/
|
|
213
|
+
export async function loadPlan(brain, planId) {
|
|
214
|
+
const entity = await brain.get(planId);
|
|
215
|
+
if (!entity || entity.metadata?._aiDataType !== 'plan')
|
|
216
|
+
return null;
|
|
217
|
+
return entity.data.plan;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Update a plan in Brainy.
|
|
221
|
+
*
|
|
222
|
+
* @param brain - Brainy instance.
|
|
223
|
+
* @param planId - Brainy entity ID.
|
|
224
|
+
* @param updates - Partial plan updates.
|
|
225
|
+
*/
|
|
226
|
+
export async function updatePlan(brain, planId, updates) {
|
|
227
|
+
const existing = await brain.get(planId);
|
|
228
|
+
if (!existing)
|
|
229
|
+
throw new Error(`Plan not found: ${planId}`);
|
|
230
|
+
const updatedPlan = { ...existing.data.plan, ...updates };
|
|
231
|
+
await brain.update({
|
|
232
|
+
id: planId,
|
|
233
|
+
data: { ...existing.data, plan: updatedPlan },
|
|
234
|
+
metadata: { ...existing.metadata, status: updatedPlan.status },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Approve a pending plan for execution.
|
|
239
|
+
*
|
|
240
|
+
* @param brain - Brainy instance.
|
|
241
|
+
* @param planId - Brainy entity ID.
|
|
242
|
+
* @returns The approved plan.
|
|
243
|
+
*/
|
|
244
|
+
export async function approvePlan(brain, planId) {
|
|
245
|
+
const plan = await loadPlan(brain, planId);
|
|
246
|
+
if (!plan)
|
|
247
|
+
throw new Error(`Plan not found: ${planId}`);
|
|
248
|
+
if (plan.status !== 'pending') {
|
|
249
|
+
throw new Error(`Plan cannot be approved — current status: ${plan.status}`);
|
|
250
|
+
}
|
|
251
|
+
const updates = {
|
|
252
|
+
status: 'approved',
|
|
253
|
+
approvedAt: new Date().toISOString(),
|
|
254
|
+
};
|
|
255
|
+
await updatePlan(brain, planId, updates);
|
|
256
|
+
return { ...plan, ...updates };
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Cancel a plan.
|
|
260
|
+
*
|
|
261
|
+
* @param brain - Brainy instance.
|
|
262
|
+
* @param planId - Brainy entity ID.
|
|
263
|
+
*/
|
|
264
|
+
export async function cancelPlan(brain, planId) {
|
|
265
|
+
await updatePlan(brain, planId, { status: 'cancelled' });
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Get all pending plans for a conversation.
|
|
269
|
+
*
|
|
270
|
+
* @param brain - Brainy instance.
|
|
271
|
+
* @param conversationId - Conversation entity ID.
|
|
272
|
+
* @returns Array of pending plans.
|
|
273
|
+
*/
|
|
274
|
+
export async function getPendingPlans(brain, conversationId) {
|
|
275
|
+
const relations = await brain.getRelations({ from: conversationId });
|
|
276
|
+
const plans = [];
|
|
277
|
+
for (const rel of relations) {
|
|
278
|
+
const entity = await brain.get(rel.to);
|
|
279
|
+
if (entity?.metadata?._aiDataType === 'plan') {
|
|
280
|
+
const plan = entity.data?.plan;
|
|
281
|
+
if (plan?.status === 'pending')
|
|
282
|
+
plans.push(plan);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return plans;
|
|
286
|
+
}
|
|
287
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
288
|
+
// Plan Modification
|
|
289
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
290
|
+
/**
|
|
291
|
+
* Add a step to a pending plan.
|
|
292
|
+
*
|
|
293
|
+
* @param brain - Brainy instance.
|
|
294
|
+
* @param planId - Brainy entity ID.
|
|
295
|
+
* @param step - Step to add (status is set to 'pending').
|
|
296
|
+
* @param afterStepId - Insert after this step ID. Appends if omitted.
|
|
297
|
+
* @returns Updated plan.
|
|
298
|
+
*/
|
|
299
|
+
export async function addPlanStep(brain, planId, step, afterStepId) {
|
|
300
|
+
const plan = await loadPlan(brain, planId);
|
|
301
|
+
if (!plan)
|
|
302
|
+
throw new Error(`Plan not found: ${planId}`);
|
|
303
|
+
if (plan.status !== 'pending')
|
|
304
|
+
throw new Error('Can only modify pending plans');
|
|
305
|
+
const newStep = { ...step, status: 'pending' };
|
|
306
|
+
let newSteps;
|
|
307
|
+
if (afterStepId) {
|
|
308
|
+
const idx = plan.steps.findIndex(s => s.id === afterStepId);
|
|
309
|
+
newSteps = idx === -1
|
|
310
|
+
? [...plan.steps, newStep]
|
|
311
|
+
: [...plan.steps.slice(0, idx + 1), newStep, ...plan.steps.slice(idx + 1)];
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
newSteps = [...plan.steps, newStep];
|
|
315
|
+
}
|
|
316
|
+
await updatePlan(brain, planId, { steps: newSteps });
|
|
317
|
+
return { ...plan, steps: newSteps };
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Remove a step from a pending plan.
|
|
321
|
+
*
|
|
322
|
+
* Also cleans up dependency references to the removed step.
|
|
323
|
+
*
|
|
324
|
+
* @param brain - Brainy instance.
|
|
325
|
+
* @param planId - Brainy entity ID.
|
|
326
|
+
* @param stepId - Step to remove.
|
|
327
|
+
* @returns Updated plan.
|
|
328
|
+
*/
|
|
329
|
+
export async function removePlanStep(brain, planId, stepId) {
|
|
330
|
+
const plan = await loadPlan(brain, planId);
|
|
331
|
+
if (!plan)
|
|
332
|
+
throw new Error(`Plan not found: ${planId}`);
|
|
333
|
+
if (plan.status !== 'pending')
|
|
334
|
+
throw new Error('Can only modify pending plans');
|
|
335
|
+
const newSteps = plan.steps
|
|
336
|
+
.filter(s => s.id !== stepId)
|
|
337
|
+
.map(s => ({
|
|
338
|
+
...s,
|
|
339
|
+
dependencies: s.dependencies.filter(d => d !== stepId),
|
|
340
|
+
}));
|
|
341
|
+
await updatePlan(brain, planId, { steps: newSteps });
|
|
342
|
+
return { ...plan, steps: newSteps };
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../../src/server/handlers/chat/planner.ts"],"names":[],"mappings":"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"}
|