@synergenius/flow-weaver-pack-weaver 0.9.96 → 0.9.98

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.
Files changed (65) hide show
  1. package/dist/bot/types.d.ts +1 -0
  2. package/dist/bot/types.d.ts.map +1 -1
  3. package/dist/node-types/bot-report.d.ts +1 -1
  4. package/dist/node-types/bot-report.js +1 -1
  5. package/dist/node-types/exec-validate-retry.d.ts +1 -1
  6. package/dist/node-types/exec-validate-retry.js +1 -1
  7. package/dist/node-types/execute-plan.d.ts +1 -1
  8. package/dist/node-types/execute-plan.js +1 -1
  9. package/dist/node-types/execute-target.d.ts +1 -1
  10. package/dist/node-types/execute-target.js +1 -1
  11. package/dist/node-types/genesis-approve.d.ts +1 -1
  12. package/dist/node-types/genesis-approve.js +1 -1
  13. package/dist/node-types/genesis-check-stabilize.d.ts +1 -1
  14. package/dist/node-types/genesis-check-stabilize.js +1 -1
  15. package/dist/node-types/genesis-check-threshold.d.ts +1 -1
  16. package/dist/node-types/genesis-check-threshold.js +1 -1
  17. package/dist/node-types/genesis-compile-validate.d.ts +1 -1
  18. package/dist/node-types/genesis-compile-validate.js +1 -1
  19. package/dist/node-types/genesis-escrow-grace.d.ts +1 -1
  20. package/dist/node-types/genesis-escrow-grace.js +1 -1
  21. package/dist/node-types/genesis-escrow-validate.d.ts +1 -1
  22. package/dist/node-types/genesis-escrow-validate.js +1 -1
  23. package/dist/node-types/genesis-report.d.ts +1 -1
  24. package/dist/node-types/genesis-report.js +1 -1
  25. package/dist/node-types/genesis-snapshot.d.ts +1 -1
  26. package/dist/node-types/genesis-snapshot.js +1 -1
  27. package/dist/node-types/genesis-validate-proposal.d.ts +1 -1
  28. package/dist/node-types/genesis-validate-proposal.js +1 -1
  29. package/dist/node-types/plan-task.d.ts +1 -1
  30. package/dist/node-types/plan-task.js +1 -1
  31. package/dist/node-types/report.d.ts +1 -1
  32. package/dist/node-types/report.js +1 -1
  33. package/dist/node-types/review-result.d.ts +19 -0
  34. package/dist/node-types/review-result.d.ts.map +1 -0
  35. package/dist/node-types/review-result.js +177 -0
  36. package/dist/node-types/review-result.js.map +1 -0
  37. package/dist/node-types/validate-gate.d.ts +1 -1
  38. package/dist/node-types/validate-gate.js +1 -1
  39. package/dist/node-types/validate-result.d.ts +1 -1
  40. package/dist/node-types/validate-result.js +1 -1
  41. package/dist/workflows/weaver-bot.d.ts +8 -5
  42. package/dist/workflows/weaver-bot.d.ts.map +1 -1
  43. package/dist/workflows/weaver-bot.js +8 -5
  44. package/dist/workflows/weaver-bot.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/bot/types.ts +1 -0
  47. package/src/node-types/bot-report.ts +1 -1
  48. package/src/node-types/exec-validate-retry.ts +1 -1
  49. package/src/node-types/execute-plan.ts +1 -1
  50. package/src/node-types/execute-target.ts +1 -1
  51. package/src/node-types/genesis-approve.ts +1 -1
  52. package/src/node-types/genesis-check-stabilize.ts +1 -1
  53. package/src/node-types/genesis-check-threshold.ts +1 -1
  54. package/src/node-types/genesis-compile-validate.ts +1 -1
  55. package/src/node-types/genesis-escrow-grace.ts +1 -1
  56. package/src/node-types/genesis-escrow-validate.ts +1 -1
  57. package/src/node-types/genesis-report.ts +1 -1
  58. package/src/node-types/genesis-snapshot.ts +1 -1
  59. package/src/node-types/genesis-validate-proposal.ts +1 -1
  60. package/src/node-types/plan-task.ts +1 -1
  61. package/src/node-types/report.ts +1 -1
  62. package/src/node-types/review-result.ts +207 -0
  63. package/src/node-types/validate-gate.ts +1 -1
  64. package/src/node-types/validate-result.ts +1 -1
  65. package/src/workflows/weaver-bot.ts +9 -5
