@q1k-oss/behaviour-tree-workflows 0.0.2 → 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 +514 -11
- package/dist/index.d.cts +370 -821
- package/dist/index.d.ts +370 -821
- package/dist/index.js +508 -11
- package/dist/types-BJPlUisg.d.cts +931 -0
- package/dist/types-BJPlUisg.d.ts +931 -0
- package/package.json +35 -3
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ __export(index_exports, {
|
|
|
60
60
|
Invert: () => Invert,
|
|
61
61
|
KeepRunningUntilFailure: () => KeepRunningUntilFailure,
|
|
62
62
|
LLMChat: () => LLMChat,
|
|
63
|
+
LLMToolCall: () => LLMToolCall,
|
|
63
64
|
LogMessage: () => LogMessage,
|
|
64
65
|
MemoryDataStore: () => MemoryDataStore,
|
|
65
66
|
MemorySequence: () => MemorySequence,
|
|
@@ -86,14 +87,19 @@ __export(index_exports, {
|
|
|
86
87
|
SemanticValidationError: () => SemanticValidationError,
|
|
87
88
|
Sequence: () => Sequence,
|
|
88
89
|
SequenceWithMemory: () => SequenceWithMemory,
|
|
90
|
+
SetVariable: () => SetVariable,
|
|
89
91
|
SoftAssert: () => SoftAssert,
|
|
92
|
+
StreamingSink: () => StreamingSink,
|
|
90
93
|
StructureValidationError: () => StructureValidationError,
|
|
91
94
|
SubTree: () => SubTree,
|
|
92
95
|
SuccessNode: () => SuccessNode,
|
|
93
96
|
Timeout: () => Timeout,
|
|
97
|
+
ToolExecutor: () => ToolExecutor,
|
|
98
|
+
ToolRouter: () => ToolRouter,
|
|
94
99
|
ValidationError: () => ValidationError,
|
|
95
100
|
ValidationErrors: () => ValidationErrors,
|
|
96
101
|
WaitAction: () => WaitAction,
|
|
102
|
+
WaitForSignal: () => WaitForSignal,
|
|
97
103
|
While: () => While,
|
|
98
104
|
YamlSyntaxError: () => YamlSyntaxError,
|
|
99
105
|
clearPieceCache: () => clearPieceCache,
|
|
@@ -2354,6 +2360,52 @@ var SoftAssert = class extends DecoratorNode {
|
|
|
2354
2360
|
}
|
|
2355
2361
|
};
|
|
2356
2362
|
|
|
2363
|
+
// src/decorators/streaming-sink.ts
|
|
2364
|
+
var StreamingSink = class extends DecoratorNode {
|
|
2365
|
+
channelId;
|
|
2366
|
+
channelKey;
|
|
2367
|
+
constructor(config) {
|
|
2368
|
+
super(config);
|
|
2369
|
+
if (!config.channelId && !config.channelKey) {
|
|
2370
|
+
throw new ConfigurationError(
|
|
2371
|
+
"StreamingSink requires either channelId or channelKey"
|
|
2372
|
+
);
|
|
2373
|
+
}
|
|
2374
|
+
this.channelId = config.channelId;
|
|
2375
|
+
this.channelKey = config.channelKey;
|
|
2376
|
+
}
|
|
2377
|
+
async executeTick(context) {
|
|
2378
|
+
if (!this.child) {
|
|
2379
|
+
throw new ConfigurationError(
|
|
2380
|
+
`${this.name}: Decorator must have a child`
|
|
2381
|
+
);
|
|
2382
|
+
}
|
|
2383
|
+
let resolvedChannelId = this.channelId;
|
|
2384
|
+
if (this.channelKey) {
|
|
2385
|
+
const varCtx = {
|
|
2386
|
+
blackboard: context.blackboard,
|
|
2387
|
+
input: context.input,
|
|
2388
|
+
testData: context.testData
|
|
2389
|
+
};
|
|
2390
|
+
resolvedChannelId = resolveValue(this.channelKey, varCtx);
|
|
2391
|
+
}
|
|
2392
|
+
const previousValue = context.blackboard.get("__streamChannelId");
|
|
2393
|
+
context.blackboard.set("__streamChannelId", resolvedChannelId);
|
|
2394
|
+
this.log(`Set streaming channel: ${resolvedChannelId}`);
|
|
2395
|
+
try {
|
|
2396
|
+
const childStatus = await this.child.tick(context);
|
|
2397
|
+
this._status = childStatus;
|
|
2398
|
+
return childStatus;
|
|
2399
|
+
} finally {
|
|
2400
|
+
if (previousValue !== void 0) {
|
|
2401
|
+
context.blackboard.set("__streamChannelId", previousValue);
|
|
2402
|
+
} else {
|
|
2403
|
+
context.blackboard.delete("__streamChannelId");
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
};
|
|
2408
|
+
|
|
2357
2409
|
// src/decorators/timeout.ts
|
|
2358
2410
|
var import_workflow2 = require("@temporalio/workflow");
|
|
2359
2411
|
var Timeout = class extends DecoratorNode {
|
|
@@ -2631,8 +2683,81 @@ var humanTaskSchema = createNodeSchema("HumanTask", {
|
|
|
2631
2683
|
outputKey: import_zod5.z.string().optional()
|
|
2632
2684
|
});
|
|
2633
2685
|
|
|
2634
|
-
// src/
|
|
2686
|
+
// src/utilities/set-variable.schema.ts
|
|
2635
2687
|
var import_zod6 = require("zod");
|
|
2688
|
+
var setVariableSchema = createNodeSchema("SetVariable", {
|
|
2689
|
+
key: import_zod6.z.string().min(1, "key is required"),
|
|
2690
|
+
value: import_zod6.z.unknown()
|
|
2691
|
+
});
|
|
2692
|
+
|
|
2693
|
+
// src/actions/llm-tool-call.schema.ts
|
|
2694
|
+
var import_zod7 = require("zod");
|
|
2695
|
+
var toolDefinitionSchema = import_zod7.z.object({
|
|
2696
|
+
name: import_zod7.z.string().min(1),
|
|
2697
|
+
description: import_zod7.z.string().min(1),
|
|
2698
|
+
inputSchema: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.unknown())
|
|
2699
|
+
});
|
|
2700
|
+
var llmToolCallSchema = createNodeSchema("LLMToolCall", {
|
|
2701
|
+
provider: import_zod7.z.enum(["anthropic", "openai", "google", "ollama"]),
|
|
2702
|
+
model: import_zod7.z.string().min(1, "Model is required"),
|
|
2703
|
+
systemPrompt: import_zod7.z.string().optional(),
|
|
2704
|
+
messagesKey: import_zod7.z.string().min(1, "messagesKey is required"),
|
|
2705
|
+
userMessageKey: import_zod7.z.string().optional(),
|
|
2706
|
+
toolsKey: import_zod7.z.string().optional(),
|
|
2707
|
+
tools: import_zod7.z.array(toolDefinitionSchema).optional(),
|
|
2708
|
+
temperature: import_zod7.z.number().min(0).max(2).optional(),
|
|
2709
|
+
maxTokens: import_zod7.z.number().int().positive().optional(),
|
|
2710
|
+
outputKey: import_zod7.z.string().min(1, "outputKey is required")
|
|
2711
|
+
});
|
|
2712
|
+
|
|
2713
|
+
// src/actions/tool-executor.schema.ts
|
|
2714
|
+
var import_zod8 = require("zod");
|
|
2715
|
+
var toolExecutorSchema = createNodeSchema("ToolExecutor", {
|
|
2716
|
+
responseKey: import_zod8.z.string().min(1, "responseKey is required"),
|
|
2717
|
+
messagesKey: import_zod8.z.string().min(1, "messagesKey is required"),
|
|
2718
|
+
outputKey: import_zod8.z.string().optional()
|
|
2719
|
+
});
|
|
2720
|
+
|
|
2721
|
+
// src/actions/wait-for-signal.schema.ts
|
|
2722
|
+
var import_zod9 = require("zod");
|
|
2723
|
+
var waitForSignalSchema = createNodeSchema("WaitForSignal", {
|
|
2724
|
+
signalName: import_zod9.z.string().min(1, "signalName is required"),
|
|
2725
|
+
signalKey: import_zod9.z.string().optional(),
|
|
2726
|
+
timeoutMs: import_zod9.z.number().int().positive().optional().default(864e5),
|
|
2727
|
+
outputKey: import_zod9.z.string().min(1, "outputKey is required")
|
|
2728
|
+
});
|
|
2729
|
+
|
|
2730
|
+
// src/actions/tool-router.schema.ts
|
|
2731
|
+
var import_zod10 = require("zod");
|
|
2732
|
+
var toolDefinitionSchema2 = import_zod10.z.object({
|
|
2733
|
+
name: import_zod10.z.string().min(1),
|
|
2734
|
+
description: import_zod10.z.string().min(1),
|
|
2735
|
+
inputSchema: import_zod10.z.record(import_zod10.z.string(), import_zod10.z.unknown())
|
|
2736
|
+
});
|
|
2737
|
+
var ruleSchema = import_zod10.z.object({
|
|
2738
|
+
pattern: import_zod10.z.string().min(1),
|
|
2739
|
+
toolSets: import_zod10.z.array(import_zod10.z.string().min(1)).min(1)
|
|
2740
|
+
});
|
|
2741
|
+
var toolRouterSchema = createNodeSchema("ToolRouter", {
|
|
2742
|
+
intentKey: import_zod10.z.string().min(1, "intentKey is required"),
|
|
2743
|
+
toolSets: import_zod10.z.record(import_zod10.z.string(), import_zod10.z.array(toolDefinitionSchema2)),
|
|
2744
|
+
defaultTools: import_zod10.z.array(import_zod10.z.string()).optional(),
|
|
2745
|
+
rules: import_zod10.z.array(ruleSchema).optional(),
|
|
2746
|
+
outputKey: import_zod10.z.string().min(1, "outputKey is required")
|
|
2747
|
+
});
|
|
2748
|
+
|
|
2749
|
+
// src/decorators/streaming-sink.schema.ts
|
|
2750
|
+
var import_zod11 = require("zod");
|
|
2751
|
+
var streamingSinkSchema = createNodeSchema("StreamingSink", {
|
|
2752
|
+
channelId: import_zod11.z.string().optional(),
|
|
2753
|
+
channelKey: import_zod11.z.string().optional()
|
|
2754
|
+
}).refine(
|
|
2755
|
+
(data) => data.channelId || data.channelKey,
|
|
2756
|
+
{ message: "Either channelId or channelKey must be provided" }
|
|
2757
|
+
);
|
|
2758
|
+
|
|
2759
|
+
// src/schemas/validation.ts
|
|
2760
|
+
var import_zod12 = require("zod");
|
|
2636
2761
|
function zodErrorToConfigurationError(error, nodeType, nodeId) {
|
|
2637
2762
|
const nodeIdentifier = nodeId ? `${nodeType}:${nodeId}` : nodeType;
|
|
2638
2763
|
const issues = error.issues.map((issue) => {
|
|
@@ -2648,7 +2773,7 @@ function validateConfiguration(schema, config, nodeType, nodeId) {
|
|
|
2648
2773
|
try {
|
|
2649
2774
|
return schema.parse(config);
|
|
2650
2775
|
} catch (error) {
|
|
2651
|
-
if (error instanceof
|
|
2776
|
+
if (error instanceof import_zod12.z.ZodError) {
|
|
2652
2777
|
throw zodErrorToConfigurationError(error, nodeType, nodeId);
|
|
2653
2778
|
}
|
|
2654
2779
|
throw error;
|
|
@@ -2667,14 +2792,14 @@ function safeValidateConfiguration(schema, config, nodeType, nodeId) {
|
|
|
2667
2792
|
}
|
|
2668
2793
|
|
|
2669
2794
|
// src/schemas/tree-definition.schema.ts
|
|
2670
|
-
var
|
|
2671
|
-
var treeDefSchemaObject =
|
|
2672
|
-
type:
|
|
2673
|
-
id:
|
|
2674
|
-
name:
|
|
2675
|
-
props:
|
|
2676
|
-
children:
|
|
2677
|
-
|
|
2795
|
+
var import_zod13 = require("zod");
|
|
2796
|
+
var treeDefSchemaObject = import_zod13.z.object({
|
|
2797
|
+
type: import_zod13.z.string().min(1, "Node type is required"),
|
|
2798
|
+
id: import_zod13.z.string().optional(),
|
|
2799
|
+
name: import_zod13.z.string().optional(),
|
|
2800
|
+
props: import_zod13.z.record(import_zod13.z.string(), import_zod13.z.unknown()).optional(),
|
|
2801
|
+
children: import_zod13.z.array(
|
|
2802
|
+
import_zod13.z.lazy(() => treeDefinitionSchema)
|
|
2678
2803
|
).optional()
|
|
2679
2804
|
});
|
|
2680
2805
|
var treeDefinitionSchema = treeDefSchemaObject;
|
|
@@ -2756,6 +2881,12 @@ var SchemaRegistry = class {
|
|
|
2756
2881
|
this.register("LLMChat", llmChatSchema);
|
|
2757
2882
|
this.register("BrowserAgent", browserAgentSchema);
|
|
2758
2883
|
this.register("HumanTask", humanTaskSchema);
|
|
2884
|
+
this.register("SetVariable", setVariableSchema);
|
|
2885
|
+
this.register("LLMToolCall", llmToolCallSchema);
|
|
2886
|
+
this.register("ToolExecutor", toolExecutorSchema);
|
|
2887
|
+
this.register("WaitForSignal", waitForSignalSchema);
|
|
2888
|
+
this.register("ToolRouter", toolRouterSchema);
|
|
2889
|
+
this.register("StreamingSink", streamingSinkSchema);
|
|
2759
2890
|
}
|
|
2760
2891
|
/**
|
|
2761
2892
|
* Register a validation schema for a node type
|
|
@@ -3225,8 +3356,32 @@ var CheckCondition = class extends ConditionNode {
|
|
|
3225
3356
|
this.operator = config.operator || "==";
|
|
3226
3357
|
this.value = config.value;
|
|
3227
3358
|
}
|
|
3359
|
+
/**
|
|
3360
|
+
* Resolve a potentially dotted key from the blackboard.
|
|
3361
|
+
* Tries exact key first (backward compatible), then dotted path traversal.
|
|
3362
|
+
*/
|
|
3363
|
+
resolveBlackboardValue(context) {
|
|
3364
|
+
const exact = context.blackboard.get(this.key);
|
|
3365
|
+
if (exact !== void 0) {
|
|
3366
|
+
return exact;
|
|
3367
|
+
}
|
|
3368
|
+
if (this.key.includes(".")) {
|
|
3369
|
+
const segments = this.key.split(".");
|
|
3370
|
+
const rootKey = segments[0];
|
|
3371
|
+
let current = context.blackboard.get(rootKey);
|
|
3372
|
+
for (let i = 1; i < segments.length; i++) {
|
|
3373
|
+
if (current == null || typeof current !== "object") {
|
|
3374
|
+
return void 0;
|
|
3375
|
+
}
|
|
3376
|
+
const segment = segments[i];
|
|
3377
|
+
current = current[segment];
|
|
3378
|
+
}
|
|
3379
|
+
return current;
|
|
3380
|
+
}
|
|
3381
|
+
return void 0;
|
|
3382
|
+
}
|
|
3228
3383
|
async executeTick(context) {
|
|
3229
|
-
const actualValue =
|
|
3384
|
+
const actualValue = this.resolveBlackboardValue(context);
|
|
3230
3385
|
let result = false;
|
|
3231
3386
|
switch (this.operator) {
|
|
3232
3387
|
case "==":
|
|
@@ -3418,6 +3573,35 @@ var RegexExtract = class extends ActionNode {
|
|
|
3418
3573
|
}
|
|
3419
3574
|
};
|
|
3420
3575
|
|
|
3576
|
+
// src/utilities/set-variable.ts
|
|
3577
|
+
var SetVariable = class extends ActionNode {
|
|
3578
|
+
key;
|
|
3579
|
+
value;
|
|
3580
|
+
constructor(config) {
|
|
3581
|
+
super(config);
|
|
3582
|
+
this.key = config.key;
|
|
3583
|
+
this.value = config.value;
|
|
3584
|
+
}
|
|
3585
|
+
async executeTick(context) {
|
|
3586
|
+
try {
|
|
3587
|
+
const varCtx = {
|
|
3588
|
+
blackboard: context.blackboard,
|
|
3589
|
+
input: context.input,
|
|
3590
|
+
testData: context.testData
|
|
3591
|
+
};
|
|
3592
|
+
const resolvedKey = typeof this.key === "string" ? resolveValue(this.key, varCtx) : String(this.key);
|
|
3593
|
+
const resolvedValue = typeof this.value === "string" ? resolveValue(this.value, varCtx) : this.value;
|
|
3594
|
+
context.blackboard.set(resolvedKey, resolvedValue);
|
|
3595
|
+
this.log(`Set ${resolvedKey} = ${JSON.stringify(resolvedValue)}`);
|
|
3596
|
+
return "SUCCESS" /* SUCCESS */;
|
|
3597
|
+
} catch (error) {
|
|
3598
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
3599
|
+
this.log(`SetVariable failed: ${this._lastError}`);
|
|
3600
|
+
return "FAILURE" /* FAILURE */;
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
};
|
|
3604
|
+
|
|
3421
3605
|
// src/integrations/piece-executor.ts
|
|
3422
3606
|
var PROVIDER_TO_PIECE = {
|
|
3423
3607
|
// Google services
|
|
@@ -4584,6 +4768,313 @@ function setNestedPath(obj, path2, value) {
|
|
|
4584
4768
|
}
|
|
4585
4769
|
}
|
|
4586
4770
|
|
|
4771
|
+
// src/actions/llm-tool-call.ts
|
|
4772
|
+
var LLMToolCall = class extends ActionNode {
|
|
4773
|
+
provider;
|
|
4774
|
+
model;
|
|
4775
|
+
systemPrompt;
|
|
4776
|
+
messagesKey;
|
|
4777
|
+
userMessageKey;
|
|
4778
|
+
toolsKey;
|
|
4779
|
+
tools;
|
|
4780
|
+
temperature;
|
|
4781
|
+
maxTokens;
|
|
4782
|
+
outputKey;
|
|
4783
|
+
constructor(config) {
|
|
4784
|
+
super(config);
|
|
4785
|
+
if (!config.provider) {
|
|
4786
|
+
throw new ConfigurationError("LLMToolCall requires provider");
|
|
4787
|
+
}
|
|
4788
|
+
if (!config.model) {
|
|
4789
|
+
throw new ConfigurationError("LLMToolCall requires model");
|
|
4790
|
+
}
|
|
4791
|
+
if (!config.messagesKey) {
|
|
4792
|
+
throw new ConfigurationError("LLMToolCall requires messagesKey");
|
|
4793
|
+
}
|
|
4794
|
+
if (!config.outputKey) {
|
|
4795
|
+
throw new ConfigurationError("LLMToolCall requires outputKey");
|
|
4796
|
+
}
|
|
4797
|
+
this.provider = config.provider;
|
|
4798
|
+
this.model = config.model;
|
|
4799
|
+
this.systemPrompt = config.systemPrompt;
|
|
4800
|
+
this.messagesKey = config.messagesKey;
|
|
4801
|
+
this.userMessageKey = config.userMessageKey;
|
|
4802
|
+
this.toolsKey = config.toolsKey;
|
|
4803
|
+
this.tools = config.tools;
|
|
4804
|
+
this.temperature = config.temperature;
|
|
4805
|
+
this.maxTokens = config.maxTokens;
|
|
4806
|
+
this.outputKey = config.outputKey;
|
|
4807
|
+
}
|
|
4808
|
+
async executeTick(context) {
|
|
4809
|
+
if (!context.activities?.agentLoopTurn) {
|
|
4810
|
+
this._lastError = "LLMToolCall requires activities.agentLoopTurn to be configured.";
|
|
4811
|
+
this.log(`Error: ${this._lastError}`);
|
|
4812
|
+
return "FAILURE" /* FAILURE */;
|
|
4813
|
+
}
|
|
4814
|
+
try {
|
|
4815
|
+
const varCtx = {
|
|
4816
|
+
blackboard: context.blackboard,
|
|
4817
|
+
input: context.input,
|
|
4818
|
+
testData: context.testData
|
|
4819
|
+
};
|
|
4820
|
+
let messages = context.blackboard.get(this.messagesKey) || [];
|
|
4821
|
+
if (this.userMessageKey) {
|
|
4822
|
+
const userMsg = context.blackboard.get(this.userMessageKey);
|
|
4823
|
+
if (userMsg !== void 0 && userMsg !== null) {
|
|
4824
|
+
const content = typeof userMsg === "string" ? userMsg : String(userMsg);
|
|
4825
|
+
messages = [...messages, { role: "user", content }];
|
|
4826
|
+
context.blackboard.set(this.userMessageKey, null);
|
|
4827
|
+
}
|
|
4828
|
+
}
|
|
4829
|
+
const tools = this.toolsKey ? context.blackboard.get(this.toolsKey) || [] : this.tools || [];
|
|
4830
|
+
const resolvedModel = resolveValue(this.model, varCtx);
|
|
4831
|
+
const resolvedSystemPrompt = this.systemPrompt ? resolveValue(this.systemPrompt, varCtx) : void 0;
|
|
4832
|
+
const streamChannelId = context.blackboard.get("__streamChannelId");
|
|
4833
|
+
const request = {
|
|
4834
|
+
provider: this.provider,
|
|
4835
|
+
model: resolvedModel,
|
|
4836
|
+
systemPrompt: resolvedSystemPrompt,
|
|
4837
|
+
messages,
|
|
4838
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
4839
|
+
temperature: this.temperature,
|
|
4840
|
+
maxTokens: this.maxTokens,
|
|
4841
|
+
streamChannelId: streamChannelId || void 0
|
|
4842
|
+
};
|
|
4843
|
+
this.log(
|
|
4844
|
+
`LLMToolCall ${this.provider}/${resolvedModel} - ${messages.length} messages, ${tools.length} tools`
|
|
4845
|
+
);
|
|
4846
|
+
const result = await context.activities.agentLoopTurn(request);
|
|
4847
|
+
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
4848
|
+
const contentBlocks = [];
|
|
4849
|
+
if (result.content) {
|
|
4850
|
+
contentBlocks.push({ type: "text", text: result.content });
|
|
4851
|
+
}
|
|
4852
|
+
for (const tc of result.toolCalls) {
|
|
4853
|
+
contentBlocks.push({
|
|
4854
|
+
type: "tool_use",
|
|
4855
|
+
id: tc.id,
|
|
4856
|
+
name: tc.name,
|
|
4857
|
+
input: tc.input
|
|
4858
|
+
});
|
|
4859
|
+
}
|
|
4860
|
+
messages = [...messages, { role: "assistant", content: contentBlocks }];
|
|
4861
|
+
} else {
|
|
4862
|
+
messages = [...messages, { role: "assistant", content: result.content }];
|
|
4863
|
+
}
|
|
4864
|
+
context.blackboard.set(this.messagesKey, messages);
|
|
4865
|
+
context.blackboard.set(this.outputKey, {
|
|
4866
|
+
content: result.content,
|
|
4867
|
+
toolCalls: result.toolCalls,
|
|
4868
|
+
stopReason: result.stopReason,
|
|
4869
|
+
usage: result.usage
|
|
4870
|
+
});
|
|
4871
|
+
this.log(
|
|
4872
|
+
`LLMToolCall completed: stopReason=${result.stopReason}, tools=${result.toolCalls?.length || 0}, tokens=${result.usage.totalTokens}`
|
|
4873
|
+
);
|
|
4874
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4875
|
+
} catch (error) {
|
|
4876
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4877
|
+
this.log(`LLMToolCall failed: ${this._lastError}`);
|
|
4878
|
+
return "FAILURE" /* FAILURE */;
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
};
|
|
4882
|
+
|
|
4883
|
+
// src/actions/tool-executor.ts
|
|
4884
|
+
var ToolExecutor = class extends ActionNode {
|
|
4885
|
+
responseKey;
|
|
4886
|
+
messagesKey;
|
|
4887
|
+
outputKey;
|
|
4888
|
+
constructor(config) {
|
|
4889
|
+
super(config);
|
|
4890
|
+
if (!config.responseKey) {
|
|
4891
|
+
throw new ConfigurationError("ToolExecutor requires responseKey");
|
|
4892
|
+
}
|
|
4893
|
+
if (!config.messagesKey) {
|
|
4894
|
+
throw new ConfigurationError("ToolExecutor requires messagesKey");
|
|
4895
|
+
}
|
|
4896
|
+
this.responseKey = config.responseKey;
|
|
4897
|
+
this.messagesKey = config.messagesKey;
|
|
4898
|
+
this.outputKey = config.outputKey;
|
|
4899
|
+
}
|
|
4900
|
+
async executeTick(context) {
|
|
4901
|
+
if (!context.activities?.executeAgentTool) {
|
|
4902
|
+
this._lastError = "ToolExecutor requires activities.executeAgentTool to be configured.";
|
|
4903
|
+
this.log(`Error: ${this._lastError}`);
|
|
4904
|
+
return "FAILURE" /* FAILURE */;
|
|
4905
|
+
}
|
|
4906
|
+
try {
|
|
4907
|
+
const response = context.blackboard.get(this.responseKey);
|
|
4908
|
+
const toolCalls = response?.toolCalls;
|
|
4909
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
4910
|
+
this.log("No tool calls to execute");
|
|
4911
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4912
|
+
}
|
|
4913
|
+
const toolResults = [];
|
|
4914
|
+
for (const tc of toolCalls) {
|
|
4915
|
+
this.log(`Executing tool: ${tc.name} (${tc.id})`);
|
|
4916
|
+
const result = await context.activities.executeAgentTool({
|
|
4917
|
+
toolName: tc.name,
|
|
4918
|
+
toolInput: tc.input
|
|
4919
|
+
});
|
|
4920
|
+
toolResults.push({
|
|
4921
|
+
toolUseId: tc.id,
|
|
4922
|
+
toolName: tc.name,
|
|
4923
|
+
content: result.content,
|
|
4924
|
+
isError: result.isError
|
|
4925
|
+
});
|
|
4926
|
+
this.log(
|
|
4927
|
+
`Tool ${tc.name} ${result.isError ? "errored" : "completed"}: ${result.content.substring(0, 100)}`
|
|
4928
|
+
);
|
|
4929
|
+
}
|
|
4930
|
+
const resultBlocks = toolResults.map((tr) => ({
|
|
4931
|
+
type: "tool_result",
|
|
4932
|
+
tool_use_id: tr.toolUseId,
|
|
4933
|
+
content: tr.content,
|
|
4934
|
+
is_error: tr.isError
|
|
4935
|
+
}));
|
|
4936
|
+
const messages = context.blackboard.get(this.messagesKey) || [];
|
|
4937
|
+
const updatedMessages = [
|
|
4938
|
+
...messages,
|
|
4939
|
+
{ role: "user", content: resultBlocks }
|
|
4940
|
+
];
|
|
4941
|
+
context.blackboard.set(this.messagesKey, updatedMessages);
|
|
4942
|
+
if (this.outputKey) {
|
|
4943
|
+
context.blackboard.set(this.outputKey, toolResults);
|
|
4944
|
+
}
|
|
4945
|
+
this.log(`Executed ${toolResults.length} tool(s), results appended to conversation`);
|
|
4946
|
+
return "SUCCESS" /* SUCCESS */;
|
|
4947
|
+
} catch (error) {
|
|
4948
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
4949
|
+
this.log(`ToolExecutor failed: ${this._lastError}`);
|
|
4950
|
+
return "FAILURE" /* FAILURE */;
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
};
|
|
4954
|
+
|
|
4955
|
+
// src/actions/wait-for-signal.ts
|
|
4956
|
+
var WaitForSignal = class extends ActionNode {
|
|
4957
|
+
signalName;
|
|
4958
|
+
signalKey;
|
|
4959
|
+
timeoutMs;
|
|
4960
|
+
outputKey;
|
|
4961
|
+
constructor(config) {
|
|
4962
|
+
super(config);
|
|
4963
|
+
if (!config.signalName) {
|
|
4964
|
+
throw new ConfigurationError("WaitForSignal requires signalName");
|
|
4965
|
+
}
|
|
4966
|
+
if (!config.outputKey) {
|
|
4967
|
+
throw new ConfigurationError("WaitForSignal requires outputKey");
|
|
4968
|
+
}
|
|
4969
|
+
this.signalName = config.signalName;
|
|
4970
|
+
this.signalKey = config.signalKey;
|
|
4971
|
+
this.timeoutMs = config.timeoutMs ?? 864e5;
|
|
4972
|
+
this.outputKey = config.outputKey;
|
|
4973
|
+
}
|
|
4974
|
+
async executeTick(context) {
|
|
4975
|
+
if (!context.activities?.waitForSignal) {
|
|
4976
|
+
this._lastError = "WaitForSignal requires activities.waitForSignal to be configured. This is implemented as a Temporal condition in the workflow layer.";
|
|
4977
|
+
this.log(`Error: ${this._lastError}`);
|
|
4978
|
+
return "FAILURE" /* FAILURE */;
|
|
4979
|
+
}
|
|
4980
|
+
try {
|
|
4981
|
+
const varCtx = {
|
|
4982
|
+
blackboard: context.blackboard,
|
|
4983
|
+
input: context.input,
|
|
4984
|
+
testData: context.testData
|
|
4985
|
+
};
|
|
4986
|
+
const resolvedSignalKey = this.signalKey ? resolveValue(this.signalKey, varCtx) : void 0;
|
|
4987
|
+
this.log(
|
|
4988
|
+
`Waiting for signal "${this.signalName}"${resolvedSignalKey ? `:${resolvedSignalKey}` : ""} (timeout: ${this.timeoutMs}ms)`
|
|
4989
|
+
);
|
|
4990
|
+
const result = await context.activities.waitForSignal({
|
|
4991
|
+
signalName: this.signalName,
|
|
4992
|
+
signalKey: resolvedSignalKey,
|
|
4993
|
+
timeoutMs: this.timeoutMs
|
|
4994
|
+
});
|
|
4995
|
+
if (result.timedOut) {
|
|
4996
|
+
this._lastError = `Signal "${this.signalName}" timed out after ${this.timeoutMs}ms`;
|
|
4997
|
+
this.log(this._lastError);
|
|
4998
|
+
return "FAILURE" /* FAILURE */;
|
|
4999
|
+
}
|
|
5000
|
+
context.blackboard.set(this.outputKey, result.data);
|
|
5001
|
+
this.log(`Signal received, data stored at "${this.outputKey}"`);
|
|
5002
|
+
return "SUCCESS" /* SUCCESS */;
|
|
5003
|
+
} catch (error) {
|
|
5004
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
5005
|
+
this.log(`WaitForSignal failed: ${this._lastError}`);
|
|
5006
|
+
return "FAILURE" /* FAILURE */;
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
5009
|
+
};
|
|
5010
|
+
|
|
5011
|
+
// src/actions/tool-router.ts
|
|
5012
|
+
var ToolRouter = class extends ActionNode {
|
|
5013
|
+
intentKey;
|
|
5014
|
+
toolSets;
|
|
5015
|
+
defaultTools;
|
|
5016
|
+
rules;
|
|
5017
|
+
outputKey;
|
|
5018
|
+
constructor(config) {
|
|
5019
|
+
super(config);
|
|
5020
|
+
if (!config.intentKey) {
|
|
5021
|
+
throw new ConfigurationError("ToolRouter requires intentKey");
|
|
5022
|
+
}
|
|
5023
|
+
if (!config.toolSets || Object.keys(config.toolSets).length === 0) {
|
|
5024
|
+
throw new ConfigurationError("ToolRouter requires at least one toolSet");
|
|
5025
|
+
}
|
|
5026
|
+
if (!config.outputKey) {
|
|
5027
|
+
throw new ConfigurationError("ToolRouter requires outputKey");
|
|
5028
|
+
}
|
|
5029
|
+
this.intentKey = config.intentKey;
|
|
5030
|
+
this.toolSets = config.toolSets;
|
|
5031
|
+
this.defaultTools = config.defaultTools || [];
|
|
5032
|
+
this.rules = config.rules || [];
|
|
5033
|
+
this.outputKey = config.outputKey;
|
|
5034
|
+
}
|
|
5035
|
+
async executeTick(context) {
|
|
5036
|
+
try {
|
|
5037
|
+
const varCtx = {
|
|
5038
|
+
blackboard: context.blackboard,
|
|
5039
|
+
input: context.input,
|
|
5040
|
+
testData: context.testData
|
|
5041
|
+
};
|
|
5042
|
+
const intentRaw = context.blackboard.get(this.intentKey);
|
|
5043
|
+
const intent = typeof intentRaw === "string" ? intentRaw : "";
|
|
5044
|
+
const selectedSetNames = new Set(this.defaultTools);
|
|
5045
|
+
for (const rule of this.rules) {
|
|
5046
|
+
const regex = new RegExp(rule.pattern, "i");
|
|
5047
|
+
if (regex.test(intent)) {
|
|
5048
|
+
for (const setName of rule.toolSets) {
|
|
5049
|
+
selectedSetNames.add(setName);
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
5052
|
+
}
|
|
5053
|
+
const toolsByName = /* @__PURE__ */ new Map();
|
|
5054
|
+
for (const setName of selectedSetNames) {
|
|
5055
|
+
const tools = this.toolSets[setName];
|
|
5056
|
+
if (tools) {
|
|
5057
|
+
for (const tool of tools) {
|
|
5058
|
+
if (!toolsByName.has(tool.name)) {
|
|
5059
|
+
toolsByName.set(tool.name, tool);
|
|
5060
|
+
}
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
const selectedTools = Array.from(toolsByName.values());
|
|
5065
|
+
context.blackboard.set(this.outputKey, selectedTools);
|
|
5066
|
+
this.log(
|
|
5067
|
+
`Selected ${selectedTools.length} tools from sets [${Array.from(selectedSetNames).join(", ")}] for intent "${intent.substring(0, 50)}"`
|
|
5068
|
+
);
|
|
5069
|
+
return "SUCCESS" /* SUCCESS */;
|
|
5070
|
+
} catch (error) {
|
|
5071
|
+
this._lastError = error instanceof Error ? error.message : String(error);
|
|
5072
|
+
this.log(`ToolRouter failed: ${this._lastError}`);
|
|
5073
|
+
return "FAILURE" /* FAILURE */;
|
|
5074
|
+
}
|
|
5075
|
+
}
|
|
5076
|
+
};
|
|
5077
|
+
|
|
4587
5078
|
// src/registry-utils.ts
|
|
4588
5079
|
function registerStandardNodes(registry) {
|
|
4589
5080
|
registry.register("Sequence", Sequence, { category: "composite" });
|
|
@@ -4637,6 +5128,7 @@ function registerStandardNodes(registry) {
|
|
|
4637
5128
|
registry.register("WaitAction", WaitAction, { category: "action" });
|
|
4638
5129
|
registry.register("LogMessage", LogMessage, { category: "action" });
|
|
4639
5130
|
registry.register("RegexExtract", RegexExtract, { category: "action" });
|
|
5131
|
+
registry.register("SetVariable", SetVariable, { category: "action" });
|
|
4640
5132
|
registry.register("IntegrationAction", IntegrationAction, { category: "action" });
|
|
4641
5133
|
registry.register("PythonScript", PythonScript, { category: "action" });
|
|
4642
5134
|
registry.register("ParseFile", ParseFile, { category: "action" });
|
|
@@ -4648,6 +5140,11 @@ function registerStandardNodes(registry) {
|
|
|
4648
5140
|
registry.register("ClaudeAgent", ClaudeAgent, { category: "action" });
|
|
4649
5141
|
registry.register("GitHubAction", GitHubAction, { category: "action" });
|
|
4650
5142
|
registry.register("HumanTask", HumanTask, { category: "action" });
|
|
5143
|
+
registry.register("LLMToolCall", LLMToolCall, { category: "action" });
|
|
5144
|
+
registry.register("ToolExecutor", ToolExecutor, { category: "action" });
|
|
5145
|
+
registry.register("WaitForSignal", WaitForSignal, { category: "action" });
|
|
5146
|
+
registry.register("ToolRouter", ToolRouter, { category: "action" });
|
|
5147
|
+
registry.register("StreamingSink", StreamingSink, { category: "decorator" });
|
|
4651
5148
|
}
|
|
4652
5149
|
|
|
4653
5150
|
// src/data-store/memory-store.ts
|
|
@@ -5511,6 +6008,7 @@ function createObservabilitySinkHandler(config = {}) {
|
|
|
5511
6008
|
Invert,
|
|
5512
6009
|
KeepRunningUntilFailure,
|
|
5513
6010
|
LLMChat,
|
|
6011
|
+
LLMToolCall,
|
|
5514
6012
|
LogMessage,
|
|
5515
6013
|
MemoryDataStore,
|
|
5516
6014
|
MemorySequence,
|
|
@@ -5537,14 +6035,19 @@ function createObservabilitySinkHandler(config = {}) {
|
|
|
5537
6035
|
SemanticValidationError,
|
|
5538
6036
|
Sequence,
|
|
5539
6037
|
SequenceWithMemory,
|
|
6038
|
+
SetVariable,
|
|
5540
6039
|
SoftAssert,
|
|
6040
|
+
StreamingSink,
|
|
5541
6041
|
StructureValidationError,
|
|
5542
6042
|
SubTree,
|
|
5543
6043
|
SuccessNode,
|
|
5544
6044
|
Timeout,
|
|
6045
|
+
ToolExecutor,
|
|
6046
|
+
ToolRouter,
|
|
5545
6047
|
ValidationError,
|
|
5546
6048
|
ValidationErrors,
|
|
5547
6049
|
WaitAction,
|
|
6050
|
+
WaitForSignal,
|
|
5548
6051
|
While,
|
|
5549
6052
|
YamlSyntaxError,
|
|
5550
6053
|
clearPieceCache,
|