@exellix/ai-tasks 9.1.0 → 9.1.1
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/CHANGELOG.md +15 -4
- package/README.md +2 -2
- package/RUNTASK_REQUEST.md +17 -15
- package/dist/compile/compileTaskConfiguration.d.ts.map +1 -1
- package/dist/compile/compileTaskConfiguration.js +3 -0
- package/dist/compile/compileTaskConfiguration.js.map +1 -1
- package/dist/core/task-sdk.d.ts.map +1 -1
- package/dist/core/task-sdk.js +112 -166
- package/dist/core/task-sdk.js.map +1 -1
- package/dist/invocation/types.d.ts +1 -1
- package/dist/narrix/narrixUnitExecution.js +2 -2
- package/dist/narrix/narrixUnitExecution.js.map +1 -1
- package/dist/node-execution/buildRequestFromNodePlan.d.ts +4 -0
- package/dist/node-execution/buildRequestFromNodePlan.d.ts.map +1 -1
- package/dist/node-execution/buildRequestFromNodePlan.js +4 -13
- package/dist/node-execution/buildRequestFromNodePlan.js.map +1 -1
- package/dist/node-execution/compileProfessionalAnswerRequest.d.ts +2 -0
- package/dist/node-execution/compileProfessionalAnswerRequest.d.ts.map +1 -0
- package/dist/node-execution/compileProfessionalAnswerRequest.js +4 -0
- package/dist/node-execution/compileProfessionalAnswerRequest.js.map +1 -0
- package/dist/node-execution/rejectForbiddenWireFields.d.ts +2 -0
- package/dist/node-execution/rejectForbiddenWireFields.d.ts.map +1 -1
- package/dist/node-execution/rejectForbiddenWireFields.js +42 -7
- package/dist/node-execution/rejectForbiddenWireFields.js.map +1 -1
- package/dist/post-steps/audit/auditChecklistFuncxEnvelope.d.ts +19 -3
- package/dist/post-steps/audit/auditChecklistFuncxEnvelope.d.ts.map +1 -1
- package/dist/post-steps/audit/auditChecklistFuncxEnvelope.js +7 -1
- package/dist/post-steps/audit/auditChecklistFuncxEnvelope.js.map +1 -1
- package/dist/post-steps/audit/loadAuditTemplates.d.ts +2 -55
- package/dist/post-steps/audit/loadAuditTemplates.d.ts.map +1 -1
- package/dist/post-steps/audit/loadAuditTemplates.js +3 -38
- package/dist/post-steps/audit/loadAuditTemplates.js.map +1 -1
- package/dist/post-steps/audit/parseAuditFuncxOutput.d.ts +8 -0
- package/dist/post-steps/audit/parseAuditFuncxOutput.d.ts.map +1 -0
- package/dist/post-steps/audit/parseAuditFuncxOutput.js +62 -0
- package/dist/post-steps/audit/parseAuditFuncxOutput.js.map +1 -0
- package/dist/post-steps/audit/parseAuditOutput.d.ts +2 -0
- package/dist/post-steps/audit/parseAuditOutput.d.ts.map +1 -1
- package/dist/post-steps/audit/parseAuditOutput.js +56 -0
- package/dist/post-steps/audit/parseAuditOutput.js.map +1 -1
- package/dist/post-steps/audit/runAudit.d.ts.map +1 -1
- package/dist/post-steps/audit/runAudit.js +53 -113
- package/dist/post-steps/audit/runAudit.js.map +1 -1
- package/dist/post-steps/audit/runAuditFuncxCall.d.ts +18 -0
- package/dist/post-steps/audit/runAuditFuncxCall.d.ts.map +1 -0
- package/dist/post-steps/audit/runAuditFuncxCall.js +59 -0
- package/dist/post-steps/audit/runAuditFuncxCall.js.map +1 -0
- package/dist/synthesis/resolveSourceMaterial.d.ts.map +1 -1
- package/dist/synthesis/resolveSourceMaterial.js +14 -0
- package/dist/synthesis/resolveSourceMaterial.js.map +1 -1
- package/dist/types/task-types.d.ts +4 -3
- package/dist/types/task-types.d.ts.map +1 -1
- package/dist/utils/bridgeRunSkillGatewayMemory.d.ts.map +1 -1
- package/dist/utils/bridgeRunSkillGatewayMemory.js +1 -0
- package/dist/utils/bridgeRunSkillGatewayMemory.js.map +1 -1
- package/dist/utils/executionMemoryInputRecord.d.ts +12 -0
- package/dist/utils/executionMemoryInputRecord.d.ts.map +1 -0
- package/dist/utils/executionMemoryInputRecord.js +28 -0
- package/dist/utils/executionMemoryInputRecord.js.map +1 -0
- package/dist/utils/resolveAiProfileModel.d.ts +1 -1
- package/dist/utils/resolveAiProfileModel.d.ts.map +1 -1
- package/dist/utils/skillTemplateVariables.d.ts +3 -2
- package/dist/utils/skillTemplateVariables.d.ts.map +1 -1
- package/dist/utils/skillTemplateVariables.js +3 -2
- package/dist/utils/skillTemplateVariables.js.map +1 -1
- package/dist/validation/validateProfessionalAnswerContract.d.ts +8 -0
- package/dist/validation/validateProfessionalAnswerContract.d.ts.map +1 -0
- package/dist/validation/validateProfessionalAnswerContract.js +45 -0
- package/dist/validation/validateProfessionalAnswerContract.js.map +1 -0
- package/dist/validation/validateRunTaskConfig.d.ts.map +1 -1
- package/dist/validation/validateRunTaskConfig.js +2 -0
- package/dist/validation/validateRunTaskConfig.js.map +1 -1
- package/documenations/record-and-template-variables.md +21 -13
- package/documenations/run-task-execution-flow.md +1 -1
- package/documenations/upstream-feature-requests/README.md +9 -5
- package/documenations/upstream-feature-requests/ai-skills-orchestrator-invoke-contract-5.9.md +1 -1
- package/documenations/upstream-feature-requests/funcx-4.9.13-open-items.md +62 -0
- package/documenations/upstream-feature-requests/funcx-gap-analysis-cr-fr.md +401 -0
- package/documenations/upstream-feature-requests/funcx-pre-post-sidekick-actions.md +1 -0
- package/documenations/upstream-feature-requests/graph-engine-runtask-contract-alignment-investigation.md +370 -0
- package/documenations/upstream-feature-requests/xynthesis-ai-profiles-2.1-import-break.md +2 -2
- package/documenations/upstream-feature-requests/xynthesis-openrouter-wire-model-double-prefix-bug.md +1 -1
- package/documenations/upstream-feature-requests/xynthesis-orchestrator-invoke-contract-4.2.md +1 -1
- package/package.json +10 -9
- package/.docs/DOWNSTREAM_ENV.md +0 -42
- package/.docs/FEEDBACK_TO_CLIENT_DOWNSTREAM_FIXES.md +0 -64
- package/.docs/INTERMEDIATE_STEPS.md +0 -82
- package/.docs/activity-structure.md +0 -31
- package/.docs/ai-task-ai-scoping-spec.md +0 -338
- package/.docs/ai-tasks-model-profile-aliases-7x.md +0 -96
- package/.docs/blockers-and-issues.md +0 -346
- package/.docs/building-runTask-sdk.md +0 -659
- package/.docs/building-skill-execution-orchestrator.md +0 -968
- package/.docs/code-used-before/run-task.txt +0 -39
- package/.docs/code-used-before/task-executor.ts.old +0 -57
- package/.docs/code-used-before/test-run-task.ts.old +0 -42
- package/.docs/code-used-before/types.txt +0 -23
- package/.docs/env-ready-policy.md +0 -40
- package/.docs/flow-io/flow-README.md +0 -76
- package/.docs/flow-io/narrix.md +0 -124
- package/.docs/flow-io/web-scoping.md +0 -135
- package/.docs/flow-io/xynthesis-post.md +0 -154
- package/.docs/flow-io/xynthesis-pre.md +0 -181
- package/.docs/gap-analysis.md +0 -201
- package/.docs/integration-facts-ai-tasks.md +0 -109
- package/.docs/investigation/ai-skills.md +0 -170
- package/.docs/investigation/external-packages-assignments.md +0 -66
- package/.docs/investigation/integration-summary.md +0 -20
- package/.docs/investigation/narrix-catalox.md +0 -29
- package/.docs/investigation/workplan-close-graph-engine-gaps.md +0 -101
- package/.docs/logging-stack.md +0 -30
- package/.docs/memory-narrix-adapter-developer-guide.md +0 -402
- package/.docs/memory-narrix-adapter-requirements.md +0 -112
- package/.docs/narrix-context-consumption-gap.md +0 -184
- package/.docs/narrix-context-downstream-report.md +0 -30
- package/.docs/narrix-ingest-and-packs-library-spec.md +0 -240
- package/.docs/narrix-record-input-current-design.md +0 -48
- package/.docs/pacakge.md +0 -48
- package/.docs/possible-components/README.md +0 -11
- package/.docs/possible-components/integration/README.md +0 -10
- package/.docs/possible-components/integration/gaps-when-merging.md +0 -16
- package/.docs/possible-components/integration/platform.md +0 -54
- package/.docs/possible-components/integration/reintegrate-into-ai-tasks.md +0 -26
- package/.docs/possible-components/integration/roadmap-and-checklists.md +0 -54
- package/.docs/possible-components/post-component/README.md +0 -18
- package/.docs/possible-components/post-component/builder-guide.md +0 -175
- package/.docs/possible-components/post-component/gaps-and-artifacts.md +0 -52
- package/.docs/possible-components/post-component/handler-audit.md +0 -47
- package/.docs/possible-components/post-component/handler-polish.md +0 -41
- package/.docs/possible-components/post-component/unified-protocol.md +0 -59
- package/.docs/possible-components/pre-component/README.md +0 -22
- package/.docs/possible-components/pre-component/builder-guide.md +0 -127
- package/.docs/possible-components/pre-component/gaps-and-artifacts.md +0 -35
- package/.docs/possible-components/pre-component/handler-ai-scoping.md +0 -45
- package/.docs/possible-components/pre-component/handler-narrix-preprocessor.md +0 -49
- package/.docs/possible-components/pre-component/handler-narrix-system2.md +0 -35
- package/.docs/possible-components/pre-component/handler-synthesized-context.md +0 -65
- package/.docs/possible-components/pre-component/handler-web-scope.md +0 -29
- package/.docs/possible-components/pre-component/unified-protocol.md +0 -89
- package/.docs/prefer-openrouter-routing-policy.md +0 -114
- package/.docs/questions-for-ai-skills.md +0 -123
- package/.docs/realtime-narrixing-gap-analysis.md +0 -40
- package/.docs/realtime-narrixing.md +0 -433
- package/.docs/run-context-object.md +0 -32
- package/.docs/session-id-usage.md +0 -26
- package/.docs/skill-library-spec.md +0 -249
- package/.docs/synthesized-context-strategy-spec.md +0 -906
- package/.docs/upstream-issue/2026-03-21_woroces-ai-tasks_ISSUE-006_web-scope-question-from-cni-entity.md +0 -46
- package/.docs/web-scopper-embed.md +0 -93
- package/.docs/xynthesis-wiring-and-io.md +0 -12
- package/documenations/activix-feature-request-identity.md +0 -123
- package/documenations/bug-report-xynthesis-and-synthesis-call.md +0 -217
- package/documenations/feature-request-ai-skills-raw-template-access.md +0 -82
- package/documenations/feature-request-athenix-core-directive.md +0 -145
- package/documenations/feature-request-athenix-token-extraction.md +0 -124
- package/documenations/funcx-upstream-github-issues-draft.md +0 -153
- package/documenations/identity-metadata-contract.md +0 -165
- package/documenations/run-task-single-run-checklist.md +0 -109
- package/documenations/sessions/2026-06-08-subnets-model-resolution/CR-1-no-concrete-wire-in-graph-plans.md +0 -93
- package/documenations/sessions/2026-06-08-subnets-model-resolution/CR-2-skillModel-profile-only-at-storage.md +0 -88
- package/documenations/sessions/2026-06-08-subnets-model-resolution/CR-3-reject-concrete-models-in-catalog-rows.md +0 -76
- package/documenations/sessions/2026-06-08-subnets-model-resolution/FR-1-suggested-profile-in-catalogs.md +0 -96
- package/documenations/sessions/2026-06-08-subnets-model-resolution/FR-2-graph-engine-failure-phase-attribution.md +0 -92
- package/documenations/sessions/2026-06-08-subnets-model-resolution/INVESTIGATION-original-bug.md +0 -182
- package/documenations/sessions/2026-06-08-subnets-model-resolution/PROBLEM.md +0 -236
- package/documenations/sessions/2026-06-08-subnets-model-resolution/README.md +0 -11
- package/documenations/sessions/2026-06-08-subnets-model-resolution/funcx-test-resolveModel.cheapDefaultWireSlug.test.ts +0 -117
- package/documenations/upstream-feature-requests/ai-tasks-wrap-up-after-upstream.md +0 -129
- package/documenations/upstream-feedback-request-shape-clarification.md +0 -101
- package/documenations/web-context-precedence.md +0 -33
- package/documenations/xynthesis-activix-telemetry.md +0 -28
|
@@ -1,968 +0,0 @@
|
|
|
1
|
-
# Building an External Package for Skill Execution Orchestration
|
|
2
|
-
|
|
3
|
-
This guide explains how to create an external package that uses `@woroces/ai-skills`'s `runTask` method to orchestrate skill execution with different execution strategies. This package will handle running skills, manage execution strategies, coordinate workflows, and provide a higher-level API for task orchestration.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
1. [Overview](#overview)
|
|
8
|
-
2. [Architecture](#architecture)
|
|
9
|
-
3. [Prerequisites](#prerequisites)
|
|
10
|
-
4. [Project Setup](#project-setup)
|
|
11
|
-
5. [Core Components](#core-components)
|
|
12
|
-
6. [Execution Strategy System](#execution-strategy-system)
|
|
13
|
-
7. [Skill Execution Manager](#skill-execution-manager)
|
|
14
|
-
8. [Workflow Orchestration](#workflow-orchestration)
|
|
15
|
-
9. [Complete Implementation](#complete-implementation)
|
|
16
|
-
10. [Usage Examples](#usage-examples)
|
|
17
|
-
11. [Advanced Features](#advanced-features)
|
|
18
|
-
12. [Testing](#testing)
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Overview
|
|
23
|
-
|
|
24
|
-
### What This Package Does
|
|
25
|
-
|
|
26
|
-
This external package provides:
|
|
27
|
-
|
|
28
|
-
- **Skill Execution Orchestration**: Manages the execution of skills using `runTask`
|
|
29
|
-
- **Execution Strategy Management**: Handles different execution strategies (DIRECT, and extensible for future types)
|
|
30
|
-
- **Workflow Coordination**: Manages multi-step skill execution workflows
|
|
31
|
-
- **Memory Management**: Tracks and manages `jobMemory` and `taskMemory` across executions
|
|
32
|
-
- **Error Handling & Retry Logic**: Robust error handling with configurable retry strategies
|
|
33
|
-
- **Result Aggregation**: Combines results from multiple skill executions
|
|
34
|
-
|
|
35
|
-
### Key Concepts
|
|
36
|
-
|
|
37
|
-
- **Task**: A single skill execution request with a specific execution strategy
|
|
38
|
-
- **Execution Strategy**: How a task should be executed (currently `DIRECT`, designed to support more)
|
|
39
|
-
- **Workflow**: A sequence of tasks that execute in order, with memory passed between them
|
|
40
|
-
- **Job**: A collection of workflows or tasks that share the same `jobId` and `jobMemory`
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Architecture
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
┌─────────────────────────────────────────────────────────┐
|
|
48
|
-
│ Your External Package │
|
|
49
|
-
│ │
|
|
50
|
-
│ ┌──────────────────────────────────────────────────┐ │
|
|
51
|
-
│ │ SkillExecutionOrchestrator │ │
|
|
52
|
-
│ │ - Manages execution strategies │ │
|
|
53
|
-
│ │ - Coordinates workflows │ │
|
|
54
|
-
│ │ - Handles memory management │ │
|
|
55
|
-
│ └──────────────────────────────────────────────────┘ │
|
|
56
|
-
│ │ │
|
|
57
|
-
│ ▼ │
|
|
58
|
-
│ ┌──────────────────────────────────────────────────┐ │
|
|
59
|
-
│ │ ExecutionStrategyManager │ │
|
|
60
|
-
│ │ - DIRECT strategy handler │ │
|
|
61
|
-
│ │ - Extensible for future strategies │ │
|
|
62
|
-
│ └──────────────────────────────────────────────────┘ │
|
|
63
|
-
│ │ │
|
|
64
|
-
│ ▼ │
|
|
65
|
-
│ ┌──────────────────────────────────────────────────┐ │
|
|
66
|
-
│ │ @woroces/ai-skills │ │
|
|
67
|
-
│ │ - XeonoxSkillsClient.runTask() │ │
|
|
68
|
-
│ │ - Handles gateway, registry, parsing │ │
|
|
69
|
-
│ └──────────────────────────────────────────────────┘ │
|
|
70
|
-
└─────────────────────────────────────────────────────────┘
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## Prerequisites
|
|
76
|
-
|
|
77
|
-
- Node.js >= 18.0.0
|
|
78
|
-
- TypeScript knowledge
|
|
79
|
-
- Understanding of `@woroces/ai-skills` package
|
|
80
|
-
- Access to GitHub Package Registry
|
|
81
|
-
- Understanding of execution memory management concepts
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Project Setup
|
|
86
|
-
|
|
87
|
-
### Step 1: Initialize Project
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
mkdir skill-execution-orchestrator
|
|
91
|
-
cd skill-execution-orchestrator
|
|
92
|
-
npm init -y
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Step 2: Install Dependencies
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
# Core dependencies
|
|
99
|
-
npm install @woroces/ai-skills @athenices/execution-memory-manager
|
|
100
|
-
|
|
101
|
-
# Development dependencies
|
|
102
|
-
npm install --save-dev typescript @types/node ts-node jest @types/jest ts-jest
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Step 3: Configure TypeScript
|
|
106
|
-
|
|
107
|
-
Create `tsconfig.json`:
|
|
108
|
-
|
|
109
|
-
```json
|
|
110
|
-
{
|
|
111
|
-
"compilerOptions": {
|
|
112
|
-
"target": "ES2020",
|
|
113
|
-
"module": "commonjs",
|
|
114
|
-
"lib": ["ES2020"],
|
|
115
|
-
"outDir": "./dist",
|
|
116
|
-
"rootDir": "./src",
|
|
117
|
-
"strict": true,
|
|
118
|
-
"esModuleInterop": true,
|
|
119
|
-
"skipLibCheck": true,
|
|
120
|
-
"forceConsistentCasingInFileNames": true,
|
|
121
|
-
"declaration": true,
|
|
122
|
-
"declarationMap": true,
|
|
123
|
-
"sourceMap": true,
|
|
124
|
-
"resolveJsonModule": true
|
|
125
|
-
},
|
|
126
|
-
"include": ["src/**/*"],
|
|
127
|
-
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Step 4: Configure npm Registry
|
|
132
|
-
|
|
133
|
-
Create `.npmrc`:
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
@woroces:registry=https://npm.pkg.github.com
|
|
137
|
-
@athenices:registry=https://npm.pkg.github.com
|
|
138
|
-
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Core Components
|
|
144
|
-
|
|
145
|
-
### 1. Execution Strategy Interface
|
|
146
|
-
|
|
147
|
-
Create `src/strategies/execution-strategy.ts`:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { RunTaskRequest, RunSkillResponse } from "@woroces/ai-skills";
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Base interface for execution strategies.
|
|
154
|
-
*
|
|
155
|
-
* Each strategy defines how a task should be executed.
|
|
156
|
-
* Currently supports DIRECT, but designed to be extensible.
|
|
157
|
-
*/
|
|
158
|
-
export interface IExecutionStrategy {
|
|
159
|
-
/**
|
|
160
|
-
* Execute a task using this strategy.
|
|
161
|
-
*
|
|
162
|
-
* @param request The task request
|
|
163
|
-
* @returns Promise resolving to the execution result
|
|
164
|
-
*/
|
|
165
|
-
execute<TParsed = any>(
|
|
166
|
-
request: RunTaskRequest
|
|
167
|
-
): Promise<RunSkillResponse<TParsed>>;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Get the strategy name/type.
|
|
171
|
-
*/
|
|
172
|
-
getType(): string;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Check if this strategy can handle the given request.
|
|
176
|
-
*/
|
|
177
|
-
canHandle(request: RunTaskRequest): boolean;
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### 2. Direct Execution Strategy
|
|
182
|
-
|
|
183
|
-
Create `src/strategies/direct-strategy.ts`:
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
import {
|
|
187
|
-
XeonoxSkillsClient,
|
|
188
|
-
RunTaskRequest,
|
|
189
|
-
RunSkillResponse,
|
|
190
|
-
ExecutionType
|
|
191
|
-
} from "@woroces/ai-skills";
|
|
192
|
-
import type { IExecutionStrategy } from "./execution-strategy";
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Direct execution strategy.
|
|
196
|
-
*
|
|
197
|
-
* Executes tasks by directly passing through to the skill executor.
|
|
198
|
-
* This is the simplest and most common execution strategy.
|
|
199
|
-
*/
|
|
200
|
-
export class DirectExecutionStrategy implements IExecutionStrategy {
|
|
201
|
-
private client: XeonoxSkillsClient;
|
|
202
|
-
|
|
203
|
-
constructor(client: XeonoxSkillsClient) {
|
|
204
|
-
this.client = client;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
async execute<TParsed = any>(
|
|
208
|
-
request: RunTaskRequest
|
|
209
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
210
|
-
// Ensure execution type is set to DIRECT
|
|
211
|
-
const taskRequest: RunTaskRequest = {
|
|
212
|
-
...request,
|
|
213
|
-
executionType: ExecutionType.DIRECT
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
return this.client.runTask<TParsed>(taskRequest);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
getType(): string {
|
|
220
|
-
return ExecutionType.DIRECT;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
canHandle(request: RunTaskRequest): boolean {
|
|
224
|
-
return request.executionType === ExecutionType.DIRECT ||
|
|
225
|
-
!request.executionType; // Default to DIRECT if not specified
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### 3. Execution Strategy Manager
|
|
231
|
-
|
|
232
|
-
Create `src/strategies/strategy-manager.ts`:
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
import { RunTaskRequest, RunSkillResponse, ExecutionType } from "@woroces/ai-skills";
|
|
236
|
-
import type { IExecutionStrategy } from "./execution-strategy";
|
|
237
|
-
import { DirectExecutionStrategy } from "./direct-strategy";
|
|
238
|
-
import { XeonoxSkillsClient } from "@woroces/ai-skills";
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Manages execution strategies.
|
|
242
|
-
*
|
|
243
|
-
* Responsible for:
|
|
244
|
-
* - Registering available strategies
|
|
245
|
-
* - Selecting the appropriate strategy for a task
|
|
246
|
-
* - Providing extensibility for future strategy types
|
|
247
|
-
*/
|
|
248
|
-
export class ExecutionStrategyManager {
|
|
249
|
-
private strategies: Map<string, IExecutionStrategy> = new Map();
|
|
250
|
-
private defaultStrategy: IExecutionStrategy;
|
|
251
|
-
|
|
252
|
-
constructor(client: XeonoxSkillsClient) {
|
|
253
|
-
// Register default DIRECT strategy
|
|
254
|
-
const directStrategy = new DirectExecutionStrategy(client);
|
|
255
|
-
this.defaultStrategy = directStrategy;
|
|
256
|
-
this.strategies.set(ExecutionType.DIRECT, directStrategy);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Register a new execution strategy.
|
|
261
|
-
*/
|
|
262
|
-
registerStrategy(strategy: IExecutionStrategy): void {
|
|
263
|
-
this.strategies.set(strategy.getType(), strategy);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Get the appropriate strategy for a task request.
|
|
268
|
-
*/
|
|
269
|
-
getStrategy(request: RunTaskRequest): IExecutionStrategy {
|
|
270
|
-
// Try to find a strategy that can handle this request
|
|
271
|
-
for (const strategy of this.strategies.values()) {
|
|
272
|
-
if (strategy.canHandle(request)) {
|
|
273
|
-
return strategy;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Fall back to default (DIRECT)
|
|
278
|
-
return this.defaultStrategy;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Execute a task using the appropriate strategy.
|
|
283
|
-
*/
|
|
284
|
-
async execute<TParsed = any>(
|
|
285
|
-
request: RunTaskRequest
|
|
286
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
287
|
-
const strategy = this.getStrategy(request);
|
|
288
|
-
return strategy.execute<TParsed>(request);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Get all registered strategy types.
|
|
293
|
-
*/
|
|
294
|
-
getAvailableStrategies(): string[] {
|
|
295
|
-
return Array.from(this.strategies.keys());
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## Skill Execution Manager
|
|
303
|
-
|
|
304
|
-
Create `src/skill-execution-manager.ts`:
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
import {
|
|
308
|
-
XeonoxSkillsClient,
|
|
309
|
-
RunTaskRequest,
|
|
310
|
-
RunSkillResponse,
|
|
311
|
-
ExecutionType
|
|
312
|
-
} from "@woroces/ai-skills";
|
|
313
|
-
import type { XeonoxSkillsClientOptions } from "@woroces/ai-skills";
|
|
314
|
-
import type { JobHistory, TaskHistory } from "@athenices/execution-memory-manager";
|
|
315
|
-
import { ExecutionStrategyManager } from "./strategies/strategy-manager";
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Options for skill execution.
|
|
319
|
-
*/
|
|
320
|
-
export interface SkillExecutionOptions {
|
|
321
|
-
jobId?: string;
|
|
322
|
-
agentId?: string;
|
|
323
|
-
timeoutMs?: number;
|
|
324
|
-
retryConfig?: RetryConfig;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Retry configuration for failed executions.
|
|
329
|
-
*/
|
|
330
|
-
export interface RetryConfig {
|
|
331
|
-
maxRetries?: number;
|
|
332
|
-
retryDelayMs?: number;
|
|
333
|
-
retryableErrors?: string[];
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Skill Execution Manager
|
|
338
|
-
*
|
|
339
|
-
* High-level manager for executing skills with different strategies.
|
|
340
|
-
* Handles:
|
|
341
|
-
* - Strategy selection and execution
|
|
342
|
-
* - Memory management
|
|
343
|
-
* - Error handling and retries
|
|
344
|
-
* - Result tracking
|
|
345
|
-
*/
|
|
346
|
-
export class SkillExecutionManager {
|
|
347
|
-
private client: XeonoxSkillsClient;
|
|
348
|
-
private strategyManager: ExecutionStrategyManager;
|
|
349
|
-
private jobMemory: Map<string, JobHistory> = new Map();
|
|
350
|
-
private taskMemory: Map<string, TaskHistory> = new Map();
|
|
351
|
-
|
|
352
|
-
constructor(options?: XeonoxSkillsClientOptions) {
|
|
353
|
-
this.client = new XeonoxSkillsClient(options);
|
|
354
|
-
this.strategyManager = new ExecutionStrategyManager(this.client);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Execute a single skill.
|
|
359
|
-
*
|
|
360
|
-
* @param skillKey The skill to execute (e.g., "skills/professional-answer")
|
|
361
|
-
* @param input The input data for the skill
|
|
362
|
-
* @param options Execution options
|
|
363
|
-
*/
|
|
364
|
-
async executeSkill<TParsed = any>(
|
|
365
|
-
skillKey: string,
|
|
366
|
-
input: Record<string, any> | string,
|
|
367
|
-
options?: SkillExecutionOptions
|
|
368
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
369
|
-
const jobId = options?.jobId || `job-${Date.now()}`;
|
|
370
|
-
|
|
371
|
-
// Get or initialize memory for this job
|
|
372
|
-
const jobMemory = this.jobMemory.get(jobId);
|
|
373
|
-
const taskMemory = this.taskMemory.get(jobId) || {};
|
|
374
|
-
|
|
375
|
-
const taskRequest: RunTaskRequest = {
|
|
376
|
-
skillKey,
|
|
377
|
-
input,
|
|
378
|
-
executionType: ExecutionType.DIRECT,
|
|
379
|
-
jobId,
|
|
380
|
-
agentId: options?.agentId,
|
|
381
|
-
timeoutMs: options?.timeoutMs,
|
|
382
|
-
jobMemory,
|
|
383
|
-
taskMemory
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
// Execute with retry logic if configured
|
|
387
|
-
if (options?.retryConfig) {
|
|
388
|
-
return this.executeWithRetry<TParsed>(taskRequest, options.retryConfig);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const result = await this.strategyManager.execute<TParsed>(taskRequest);
|
|
392
|
-
|
|
393
|
-
// Update memory with this execution
|
|
394
|
-
this.updateMemory(jobId, result);
|
|
395
|
-
|
|
396
|
-
return result;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* Execute a skill with variables/context.
|
|
401
|
-
*/
|
|
402
|
-
async executeSkillWithContext<TParsed = any>(
|
|
403
|
-
skillKey: string,
|
|
404
|
-
input: Record<string, any> | string,
|
|
405
|
-
variables?: Record<string, any>,
|
|
406
|
-
context?: Record<string, any> | string,
|
|
407
|
-
options?: SkillExecutionOptions
|
|
408
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
409
|
-
const jobId = options?.jobId || `job-${Date.now()}`;
|
|
410
|
-
const jobMemory = this.jobMemory.get(jobId);
|
|
411
|
-
const taskMemory = this.taskMemory.get(jobId) || {};
|
|
412
|
-
|
|
413
|
-
const taskRequest: RunTaskRequest = {
|
|
414
|
-
skillKey,
|
|
415
|
-
input,
|
|
416
|
-
variables,
|
|
417
|
-
context,
|
|
418
|
-
executionType: ExecutionType.DIRECT,
|
|
419
|
-
jobId,
|
|
420
|
-
agentId: options?.agentId,
|
|
421
|
-
timeoutMs: options?.timeoutMs,
|
|
422
|
-
jobMemory,
|
|
423
|
-
taskMemory
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
if (options?.retryConfig) {
|
|
427
|
-
return this.executeWithRetry<TParsed>(taskRequest, options.retryConfig);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
const result = await this.strategyManager.execute<TParsed>(taskRequest);
|
|
431
|
-
this.updateMemory(jobId, result);
|
|
432
|
-
|
|
433
|
-
return result;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Execute a task with a specific execution strategy.
|
|
438
|
-
*/
|
|
439
|
-
async executeTask<TParsed = any>(
|
|
440
|
-
taskRequest: RunTaskRequest
|
|
441
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
442
|
-
const jobId = taskRequest.jobId || `job-${Date.now()}`;
|
|
443
|
-
|
|
444
|
-
// Ensure memory is attached
|
|
445
|
-
const enrichedRequest: RunTaskRequest = {
|
|
446
|
-
...taskRequest,
|
|
447
|
-
jobId,
|
|
448
|
-
jobMemory: taskRequest.jobMemory || this.jobMemory.get(jobId),
|
|
449
|
-
taskMemory: taskRequest.taskMemory || this.taskMemory.get(jobId)
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
const result = await this.strategyManager.execute<TParsed>(enrichedRequest);
|
|
453
|
-
this.updateMemory(jobId, result);
|
|
454
|
-
|
|
455
|
-
return result;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Execute with retry logic.
|
|
460
|
-
*/
|
|
461
|
-
private async executeWithRetry<TParsed = any>(
|
|
462
|
-
request: RunTaskRequest,
|
|
463
|
-
config: RetryConfig
|
|
464
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
465
|
-
const maxRetries = config.maxRetries || 3;
|
|
466
|
-
const retryDelay = config.retryDelayMs || 1000;
|
|
467
|
-
const retryableErrors = config.retryableErrors || [];
|
|
468
|
-
|
|
469
|
-
let lastError: Error | null = null;
|
|
470
|
-
|
|
471
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
472
|
-
try {
|
|
473
|
-
return await this.strategyManager.execute<TParsed>(request);
|
|
474
|
-
} catch (error: any) {
|
|
475
|
-
lastError = error;
|
|
476
|
-
|
|
477
|
-
// Check if error is retryable
|
|
478
|
-
const isRetryable = retryableErrors.length === 0 ||
|
|
479
|
-
retryableErrors.some(pattern =>
|
|
480
|
-
error.message?.includes(pattern) ||
|
|
481
|
-
error.code === pattern
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
if (!isRetryable || attempt === maxRetries) {
|
|
485
|
-
throw error;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// Wait before retrying
|
|
489
|
-
await new Promise(resolve => setTimeout(resolve, retryDelay * (attempt + 1)));
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
throw lastError || new Error("Execution failed after retries");
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Update memory with execution result.
|
|
498
|
-
*/
|
|
499
|
-
private updateMemory(jobId: string, result: RunSkillResponse<any>): void {
|
|
500
|
-
// Update job memory (history of all task results)
|
|
501
|
-
const currentJobMemory = this.jobMemory.get(jobId) || {};
|
|
502
|
-
const updatedJobMemory: JobHistory = {
|
|
503
|
-
...currentJobMemory,
|
|
504
|
-
[result.skillKey]: {
|
|
505
|
-
result: result.parsed,
|
|
506
|
-
metadata: result.metadata,
|
|
507
|
-
timestamp: Date.now()
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
this.jobMemory.set(jobId, updatedJobMemory);
|
|
511
|
-
|
|
512
|
-
// Update task memory (history of skills executed)
|
|
513
|
-
const currentTaskMemory = this.taskMemory.get(jobId) || {};
|
|
514
|
-
const updatedTaskMemory: TaskHistory = {
|
|
515
|
-
...currentTaskMemory,
|
|
516
|
-
[result.skillKey]: {
|
|
517
|
-
activityId: result.metadata.activityId,
|
|
518
|
-
timestamp: Date.now()
|
|
519
|
-
}
|
|
520
|
-
};
|
|
521
|
-
this.taskMemory.set(jobId, updatedTaskMemory);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Get job memory for a specific job.
|
|
526
|
-
*/
|
|
527
|
-
getJobMemory(jobId: string): JobHistory | undefined {
|
|
528
|
-
return this.jobMemory.get(jobId);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
/**
|
|
532
|
-
* Get task memory for a specific job.
|
|
533
|
-
*/
|
|
534
|
-
getTaskMemory(jobId: string): TaskHistory | undefined {
|
|
535
|
-
return this.taskMemory.get(jobId);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Clear memory for a job.
|
|
540
|
-
*/
|
|
541
|
-
clearMemory(jobId: string): void {
|
|
542
|
-
this.jobMemory.delete(jobId);
|
|
543
|
-
this.taskMemory.delete(jobId);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Get available execution strategies.
|
|
548
|
-
*/
|
|
549
|
-
getAvailableStrategies(): string[] {
|
|
550
|
-
return this.strategyManager.getAvailableStrategies();
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
## Workflow Orchestration
|
|
558
|
-
|
|
559
|
-
Create `src/workflow-orchestrator.ts`:
|
|
560
|
-
|
|
561
|
-
```typescript
|
|
562
|
-
import {
|
|
563
|
-
RunTaskRequest,
|
|
564
|
-
RunSkillResponse,
|
|
565
|
-
ExecutionType
|
|
566
|
-
} from "@woroces/ai-skills";
|
|
567
|
-
import { SkillExecutionManager } from "./skill-execution-manager";
|
|
568
|
-
import type { SkillExecutionOptions } from "./skill-execution-manager";
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Definition of a single step in a workflow.
|
|
572
|
-
*/
|
|
573
|
-
export interface WorkflowStep {
|
|
574
|
-
skillKey: string;
|
|
575
|
-
input: Record<string, any> | string;
|
|
576
|
-
variables?: Record<string, any>;
|
|
577
|
-
context?: Record<string, any> | string;
|
|
578
|
-
executionType?: ExecutionType;
|
|
579
|
-
condition?: (previousResults: RunSkillResponse<any>[]) => boolean;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
/**
|
|
583
|
-
* Workflow execution result.
|
|
584
|
-
*/
|
|
585
|
-
export interface WorkflowResult {
|
|
586
|
-
jobId: string;
|
|
587
|
-
steps: Array<{
|
|
588
|
-
step: WorkflowStep;
|
|
589
|
-
result: RunSkillResponse<any>;
|
|
590
|
-
success: boolean;
|
|
591
|
-
error?: Error;
|
|
592
|
-
}>;
|
|
593
|
-
success: boolean;
|
|
594
|
-
finalResult?: RunSkillResponse<any>;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
/**
|
|
598
|
-
* Workflow Orchestrator
|
|
599
|
-
*
|
|
600
|
-
* Manages execution of multi-step workflows where:
|
|
601
|
-
* - Steps execute in sequence
|
|
602
|
-
* - Memory is passed between steps
|
|
603
|
-
* - Conditional execution is supported
|
|
604
|
-
* - Results are aggregated
|
|
605
|
-
*/
|
|
606
|
-
export class WorkflowOrchestrator {
|
|
607
|
-
private executionManager: SkillExecutionManager;
|
|
608
|
-
|
|
609
|
-
constructor(executionManager: SkillExecutionManager) {
|
|
610
|
-
this.executionManager = executionManager;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
* Execute a workflow (sequence of steps).
|
|
615
|
-
*/
|
|
616
|
-
async executeWorkflow(
|
|
617
|
-
steps: WorkflowStep[],
|
|
618
|
-
options?: SkillExecutionOptions
|
|
619
|
-
): Promise<WorkflowResult> {
|
|
620
|
-
const jobId = options?.jobId || `workflow-${Date.now()}`;
|
|
621
|
-
const results: WorkflowResult['steps'] = [];
|
|
622
|
-
let previousResults: RunSkillResponse<any>[] = [];
|
|
623
|
-
|
|
624
|
-
for (const step of steps) {
|
|
625
|
-
// Check condition if provided
|
|
626
|
-
if (step.condition && !step.condition(previousResults)) {
|
|
627
|
-
results.push({
|
|
628
|
-
step,
|
|
629
|
-
result: {} as RunSkillResponse<any>,
|
|
630
|
-
success: false,
|
|
631
|
-
error: new Error("Step condition not met")
|
|
632
|
-
});
|
|
633
|
-
continue;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
try {
|
|
637
|
-
// Build input that can reference previous results
|
|
638
|
-
const enrichedInput = this.enrichInputWithPreviousResults(
|
|
639
|
-
step.input,
|
|
640
|
-
previousResults
|
|
641
|
-
);
|
|
642
|
-
|
|
643
|
-
// Execute the step
|
|
644
|
-
const taskRequest: RunTaskRequest = {
|
|
645
|
-
skillKey: step.skillKey,
|
|
646
|
-
input: enrichedInput,
|
|
647
|
-
variables: step.variables,
|
|
648
|
-
context: step.context,
|
|
649
|
-
executionType: step.executionType || ExecutionType.DIRECT,
|
|
650
|
-
jobId,
|
|
651
|
-
agentId: options?.agentId,
|
|
652
|
-
timeoutMs: options?.timeoutMs,
|
|
653
|
-
jobMemory: this.executionManager.getJobMemory(jobId),
|
|
654
|
-
taskMemory: this.executionManager.getTaskMemory(jobId)
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
const result = await this.executionManager.executeTask(taskRequest);
|
|
658
|
-
previousResults.push(result);
|
|
659
|
-
|
|
660
|
-
results.push({
|
|
661
|
-
step,
|
|
662
|
-
result,
|
|
663
|
-
success: true
|
|
664
|
-
});
|
|
665
|
-
} catch (error: any) {
|
|
666
|
-
results.push({
|
|
667
|
-
step,
|
|
668
|
-
result: {} as RunSkillResponse<any>,
|
|
669
|
-
success: false,
|
|
670
|
-
error
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
// Optionally stop on error
|
|
674
|
-
break;
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
const success = results.every(r => r.success);
|
|
679
|
-
const finalResult = previousResults.length > 0
|
|
680
|
-
? previousResults[previousResults.length - 1]
|
|
681
|
-
: undefined;
|
|
682
|
-
|
|
683
|
-
return {
|
|
684
|
-
jobId,
|
|
685
|
-
steps: results,
|
|
686
|
-
success,
|
|
687
|
-
finalResult
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
/**
|
|
692
|
-
* Enrich input with results from previous steps.
|
|
693
|
-
*/
|
|
694
|
-
private enrichInputWithPreviousResults(
|
|
695
|
-
input: Record<string, any> | string,
|
|
696
|
-
previousResults: RunSkillResponse<any>[]
|
|
697
|
-
): Record<string, any> | string {
|
|
698
|
-
if (typeof input === 'string') {
|
|
699
|
-
// Simple string replacement for previous results
|
|
700
|
-
let enriched = input;
|
|
701
|
-
previousResults.forEach((result, index) => {
|
|
702
|
-
enriched = enriched.replace(
|
|
703
|
-
new RegExp(`\\$\\{step${index + 1}\\}`, 'g'),
|
|
704
|
-
JSON.stringify(result.parsed)
|
|
705
|
-
);
|
|
706
|
-
});
|
|
707
|
-
return enriched;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// For object inputs, merge previous results
|
|
711
|
-
const enriched: Record<string, any> = { ...input };
|
|
712
|
-
|
|
713
|
-
// Add previous results as $previousSteps array
|
|
714
|
-
enriched.$previousSteps = previousResults.map(r => r.parsed);
|
|
715
|
-
|
|
716
|
-
// Add individual step results as $step1, $step2, etc.
|
|
717
|
-
previousResults.forEach((result, index) => {
|
|
718
|
-
enriched[`$step${index + 1}`] = result.parsed;
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
return enriched;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
---
|
|
727
|
-
|
|
728
|
-
## Complete Implementation
|
|
729
|
-
|
|
730
|
-
### Main Entry Point
|
|
731
|
-
|
|
732
|
-
Create `src/index.ts`:
|
|
733
|
-
|
|
734
|
-
```typescript
|
|
735
|
-
// Core exports
|
|
736
|
-
export { SkillExecutionManager } from "./skill-execution-manager";
|
|
737
|
-
export { WorkflowOrchestrator } from "./workflow-orchestrator";
|
|
738
|
-
export { ExecutionStrategyManager } from "./strategies/strategy-manager";
|
|
739
|
-
|
|
740
|
-
// Strategy exports
|
|
741
|
-
export { DirectExecutionStrategy } from "./strategies/direct-strategy";
|
|
742
|
-
export type { IExecutionStrategy } from "./strategies/execution-strategy";
|
|
743
|
-
|
|
744
|
-
// Type exports
|
|
745
|
-
export type { SkillExecutionOptions, RetryConfig } from "./skill-execution-manager";
|
|
746
|
-
export type { WorkflowStep, WorkflowResult } from "./workflow-orchestrator";
|
|
747
|
-
|
|
748
|
-
// Re-export from @woroces/ai-skills for convenience
|
|
749
|
-
export type {
|
|
750
|
-
RunTaskRequest,
|
|
751
|
-
RunSkillResponse,
|
|
752
|
-
ExecutionType
|
|
753
|
-
} from "@woroces/ai-skills";
|
|
754
|
-
export { ExecutionType } from "@woroces/ai-skills";
|
|
755
|
-
```
|
|
756
|
-
|
|
757
|
-
---
|
|
758
|
-
|
|
759
|
-
## Usage Examples
|
|
760
|
-
|
|
761
|
-
### Example 1: Basic Skill Execution
|
|
762
|
-
|
|
763
|
-
```typescript
|
|
764
|
-
import { SkillExecutionManager } from "skill-execution-orchestrator";
|
|
765
|
-
|
|
766
|
-
const manager = new SkillExecutionManager({
|
|
767
|
-
enableContentRegistry: true,
|
|
768
|
-
contentRegistryLocalPath: "./.metadata"
|
|
769
|
-
});
|
|
770
|
-
|
|
771
|
-
// Execute a single skill
|
|
772
|
-
const result = await manager.executeSkill(
|
|
773
|
-
"skills/professional-answer",
|
|
774
|
-
{ question: "What is AI?" },
|
|
775
|
-
{
|
|
776
|
-
jobId: "job-123",
|
|
777
|
-
agentId: "agent-abc"
|
|
778
|
-
}
|
|
779
|
-
);
|
|
780
|
-
|
|
781
|
-
console.log("Answer:", result.parsed);
|
|
782
|
-
```
|
|
783
|
-
|
|
784
|
-
### Example 2: Skill Execution with Context
|
|
785
|
-
|
|
786
|
-
```typescript
|
|
787
|
-
const result = await manager.executeSkillWithContext(
|
|
788
|
-
"skills/professional-decision",
|
|
789
|
-
{ scenario: "Should we migrate to cloud?" },
|
|
790
|
-
{ orgName: "TechCorp", department: "Engineering" },
|
|
791
|
-
{ industry: "Technology", size: "Enterprise" },
|
|
792
|
-
{
|
|
793
|
-
jobId: "job-456",
|
|
794
|
-
timeoutMs: 30000
|
|
795
|
-
}
|
|
796
|
-
);
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
### Example 3: Workflow Execution
|
|
800
|
-
|
|
801
|
-
```typescript
|
|
802
|
-
import { SkillExecutionManager, WorkflowOrchestrator } from "skill-execution-orchestrator";
|
|
803
|
-
import { ExecutionType } from "@woroces/ai-skills";
|
|
804
|
-
|
|
805
|
-
const manager = new SkillExecutionManager();
|
|
806
|
-
const orchestrator = new WorkflowOrchestrator(manager);
|
|
807
|
-
|
|
808
|
-
// Define a workflow
|
|
809
|
-
const workflow = [
|
|
810
|
-
{
|
|
811
|
-
skillKey: "skills/professional-answer",
|
|
812
|
-
input: { question: "What are the benefits of cloud migration?" },
|
|
813
|
-
executionType: ExecutionType.DIRECT
|
|
814
|
-
},
|
|
815
|
-
{
|
|
816
|
-
skillKey: "skills/professional-decision",
|
|
817
|
-
input: { scenario: "Based on the analysis, should we migrate?" },
|
|
818
|
-
variables: { orgName: "TechCorp" },
|
|
819
|
-
// Only execute if first step succeeded
|
|
820
|
-
condition: (results) => results.length > 0 && results[0].parsed
|
|
821
|
-
}
|
|
822
|
-
];
|
|
823
|
-
|
|
824
|
-
// Execute workflow
|
|
825
|
-
const workflowResult = await orchestrator.executeWorkflow(workflow, {
|
|
826
|
-
jobId: "workflow-789"
|
|
827
|
-
});
|
|
828
|
-
|
|
829
|
-
if (workflowResult.success) {
|
|
830
|
-
console.log("Workflow completed:", workflowResult.finalResult);
|
|
831
|
-
} else {
|
|
832
|
-
console.error("Workflow failed:", workflowResult.steps);
|
|
833
|
-
}
|
|
834
|
-
```
|
|
835
|
-
|
|
836
|
-
### Example 4: With Retry Logic
|
|
837
|
-
|
|
838
|
-
```typescript
|
|
839
|
-
const result = await manager.executeSkill(
|
|
840
|
-
"skills/professional-answer",
|
|
841
|
-
{ question: "Complex question here" },
|
|
842
|
-
{
|
|
843
|
-
jobId: "job-retry",
|
|
844
|
-
retryConfig: {
|
|
845
|
-
maxRetries: 3,
|
|
846
|
-
retryDelayMs: 2000,
|
|
847
|
-
retryableErrors: ["timeout", "rate limit", "network"]
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
);
|
|
851
|
-
```
|
|
852
|
-
|
|
853
|
-
---
|
|
854
|
-
|
|
855
|
-
## Advanced Features
|
|
856
|
-
|
|
857
|
-
### Custom Execution Strategy
|
|
858
|
-
|
|
859
|
-
You can extend the system with custom strategies:
|
|
860
|
-
|
|
861
|
-
```typescript
|
|
862
|
-
import { IExecutionStrategy, ExecutionStrategyManager } from "skill-execution-orchestrator";
|
|
863
|
-
import { RunTaskRequest, RunSkillResponse } from "@woroces/ai-skills";
|
|
864
|
-
|
|
865
|
-
class ParallelExecutionStrategy implements IExecutionStrategy {
|
|
866
|
-
async execute<TParsed = any>(
|
|
867
|
-
request: RunTaskRequest
|
|
868
|
-
): Promise<RunSkillResponse<TParsed>> {
|
|
869
|
-
// Custom parallel execution logic
|
|
870
|
-
// This is a placeholder for future implementation
|
|
871
|
-
throw new Error("Parallel execution not yet implemented");
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
getType(): string {
|
|
875
|
-
return "parallel";
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
canHandle(request: RunTaskRequest): boolean {
|
|
879
|
-
return request.executionType === "parallel";
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// Register the strategy
|
|
884
|
-
const manager = new SkillExecutionManager();
|
|
885
|
-
// Access strategy manager and register (would need to expose this)
|
|
886
|
-
```
|
|
887
|
-
|
|
888
|
-
---
|
|
889
|
-
|
|
890
|
-
## Testing
|
|
891
|
-
|
|
892
|
-
### Unit Tests Example
|
|
893
|
-
|
|
894
|
-
Create `src/skill-execution-manager.test.ts`:
|
|
895
|
-
|
|
896
|
-
```typescript
|
|
897
|
-
import { SkillExecutionManager } from "./skill-execution-manager";
|
|
898
|
-
import { ExecutionType } from "@woroces/ai-skills";
|
|
899
|
-
|
|
900
|
-
describe("SkillExecutionManager", () => {
|
|
901
|
-
let manager: SkillExecutionManager;
|
|
902
|
-
|
|
903
|
-
beforeEach(() => {
|
|
904
|
-
manager = new SkillExecutionManager({
|
|
905
|
-
enableContentRegistry: true,
|
|
906
|
-
contentRegistryLocalPath: "./.metadata"
|
|
907
|
-
});
|
|
908
|
-
});
|
|
909
|
-
|
|
910
|
-
test("should execute a skill", async () => {
|
|
911
|
-
const result = await manager.executeSkill(
|
|
912
|
-
"skills/professional-answer",
|
|
913
|
-
{ question: "Test question" },
|
|
914
|
-
{ jobId: "test-job" }
|
|
915
|
-
);
|
|
916
|
-
|
|
917
|
-
expect(result).toBeDefined();
|
|
918
|
-
expect(result.skillKey).toBe("skills/professional-answer");
|
|
919
|
-
expect(result.flexMd).toBeDefined();
|
|
920
|
-
});
|
|
921
|
-
|
|
922
|
-
test("should manage job memory", async () => {
|
|
923
|
-
const jobId = "memory-test";
|
|
924
|
-
|
|
925
|
-
await manager.executeSkill(
|
|
926
|
-
"skills/professional-answer",
|
|
927
|
-
{ question: "First question" },
|
|
928
|
-
{ jobId }
|
|
929
|
-
);
|
|
930
|
-
|
|
931
|
-
const memory = manager.getJobMemory(jobId);
|
|
932
|
-
expect(memory).toBeDefined();
|
|
933
|
-
});
|
|
934
|
-
});
|
|
935
|
-
```
|
|
936
|
-
|
|
937
|
-
---
|
|
938
|
-
|
|
939
|
-
## Summary
|
|
940
|
-
|
|
941
|
-
You've now created an external package that:
|
|
942
|
-
|
|
943
|
-
1. ✅ Uses `runTask` from `@woroces/ai-skills` for skill execution
|
|
944
|
-
2. ✅ Manages different execution strategies (extensible architecture)
|
|
945
|
-
3. ✅ Handles skill execution with memory management
|
|
946
|
-
4. ✅ Provides workflow orchestration for multi-step processes
|
|
947
|
-
5. ✅ Includes retry logic and error handling
|
|
948
|
-
6. ✅ Offers a clean, high-level API
|
|
949
|
-
|
|
950
|
-
### Key Benefits
|
|
951
|
-
|
|
952
|
-
- **Separation of Concerns**: Your package handles orchestration, `@woroces/ai-skills` handles execution
|
|
953
|
-
- **Extensibility**: Easy to add new execution strategies
|
|
954
|
-
- **Memory Management**: Automatic tracking of job and task memory
|
|
955
|
-
- **Workflow Support**: Built-in support for multi-step processes
|
|
956
|
-
- **Error Resilience**: Configurable retry logic
|
|
957
|
-
|
|
958
|
-
### Next Steps
|
|
959
|
-
|
|
960
|
-
1. Add more execution strategies (parallel, sequential with dependencies, etc.)
|
|
961
|
-
2. Implement workflow visualization
|
|
962
|
-
3. Add result caching
|
|
963
|
-
4. Implement workflow templates/presets
|
|
964
|
-
5. Add monitoring and metrics collection
|
|
965
|
-
|
|
966
|
-
---
|
|
967
|
-
|
|
968
|
-
**Questions?** Refer to the `@woroces/ai-skills` documentation for details on the underlying execution system.
|