@@ -0,0 +1,207 @@
1
+ import type { WeaverContext } from '../bot/types.js';
2
+ import {
3
+ runAgentLoop,
4
+ createAnthropicProvider,
5
+ getOrCreateCliSession,
6
+ type AgentProvider,
7
+ type StreamEvent,
8
+ } from '@synergenius/flow-weaver/agent';
9
+
10
+ /**
11
+ * LLM-powered task completion reviewer.
12
+ * Makes a single judgment call: did the bot accomplish the assigned task?
13
+ *
14
+ * @flowWeaver nodeType
15
+ * @label Review Result
16
+ * @icon spellcheck
17
+ * @color green
18
+ * @input ctx [order:0] - Weaver context with results (JSON)
19
+ * @output ctx [order:0] - Weaver context with review (JSON)
20
+ * @output onSuccess [order:-2] - Review passed
21
+ * @output onFailure [order:-1] [hidden] - Review failed
22
+ */
23
+ export async function weaverReviewResult(
24
+ execute: boolean,
25
+ ctx: string,
26
+ ): Promise<{
27
+ onSuccess: boolean; onFailure: boolean;
28
+ ctx: string;
29
+ }> {
30
+ const context = JSON.parse(ctx) as WeaverContext;
31
+
32
+ if (!execute) {
33
+ context.reviewJson = JSON.stringify({ pass: true, reason: 'Dry run' });
34
+ return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
35
+ }
36
+
37
+ // Extract task info
38
+ let taskTitle = 'Unknown task';
39
+ let taskDescription = '';
40
+ try {
41
+ const task = JSON.parse(context.taskJson ?? '{}');
42
+ const instruction = task.instruction ?? '';
43
+ const titleMatch = instruction.match(/^##\s*Task:\s*(.+)/m);
44
+ taskTitle = titleMatch ? titleMatch[1].trim() : (instruction.split('\n')[0] || 'Unknown task');
45
+ // Description is everything after the title line until the next ## heading
46
+ const descMatch = instruction.match(/^##\s*Task:[^\n]*\n\n([\s\S]*?)(?=\n##|\n*$)/m);
47
+ taskDescription = descMatch ? descMatch[1].trim() : '';
48
+ } catch { /* use defaults */ }
49
+
50
+ // Extract evidence
51
+ let toolCalls = 'none';
52
+ try {
53
+ const steps = JSON.parse(context.stepLogJson ?? '[]') as Array<{ step: string; status: string }>;
54
+ if (steps.length > 0) {
55
+ toolCalls = steps.map(s => `${s.step} (${s.status})`).join(', ');
56
+ }
57
+ } catch { /* use default */ }
58
+
59
+ let filesModified = 'none';
60
+ try {
61
+ const files = JSON.parse(context.filesModified ?? '[]') as string[];
62
+ if (files.length > 0) filesModified = files.join(', ');
63
+ } catch { /* use default */ }
64
+
65
+ let agentSummary = 'No summary available';
66
+ try {
67
+ const result = JSON.parse(context.resultJson ?? '{}');
68
+ if (result.summary) agentSummary = result.summary;
69
+ } catch { /* use default */ }
70
+
71
+ const prompt = `You are reviewing whether a bot completed its assigned task.
72
+
73
+ ## Task
74
+ ${taskTitle}
75
+ ${taskDescription}
76
+
77
+ ## What the bot did
78
+ Tool calls: ${toolCalls}
79
+ Files modified: ${filesModified}
80
+ Bot's summary: ${agentSummary}
81
+
82
+ Did the bot accomplish the task? Judge based on what was asked vs what was done.
83
+
84
+ Respond with exactly: {"pass": true/false, "reason": "one sentence"}`;
85
+
86
+ try {
87
+ const { env } = context;
88
+ const pInfo = env.providerInfo;
89
+ const provider = await createReviewProvider(pInfo, env.projectDir);
90
+
91
+ const result = await runAgentLoop(
92
+ provider,
93
+ [], // no tools needed — just a judgment call
94
+ async () => ({ result: '', isError: true }), // no-op executor
95
+ [{ role: 'user', content: prompt }],
96
+ { maxIterations: 1 },
97
+ );
98
+
99
+ // Parse the response
100
+ let pass = true;
101
+ let reason = 'Review completed';
102
+ const jsonMatch = result.summary.match(/\{[\s\S]*"pass"[\s\S]*\}/);
103
+ if (jsonMatch) {
104
+ try {
105
+ const parsed = JSON.parse(jsonMatch[0]);
106
+ pass = parsed.pass === true;
107
+ reason = parsed.reason ?? reason;
108
+ } catch {
109
+ // JSON-like but unparseable — check for fail signal in matched text
110
+ if (jsonMatch[0].includes('"pass": false') || jsonMatch[0].includes('"pass":false')) {
111
+ pass = false;
112
+ reason = result.summary.slice(0, 200);
113
+ }
114
+ }
115
+ } else {
116
+ // No JSON found — check for obvious fail signals in raw text
117
+ const lower = result.summary.toLowerCase();
118
+ if (lower.includes('"pass": false') || lower.includes('"pass":false')) {
119
+ pass = false;
120
+ reason = result.summary.slice(0, 200);
121
+ }
122
+ }
123
+
124
+ context.reviewJson = JSON.stringify({ pass, reason });
125
+
126
+ if (!pass) {
127
+ console.log(`\x1b[33m→ Review FAILED: ${reason}\x1b[0m`);
128
+ } else {
129
+ console.log(`\x1b[32m→ Review passed: ${reason}\x1b[0m`);
130
+ }
131
+
132
+ return { onSuccess: pass, onFailure: !pass, ctx: JSON.stringify(context) };
133
+ } catch (err) {
134
+ // Review failure is non-fatal — don't block the pipeline
135
+ const msg = err instanceof Error ? err.message : String(err);
136
+ console.log(`\x1b[33m→ Review skipped (error): ${msg}\x1b[0m`);
137
+ context.reviewJson = JSON.stringify({ pass: true, reason: `Review skipped: ${msg}` });
138
+ return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Create a provider for the review call — same logic as agent-execute.
144
+ */
145
+ async function createReviewProvider(
146
+ pInfo: { type: string; apiKey?: string; model?: string; maxTokens?: number },
147
+ projectDir?: string,
148
+ ): Promise<AgentProvider> {
149
+ const type = pInfo.type ?? 'auto';
150
+
151
+ if (type === 'anthropic' && pInfo.apiKey) {
152
+ return createAnthropicProvider({
153
+ apiKey: pInfo.apiKey,
154
+ model: pInfo.model,
155
+ maxTokens: 256,
156
+ });
157
+ }
158
+
159
+ if (type === 'claude-cli') {
160
+ const key = projectDir ?? process.cwd();
161
+ const session = getOrCreateCliSession(`${key}:reviewer`, {
162
+ binPath: 'claude',
163
+ cwd: key,
164
+ model: pInfo.model ?? 'claude-sonnet-4-6',
165
+ });
166
+ return new CliReviewProvider(session);
167
+ }
168
+
169
+ if (type === 'auto') {
170
+ if (process.env.ANTHROPIC_API_KEY) {
171
+ return createAnthropicProvider({
172
+ apiKey: process.env.ANTHROPIC_API_KEY,
173
+ model: pInfo.model,
174
+ maxTokens: 256,
175
+ });
176
+ }
177
+ const key = projectDir ?? process.cwd();
178
+ const session = getOrCreateCliSession(`${key}:reviewer`, {
179
+ binPath: 'claude',
180
+ cwd: key,
181
+ model: pInfo.model ?? 'claude-sonnet-4-6',
182
+ });
183
+ return new CliReviewProvider(session);
184
+ }
185
+
186
+ throw new Error(`Unsupported provider type: ${type}`);
187
+ }
188
+
189
+ class CliReviewProvider implements AgentProvider {
190
+ constructor(
191
+ private session: { ready: boolean; spawn: () => Promise<void>; send: (msg: string) => AsyncGenerator<StreamEvent> },
192
+ ) {}
193
+
194
+ async *stream(
195
+ messages: import('@synergenius/flow-weaver/agent').AgentMessage[],
196
+ _tools: import('@synergenius/flow-weaver/agent').ToolDefinition[],
197
+ _options?: import('@synergenius/flow-weaver/agent').StreamOptions,
198
+ ): AsyncGenerator<StreamEvent> {
199
+ if (!this.session.ready) await this.session.spawn();
200
+ const prompt = messages
201
+ .map(m => typeof m.content === 'string' ? m.content : JSON.stringify(m.content))
202
+ .filter(Boolean)
203
+ .join('\n');
204
+ if (!prompt) return;
205
+ yield* this.session.send(prompt);
206
+ }
207
+ }
@@ -9,7 +9,7 @@ import type { WeaverContext } from '../bot/types.js';
9
9
  * @flowWeaver nodeType
10
10
  * @expression
11
11
  * @label Validate Gate
12
- * @icon check
12
+ * @icon checkCircle
13
13
  * @color green
14
14
  * @input ctx [order:0] - Weaver context (JSON)
15
15
  * @output ctx [order:0] - Weaver context with validation result (JSON)
@@ -8,7 +8,7 @@ import { validateFiles } from '../bot/file-validator.js';
8
8
  * @flowWeaver nodeType
9
9
  * @expression
10
10
  * @label Validate Result
11
- * @icon check
11
+ * @icon checkCircle
12
12
  * @color green
13
13
  * @input env [order:0] - Weaver environment bundle
14
14
  * @input executionResultJson [order:1] - Execution result (JSON)
@@ -11,6 +11,7 @@ import { weaverPlanTask } from '../node-types/plan-task.js';
11
11
  import { weaverApprovalGate } from '../node-types/approval-gate.js';
12
12
  import { weaverAbortTask } from '../node-types/abort-task.js';
13
13
  import { weaverExecValidateRetry } from '../node-types/exec-validate-retry.js';
14
+ import { weaverReviewResult } from '../node-types/review-result.js';
14
15
  import { weaverGitOps } from '../node-types/git-ops.js';
15
16
  import { weaverSendNotify } from '../node-types/send-notify.js';
16
17
  import { weaverBotReport } from '../node-types/bot-report.js';
@@ -37,21 +38,24 @@ declare const __flowWeaverDebugger__: TDebugger | undefined;
37
38
  * @node approve weaverApprovalGate [color: "orange"] [icon: "send"] [position: 1400 200]
38
39
  * @node abort weaverAbortTask [color: "red"] [icon: "code"] [position: 1600 450]
39
40
  * @node execRetry weaverExecValidateRetry [color: "purple"] [icon: "code"] [position: 1600 200]
40
- * @node gitOps weaverGitOps [color: "green"] [icon: "code"] [position: 1800 100]
41
- * @node notify weaverSendNotify [color: "yellow"] [icon: "send"] [position: 1800 300] [suppress: "UNUSED_OUTPUT_PORT"]
42
- * @node report weaverBotReport [color: "green"] [icon: "description"] [position: 2000 200] [suppress: "UNUSED_OUTPUT_PORT", "DESIGN_ASYNC_NO_ERROR_PATH"]
43
- * @path Start -> cfg -> detect -> receive -> route -> context -> plan -> approve -> execRetry -> gitOps -> report -> Exit
41
+ * @node review weaverReviewResult [color: "green"] [icon: "spellcheck"] [position: 1700 200]
42
+ * @node gitOps weaverGitOps [color: "green"] [icon: "code"] [position: 1900 100]
43
+ * @node notify weaverSendNotify [color: "yellow"] [icon: "send"] [position: 1900 300] [suppress: "UNUSED_OUTPUT_PORT"]
44
+ * @node report weaverBotReport [color: "green"] [icon: "description"] [position: 2100 200] [suppress: "UNUSED_OUTPUT_PORT", "DESIGN_ASYNC_NO_ERROR_PATH"]
45
+ * @path Start -> cfg -> detect -> receive -> route -> context -> plan -> approve -> execRetry -> review -> gitOps -> report -> Exit
44
46
  * @path execRetry -> notify
45
47
  * @path route:fail -> readWf
46
48
  * @path approve:fail -> abort
47
49
  * @path receive:fail -> report
48
50
  * @path plan:fail -> report
49
51
  * @path execRetry:fail -> report
52
+ * @path review:fail -> report
50
53
  * @position Start 0 200
51
- * @position Exit 2200 200
54
+ * @position Exit 2300 200
52
55
  * @connect readWf.onSuccess -> report.execute
53
56
  * @connect abort.onSuccess -> report.execute
54
57
  * @connect notify.onSuccess -> report.execute
58
+ * @connect review.ctx -> gitOps.ctx
55
59
  * @connect gitOps.ctx -> report.mainCtx
56
60
  * @connect readWf.ctx -> report.readCtx
57
61
  * @connect abort.ctx -> report.abortCtx