@q1k-oss/behaviour-tree-workflows 0.0.1 → 0.0.3
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/ai-sdk/index.cjs +296 -0
- package/dist/ai-sdk/index.d.cts +82 -0
- package/dist/ai-sdk/index.d.ts +82 -0
- package/dist/ai-sdk/index.js +269 -0
- package/dist/index.cjs +1091 -14
- package/dist/index.d.cts +853 -524
- package/dist/index.d.ts +853 -524
- package/dist/index.js +1080 -14
- package/dist/types-BJPlUisg.d.cts +931 -0
- package/dist/types-BJPlUisg.d.ts +931 -0
- package/package.json +35 -3
package/dist/index.js
CHANGED
|
@@ -286,6 +286,19 @@ var ActionNode = class extends BaseNode {
|
|
|
286
286
|
});
|
|
287
287
|
const status = await this.executeTick(context);
|
|
288
288
|
this._status = status;
|
|
289
|
+
if (status === "FAILURE" /* FAILURE */ && this._lastError) {
|
|
290
|
+
context.eventEmitter?.emit({
|
|
291
|
+
type: "error" /* ERROR */,
|
|
292
|
+
nodeId: this.id,
|
|
293
|
+
nodeName: this.name,
|
|
294
|
+
nodeType: this.type,
|
|
295
|
+
timestamp: Date.now(),
|
|
296
|
+
data: {
|
|
297
|
+
error: { message: this._lastError },
|
|
298
|
+
blackboard: context.blackboard?.toJSON?.() ?? {}
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
289
302
|
context.eventEmitter?.emit({
|
|
290
303
|
type: "tick_end" /* TICK_END */,
|
|
291
304
|
nodeId: this.id,
|
|
@@ -352,6 +365,19 @@ var ConditionNode = class extends BaseNode {
|
|
|
352
365
|
});
|
|
353
366
|
const status = await this.executeTick(context);
|
|
354
367
|
this._status = status;
|
|
368
|
+
if (status === "FAILURE" /* FAILURE */ && this._lastError) {
|
|
369
|
+
context.eventEmitter?.emit({
|
|
370
|
+
type: "error" /* ERROR */,
|
|
371
|
+
nodeId: this.id,
|
|
372
|
+
nodeName: this.name,
|
|
373
|
+
nodeType: this.type,
|
|
374
|
+
timestamp: Date.now(),
|
|
375
|
+
data: {
|
|
376
|
+
error: { message: this._lastError },
|
|
377
|
+
blackboard: context.blackboard?.toJSON?.() ?? {}
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
355
381
|
context.eventEmitter?.emit({
|
|
356
382
|
type: "tick_end" /* TICK_END */,
|
|
357
383
|
nodeId: this.id,
|
|
@@ -830,9 +856,9 @@ var BehaviorTree = class _BehaviorTree {
|
|
|
830
856
|
*
|
|
831
857
|
* @example
|
|
832
858
|
* ```typescript
|
|
833
|
-
* import { BehaviorTree } from '@
|
|
834
|
-
* import { Sequence } from '@
|
|
835
|
-
* import { PrintAction } from '@
|
|
859
|
+
* import { BehaviorTree } from '@q1k-oss/behaviour-tree-workflows';
|
|
860
|
+
* import { Sequence } from '@q1k-oss/behaviour-tree-workflows';
|
|
861
|
+
* import { PrintAction } from '@q1k-oss/behaviour-tree-workflows';
|
|
836
862
|
*
|
|
837
863
|
* const root = new Sequence({ id: 'root' });
|
|
838
864
|
* root.addChild(new PrintAction({ id: 'step1', message: 'Hello' }));
|
|
@@ -2192,6 +2218,52 @@ var SoftAssert = class extends DecoratorNode {
|
|
|
2192
2218
|
}
|
|
2193
2219
|
};
|
|
2194
2220
|
|
|
2221
|
+
// src/decorators/streaming-sink.ts
|
|
2222
|
+
var StreamingSink = class extends DecoratorNode {
|
|
2223
|
+
channelId;
|
|
2224
|
+
channelKey;
|
|
2225
|
+
constructor(config) {
|
|
2226
|
+
super(config);
|
|
2227
|
+
if (!config.channelId && !config.channelKey) {
|
|
2228
|
+
throw new ConfigurationError(
|
|
2229
|
+
"StreamingSink requires either channelId or channelKey"
|
|
2230
|
+
);
|
|
2231
|
+
}
|
|
2232
|
+
this.channelId = config.channelId;
|
|
2233
|
+
this.channelKey = config.channelKey;
|
|
2234
|
+
}
|
|
2235
|
+
async executeTick(context) {
|
|
2236
|
+
if (!this.child) {
|
|
2237
|
+
throw new ConfigurationError(
|
|
2238
|
+
`${this.name}: Decorator must have a child`
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
let resolvedChannelId = this.channelId;
|
|
2242
|
+
if (this.channelKey) {
|
|
2243
|
+
const varCtx = {
|
|
2244
|
+
blackboard: context.blackboard,
|
|
2245
|
+
input: context.input,
|
|
2246
|
+
testData: context.testData
|
|
2247
|
+
};
|
|
2248
|
+
resolvedChannelId = resolveValue(this.channelKey, varCtx);
|
|
2249
|
+
}
|
|
2250
|
+
const previousValue = context.blackboard.get("__streamChannelId");
|
|
2251
|
+
context.blackboard.set("__streamChannelId", resolvedChannelId);
|
|
2252
|
+
this.log(`Set streaming channel: ${resolvedChannelId}`);
|
|
2253
|
+
try {
|
|
2254
|
+
const childStatus = await this.child.tick(context);
|
|
2255
|
+
this._status = childStatus;
|
|
2256
|
+
return childStatus;
|
|
2257
|
+
} finally {
|
|
2258
|
+
if (previousValue !== void 0) {
|
|
2259
|
+
context.blackboard.set("__streamChannelId", previousValue);
|
|
2260
|
+
} else {
|
|
2261
|
+
context.blackboard.delete("__streamChannelId");
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
};
|
|
2266
|
+
|
|
2195
2267
|
// src/decorators/timeout.ts
|
|
2196
2268
|
import { CancellationScope, isCancellation } from "@temporalio/workflow";
|
|
2197
2269
|
var Timeout = class extends DecoratorNode {
|
|
@@ -2414,8 +2486,136 @@ var memorySequenceConfigurationSchema = nodeConfigurationSchema;
|
|
|
2414
2486
|
// src/composites/recovery.schema.ts
|
|
2415
2487
|
var recoveryConfigurationSchema = nodeConfigurationSchema;
|
|
2416
2488
|
|
|
2417
|
-
// src/
|
|
2489
|
+
// src/actions/llm-chat.schema.ts
|
|
2418
2490
|
import { z as z3 } from "zod";
|
|
2491
|
+
var messageSchema = z3.object({
|
|
2492
|
+
role: z3.enum(["system", "user", "assistant"]),
|
|
2493
|
+
content: z3.string().min(1, "Message content cannot be empty")
|
|
2494
|
+
});
|
|
2495
|
+
var llmChatSchema = createNodeSchema("LLMChat", {
|
|
2496
|
+
provider: z3.enum(["anthropic", "openai", "google", "ollama"]),
|
|
2497
|
+
model: z3.string().min(1, "Model is required"),
|
|
2498
|
+
messages: z3.array(messageSchema).min(1, "At least one message is required"),
|
|
2499
|
+
systemPrompt: z3.string().optional(),
|
|
2500
|
+
temperature: z3.number().min(0).max(2).optional(),
|
|
2501
|
+
maxTokens: z3.number().int().positive().optional(),
|
|
2502
|
+
responseFormat: z3.enum(["text", "json"]).optional().default("text"),
|
|
2503
|
+
jsonSchema: z3.record(z3.string(), z3.unknown()).optional(),
|
|
2504
|
+
timeout: z3.number().int().positive().optional().default(6e4),
|
|
2505
|
+
baseUrl: z3.string().url().optional(),
|
|
2506
|
+
outputKey: z3.string().min(1, "outputKey is required")
|
|
2507
|
+
});
|
|
2508
|
+
|
|
2509
|
+
// src/actions/browser-agent.schema.ts
|
|
2510
|
+
import { z as z4 } from "zod";
|
|
2511
|
+
var browserAgentSchema = createNodeSchema("BrowserAgent", {
|
|
2512
|
+
goal: z4.string().min(1, "Goal is required"),
|
|
2513
|
+
startUrl: z4.string().optional(),
|
|
2514
|
+
contextKey: z4.string().optional(),
|
|
2515
|
+
persistContext: z4.boolean().optional().default(false),
|
|
2516
|
+
timeout: z4.number().int().positive().optional().default(6e4),
|
|
2517
|
+
maxSteps: z4.number().int().positive().optional().default(20),
|
|
2518
|
+
llmProvider: z4.enum(["anthropic", "openai", "google", "ollama"]).optional(),
|
|
2519
|
+
llmModel: z4.string().optional(),
|
|
2520
|
+
outputKey: z4.string().min(1, "outputKey is required")
|
|
2521
|
+
});
|
|
2522
|
+
|
|
2523
|
+
// src/actions/human-task.schema.ts
|
|
2524
|
+
import { z as z5 } from "zod";
|
|
2525
|
+
var a2uiComponentSchema = z5.object({
|
|
2526
|
+
id: z5.string().min(1, "Component ID cannot be empty"),
|
|
2527
|
+
component: z5.record(z5.string(), z5.unknown()),
|
|
2528
|
+
weight: z5.number().optional()
|
|
2529
|
+
});
|
|
2530
|
+
var humanTaskSchema = createNodeSchema("HumanTask", {
|
|
2531
|
+
title: z5.string().min(1, "Title is required"),
|
|
2532
|
+
description: z5.string().optional(),
|
|
2533
|
+
assignee: z5.string().optional(),
|
|
2534
|
+
assigneeRole: z5.string().optional(),
|
|
2535
|
+
a2ui: z5.object({
|
|
2536
|
+
components: z5.array(a2uiComponentSchema).min(1, "At least one A2UI component is required"),
|
|
2537
|
+
dataBindings: z5.record(z5.string(), z5.string()).optional()
|
|
2538
|
+
}),
|
|
2539
|
+
timeoutMs: z5.number().int().positive().optional().default(864e5),
|
|
2540
|
+
onTimeout: z5.enum(["expire", "approve", "reject"]).optional().default("expire"),
|
|
2541
|
+
outputKey: z5.string().optional()
|
|
2542
|
+
});
|
|
2543
|
+
|
|
2544
|
+
// src/utilities/set-variable.schema.ts
|
|
2545
|
+
import { z as z6 } from "zod";
|
|
2546
|
+
var setVariableSchema = createNodeSchema("SetVariable", {
|
|
2547
|
+
key: z6.string().min(1, "key is required"),
|
|
2548
|
+
value: z6.unknown()
|
|
2549
|
+
});
|
|
2550
|
+
|
|
2551
|
+
// src/actions/llm-tool-call.schema.ts
|
|
2552
|
+
import { z as z7 } from "zod";
|
|
2553
|
+
var toolDefinitionSchema = z7.object({
|
|
2554
|
+
name: z7.string().min(1),
|
|
2555
|
+
description: z7.string().min(1),
|
|
2556
|
+
inputSchema: z7.record(z7.string(), z7.unknown())
|
|
2557
|
+
});
|
|
2558
|
+
var llmToolCallSchema = createNodeSchema("LLMToolCall", {
|
|
2559
|
+
provider: z7.enum(["anthropic", "openai", "google", "ollama"]),
|
|
2560
|
+
model: z7.string().min(1, "Model is required"),
|
|
2561
|
+
systemPrompt: z7.string().optional(),
|
|
2562
|
+
messagesKey: z7.string().min(1, "messagesKey is required"),
|
|
2563
|
+
userMessageKey: z7.string().optional(),
|
|
2564
|
+
toolsKey: z7.string().optional(),
|
|
2565
|
+
tools: z7.array(toolDefinitionSchema).optional(),
|
|
2566
|
+
temperature: z7.number().min(0).max(2).optional(),
|
|
2567
|
+
maxTokens: z7.number().int().positive().optional(),
|
|
2568
|
+
outputKey: z7.string().min(1, "outputKey is required")
|
|
2569
|
+
});
|
|
2570
|
+
|
|
2571
|
+
// src/actions/tool-executor.schema.ts
|
|
2572
|
+
import { z as z8 } from "zod";
|
|
2573
|
+
var toolExecutorSchema = createNodeSchema("ToolExecutor", {
|
|
2574
|
+
responseKey: z8.string().min(1, "responseKey is required"),
|
|
2575
|
+
messagesKey: z8.string().min(1, "messagesKey is required"),
|
|
2576
|
+
outputKey: z8.string().optional()
|
|
2577
|
+
});
|
|
2578
|
+
|
|
2579
|
+
// src/actions/wait-for-signal.schema.ts
|
|
2580
|
+
import { z as z9 } from "zod";
|
|
2581
|
+
var waitForSignalSchema = createNodeSchema("WaitForSignal", {
|
|
2582
|
+
signalName: z9.string().min(1, "signalName is required"),
|
|
2583
|
+
signalKey: z9.string().optional(),
|
|
2584
|
+
timeoutMs: z9.number().int().positive().optional().default(864e5),
|
|
2585
|
+
outputKey: z9.string().min(1, "outputKey is required")
|
|
2586
|
+
});
|
|
2587
|
+
|
|
2588
|
+
// src/actions/tool-router.schema.ts
|
|
2589
|
+
import { z as z10 } from "zod";
|
|
2590
|
+
var toolDefinitionSchema2 = z10.object({
|
|
2591
|
+
name: z10.string().min(1),
|
|
2592
|
+
description: z10.string().min(1),
|
|
2593
|
+
inputSchema: z10.record(z10.string(), z10.unknown())
|
|
2594
|
+
});
|
|
2595
|
+
var ruleSchema = z10.object({
|
|
2596
|
+
pattern: z10.string().min(1),
|
|
2597
|
+
toolSets: z10.array(z10.string().min(1)).min(1)
|
|
2598
|
+
});
|
|
2599
|
+
var toolRouterSchema = createNodeSchema("ToolRouter", {
|
|
2600
|
+
intentKey: z10.string().min(1, "intentKey is required"),
|
|
2601
|
+
toolSets: z10.record(z10.string(), z10.array(toolDefinitionSchema2)),
|
|
2602
|
+
defaultTools: z10.array(z10.string()).optional(),
|
|
2603
|
+
rules: z10.array(ruleSchema).optional(),
|
|
2604
|
+
outputKey: z10.string().min(1, "outputKey is required")
|
|
2605
|
+
});
|
|
2606
|
+
|
|
2607
|
+
// src/decorators/streaming-sink.schema.ts
|
|
2608
|
+
import { z as z11 } from "zod";
|
|
2609
|
+
var streamingSinkSchema = createNodeSchema("StreamingSink", {
|
|
2610
|
+
channelId: z11.string().optional(),
|
|
2611
|
+
channelKey: z11.string().optional()
|
|
2612
|
+
}).refine(
|
|
2613
|
+
(data) => data.channelId || data.channelKey,
|
|
2614
|
+
{ message: "Either channelId or channelKey must be provided" }
|
|
2615
|
+
);
|
|
2616
|
+
|
|
2617
|
+
// src/schemas/validation.ts
|
|
2618
|
+
import { z as z12 } from "zod";
|
|
2419
2619
|
function zodErrorToConfigurationError(error, nodeType, nodeId) {
|
|
2420
2620
|
const nodeIdentifier = nodeId ? `${nodeType}:${nodeId}` : nodeType;
|
|
2421
2621
|
const issues = error.issues.map((issue) => {
|
|
@@ -2431,7 +2631,7 @@ function validateConfiguration(schema, config, nodeType, nodeId) {
|
|
|
2431
2631
|
try {
|
|
2432
2632
|
return schema.parse(config);
|
|
2433
2633
|
} catch (error) {
|
|
2434
|
-
if (error instanceof
|
|
2634
|
+
if (error instanceof z12.ZodError) {
|
|
2435
2635
|
throw zodErrorToConfigurationError(error, nodeType, nodeId);
|
|
2436
2636
|
}
|
|
2437
2637
|
throw error;
|
|
@@ -2450,14 +2650,14 @@ function safeValidateConfiguration(schema, config, nodeType, nodeId) {
|
|
|
2450
2650
|
}
|
|
2451
2651
|
|
|
2452
2652
|
// src/schemas/tree-definition.schema.ts
|
|
2453
|
-
import { z as
|
|
2454
|
-
var treeDefSchemaObject =
|
|
2455
|
-
type:
|
|
2456
|
-
id:
|
|
2457
|
-
name:
|
|
2458
|
-
props:
|
|
2459
|
-
children:
|
|
2460
|
-
|
|
2653
|
+
import { z as z13 } from "zod";
|
|
2654
|
+
var treeDefSchemaObject = z13.object({
|
|
2655
|
+
type: z13.string().min(1, "Node type is required"),
|
|
2656
|
+
id: z13.string().optional(),
|
|
2657
|
+
name: z13.string().optional(),
|
|
2658
|
+
props: z13.record(z13.string(), z13.unknown()).optional(),
|
|
2659
|
+
children: z13.array(
|
|
2660
|
+
z13.lazy(() => treeDefinitionSchema)
|
|
2461
2661
|
).optional()
|
|
2462
2662
|
});
|
|
2463
2663
|
var treeDefinitionSchema = treeDefSchemaObject;
|
|
@@ -2536,6 +2736,15 @@ var SchemaRegistry = class {
|
|
|
2536
2736
|
this.register("ReactiveSequence", reactiveSequenceConfigurationSchema);
|
|
2537
2737
|
this.register("MemorySequence", memorySequenceConfigurationSchema);
|
|
2538
2738
|
this.register("Recovery", recoveryConfigurationSchema);
|
|
2739
|
+
this.register("LLMChat", llmChatSchema);
|
|
2740
|
+
this.register("BrowserAgent", browserAgentSchema);
|
|
2741
|
+
this.register("HumanTask", humanTaskSchema);
|
|
2742
|
+
this.register("SetVariable", setVariableSchema);
|
|
2743
|
+
this.register("LLMToolCall", llmToolCallSchema);
|
|
2744
|
+
this.register("ToolExecutor", toolExecutorSchema);
|
|
2745
|
+
this.register("WaitForSignal", waitForSignalSchema);
|
|
2746
|
+
this.register("ToolRouter", toolRouterSchema);
|
|
2747
|
+
this.register("StreamingSink", streamingSinkSchema);
|
|
2539
2748
|
}
|
|
2540
2749
|
/**
|
|
2541
2750
|
* Register a validation schema for a node type
|
|
@@ -3005,8 +3214,32 @@ var CheckCondition = class extends ConditionNode {
|
|
|
3005
3214
|
this.operator = config.operator || "==";
|
|
3006
3215
|
this.value = config.value;
|
|
3007
3216
|
}
|
|
3217
|
+
/**
|
|
3218
|
+
* Resolve a potentially dotted key from the blackboard.
|
|
3219
|
+
* Tries exact key first (backward compatible), then dotted path traversal.
|
|
3220
|
+
*/
|
|
3221
|
+
resolveBlackboardValue(context) {
|
|
3222
|
+
const exact = context.blackboard.get(this.key);
|
|
3223
|
+
if (exact !== void 0) {
|
|
3224
|
+
return exact;
|
|
3225
|
+
}
|
|
3226
|
+
if (this.key.includes(".")) {
|
|
3227
|
+
const segments = this.key.split(".");
|
|
3228
|
+
const rootKey = segments[0];
|
|
3229
|
+
let current = context.blackboard.get(rootKey);
|
|
3230
|
+
for (let i = 1; i < segments.length; i++) {
|
|
3231
|
+
if (current == null || typeof current !== "object") {
|
|
3232
|
+
return void 0;
|
|
3233
|
+
}
|
|
3234
|
+
const segment = segments[i];
|
|
3235
|
+
current = current[segment];
|
|
3236
|
+
}
|
|
3237
|
+
return current;
|
|
3238
|
+
}
|
|
3239
|
+
return void 0;
|
|
3240
|
+
}
|
|
3008
3241
|
async executeTick(context) {
|
|
3009
|
-
const actualValue =
|
|
3242
|
+
const actualValue = this.resolveBlackboardValue(context);
|
|
3010
3243
|
let result = false;
|
|
3011
3244
|
switch (this.operator) {
|
|
3012
3245
|
case "==":
|
|
@@ -3198,6 +3431,35 @@ var RegexExtract = class extends ActionNode {
|
|
|
3198
3431
|
}
|
|
3199
3432
|
};
|
|
3200
3433
|
|
|
3434
|
+
// src/utilities/set-variable.ts
|
|
3435
|
+
var SetVariable = class extends ActionNode {
|
|
3436
|
+
key;
|
|
3437
|
+
value;
|
|
3438
|
+
constructor(config) {
|
|
3439
|
+
super(config);
|
|
3440
|
+
this.key = config.key;
|
|
3441
|
+
this.value = config.value;
|
|
3442
|
+
}
|
|
3443
|
+
async executeTick(context) {
|
|
3444
|
+
try {
|
|
3445
|
+
const varCtx = {
|
|
3446
|
+
blackboard: context.blackboard,
|
|
3447
|
+
input: context.input,
|
|
3448
|
+
testData: context.testData
|
|
3449
|
+
};
|
|
3450
|
+
const resolvedKey = typeof this.key === "string" ? resolveValue(this.key, varCtx) : String(this.key);
|
|
3451
|
+
const resolvedValue = typeof this.value === "string" ? resolveValue(this.value, varCtx) : this.value;
|
|
3452
|
+
context.blackboard.set(resolvedKey, resolvedValue);
|
|
3453
|
+
this.log(`Set ${resolvedKey} = ${JSON.stringify(resolvedValue)}`);
|
|
3454
|
+
return "SUCCESS" /* SUCCESS */;
|
|
3455
|
+
} catch (error) {
|
|
3456
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
3457
|
+
this.log(`SetVariable failed: ${this._lastError}`);
|
|
3458
|
+
return "FAILURE" /* FAILURE */;
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
};
|
|
3462
|
+
|
|
3201
3463
|
// src/integrations/piece-executor.ts
|
|
3202
3464
|
var PROVIDER_TO_PIECE = {
|
|
3203
3465
|
// Google services
|
|
@@ -3889,6 +4151,788 @@ var CodeExecution = class extends ActionNode {
|
|
|
3889
4151
|
}
|
|
3890
4152
|
};
|
|
3891
4153
|
|
|
4154
|
+
// src/actions/llm-chat.ts
|
|
4155
|
+
var LLMChat = class extends ActionNode {
|
|
4156
|
+
provider;
|
|
4157
|
+
model;
|
|
4158
|
+
messages;
|
|
4159
|
+
systemPrompt;
|
|
4160
|
+
temperature;
|
|
4161
|
+
maxTokens;
|
|
4162
|
+
responseFormat;
|
|
4163
|
+
jsonSchema;
|
|
4164
|
+
timeout;
|
|
4165
|
+
baseUrl;
|
|
4166
|
+
outputKey;
|
|
4167
|
+
constructor(config) {
|
|
4168
|
+
super(config);
|
|
4169
|
+
if (!config.provider) {
|
|
4170
|
+
throw new ConfigurationError("LLMChat requires provider");
|
|
4171
|
+
}
|
|
4172
|
+
if (!config.model) {
|
|
4173
|
+
throw new ConfigurationError("LLMChat requires model");
|
|
4174
|
+
}
|
|
4175
|
+
if (!config.messages || config.messages.length === 0) {
|
|
4176
|
+
throw new ConfigurationError(
|
|
4177
|
+
"LLMChat requires at least one message"
|
|
4178
|
+
);
|
|
4179
|
+
}
|
|
4180
|
+
if (!config.outputKey) {
|
|
4181
|
+
throw new ConfigurationError("LLMChat requires outputKey");
|
|
4182
|
+
}
|
|
4183
|
+
this.provider = config.provider;
|
|
4184
|
+
this.model = config.model;
|
|
4185
|
+
this.messages = config.messages;
|
|
4186
|
+
this.systemPrompt = config.systemPrompt;
|
|
4187
|
+
this.temperature = config.temperature;
|
|
4188
|
+
this.maxTokens = config.maxTokens;
|
|
4189
|
+
this.responseFormat = config.responseFormat || "text";
|
|
4190
|
+
this.jsonSchema = config.jsonSchema;
|
|
4191
|
+
this.timeout = config.timeout;
|
|
4192
|
+
this.baseUrl = config.baseUrl;
|
|
4193
|
+
this.outputKey = config.outputKey;
|
|
4194
|
+
}
|
|
4195
|
+
async executeTick(context) {
|
|
4196
|
+
if (!context.activities?.llmChat) {
|
|
4197
|
+
this._lastError = "LLMChat requires activities.llmChat to be configured. This activity handles LLM API calls outside the workflow sandbox.";
|
|
4198
|
+
this.log(`Error: ${this._lastError}`);
|
|
4199
|
+
return "FAILURE" /* FAILURE */;
|
|
4200
|
+
}
|
|
4201
|
+
try {
|
|
4202
|
+
const varCtx = {
|
|
4203
|
+
blackboard: context.blackboard,
|
|
4204
|
+
input: context.input,
|
|
4205
|
+
testData: context.testData
|
|
4206
|
+
};
|
|
4207
|
+
const resolvedMessages = this.messages.map((msg) => ({
|
|
4208
|
+
role: msg.role,
|
|
4209
|
+
content: resolveValue(msg.content, varCtx)
|
|
4210
|
+
}));
|
|
4211
|
+
const resolvedSystemPrompt = this.systemPrompt ? resolveValue(this.systemPrompt, varCtx) : void 0;
|
|
4212
|
+
const resolvedModel = resolveValue(this.model, varCtx);
|
|
4213
|
+
const request = {
|
|
4214
|
+
provider: this.provider,
|
|
4215
|
+
model: resolvedModel,
|
|
4216
|
+
messages: resolvedMessages,
|
|
4217
|
+
systemPrompt: resolvedSystemPrompt,
|
|
4218
|
+
temperature: this.temperature,
|
|
4219
|
+
maxTokens: this.maxTokens,
|
|
4220
|
+
responseFormat: this.responseFormat,
|
|
4221
|
+
jsonSchema: this.jsonSchema,
|
|
4222
|
+
timeout: this.timeout,
|
|
4223
|
+
baseUrl: this.baseUrl
|
|
4224
|
+
};
|
|
4225
|
+
this.log(
|
|
4226
|
+
`LLM ${this.provider}/${resolvedModel} - ${resolvedMessages.length} messages`
|
|
4227
|
+
);
|
|
4228
|
+
const result = await context.activities.llmChat(request);
|
|
4229
|
+
context.blackboard.set(this.outputKey, result);
|
|
4230
|
+
if (result.finishReason === "error") {
|
|
4231
|
+
this._lastError = `LLM returned error: ${result.content}`;
|
|
4232
|
+
this.log(`Error: ${this._lastError}`);
|
|
4233
|
+
return "FAILURE" /* FAILURE */;
|
|
4234
|
+
}
|
|
4235
|
+
this.log(
|
|
4236
|
+
`LLM ${this.provider}/${resolvedModel} completed: ${result.usage.totalTokens} tokens, finish: ${result.finishReason}`
|
|
4237
|
+
);
|
|
4238
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4239
|
+
} catch (error) {
|
|
4240
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4241
|
+
this.log(`LLM chat failed: ${this._lastError}`);
|
|
4242
|
+
return "FAILURE" /* FAILURE */;
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
};
|
|
4246
|
+
|
|
4247
|
+
// src/actions/browser-agent.ts
|
|
4248
|
+
var BrowserAgent = class extends ActionNode {
|
|
4249
|
+
goal;
|
|
4250
|
+
startUrl;
|
|
4251
|
+
contextKey;
|
|
4252
|
+
persistContext;
|
|
4253
|
+
timeout;
|
|
4254
|
+
maxSteps;
|
|
4255
|
+
llmProvider;
|
|
4256
|
+
llmModel;
|
|
4257
|
+
outputKey;
|
|
4258
|
+
constructor(config) {
|
|
4259
|
+
super(config);
|
|
4260
|
+
if (!config.goal) {
|
|
4261
|
+
throw new ConfigurationError("BrowserAgent requires goal");
|
|
4262
|
+
}
|
|
4263
|
+
if (!config.outputKey) {
|
|
4264
|
+
throw new ConfigurationError("BrowserAgent requires outputKey");
|
|
4265
|
+
}
|
|
4266
|
+
this.goal = config.goal;
|
|
4267
|
+
this.startUrl = config.startUrl;
|
|
4268
|
+
this.contextKey = config.contextKey;
|
|
4269
|
+
this.persistContext = config.persistContext ?? false;
|
|
4270
|
+
this.timeout = config.timeout;
|
|
4271
|
+
this.maxSteps = config.maxSteps;
|
|
4272
|
+
this.llmProvider = config.llmProvider;
|
|
4273
|
+
this.llmModel = config.llmModel;
|
|
4274
|
+
this.outputKey = config.outputKey;
|
|
4275
|
+
}
|
|
4276
|
+
async executeTick(context) {
|
|
4277
|
+
if (!context.activities?.browserAgent) {
|
|
4278
|
+
this._lastError = "BrowserAgent requires activities.browserAgent to be configured. This activity handles browser automation via Browserbase + Stagehand.";
|
|
4279
|
+
this.log(`Error: ${this._lastError}`);
|
|
4280
|
+
return "FAILURE" /* FAILURE */;
|
|
4281
|
+
}
|
|
4282
|
+
try {
|
|
4283
|
+
const varCtx = {
|
|
4284
|
+
blackboard: context.blackboard,
|
|
4285
|
+
input: context.input,
|
|
4286
|
+
testData: context.testData
|
|
4287
|
+
};
|
|
4288
|
+
const resolvedGoal = resolveValue(this.goal, varCtx);
|
|
4289
|
+
const resolvedStartUrl = this.startUrl ? resolveValue(this.startUrl, varCtx) : void 0;
|
|
4290
|
+
const contextId = this.contextKey ? context.blackboard.get(this.contextKey) : void 0;
|
|
4291
|
+
const request = {
|
|
4292
|
+
goal: resolvedGoal,
|
|
4293
|
+
startUrl: resolvedStartUrl,
|
|
4294
|
+
contextId,
|
|
4295
|
+
persistContext: this.persistContext,
|
|
4296
|
+
timeout: this.timeout,
|
|
4297
|
+
maxSteps: this.maxSteps,
|
|
4298
|
+
llmProvider: this.llmProvider,
|
|
4299
|
+
llmModel: this.llmModel
|
|
4300
|
+
};
|
|
4301
|
+
this.log(
|
|
4302
|
+
`Browser agent: ${resolvedGoal.substring(0, 50)}${resolvedGoal.length > 50 ? "..." : ""}`
|
|
4303
|
+
);
|
|
4304
|
+
const result = await context.activities.browserAgent(request);
|
|
4305
|
+
if (this.contextKey && result.contextId) {
|
|
4306
|
+
context.blackboard.set(this.contextKey, result.contextId);
|
|
4307
|
+
}
|
|
4308
|
+
context.blackboard.set(this.outputKey, result);
|
|
4309
|
+
if (!result.success) {
|
|
4310
|
+
this._lastError = `Browser agent failed to achieve goal: ${result.message}`;
|
|
4311
|
+
this.log(`Error: ${this._lastError}`);
|
|
4312
|
+
this.log(`Debug session: ${result.debugUrl}`);
|
|
4313
|
+
return "FAILURE" /* FAILURE */;
|
|
4314
|
+
}
|
|
4315
|
+
if (!result.completed) {
|
|
4316
|
+
this._lastError = `Browser agent hit step limit before completing: ${result.message}`;
|
|
4317
|
+
this.log(`Error: ${this._lastError}`);
|
|
4318
|
+
this.log(`Debug session: ${result.debugUrl}`);
|
|
4319
|
+
return "FAILURE" /* FAILURE */;
|
|
4320
|
+
}
|
|
4321
|
+
this.log(`Browser agent succeeded: ${result.message}`);
|
|
4322
|
+
this.log(`Debug session: ${result.debugUrl}`);
|
|
4323
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4324
|
+
} catch (error) {
|
|
4325
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4326
|
+
this.log(`Browser agent failed: ${this._lastError}`);
|
|
4327
|
+
return "FAILURE" /* FAILURE */;
|
|
4328
|
+
}
|
|
4329
|
+
}
|
|
4330
|
+
};
|
|
4331
|
+
|
|
4332
|
+
// src/actions/claude-agent.ts
|
|
4333
|
+
var ClaudeAgent = class extends ActionNode {
|
|
4334
|
+
prompt;
|
|
4335
|
+
model;
|
|
4336
|
+
systemPrompt;
|
|
4337
|
+
allowedTools;
|
|
4338
|
+
permissionMode;
|
|
4339
|
+
maxTurns;
|
|
4340
|
+
maxBudgetUsd;
|
|
4341
|
+
agentCwd;
|
|
4342
|
+
mcpServers;
|
|
4343
|
+
agents;
|
|
4344
|
+
outputKey;
|
|
4345
|
+
constructor(config) {
|
|
4346
|
+
super(config);
|
|
4347
|
+
if (!config.prompt) {
|
|
4348
|
+
throw new ConfigurationError("ClaudeAgent requires prompt");
|
|
4349
|
+
}
|
|
4350
|
+
if (!config.outputKey) {
|
|
4351
|
+
throw new ConfigurationError("ClaudeAgent requires outputKey");
|
|
4352
|
+
}
|
|
4353
|
+
this.prompt = config.prompt;
|
|
4354
|
+
this.model = config.model;
|
|
4355
|
+
this.systemPrompt = config.systemPrompt;
|
|
4356
|
+
this.allowedTools = config.allowedTools;
|
|
4357
|
+
this.permissionMode = config.permissionMode ?? "default";
|
|
4358
|
+
this.maxTurns = config.maxTurns ?? 50;
|
|
4359
|
+
this.maxBudgetUsd = config.maxBudgetUsd;
|
|
4360
|
+
this.agentCwd = config.cwd;
|
|
4361
|
+
this.mcpServers = config.mcpServers;
|
|
4362
|
+
this.agents = config.agents;
|
|
4363
|
+
this.outputKey = config.outputKey;
|
|
4364
|
+
}
|
|
4365
|
+
async executeTick(context) {
|
|
4366
|
+
if (!context.activities?.claudeAgent) {
|
|
4367
|
+
this._lastError = "ClaudeAgent requires activities.claudeAgent to be configured. This activity handles autonomous agent execution via the Claude Agent SDK.";
|
|
4368
|
+
this.log(`Error: ${this._lastError}`);
|
|
4369
|
+
return "FAILURE" /* FAILURE */;
|
|
4370
|
+
}
|
|
4371
|
+
try {
|
|
4372
|
+
const varCtx = {
|
|
4373
|
+
blackboard: context.blackboard,
|
|
4374
|
+
input: context.input,
|
|
4375
|
+
testData: context.testData
|
|
4376
|
+
};
|
|
4377
|
+
const resolvedPrompt = resolveValue(this.prompt, varCtx);
|
|
4378
|
+
const resolvedSystemPrompt = this.systemPrompt ? resolveValue(this.systemPrompt, varCtx) : void 0;
|
|
4379
|
+
const resolvedModel = this.model ? resolveValue(this.model, varCtx) : void 0;
|
|
4380
|
+
const resolvedCwd = this.agentCwd ? resolveValue(this.agentCwd, varCtx) : void 0;
|
|
4381
|
+
const request = {
|
|
4382
|
+
prompt: resolvedPrompt,
|
|
4383
|
+
model: resolvedModel,
|
|
4384
|
+
systemPrompt: resolvedSystemPrompt,
|
|
4385
|
+
allowedTools: this.allowedTools,
|
|
4386
|
+
permissionMode: this.permissionMode,
|
|
4387
|
+
maxTurns: this.maxTurns,
|
|
4388
|
+
maxBudgetUsd: this.maxBudgetUsd,
|
|
4389
|
+
cwd: resolvedCwd,
|
|
4390
|
+
mcpServers: this.mcpServers,
|
|
4391
|
+
agents: this.agents
|
|
4392
|
+
};
|
|
4393
|
+
this.log(
|
|
4394
|
+
`Claude agent: ${resolvedPrompt.substring(0, 80)}${resolvedPrompt.length > 80 ? "..." : ""}`
|
|
4395
|
+
);
|
|
4396
|
+
const result = await context.activities.claudeAgent(request);
|
|
4397
|
+
context.blackboard.set(this.outputKey, result);
|
|
4398
|
+
if (!result.success) {
|
|
4399
|
+
this._lastError = `Claude agent failed: ${result.errors?.join(", ") || "unknown error"}`;
|
|
4400
|
+
this.log(`Error: ${this._lastError}`);
|
|
4401
|
+
return "FAILURE" /* FAILURE */;
|
|
4402
|
+
}
|
|
4403
|
+
this.log(
|
|
4404
|
+
`Claude agent completed in ${result.numTurns} turns, $${result.totalCostUsd.toFixed(4)}, ${result.durationMs}ms`
|
|
4405
|
+
);
|
|
4406
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4407
|
+
} catch (error) {
|
|
4408
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4409
|
+
this.log(`Claude agent failed: ${this._lastError}`);
|
|
4410
|
+
return "FAILURE" /* FAILURE */;
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
};
|
|
4414
|
+
|
|
4415
|
+
// src/actions/github-action.ts
|
|
4416
|
+
var VALID_OPERATIONS = [
|
|
4417
|
+
"createBranch",
|
|
4418
|
+
"createPullRequest",
|
|
4419
|
+
"getPullRequest",
|
|
4420
|
+
"mergePullRequest",
|
|
4421
|
+
"closePullRequest",
|
|
4422
|
+
"createReview",
|
|
4423
|
+
"listIssues",
|
|
4424
|
+
"addLabels",
|
|
4425
|
+
"createComment",
|
|
4426
|
+
"createRelease"
|
|
4427
|
+
];
|
|
4428
|
+
var GitHubAction = class extends ActionNode {
|
|
4429
|
+
operation;
|
|
4430
|
+
repo;
|
|
4431
|
+
params;
|
|
4432
|
+
outputKey;
|
|
4433
|
+
constructor(config) {
|
|
4434
|
+
super(config);
|
|
4435
|
+
if (!config.operation) {
|
|
4436
|
+
throw new ConfigurationError("GitHubAction requires operation");
|
|
4437
|
+
}
|
|
4438
|
+
if (!VALID_OPERATIONS.includes(config.operation)) {
|
|
4439
|
+
throw new ConfigurationError(
|
|
4440
|
+
`GitHubAction: invalid operation "${config.operation}". Valid operations: ${VALID_OPERATIONS.join(", ")}`
|
|
4441
|
+
);
|
|
4442
|
+
}
|
|
4443
|
+
if (!config.repo) {
|
|
4444
|
+
throw new ConfigurationError("GitHubAction requires repo");
|
|
4445
|
+
}
|
|
4446
|
+
if (!config.outputKey) {
|
|
4447
|
+
throw new ConfigurationError("GitHubAction requires outputKey");
|
|
4448
|
+
}
|
|
4449
|
+
this.operation = config.operation;
|
|
4450
|
+
this.repo = config.repo;
|
|
4451
|
+
this.params = config.params ?? {};
|
|
4452
|
+
this.outputKey = config.outputKey;
|
|
4453
|
+
}
|
|
4454
|
+
async executeTick(context) {
|
|
4455
|
+
if (!context.activities?.githubAction) {
|
|
4456
|
+
this._lastError = "GitHubAction requires activities.githubAction to be configured. This activity handles GitHub API operations.";
|
|
4457
|
+
this.log(`Error: ${this._lastError}`);
|
|
4458
|
+
return "FAILURE" /* FAILURE */;
|
|
4459
|
+
}
|
|
4460
|
+
try {
|
|
4461
|
+
const varCtx = {
|
|
4462
|
+
blackboard: context.blackboard,
|
|
4463
|
+
input: context.input,
|
|
4464
|
+
testData: context.testData
|
|
4465
|
+
};
|
|
4466
|
+
const resolvedRepo = resolveValue(this.repo, varCtx);
|
|
4467
|
+
const resolvedParams = {};
|
|
4468
|
+
for (const [key, value] of Object.entries(this.params)) {
|
|
4469
|
+
if (typeof value === "string") {
|
|
4470
|
+
resolvedParams[key] = resolveValue(value, varCtx);
|
|
4471
|
+
} else {
|
|
4472
|
+
resolvedParams[key] = value;
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
const request = {
|
|
4476
|
+
operation: this.operation,
|
|
4477
|
+
repo: resolvedRepo,
|
|
4478
|
+
params: resolvedParams
|
|
4479
|
+
};
|
|
4480
|
+
this.log(
|
|
4481
|
+
`GitHub ${this.operation}: ${resolvedRepo}`
|
|
4482
|
+
);
|
|
4483
|
+
const result = await context.activities.githubAction(request);
|
|
4484
|
+
context.blackboard.set(this.outputKey, result.data);
|
|
4485
|
+
if (!result.success) {
|
|
4486
|
+
this._lastError = `GitHub ${this.operation} failed`;
|
|
4487
|
+
this.log(`Error: ${this._lastError}`);
|
|
4488
|
+
return "FAILURE" /* FAILURE */;
|
|
4489
|
+
}
|
|
4490
|
+
this.log(`GitHub ${this.operation} completed successfully`);
|
|
4491
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4492
|
+
} catch (error) {
|
|
4493
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4494
|
+
this.log(`GitHub ${this.operation} failed: ${this._lastError}`);
|
|
4495
|
+
return "FAILURE" /* FAILURE */;
|
|
4496
|
+
}
|
|
4497
|
+
}
|
|
4498
|
+
};
|
|
4499
|
+
|
|
4500
|
+
// src/actions/human-task.ts
|
|
4501
|
+
var HumanTask = class extends ActionNode {
|
|
4502
|
+
title;
|
|
4503
|
+
description;
|
|
4504
|
+
assignee;
|
|
4505
|
+
assigneeRole;
|
|
4506
|
+
a2ui;
|
|
4507
|
+
timeoutMs;
|
|
4508
|
+
onTimeout;
|
|
4509
|
+
outputKey;
|
|
4510
|
+
constructor(config) {
|
|
4511
|
+
super(config);
|
|
4512
|
+
if (!config.title) {
|
|
4513
|
+
throw new ConfigurationError("HumanTask requires title");
|
|
4514
|
+
}
|
|
4515
|
+
if (!config.a2ui?.components || config.a2ui.components.length === 0) {
|
|
4516
|
+
throw new ConfigurationError(
|
|
4517
|
+
"HumanTask requires a2ui.components with at least one component"
|
|
4518
|
+
);
|
|
4519
|
+
}
|
|
4520
|
+
this.title = config.title;
|
|
4521
|
+
this.description = config.description;
|
|
4522
|
+
this.assignee = config.assignee;
|
|
4523
|
+
this.assigneeRole = config.assigneeRole;
|
|
4524
|
+
this.a2ui = config.a2ui;
|
|
4525
|
+
this.timeoutMs = config.timeoutMs ?? 864e5;
|
|
4526
|
+
this.onTimeout = config.onTimeout ?? "expire";
|
|
4527
|
+
this.outputKey = config.outputKey;
|
|
4528
|
+
}
|
|
4529
|
+
async executeTick(context) {
|
|
4530
|
+
if (!context.activities?.createHumanTask) {
|
|
4531
|
+
this._lastError = "HumanTask requires activities.createHumanTask to be configured. This activity creates a task record in the database.";
|
|
4532
|
+
this.log(`Error: ${this._lastError}`);
|
|
4533
|
+
return "FAILURE" /* FAILURE */;
|
|
4534
|
+
}
|
|
4535
|
+
if (!context.activities?.waitForHumanTask) {
|
|
4536
|
+
this._lastError = "HumanTask requires activities.waitForHumanTask to be configured. This activity waits for the user to complete the task.";
|
|
4537
|
+
this.log(`Error: ${this._lastError}`);
|
|
4538
|
+
return "FAILURE" /* FAILURE */;
|
|
4539
|
+
}
|
|
4540
|
+
try {
|
|
4541
|
+
const varCtx = {
|
|
4542
|
+
blackboard: context.blackboard,
|
|
4543
|
+
input: context.input,
|
|
4544
|
+
testData: context.testData
|
|
4545
|
+
};
|
|
4546
|
+
const a2uiDataModel = {};
|
|
4547
|
+
if (this.a2ui.dataBindings) {
|
|
4548
|
+
for (const [a2uiPath, expression] of Object.entries(
|
|
4549
|
+
this.a2ui.dataBindings
|
|
4550
|
+
)) {
|
|
4551
|
+
const resolved = resolveValue(expression, varCtx);
|
|
4552
|
+
setNestedPath(a2uiDataModel, a2uiPath, resolved);
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
const resolvedTitle = resolveValue(this.title, varCtx);
|
|
4556
|
+
const resolvedDescription = this.description ? resolveValue(this.description, varCtx) : void 0;
|
|
4557
|
+
const resolvedAssignee = this.assignee ? resolveValue(this.assignee, varCtx) : void 0;
|
|
4558
|
+
const tenantId = context.blackboard.get("__tenantId") || "";
|
|
4559
|
+
const executionId = context.blackboard.get("__executionId") || context.workflowInfo?.workflowId || "";
|
|
4560
|
+
const request = {
|
|
4561
|
+
nodeId: this.id,
|
|
4562
|
+
tenantId,
|
|
4563
|
+
executionId,
|
|
4564
|
+
title: resolvedTitle,
|
|
4565
|
+
description: resolvedDescription,
|
|
4566
|
+
assigneeEmail: resolvedAssignee,
|
|
4567
|
+
assigneeRole: this.assigneeRole,
|
|
4568
|
+
a2uiComponents: this.a2ui.components,
|
|
4569
|
+
a2uiDataModel,
|
|
4570
|
+
timeoutMs: this.timeoutMs,
|
|
4571
|
+
onTimeout: this.onTimeout
|
|
4572
|
+
};
|
|
4573
|
+
this.log(
|
|
4574
|
+
`Creating human task: "${resolvedTitle}" (timeout: ${this.timeoutMs}ms)`
|
|
4575
|
+
);
|
|
4576
|
+
const createResult = await context.activities.createHumanTask(request);
|
|
4577
|
+
this.log(`Task created: ${createResult.taskId}`);
|
|
4578
|
+
this.log(
|
|
4579
|
+
`Waiting for human task ${createResult.taskId} on node ${this.id}`
|
|
4580
|
+
);
|
|
4581
|
+
const waitResult = await context.activities.waitForHumanTask({
|
|
4582
|
+
taskId: createResult.taskId,
|
|
4583
|
+
nodeId: this.id,
|
|
4584
|
+
timeoutMs: this.timeoutMs,
|
|
4585
|
+
onTimeout: this.onTimeout
|
|
4586
|
+
});
|
|
4587
|
+
const prefix = this.outputKey || this.id;
|
|
4588
|
+
context.blackboard.set(`${prefix}.taskId`, createResult.taskId);
|
|
4589
|
+
context.blackboard.set(`${prefix}.completed`, waitResult.completed);
|
|
4590
|
+
context.blackboard.set(`${prefix}.decision`, waitResult.decision);
|
|
4591
|
+
context.blackboard.set(
|
|
4592
|
+
`${prefix}.submittedData`,
|
|
4593
|
+
waitResult.submittedData
|
|
4594
|
+
);
|
|
4595
|
+
context.blackboard.set(`${prefix}.completedBy`, waitResult.completedBy);
|
|
4596
|
+
context.blackboard.set(`${prefix}.timedOut`, waitResult.timedOut);
|
|
4597
|
+
if (waitResult.timedOut) {
|
|
4598
|
+
this._lastError = `Task timed out after ${this.timeoutMs}ms`;
|
|
4599
|
+
this.log(`Task timed out, onTimeout=${this.onTimeout}`);
|
|
4600
|
+
return this.onTimeout === "approve" ? "SUCCESS" /* SUCCESS */ : "FAILURE" /* FAILURE */;
|
|
4601
|
+
}
|
|
4602
|
+
this.log(
|
|
4603
|
+
`Task completed: decision=${waitResult.decision}, completedBy=${waitResult.completedBy}`
|
|
4604
|
+
);
|
|
4605
|
+
return waitResult.completed ? "SUCCESS" /* SUCCESS */ : "FAILURE" /* FAILURE */;
|
|
4606
|
+
} catch (error) {
|
|
4607
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4608
|
+
this.log(`HumanTask failed: ${this._lastError}`);
|
|
4609
|
+
return "FAILURE" /* FAILURE */;
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
};
|
|
4613
|
+
function setNestedPath(obj, path2, value) {
|
|
4614
|
+
const parts = path2.split("/").filter(Boolean);
|
|
4615
|
+
let current = obj;
|
|
4616
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
4617
|
+
const key = parts[i];
|
|
4618
|
+
if (!(key in current) || typeof current[key] !== "object") {
|
|
4619
|
+
current[key] = {};
|
|
4620
|
+
}
|
|
4621
|
+
current = current[key];
|
|
4622
|
+
}
|
|
4623
|
+
if (parts.length > 0) {
|
|
4624
|
+
const lastKey = parts[parts.length - 1];
|
|
4625
|
+
current[lastKey] = value;
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4628
|
+
|
|
4629
|
+
// src/actions/llm-tool-call.ts
|
|
4630
|
+
var LLMToolCall = class extends ActionNode {
|
|
4631
|
+
provider;
|
|
4632
|
+
model;
|
|
4633
|
+
systemPrompt;
|
|
4634
|
+
messagesKey;
|
|
4635
|
+
userMessageKey;
|
|
4636
|
+
toolsKey;
|
|
4637
|
+
tools;
|
|
4638
|
+
temperature;
|
|
4639
|
+
maxTokens;
|
|
4640
|
+
outputKey;
|
|
4641
|
+
constructor(config) {
|
|
4642
|
+
super(config);
|
|
4643
|
+
if (!config.provider) {
|
|
4644
|
+
throw new ConfigurationError("LLMToolCall requires provider");
|
|
4645
|
+
}
|
|
4646
|
+
if (!config.model) {
|
|
4647
|
+
throw new ConfigurationError("LLMToolCall requires model");
|
|
4648
|
+
}
|
|
4649
|
+
if (!config.messagesKey) {
|
|
4650
|
+
throw new ConfigurationError("LLMToolCall requires messagesKey");
|
|
4651
|
+
}
|
|
4652
|
+
if (!config.outputKey) {
|
|
4653
|
+
throw new ConfigurationError("LLMToolCall requires outputKey");
|
|
4654
|
+
}
|
|
4655
|
+
this.provider = config.provider;
|
|
4656
|
+
this.model = config.model;
|
|
4657
|
+
this.systemPrompt = config.systemPrompt;
|
|
4658
|
+
this.messagesKey = config.messagesKey;
|
|
4659
|
+
this.userMessageKey = config.userMessageKey;
|
|
4660
|
+
this.toolsKey = config.toolsKey;
|
|
4661
|
+
this.tools = config.tools;
|
|
4662
|
+
this.temperature = config.temperature;
|
|
4663
|
+
this.maxTokens = config.maxTokens;
|
|
4664
|
+
this.outputKey = config.outputKey;
|
|
4665
|
+
}
|
|
4666
|
+
async executeTick(context) {
|
|
4667
|
+
if (!context.activities?.agentLoopTurn) {
|
|
4668
|
+
this._lastError = "LLMToolCall requires activities.agentLoopTurn to be configured.";
|
|
4669
|
+
this.log(`Error: ${this._lastError}`);
|
|
4670
|
+
return "FAILURE" /* FAILURE */;
|
|
4671
|
+
}
|
|
4672
|
+
try {
|
|
4673
|
+
const varCtx = {
|
|
4674
|
+
blackboard: context.blackboard,
|
|
4675
|
+
input: context.input,
|
|
4676
|
+
testData: context.testData
|
|
4677
|
+
};
|
|
4678
|
+
let messages = context.blackboard.get(this.messagesKey) || [];
|
|
4679
|
+
if (this.userMessageKey) {
|
|
4680
|
+
const userMsg = context.blackboard.get(this.userMessageKey);
|
|
4681
|
+
if (userMsg !== void 0 && userMsg !== null) {
|
|
4682
|
+
const content = typeof userMsg === "string" ? userMsg : String(userMsg);
|
|
4683
|
+
messages = [...messages, { role: "user", content }];
|
|
4684
|
+
context.blackboard.set(this.userMessageKey, null);
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
const tools = this.toolsKey ? context.blackboard.get(this.toolsKey) || [] : this.tools || [];
|
|
4688
|
+
const resolvedModel = resolveValue(this.model, varCtx);
|
|
4689
|
+
const resolvedSystemPrompt = this.systemPrompt ? resolveValue(this.systemPrompt, varCtx) : void 0;
|
|
4690
|
+
const streamChannelId = context.blackboard.get("__streamChannelId");
|
|
4691
|
+
const request = {
|
|
4692
|
+
provider: this.provider,
|
|
4693
|
+
model: resolvedModel,
|
|
4694
|
+
systemPrompt: resolvedSystemPrompt,
|
|
4695
|
+
messages,
|
|
4696
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
4697
|
+
temperature: this.temperature,
|
|
4698
|
+
maxTokens: this.maxTokens,
|
|
4699
|
+
streamChannelId: streamChannelId || void 0
|
|
4700
|
+
};
|
|
4701
|
+
this.log(
|
|
4702
|
+
`LLMToolCall ${this.provider}/${resolvedModel} - ${messages.length} messages, ${tools.length} tools`
|
|
4703
|
+
);
|
|
4704
|
+
const result = await context.activities.agentLoopTurn(request);
|
|
4705
|
+
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
4706
|
+
const contentBlocks = [];
|
|
4707
|
+
if (result.content) {
|
|
4708
|
+
contentBlocks.push({ type: "text", text: result.content });
|
|
4709
|
+
}
|
|
4710
|
+
for (const tc of result.toolCalls) {
|
|
4711
|
+
contentBlocks.push({
|
|
4712
|
+
type: "tool_use",
|
|
4713
|
+
id: tc.id,
|
|
4714
|
+
name: tc.name,
|
|
4715
|
+
input: tc.input
|
|
4716
|
+
});
|
|
4717
|
+
}
|
|
4718
|
+
messages = [...messages, { role: "assistant", content: contentBlocks }];
|
|
4719
|
+
} else {
|
|
4720
|
+
messages = [...messages, { role: "assistant", content: result.content }];
|
|
4721
|
+
}
|
|
4722
|
+
context.blackboard.set(this.messagesKey, messages);
|
|
4723
|
+
context.blackboard.set(this.outputKey, {
|
|
4724
|
+
content: result.content,
|
|
4725
|
+
toolCalls: result.toolCalls,
|
|
4726
|
+
stopReason: result.stopReason,
|
|
4727
|
+
usage: result.usage
|
|
4728
|
+
});
|
|
4729
|
+
this.log(
|
|
4730
|
+
`LLMToolCall completed: stopReason=${result.stopReason}, tools=${result.toolCalls?.length || 0}, tokens=${result.usage.totalTokens}`
|
|
4731
|
+
);
|
|
4732
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4733
|
+
} catch (error) {
|
|
4734
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4735
|
+
this.log(`LLMToolCall failed: ${this._lastError}`);
|
|
4736
|
+
return "FAILURE" /* FAILURE */;
|
|
4737
|
+
}
|
|
4738
|
+
}
|
|
4739
|
+
};
|
|
4740
|
+
|
|
4741
|
+
// src/actions/tool-executor.ts
|
|
4742
|
+
var ToolExecutor = class extends ActionNode {
|
|
4743
|
+
responseKey;
|
|
4744
|
+
messagesKey;
|
|
4745
|
+
outputKey;
|
|
4746
|
+
constructor(config) {
|
|
4747
|
+
super(config);
|
|
4748
|
+
if (!config.responseKey) {
|
|
4749
|
+
throw new ConfigurationError("ToolExecutor requires responseKey");
|
|
4750
|
+
}
|
|
4751
|
+
if (!config.messagesKey) {
|
|
4752
|
+
throw new ConfigurationError("ToolExecutor requires messagesKey");
|
|
4753
|
+
}
|
|
4754
|
+
this.responseKey = config.responseKey;
|
|
4755
|
+
this.messagesKey = config.messagesKey;
|
|
4756
|
+
this.outputKey = config.outputKey;
|
|
4757
|
+
}
|
|
4758
|
+
async executeTick(context) {
|
|
4759
|
+
if (!context.activities?.executeAgentTool) {
|
|
4760
|
+
this._lastError = "ToolExecutor requires activities.executeAgentTool to be configured.";
|
|
4761
|
+
this.log(`Error: ${this._lastError}`);
|
|
4762
|
+
return "FAILURE" /* FAILURE */;
|
|
4763
|
+
}
|
|
4764
|
+
try {
|
|
4765
|
+
const response = context.blackboard.get(this.responseKey);
|
|
4766
|
+
const toolCalls = response?.toolCalls;
|
|
4767
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
4768
|
+
this.log("No tool calls to execute");
|
|
4769
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4770
|
+
}
|
|
4771
|
+
const toolResults = [];
|
|
4772
|
+
for (const tc of toolCalls) {
|
|
4773
|
+
this.log(`Executing tool: ${tc.name} (${tc.id})`);
|
|
4774
|
+
const result = await context.activities.executeAgentTool({
|
|
4775
|
+
toolName: tc.name,
|
|
4776
|
+
toolInput: tc.input
|
|
4777
|
+
});
|
|
4778
|
+
toolResults.push({
|
|
4779
|
+
toolUseId: tc.id,
|
|
4780
|
+
toolName: tc.name,
|
|
4781
|
+
content: result.content,
|
|
4782
|
+
isError: result.isError
|
|
4783
|
+
});
|
|
4784
|
+
this.log(
|
|
4785
|
+
`Tool ${tc.name} ${result.isError ? "errored" : "completed"}: ${result.content.substring(0, 100)}`
|
|
4786
|
+
);
|
|
4787
|
+
}
|
|
4788
|
+
const resultBlocks = toolResults.map((tr) => ({
|
|
4789
|
+
type: "tool_result",
|
|
4790
|
+
tool_use_id: tr.toolUseId,
|
|
4791
|
+
content: tr.content,
|
|
4792
|
+
is_error: tr.isError
|
|
4793
|
+
}));
|
|
4794
|
+
const messages = context.blackboard.get(this.messagesKey) || [];
|
|
4795
|
+
const updatedMessages = [
|
|
4796
|
+
...messages,
|
|
4797
|
+
{ role: "user", content: resultBlocks }
|
|
4798
|
+
];
|
|
4799
|
+
context.blackboard.set(this.messagesKey, updatedMessages);
|
|
4800
|
+
if (this.outputKey) {
|
|
4801
|
+
context.blackboard.set(this.outputKey, toolResults);
|
|
4802
|
+
}
|
|
4803
|
+
this.log(`Executed ${toolResults.length} tool(s), results appended to conversation`);
|
|
4804
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4805
|
+
} catch (error) {
|
|
4806
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4807
|
+
this.log(`ToolExecutor failed: ${this._lastError}`);
|
|
4808
|
+
return "FAILURE" /* FAILURE */;
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
};
|
|
4812
|
+
|
|
4813
|
+
// src/actions/wait-for-signal.ts
|
|
4814
|
+
var WaitForSignal = class extends ActionNode {
|
|
4815
|
+
signalName;
|
|
4816
|
+
signalKey;
|
|
4817
|
+
timeoutMs;
|
|
4818
|
+
outputKey;
|
|
4819
|
+
constructor(config) {
|
|
4820
|
+
super(config);
|
|
4821
|
+
if (!config.signalName) {
|
|
4822
|
+
throw new ConfigurationError("WaitForSignal requires signalName");
|
|
4823
|
+
}
|
|
4824
|
+
if (!config.outputKey) {
|
|
4825
|
+
throw new ConfigurationError("WaitForSignal requires outputKey");
|
|
4826
|
+
}
|
|
4827
|
+
this.signalName = config.signalName;
|
|
4828
|
+
this.signalKey = config.signalKey;
|
|
4829
|
+
this.timeoutMs = config.timeoutMs ?? 864e5;
|
|
4830
|
+
this.outputKey = config.outputKey;
|
|
4831
|
+
}
|
|
4832
|
+
async executeTick(context) {
|
|
4833
|
+
if (!context.activities?.waitForSignal) {
|
|
4834
|
+
this._lastError = "WaitForSignal requires activities.waitForSignal to be configured. This is implemented as a Temporal condition in the workflow layer.";
|
|
4835
|
+
this.log(`Error: ${this._lastError}`);
|
|
4836
|
+
return "FAILURE" /* FAILURE */;
|
|
4837
|
+
}
|
|
4838
|
+
try {
|
|
4839
|
+
const varCtx = {
|
|
4840
|
+
blackboard: context.blackboard,
|
|
4841
|
+
input: context.input,
|
|
4842
|
+
testData: context.testData
|
|
4843
|
+
};
|
|
4844
|
+
const resolvedSignalKey = this.signalKey ? resolveValue(this.signalKey, varCtx) : void 0;
|
|
4845
|
+
this.log(
|
|
4846
|
+
`Waiting for signal "${this.signalName}"${resolvedSignalKey ? `:${resolvedSignalKey}` : ""} (timeout: ${this.timeoutMs}ms)`
|
|
4847
|
+
);
|
|
4848
|
+
const result = await context.activities.waitForSignal({
|
|
4849
|
+
signalName: this.signalName,
|
|
4850
|
+
signalKey: resolvedSignalKey,
|
|
4851
|
+
timeoutMs: this.timeoutMs
|
|
4852
|
+
});
|
|
4853
|
+
if (result.timedOut) {
|
|
4854
|
+
this._lastError = `Signal "${this.signalName}" timed out after ${this.timeoutMs}ms`;
|
|
4855
|
+
this.log(this._lastError);
|
|
4856
|
+
return "FAILURE" /* FAILURE */;
|
|
4857
|
+
}
|
|
4858
|
+
context.blackboard.set(this.outputKey, result.data);
|
|
4859
|
+
this.log(`Signal received, data stored at "${this.outputKey}"`);
|
|
4860
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4861
|
+
} catch (error) {
|
|
4862
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4863
|
+
this.log(`WaitForSignal failed: ${this._lastError}`);
|
|
4864
|
+
return "FAILURE" /* FAILURE */;
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4867
|
+
};
|
|
4868
|
+
|
|
4869
|
+
// src/actions/tool-router.ts
|
|
4870
|
+
var ToolRouter = class extends ActionNode {
|
|
4871
|
+
intentKey;
|
|
4872
|
+
toolSets;
|
|
4873
|
+
defaultTools;
|
|
4874
|
+
rules;
|
|
4875
|
+
outputKey;
|
|
4876
|
+
constructor(config) {
|
|
4877
|
+
super(config);
|
|
4878
|
+
if (!config.intentKey) {
|
|
4879
|
+
throw new ConfigurationError("ToolRouter requires intentKey");
|
|
4880
|
+
}
|
|
4881
|
+
if (!config.toolSets || Object.keys(config.toolSets).length === 0) {
|
|
4882
|
+
throw new ConfigurationError("ToolRouter requires at least one toolSet");
|
|
4883
|
+
}
|
|
4884
|
+
if (!config.outputKey) {
|
|
4885
|
+
throw new ConfigurationError("ToolRouter requires outputKey");
|
|
4886
|
+
}
|
|
4887
|
+
this.intentKey = config.intentKey;
|
|
4888
|
+
this.toolSets = config.toolSets;
|
|
4889
|
+
this.defaultTools = config.defaultTools || [];
|
|
4890
|
+
this.rules = config.rules || [];
|
|
4891
|
+
this.outputKey = config.outputKey;
|
|
4892
|
+
}
|
|
4893
|
+
async executeTick(context) {
|
|
4894
|
+
try {
|
|
4895
|
+
const varCtx = {
|
|
4896
|
+
blackboard: context.blackboard,
|
|
4897
|
+
input: context.input,
|
|
4898
|
+
testData: context.testData
|
|
4899
|
+
};
|
|
4900
|
+
const intentRaw = context.blackboard.get(this.intentKey);
|
|
4901
|
+
const intent = typeof intentRaw === "string" ? intentRaw : "";
|
|
4902
|
+
const selectedSetNames = new Set(this.defaultTools);
|
|
4903
|
+
for (const rule of this.rules) {
|
|
4904
|
+
const regex = new RegExp(rule.pattern, "i");
|
|
4905
|
+
if (regex.test(intent)) {
|
|
4906
|
+
for (const setName of rule.toolSets) {
|
|
4907
|
+
selectedSetNames.add(setName);
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4910
|
+
}
|
|
4911
|
+
const toolsByName = /* @__PURE__ */ new Map();
|
|
4912
|
+
for (const setName of selectedSetNames) {
|
|
4913
|
+
const tools = this.toolSets[setName];
|
|
4914
|
+
if (tools) {
|
|
4915
|
+
for (const tool of tools) {
|
|
4916
|
+
if (!toolsByName.has(tool.name)) {
|
|
4917
|
+
toolsByName.set(tool.name, tool);
|
|
4918
|
+
}
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
const selectedTools = Array.from(toolsByName.values());
|
|
4923
|
+
context.blackboard.set(this.outputKey, selectedTools);
|
|
4924
|
+
this.log(
|
|
4925
|
+
`Selected ${selectedTools.length} tools from sets [${Array.from(selectedSetNames).join(", ")}] for intent "${intent.substring(0, 50)}"`
|
|
4926
|
+
);
|
|
4927
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4928
|
+
} catch (error) {
|
|
4929
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4930
|
+
this.log(`ToolRouter failed: ${this._lastError}`);
|
|
4931
|
+
return "FAILURE" /* FAILURE */;
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4935
|
+
|
|
3892
4936
|
// src/registry-utils.ts
|
|
3893
4937
|
function registerStandardNodes(registry) {
|
|
3894
4938
|
registry.register("Sequence", Sequence, { category: "composite" });
|
|
@@ -3942,12 +4986,23 @@ function registerStandardNodes(registry) {
|
|
|
3942
4986
|
registry.register("WaitAction", WaitAction, { category: "action" });
|
|
3943
4987
|
registry.register("LogMessage", LogMessage, { category: "action" });
|
|
3944
4988
|
registry.register("RegexExtract", RegexExtract, { category: "action" });
|
|
4989
|
+
registry.register("SetVariable", SetVariable, { category: "action" });
|
|
3945
4990
|
registry.register("IntegrationAction", IntegrationAction, { category: "action" });
|
|
3946
4991
|
registry.register("PythonScript", PythonScript, { category: "action" });
|
|
3947
4992
|
registry.register("ParseFile", ParseFile, { category: "action" });
|
|
3948
4993
|
registry.register("GenerateFile", GenerateFile, { category: "action" });
|
|
3949
4994
|
registry.register("HttpRequest", HttpRequest, { category: "action" });
|
|
3950
4995
|
registry.register("CodeExecution", CodeExecution, { category: "action" });
|
|
4996
|
+
registry.register("LLMChat", LLMChat, { category: "action" });
|
|
4997
|
+
registry.register("BrowserAgent", BrowserAgent, { category: "action" });
|
|
4998
|
+
registry.register("ClaudeAgent", ClaudeAgent, { category: "action" });
|
|
4999
|
+
registry.register("GitHubAction", GitHubAction, { category: "action" });
|
|
5000
|
+
registry.register("HumanTask", HumanTask, { category: "action" });
|
|
5001
|
+
registry.register("LLMToolCall", LLMToolCall, { category: "action" });
|
|
5002
|
+
registry.register("ToolExecutor", ToolExecutor, { category: "action" });
|
|
5003
|
+
registry.register("WaitForSignal", WaitForSignal, { category: "action" });
|
|
5004
|
+
registry.register("ToolRouter", ToolRouter, { category: "action" });
|
|
5005
|
+
registry.register("StreamingSink", StreamingSink, { category: "decorator" });
|
|
3951
5006
|
}
|
|
3952
5007
|
|
|
3953
5008
|
// src/data-store/memory-store.ts
|
|
@@ -4784,7 +5839,9 @@ export {
|
|
|
4784
5839
|
AlwaysCondition,
|
|
4785
5840
|
BaseNode,
|
|
4786
5841
|
BehaviorTree,
|
|
5842
|
+
BrowserAgent,
|
|
4787
5843
|
CheckCondition,
|
|
5844
|
+
ClaudeAgent,
|
|
4788
5845
|
CodeExecution,
|
|
4789
5846
|
CompositeNode,
|
|
4790
5847
|
ConditionNode,
|
|
@@ -4801,10 +5858,14 @@ export {
|
|
|
4801
5858
|
ForceFailure,
|
|
4802
5859
|
ForceSuccess,
|
|
4803
5860
|
GenerateFile,
|
|
5861
|
+
GitHubAction,
|
|
4804
5862
|
HttpRequest,
|
|
5863
|
+
HumanTask,
|
|
4805
5864
|
IntegrationAction,
|
|
4806
5865
|
Invert,
|
|
4807
5866
|
KeepRunningUntilFailure,
|
|
5867
|
+
LLMChat,
|
|
5868
|
+
LLMToolCall,
|
|
4808
5869
|
LogMessage,
|
|
4809
5870
|
MemoryDataStore,
|
|
4810
5871
|
MemorySequence,
|
|
@@ -4831,14 +5892,19 @@ export {
|
|
|
4831
5892
|
SemanticValidationError,
|
|
4832
5893
|
Sequence,
|
|
4833
5894
|
SequenceWithMemory,
|
|
5895
|
+
SetVariable,
|
|
4834
5896
|
SoftAssert,
|
|
5897
|
+
StreamingSink,
|
|
4835
5898
|
StructureValidationError,
|
|
4836
5899
|
SubTree,
|
|
4837
5900
|
SuccessNode,
|
|
4838
5901
|
Timeout,
|
|
5902
|
+
ToolExecutor,
|
|
5903
|
+
ToolRouter,
|
|
4839
5904
|
ValidationError,
|
|
4840
5905
|
ValidationErrors,
|
|
4841
5906
|
WaitAction,
|
|
5907
|
+
WaitForSignal,
|
|
4842
5908
|
While,
|
|
4843
5909
|
YamlSyntaxError,
|
|
4844
5910
|
clearPieceCache,
|