@hexabot-ai/agentic 3.0.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +120 -0
- package/README.md +231 -0
- package/dist/cjs/action/abstract-action.js +141 -0
- package/dist/cjs/action/action.js +47 -0
- package/dist/cjs/action/action.types.js +7 -0
- package/dist/cjs/bindings/base-binding.js +278 -0
- package/dist/cjs/context.js +79 -0
- package/dist/cjs/dsl.types.js +318 -0
- package/dist/cjs/index.js +52 -0
- package/dist/cjs/runner-runtime-control.js +343 -0
- package/dist/cjs/step-executors/conditional-executor.js +63 -0
- package/dist/cjs/step-executors/loop-executor.js +187 -0
- package/dist/cjs/step-executors/parallel-executor.js +51 -0
- package/dist/cjs/step-executors/skip-helpers.js +29 -0
- package/dist/cjs/step-executors/task-executor.js +155 -0
- package/dist/cjs/step-executors/types.js +7 -0
- package/dist/cjs/suspension-rebuilder.js +301 -0
- package/dist/cjs/utils/deferred.js +17 -0
- package/dist/cjs/utils/naming.js +48 -0
- package/dist/cjs/utils/timeout.js +42 -0
- package/dist/cjs/utils/workflow-definition.js +102 -0
- package/dist/cjs/workflow-compiler.js +212 -0
- package/dist/cjs/workflow-event-emitter.js +40 -0
- package/dist/cjs/workflow-runner.js +448 -0
- package/dist/cjs/workflow-types.js +7 -0
- package/dist/cjs/workflow-values.js +99 -0
- package/dist/cjs/workflow.js +243 -0
- package/dist/esm/action/abstract-action.js +137 -0
- package/dist/esm/action/action.js +44 -0
- package/dist/esm/action/action.types.js +6 -0
- package/dist/esm/bindings/base-binding.js +273 -0
- package/dist/esm/context.js +75 -0
- package/dist/esm/dsl.types.js +309 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/runner-runtime-control.js +338 -0
- package/dist/esm/step-executors/conditional-executor.js +60 -0
- package/dist/esm/step-executors/loop-executor.js +182 -0
- package/dist/esm/step-executors/parallel-executor.js +48 -0
- package/dist/esm/step-executors/skip-helpers.js +25 -0
- package/dist/esm/step-executors/task-executor.js +152 -0
- package/dist/esm/step-executors/types.js +6 -0
- package/dist/esm/suspension-rebuilder.js +296 -0
- package/dist/esm/utils/deferred.js +14 -0
- package/dist/esm/utils/naming.js +42 -0
- package/dist/esm/utils/timeout.js +37 -0
- package/dist/esm/utils/workflow-definition.js +98 -0
- package/dist/esm/workflow-compiler.js +208 -0
- package/dist/esm/workflow-event-emitter.js +36 -0
- package/dist/esm/workflow-runner.js +444 -0
- package/dist/esm/workflow-types.js +6 -0
- package/dist/esm/workflow-values.js +89 -0
- package/dist/esm/workflow.js +236 -0
- package/dist/types/action/abstract-action.d.ts +54 -0
- package/dist/types/action/abstract-action.d.ts.map +1 -0
- package/dist/types/action/action.d.ts +23 -0
- package/dist/types/action/action.d.ts.map +1 -0
- package/dist/types/action/action.types.d.ts +55 -0
- package/dist/types/action/action.types.d.ts.map +1 -0
- package/dist/types/bindings/base-binding.d.ts +52 -0
- package/dist/types/bindings/base-binding.d.ts.map +1 -0
- package/dist/types/context.d.ts +105 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/dsl.types.d.ts +220 -0
- package/dist/types/dsl.types.d.ts.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/runner-runtime-control.d.ts +64 -0
- package/dist/types/runner-runtime-control.d.ts.map +1 -0
- package/dist/types/step-executors/conditional-executor.d.ts +13 -0
- package/dist/types/step-executors/conditional-executor.d.ts.map +1 -0
- package/dist/types/step-executors/loop-executor.d.ts +33 -0
- package/dist/types/step-executors/loop-executor.d.ts.map +1 -0
- package/dist/types/step-executors/parallel-executor.d.ts +14 -0
- package/dist/types/step-executors/parallel-executor.d.ts.map +1 -0
- package/dist/types/step-executors/skip-helpers.d.ts +12 -0
- package/dist/types/step-executors/skip-helpers.d.ts.map +1 -0
- package/dist/types/step-executors/task-executor.d.ts +13 -0
- package/dist/types/step-executors/task-executor.d.ts.map +1 -0
- package/dist/types/step-executors/types.d.ts +24 -0
- package/dist/types/step-executors/types.d.ts.map +1 -0
- package/dist/types/suspension-rebuilder.d.ts +67 -0
- package/dist/types/suspension-rebuilder.d.ts.map +1 -0
- package/dist/types/utils/deferred.d.ts +7 -0
- package/dist/types/utils/deferred.d.ts.map +1 -0
- package/dist/types/utils/naming.d.ts +24 -0
- package/dist/types/utils/naming.d.ts.map +1 -0
- package/dist/types/utils/timeout.d.ts +17 -0
- package/dist/types/utils/timeout.d.ts.map +1 -0
- package/dist/types/utils/workflow-definition.d.ts +3 -0
- package/dist/types/utils/workflow-definition.d.ts.map +1 -0
- package/dist/types/workflow-compiler.d.ts +12 -0
- package/dist/types/workflow-compiler.d.ts.map +1 -0
- package/dist/types/workflow-event-emitter.d.ts +70 -0
- package/dist/types/workflow-event-emitter.d.ts.map +1 -0
- package/dist/types/workflow-runner.d.ts +179 -0
- package/dist/types/workflow-runner.d.ts.map +1 -0
- package/dist/types/workflow-types.d.ts +195 -0
- package/dist/types/workflow-types.d.ts.map +1 -0
- package/dist/types/workflow-values.d.ts +34 -0
- package/dist/types/workflow-values.d.ts.map +1 -0
- package/dist/types/workflow.d.ts +75 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/examples/defs-bindings-agent/actions/ai-agent.ts +110 -0
- package/examples/defs-bindings-agent/actions/caculate-score.ts +49 -0
- package/examples/defs-bindings-agent/actions/index.ts +15 -0
- package/examples/defs-bindings-agent/bindings.ts +20 -0
- package/examples/defs-bindings-agent/context.ts +32 -0
- package/examples/defs-bindings-agent/workflow.ts +67 -0
- package/examples/defs-bindings-agent/workflow.yml +28 -0
- package/examples/full/actions/await-user-input.ts +46 -0
- package/examples/full/actions/call-llm.ts +133 -0
- package/examples/full/actions/create-ticket.ts +46 -0
- package/examples/full/actions/decision-router.ts +83 -0
- package/examples/full/actions/get-calendar-events.ts +55 -0
- package/examples/full/actions/get-user-profile.ts +72 -0
- package/examples/full/actions/index.ts +33 -0
- package/examples/full/actions/query-memory.ts +45 -0
- package/examples/full/actions/search-web.ts +53 -0
- package/examples/full/actions/send-email.ts +50 -0
- package/examples/full/context.ts +41 -0
- package/examples/full/workflow.ts +75 -0
- package/examples/full/workflow.yml +359 -0
- package/examples/loop/actions/await-reply.ts +47 -0
- package/examples/loop/actions/index.ts +19 -0
- package/examples/loop/actions/send-text-message.ts +40 -0
- package/examples/loop/context.ts +32 -0
- package/examples/loop/workflow.ts +66 -0
- package/examples/loop/workflow.yml +66 -0
- package/examples/suspend-resume/actions/format-reply.ts +43 -0
- package/examples/suspend-resume/actions/index.ts +13 -0
- package/examples/suspend-resume/actions/wait-for-user.ts +51 -0
- package/examples/suspend-resume/context.ts +32 -0
- package/examples/suspend-resume/workflow.ts +79 -0
- package/examples/suspend-resume/workflow.yml +29 -0
- package/package.json +60 -0
- package/src/__tests__/parser.test.ts +95 -0
- package/src/__tests__/suspension-rebuilder.test.ts +361 -0
- package/src/__tests__/test-helpers.ts +36 -0
- package/src/__tests__/validation.test.ts +526 -0
- package/src/__tests__/workflow-compiler.test.ts +715 -0
- package/src/__tests__/workflow-definition-path.test.ts +381 -0
- package/src/__tests__/workflow-event-emitter.test.ts +50 -0
- package/src/__tests__/workflow-runner.test.ts +1397 -0
- package/src/__tests__/workflow-values.test.ts +132 -0
- package/src/__tests__/workflow.test.ts +320 -0
- package/src/action/__tests__/abstract-action-timing.test.ts +183 -0
- package/src/action/__tests__/action.test.ts +473 -0
- package/src/action/abstract-action.ts +215 -0
- package/src/action/action.ts +83 -0
- package/src/action/action.types.ts +93 -0
- package/src/bindings/base-binding.ts +508 -0
- package/src/context.ts +179 -0
- package/src/dsl.types.ts +473 -0
- package/src/index.ts +114 -0
- package/src/runner-runtime-control.ts +544 -0
- package/src/step-executors/conditional-executor.test.ts +192 -0
- package/src/step-executors/conditional-executor.ts +83 -0
- package/src/step-executors/loop-executor.test.ts +303 -0
- package/src/step-executors/loop-executor.ts +299 -0
- package/src/step-executors/parallel-executor.test.ts +182 -0
- package/src/step-executors/parallel-executor.ts +77 -0
- package/src/step-executors/skip-helpers.ts +68 -0
- package/src/step-executors/task-executor.test.ts +257 -0
- package/src/step-executors/task-executor.ts +248 -0
- package/src/step-executors/types.ts +70 -0
- package/src/suspension-rebuilder.ts +504 -0
- package/src/utils/deferred.ts +23 -0
- package/src/utils/naming.ts +55 -0
- package/src/utils/timeout.ts +48 -0
- package/src/utils/workflow-definition.ts +173 -0
- package/src/workflow-compiler.ts +317 -0
- package/src/workflow-event-emitter.ts +86 -0
- package/src/workflow-runner.ts +603 -0
- package/src/workflow-types.ts +207 -0
- package/src/workflow-values.ts +159 -0
- package/src/workflow.ts +387 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
8
|
+
import { stepCountIs, tool, ToolLoopAgent, type ToolSet } from 'ai';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
|
|
11
|
+
import { defineAction } from '../../../src';
|
|
12
|
+
import type { AgentBindings } from '../bindings';
|
|
13
|
+
import type { AgentExampleContext } from '../context';
|
|
14
|
+
|
|
15
|
+
import { caculateScore } from './caculate-score';
|
|
16
|
+
|
|
17
|
+
const actionRegistry = {
|
|
18
|
+
caculate_score: caculateScore,
|
|
19
|
+
} as const;
|
|
20
|
+
const inputSchema = z.strictObject({
|
|
21
|
+
prompt: z.string(),
|
|
22
|
+
system: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
const outputSchema = z.strictObject({
|
|
25
|
+
steps: z.array(z.unknown()).optional(),
|
|
26
|
+
text: z.string(),
|
|
27
|
+
tool_calls: z.array(z.unknown()).optional(),
|
|
28
|
+
tool_results: z.array(z.unknown()).optional(),
|
|
29
|
+
});
|
|
30
|
+
const settingSchema = z.strictObject({
|
|
31
|
+
api_key: z.string().optional(),
|
|
32
|
+
max_steps: z.int().positive().default(2),
|
|
33
|
+
model: z.string().default('gpt-4o'),
|
|
34
|
+
provider: z.literal('openai').default('openai'),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
type AiAgentInput = z.infer<typeof inputSchema>;
|
|
38
|
+
type AiAgentOutput = z.infer<typeof outputSchema>;
|
|
39
|
+
type AiAgentSettings = z.infer<typeof settingSchema>;
|
|
40
|
+
|
|
41
|
+
const resolveTools = (
|
|
42
|
+
bindings: AgentBindings,
|
|
43
|
+
context: AgentExampleContext,
|
|
44
|
+
): ToolSet => {
|
|
45
|
+
const mountedTools = bindings.tools ?? {};
|
|
46
|
+
const tools: ToolSet = {};
|
|
47
|
+
|
|
48
|
+
for (const [toolName, toolDefinition] of Object.entries(mountedTools)) {
|
|
49
|
+
const actionName = toolDefinition.action as keyof typeof actionRegistry;
|
|
50
|
+
const action = actionRegistry[actionName];
|
|
51
|
+
|
|
52
|
+
if (!action) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Unsupported tool action "${String(toolDefinition.action)}" mounted in bindings.tools.${toolName}`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
tools[toolName] = tool({
|
|
59
|
+
description: `Workflow tool "${toolName}" delegates to action "${action.name}".`,
|
|
60
|
+
inputSchema: action.inputSchema,
|
|
61
|
+
execute: async (payload) =>
|
|
62
|
+
action.run(payload, context, toolDefinition.settings as any),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return tools;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const aiAgent = defineAction<
|
|
70
|
+
AiAgentInput,
|
|
71
|
+
AiAgentOutput,
|
|
72
|
+
AgentExampleContext,
|
|
73
|
+
AiAgentSettings,
|
|
74
|
+
AgentBindings
|
|
75
|
+
>({
|
|
76
|
+
name: 'ai_agent',
|
|
77
|
+
description:
|
|
78
|
+
'Runs a Vercel AI SDK ToolLoopAgent and resolves workflow-mounted tools through action bindings.',
|
|
79
|
+
supportedBindings: ['tools'],
|
|
80
|
+
inputSchema,
|
|
81
|
+
outputSchema,
|
|
82
|
+
settingSchema,
|
|
83
|
+
execute: async ({ input, settings, context, bindings }) => {
|
|
84
|
+
const apiKey = settings.api_key ?? process.env.OPENAI_API_KEY;
|
|
85
|
+
|
|
86
|
+
if (!apiKey) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
'Missing OpenAI API key. Set settings.api_key or OPENAI_API_KEY.',
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const provider = createOpenAI({ apiKey });
|
|
93
|
+
const model = provider(settings.model);
|
|
94
|
+
const tools = resolveTools(bindings, context);
|
|
95
|
+
const agent = new ToolLoopAgent({
|
|
96
|
+
...(input.system ? { instructions: input.system } : {}),
|
|
97
|
+
model,
|
|
98
|
+
stopWhen: stepCountIs(settings.max_steps),
|
|
99
|
+
tools,
|
|
100
|
+
});
|
|
101
|
+
const result = await agent.generate({ prompt: input.prompt });
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
steps: result.steps,
|
|
105
|
+
text: result.text,
|
|
106
|
+
tool_calls: result.toolCalls,
|
|
107
|
+
tool_results: result.toolResults,
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import { defineAction } from '../../../src';
|
|
10
|
+
import type { AgentExampleContext } from '../context';
|
|
11
|
+
|
|
12
|
+
const inputSchema = z.strictObject({
|
|
13
|
+
x: z.number(),
|
|
14
|
+
});
|
|
15
|
+
const outputSchema = z.strictObject({
|
|
16
|
+
formula: z.string(),
|
|
17
|
+
result: z.number(),
|
|
18
|
+
});
|
|
19
|
+
const settingSchema = z.strictObject({
|
|
20
|
+
bias: z.number().default(0),
|
|
21
|
+
multiplier: z.number().default(1),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
type CaculateScoreInput = z.infer<typeof inputSchema>;
|
|
25
|
+
type CaculateScoreOutput = z.infer<typeof outputSchema>;
|
|
26
|
+
type CaculateScoreSettings = z.infer<typeof settingSchema>;
|
|
27
|
+
|
|
28
|
+
export const caculateScore = defineAction<
|
|
29
|
+
CaculateScoreInput,
|
|
30
|
+
CaculateScoreOutput,
|
|
31
|
+
AgentExampleContext,
|
|
32
|
+
CaculateScoreSettings
|
|
33
|
+
>({
|
|
34
|
+
name: 'caculate_score',
|
|
35
|
+
description: 'Calculates a score with score = multiplier * x + bias.',
|
|
36
|
+
inputSchema,
|
|
37
|
+
outputSchema,
|
|
38
|
+
settingSchema,
|
|
39
|
+
execute: async ({ input, settings }) => {
|
|
40
|
+
const result = settings.multiplier * input.x + settings.bias;
|
|
41
|
+
|
|
42
|
+
console.log(`[workflow] Calculating score for x=${input.x}`);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
formula: `${settings.multiplier} * ${input.x} + ${settings.bias}`,
|
|
46
|
+
result,
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Action } from '../../../src';
|
|
8
|
+
|
|
9
|
+
import { aiAgent } from './ai-agent';
|
|
10
|
+
import { caculateScore } from './caculate-score';
|
|
11
|
+
|
|
12
|
+
export const defsBindingsActions: Record<string, Action> = {
|
|
13
|
+
ai_agent: aiAgent,
|
|
14
|
+
caculate_score: caculateScore,
|
|
15
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import type { InferWorkflowBindings } from '../../src';
|
|
10
|
+
|
|
11
|
+
export const bindingKinds = {
|
|
12
|
+
tools: {
|
|
13
|
+
schema: z.record(z.string(), z.unknown()),
|
|
14
|
+
multiple: true,
|
|
15
|
+
actionPolicy: 'required' as const,
|
|
16
|
+
supportedBindings: ['tools'],
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type AgentBindings = InferWorkflowBindings<typeof bindingKinds>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
BaseWorkflowContext,
|
|
9
|
+
WorkflowEventEmitter,
|
|
10
|
+
type WorkflowEventEmitterLike,
|
|
11
|
+
} from '../../src';
|
|
12
|
+
|
|
13
|
+
export type AgentExampleContextState = {
|
|
14
|
+
request_id: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class AgentExampleContext extends BaseWorkflowContext<AgentExampleContextState> {
|
|
18
|
+
public eventEmitter: WorkflowEventEmitterLike<WorkflowEventEmitter>;
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
state: AgentExampleContextState,
|
|
22
|
+
eventEmitter: WorkflowEventEmitterLike<WorkflowEventEmitter> = new WorkflowEventEmitter(),
|
|
23
|
+
) {
|
|
24
|
+
super(state);
|
|
25
|
+
this.eventEmitter = eventEmitter;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
log(message: string, payload?: unknown): void {
|
|
29
|
+
const suffix = payload === undefined ? '' : ` ${JSON.stringify(payload)}`;
|
|
30
|
+
console.log(`[workflow] ${message}${suffix}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
import { Workflow, WorkflowEventEmitter } from '../../src';
|
|
11
|
+
|
|
12
|
+
import { defsBindingsActions } from './actions';
|
|
13
|
+
import { bindingKinds } from './bindings';
|
|
14
|
+
import { AgentExampleContext } from './context';
|
|
15
|
+
|
|
16
|
+
const workflowPath = path.join(__dirname, 'workflow.yml');
|
|
17
|
+
|
|
18
|
+
async function main() {
|
|
19
|
+
const yamlSource = fs.readFileSync(workflowPath, 'utf8');
|
|
20
|
+
const workflow = Workflow.fromYaml(yamlSource, {
|
|
21
|
+
actions: defsBindingsActions,
|
|
22
|
+
bindingKinds,
|
|
23
|
+
});
|
|
24
|
+
const emitter = new WorkflowEventEmitter();
|
|
25
|
+
const context = new AgentExampleContext(
|
|
26
|
+
{
|
|
27
|
+
request_id: 'request-1',
|
|
28
|
+
},
|
|
29
|
+
emitter,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
emitter.on('hook:step:start', ({ step }) =>
|
|
33
|
+
context.log(`hook:step:start:${step.name}`),
|
|
34
|
+
);
|
|
35
|
+
emitter.on('hook:step:success', ({ step }) =>
|
|
36
|
+
context.log(`hook:step:success:${step.name}`),
|
|
37
|
+
);
|
|
38
|
+
emitter.on('hook:workflow:finish', ({ output }) =>
|
|
39
|
+
context.log('hook:workflow:finish', output),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const runner = await workflow.buildAsyncRunner();
|
|
43
|
+
const result = await runner.start({
|
|
44
|
+
inputData: {},
|
|
45
|
+
context,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (result.status === 'finished') {
|
|
49
|
+
console.log('Final workflow outputs:', result.output);
|
|
50
|
+
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (result.status === 'suspended') {
|
|
55
|
+
console.log(
|
|
56
|
+
`Workflow suspended at step ${result.step.id} for reason "${result.reason}"`,
|
|
57
|
+
result.data,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.error('Workflow failed:', result.error);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// OPENAI_API_KEY=... pnpm dlx ts-node packages/agentic/examples/defs-bindings-agent/workflow.ts
|
|
67
|
+
void main();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
defs:
|
|
3
|
+
calculate:
|
|
4
|
+
kind: tools
|
|
5
|
+
action: caculate_score
|
|
6
|
+
description: "LLM Tool to calculate the score"
|
|
7
|
+
settings:
|
|
8
|
+
multiplier: 2
|
|
9
|
+
bias: 1
|
|
10
|
+
my_agent:
|
|
11
|
+
kind: task
|
|
12
|
+
action: ai_agent
|
|
13
|
+
inputs:
|
|
14
|
+
prompt: "Caculate the score for x=10"
|
|
15
|
+
system: "You are a helpful assistant"
|
|
16
|
+
settings:
|
|
17
|
+
provider: "openai"
|
|
18
|
+
model: "gpt-4o"
|
|
19
|
+
max_steps: 2
|
|
20
|
+
bindings:
|
|
21
|
+
tools:
|
|
22
|
+
- calculate
|
|
23
|
+
|
|
24
|
+
flow:
|
|
25
|
+
- do: my_agent
|
|
26
|
+
|
|
27
|
+
outputs:
|
|
28
|
+
result: "=$output.my_agent.text"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import { defineAction } from '../../../src';
|
|
10
|
+
import { SettingsSchema } from '../../../src/dsl.types';
|
|
11
|
+
import type { ExampleContext } from '../context';
|
|
12
|
+
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
prompt: z.string(),
|
|
15
|
+
allow_attachments: z.boolean().optional(),
|
|
16
|
+
});
|
|
17
|
+
const outputSchema = z.object({
|
|
18
|
+
text: z.string().optional(),
|
|
19
|
+
attachments: z.array(z.string()).optional(),
|
|
20
|
+
});
|
|
21
|
+
const settingsSchema = SettingsSchema;
|
|
22
|
+
|
|
23
|
+
type AwaitUserInput = z.infer<typeof inputSchema>;
|
|
24
|
+
type AwaitUserOutput = z.infer<typeof outputSchema>;
|
|
25
|
+
type AwaitUserSettings = z.infer<typeof settingsSchema>;
|
|
26
|
+
|
|
27
|
+
export const awaitUserInput = defineAction<
|
|
28
|
+
AwaitUserInput,
|
|
29
|
+
AwaitUserOutput,
|
|
30
|
+
ExampleContext,
|
|
31
|
+
AwaitUserSettings
|
|
32
|
+
>({
|
|
33
|
+
name: 'await_user_input',
|
|
34
|
+
description: 'Placeholder action for human-in-the-loop pauses.',
|
|
35
|
+
inputSchema,
|
|
36
|
+
outputSchema,
|
|
37
|
+
settingSchema: settingsSchema,
|
|
38
|
+
execute: async ({ input, context }) => {
|
|
39
|
+
context.log('Would ask user to reply', { prompt: input.prompt });
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
text: 'Sample user reply for the demo run.',
|
|
43
|
+
attachments: input.allow_attachments ? ['file-attachment-id'] : [],
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import { defineAction } from '../../../src';
|
|
10
|
+
import { SettingsSchema } from '../../../src/dsl.types';
|
|
11
|
+
import type { ExampleContext } from '../context';
|
|
12
|
+
|
|
13
|
+
const inputSchema = z.record(z.any());
|
|
14
|
+
const outputSchema = z
|
|
15
|
+
.object({
|
|
16
|
+
intent: z.string().optional(),
|
|
17
|
+
confidence: z.number().optional(),
|
|
18
|
+
summary: z.string().optional(),
|
|
19
|
+
missing_fields: z.array(z.string()).optional(),
|
|
20
|
+
needs_human: z.boolean().optional(),
|
|
21
|
+
synthesis: z.string().optional(),
|
|
22
|
+
questions: z.array(z.string()).optional(),
|
|
23
|
+
message: z.string().optional(),
|
|
24
|
+
links: z.array(z.string()).optional(),
|
|
25
|
+
email: z.string().optional(),
|
|
26
|
+
cta: z.string().optional(),
|
|
27
|
+
})
|
|
28
|
+
.passthrough();
|
|
29
|
+
const settingsSchema = SettingsSchema;
|
|
30
|
+
|
|
31
|
+
type CallLlmInput = z.infer<typeof inputSchema>;
|
|
32
|
+
type CallLlmOutput = z.infer<typeof outputSchema>;
|
|
33
|
+
type CallLlmSettings = z.infer<typeof settingsSchema>;
|
|
34
|
+
|
|
35
|
+
const asString = (value: unknown, fallback: string): string => {
|
|
36
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return fallback;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const callLlm = defineAction<
|
|
44
|
+
CallLlmInput,
|
|
45
|
+
CallLlmOutput,
|
|
46
|
+
ExampleContext,
|
|
47
|
+
CallLlmSettings
|
|
48
|
+
>({
|
|
49
|
+
name: 'call_llm',
|
|
50
|
+
description:
|
|
51
|
+
'Mock LLM that returns deterministic data for the example workflow.',
|
|
52
|
+
inputSchema,
|
|
53
|
+
outputSchema,
|
|
54
|
+
settingSchema: settingsSchema,
|
|
55
|
+
execute: async ({ input }) => {
|
|
56
|
+
if ('system_prompt' in input) {
|
|
57
|
+
const query = asString(input.user_query, 'customer request');
|
|
58
|
+
const normalized = query.toLowerCase();
|
|
59
|
+
const intent =
|
|
60
|
+
normalized.includes('buy') || normalized.includes('price')
|
|
61
|
+
? 'sales'
|
|
62
|
+
: normalized.includes('support') ||
|
|
63
|
+
normalized.includes('bug') ||
|
|
64
|
+
normalized.includes('error')
|
|
65
|
+
? 'support'
|
|
66
|
+
: 'research';
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
intent,
|
|
70
|
+
confidence: intent === 'support' ? 0.92 : 0.88,
|
|
71
|
+
summary: query.slice(0, 120),
|
|
72
|
+
missing_fields: [],
|
|
73
|
+
needs_human: false,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
'news_snippets' in input ||
|
|
79
|
+
'memory_summary' in input ||
|
|
80
|
+
'meetings' in input
|
|
81
|
+
) {
|
|
82
|
+
const intent = asString(input.intent, 'request');
|
|
83
|
+
const profile = (input.profile as { company?: string }) ?? {};
|
|
84
|
+
const company = asString(profile.company, 'the customer');
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
synthesis: `Brief for ${company} (${intent}): combined recent context, meetings, and user clarification.`,
|
|
88
|
+
questions: ['Any extra constraints or deadlines?'],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if ('troubleshooting_guide' in input) {
|
|
93
|
+
const question = asString(input.question, 'your issue');
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
message: `Here is a support reply for ${question}.\n\n- Step 1: Restart.\n- Step 2: Apply guide specifics.`,
|
|
97
|
+
links: ['https://example.com/faq/diagnostics'],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if ('product_brief' in input) {
|
|
102
|
+
const companyNews = Array.isArray(input.company_news)
|
|
103
|
+
? input.company_news
|
|
104
|
+
: [];
|
|
105
|
+
const lead =
|
|
106
|
+
companyNews.length > 0
|
|
107
|
+
? companyNews[0]
|
|
108
|
+
: 'We have great news to share.';
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
email: `Thanks for your interest. ${lead}`,
|
|
112
|
+
cta: 'Schedule a call this week.',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if ('stakeholder' in input) {
|
|
117
|
+
const stakeholder = input.stakeholder as { name?: string };
|
|
118
|
+
const question = asString(input.question, 'the request');
|
|
119
|
+
const name = asString(stakeholder?.name, 'Stakeholder');
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
message: `${name}, quick update about ${question}. Research brief attached.`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const summary = asString(
|
|
127
|
+
input.summary,
|
|
128
|
+
'Here is a concise summary of your request.',
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return { message: summary };
|
|
132
|
+
},
|
|
133
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import { defineAction } from '../../../src';
|
|
10
|
+
import { SettingsSchema } from '../../../src/dsl.types';
|
|
11
|
+
import type { ExampleContext } from '../context';
|
|
12
|
+
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
user_id: z.string(),
|
|
15
|
+
transcript: z.unknown().optional(),
|
|
16
|
+
summary: z.string().optional(),
|
|
17
|
+
clarification: z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
const outputSchema = z.object({
|
|
20
|
+
ticket_id: z.string(),
|
|
21
|
+
status: z.string(),
|
|
22
|
+
});
|
|
23
|
+
const settingsSchema = SettingsSchema;
|
|
24
|
+
|
|
25
|
+
type CreateTicketInput = z.infer<typeof inputSchema>;
|
|
26
|
+
type CreateTicketOutput = z.infer<typeof outputSchema>;
|
|
27
|
+
type CreateTicketSettings = z.infer<typeof settingsSchema>;
|
|
28
|
+
|
|
29
|
+
export const createTicket = defineAction<
|
|
30
|
+
CreateTicketInput,
|
|
31
|
+
CreateTicketOutput,
|
|
32
|
+
ExampleContext,
|
|
33
|
+
CreateTicketSettings
|
|
34
|
+
>({
|
|
35
|
+
name: 'create_ticket',
|
|
36
|
+
description: 'Mocks creating a support ticket with the supplied context.',
|
|
37
|
+
inputSchema,
|
|
38
|
+
outputSchema,
|
|
39
|
+
settingSchema: settingsSchema,
|
|
40
|
+
execute: async ({ input, context }) => {
|
|
41
|
+
const ticket_id = `tkt-${input.user_id}-${Date.now()}`;
|
|
42
|
+
context.log('Created ticket', { ticket_id, summary: input.summary });
|
|
43
|
+
|
|
44
|
+
return { ticket_id, status: 'open' };
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import { defineAction } from '../../../src';
|
|
10
|
+
import { SettingsSchema } from '../../../src/dsl.types';
|
|
11
|
+
import type { ExampleContext } from '../context';
|
|
12
|
+
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
intent: z.string(),
|
|
15
|
+
priority: z.string().optional(),
|
|
16
|
+
confidence: z.number().optional(),
|
|
17
|
+
needs_human: z.boolean().optional(),
|
|
18
|
+
});
|
|
19
|
+
const outputSchema = z.object({
|
|
20
|
+
route: z.enum([
|
|
21
|
+
'draft_support_reply',
|
|
22
|
+
'craft_sales_pitch',
|
|
23
|
+
'escalate_to_human',
|
|
24
|
+
'send_generic_summary',
|
|
25
|
+
]),
|
|
26
|
+
explanation: z.string(),
|
|
27
|
+
});
|
|
28
|
+
const settingsSchema = SettingsSchema;
|
|
29
|
+
|
|
30
|
+
type DecisionRouterInput = z.infer<typeof inputSchema>;
|
|
31
|
+
type DecisionRouterOutput = z.infer<typeof outputSchema>;
|
|
32
|
+
type DecisionRouterSettings = z.infer<typeof settingsSchema>;
|
|
33
|
+
|
|
34
|
+
export const decisionRouter = defineAction<
|
|
35
|
+
DecisionRouterInput,
|
|
36
|
+
DecisionRouterOutput,
|
|
37
|
+
ExampleContext,
|
|
38
|
+
DecisionRouterSettings
|
|
39
|
+
>({
|
|
40
|
+
name: 'decision_router',
|
|
41
|
+
description: 'Routes work based on intent, priority, and confidence.',
|
|
42
|
+
inputSchema,
|
|
43
|
+
outputSchema,
|
|
44
|
+
settingSchema: settingsSchema,
|
|
45
|
+
execute: async ({ input, context }) => {
|
|
46
|
+
const confidence = input.confidence ?? 0;
|
|
47
|
+
|
|
48
|
+
if (input.needs_human) {
|
|
49
|
+
return {
|
|
50
|
+
route: 'escalate_to_human',
|
|
51
|
+
explanation: 'User requested human help.',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (input.intent === 'support' && confidence > 0.6) {
|
|
56
|
+
return {
|
|
57
|
+
route: 'draft_support_reply',
|
|
58
|
+
explanation: 'Confident support intent.',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (input.intent === 'sales') {
|
|
63
|
+
return {
|
|
64
|
+
route: 'craft_sales_pitch',
|
|
65
|
+
explanation: 'Sales intent detected.',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (input.priority === 'high') {
|
|
70
|
+
return {
|
|
71
|
+
route: 'escalate_to_human',
|
|
72
|
+
explanation: 'High priority requires escalation.',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
context.log('Falling back to generic summary');
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
route: 'send_generic_summary',
|
|
80
|
+
explanation: 'No specific branch matched.',
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
import { defineAction } from '../../../src';
|
|
10
|
+
import { SettingsSchema } from '../../../src/dsl.types';
|
|
11
|
+
import type { ExampleContext } from '../context';
|
|
12
|
+
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
user_email: z.string(),
|
|
15
|
+
range: z.string().optional(),
|
|
16
|
+
});
|
|
17
|
+
const outputSchema = z.object({
|
|
18
|
+
events: z.array(
|
|
19
|
+
z.object({
|
|
20
|
+
title: z.string(),
|
|
21
|
+
when: z.string(),
|
|
22
|
+
}),
|
|
23
|
+
),
|
|
24
|
+
});
|
|
25
|
+
const settingsSchema = SettingsSchema;
|
|
26
|
+
|
|
27
|
+
type GetCalendarEventsInput = z.infer<typeof inputSchema>;
|
|
28
|
+
type GetCalendarEventsOutput = z.infer<typeof outputSchema>;
|
|
29
|
+
type GetCalendarEventsSettings = z.infer<typeof settingsSchema>;
|
|
30
|
+
|
|
31
|
+
export const getCalendarEvents = defineAction<
|
|
32
|
+
GetCalendarEventsInput,
|
|
33
|
+
GetCalendarEventsOutput,
|
|
34
|
+
ExampleContext,
|
|
35
|
+
GetCalendarEventsSettings
|
|
36
|
+
>({
|
|
37
|
+
name: 'get_calendar_events',
|
|
38
|
+
description: 'Provides a short list of upcoming meetings.',
|
|
39
|
+
inputSchema,
|
|
40
|
+
outputSchema,
|
|
41
|
+
settingSchema: settingsSchema,
|
|
42
|
+
execute: async ({ input, context }) => {
|
|
43
|
+
context.log('Pulling calendar events', {
|
|
44
|
+
user_email: input.user_email,
|
|
45
|
+
range: input.range,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
events: [
|
|
50
|
+
{ title: 'Product sync', when: 'Tomorrow 10:00' },
|
|
51
|
+
{ title: 'Stakeholder update', when: 'Friday 14:00' },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
});
|