0xray 3.2.0 → 3.3.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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.2.0",
2
+ "version": "3.3.0",
3
3
  "terms": [
4
4
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
5
5
  ],
package/dist/CHANGELOG.md CHANGED
@@ -4,6 +4,32 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Conventional Commits](https://www.conventionalcommits.org/).
6
6
 
7
+ ## [3.2.0] - 2026-06-17
8
+
9
+ ### 🔄 Changes
10
+
11
+ ### ✨ Features
12
+ - Orphan file resolution: 5 dead files deleted, ~39 files integrated under typecheck
13
+ - feat: 58 type errors fixed across 6 source files
14
+ - feat: pre-existing e2e failures fixed (OpenClaw 9/9, Grok CLI 62/0)
15
+ - feat: vitest config testTimeout added for processor-logger stability
16
+ - feat: pre-tool-use hook rewritten from skeleton to full hook with resonance/decision-matrix/JSON
17
+ - feat: SelfProposalEngine integrated under typecheck with metamorphosis type support
18
+
19
+ ### 🐛 Bug Fixes
20
+ - fix: postinstall e2e version assertions (3.1.1 → 0.5.2)
21
+ - fix: AGENTS.md session entry and test assertions cleaned
22
+ - fix: enforcement-gate fallback dynamic imports `as string` cast
23
+
24
+ ### ♻️ Refactoring
25
+ - chore: removed ~180 stale @version JSDoc tags from source files
26
+ - chore: cleaned stale version badges from README, AGENTS.md, docs-site docs
27
+ - chore: removed "xray 2.0" from command docs (26 files)
28
+ - chore: release.mjs checks npm view 0xray version (was xray)
29
+ - chore: release.mjs push target master → main
30
+
31
+ ---
32
+
7
33
  ## [3.1.1] - 2026-06-17
8
34
 
9
35
  ### 🔄 Changes
@@ -472,6 +472,9 @@ export class FeaturesConfigLoader {
472
472
  getInference() {
473
473
  return this.loadConfig().inference;
474
474
  }
475
+ getMemoryRouting() {
476
+ return this.loadConfig().memory_routing;
477
+ }
475
478
  getPublish() {
476
479
  return this.loadConfig().publish;
477
480
  }
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * Agent Capabilities Configuration
3
3
  *
4
- * Centralized agent capability definitions for orchestration decisions
4
+ * Centralized agent capability definitions for orchestration decisions.
5
+ * Enriched at runtime by the active MemoryRoutingProvider (Repertoire, etc.).
5
6
  */
6
7
  import { AGENT_REGISTRY } from "../../../agents/registry.js";
8
+ import { initializeMemoryRouting } from '../../../memory-routing/index.js';
9
+ import { getProvider, toMemoryCapabilityMap, fromMemoryCapabilityMap, } from './memory-routing-bridge.js';
7
10
  const DEFAULT_AGENT_CAPABILITIES = Object.fromEntries(Object.entries(AGENT_REGISTRY).map(([name, entry]) => [
8
11
  name,
9
12
  {
@@ -12,17 +15,28 @@ const DEFAULT_AGENT_CAPABILITIES = Object.fromEntries(Object.entries(AGENT_REGIS
12
15
  concurrentTasks: entry.concurrentTasks,
13
16
  },
14
17
  ]));
18
+ initializeMemoryRouting();
15
19
  /**
16
20
  * Agent Capabilities Manager
17
21
  * Manages agent capabilities for orchestration decisions
18
22
  */
19
23
  export class AgentCapabilitiesManager {
20
24
  capabilities = new Map();
25
+ enriched = false;
21
26
  constructor() {
22
- // Initialize with default capabilities
23
27
  Object.entries(DEFAULT_AGENT_CAPABILITIES).forEach(([agent, config]) => {
24
28
  this.capabilities.set(agent, config);
25
29
  });
30
+ this.applyMemoryRoutingEnrichment();
31
+ }
32
+ applyMemoryRoutingEnrichment() {
33
+ const provider = getProvider();
34
+ if (provider.id === 'null')
35
+ return;
36
+ const memoryCaps = toMemoryCapabilityMap(this.capabilities);
37
+ const enriched = provider.enhanceAgentCapabilities(memoryCaps);
38
+ this.capabilities = fromMemoryCapabilityMap(enriched);
39
+ this.enriched = true;
26
40
  }
27
41
  /**
28
42
  * Get capabilities for a specific agent
@@ -34,6 +48,8 @@ export class AgentCapabilitiesManager {
34
48
  * Get all registered agent capabilities
35
49
  */
36
50
  getAllCapabilities() {
51
+ if (!this.enriched)
52
+ this.applyMemoryRoutingEnrichment();
37
53
  return new Map(this.capabilities);
38
54
  }
39
55
  /**
@@ -43,19 +59,20 @@ export class AgentCapabilitiesManager {
43
59
  this.capabilities.set(agentType, capability);
44
60
  }
45
61
  /**
46
- * Select the best agent for a task based on complexity and capabilities
62
+ * Select the best agent for a task based on complexity, capabilities, and memory routing.
47
63
  */
48
- selectAgentForTask(requiredCapabilities, complexity) {
64
+ selectAgentForTask(requiredCapabilities, complexity, operationDescription = '') {
65
+ const provider = getProvider();
66
+ if (provider.id !== 'null' && operationDescription) {
67
+ const memoryCaps = toMemoryCapabilityMap(this.getAllCapabilities());
68
+ return provider.selectAgent(memoryCaps, requiredCapabilities, complexity, operationDescription);
69
+ }
49
70
  let bestAgent = null;
50
71
  let bestScore = -1;
51
72
  for (const [agent, caps] of this.capabilities) {
52
- // Check if agent can handle the complexity
53
- if (complexity > caps.complexityThreshold) {
73
+ if (complexity > caps.complexityThreshold)
54
74
  continue;
55
- }
56
- // Calculate capability match score
57
- const matchCount = requiredCapabilities.filter(cap => caps.capabilities.includes(cap)).length;
58
- // Prefer agents with more concurrent tasks available
75
+ const matchCount = requiredCapabilities.filter((cap) => caps.capabilities.includes(cap)).length;
59
76
  const score = matchCount * 10 + caps.concurrentTasks;
60
77
  if (score > bestScore) {
61
78
  bestScore = score;
@@ -77,7 +94,6 @@ export class AgentCapabilitiesManager {
77
94
  return available;
78
95
  }
79
96
  }
80
- // Singleton instance
81
97
  let capabilitiesManagerInstance = null;
82
98
  export function getAgentCapabilitiesManager() {
83
99
  if (!capabilitiesManagerInstance) {
@@ -85,3 +101,6 @@ export function getAgentCapabilitiesManager() {
85
101
  }
86
102
  return capabilitiesManagerInstance;
87
103
  }
104
+ export function resetAgentCapabilitiesManager() {
105
+ capabilitiesManagerInstance = null;
106
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Bridge between orchestrator types and the pluggable MemoryRoutingProvider.
3
+ */
4
+ import { getMemoryRoutingProviderSync, } from '../../../memory-routing/index.js';
5
+ export function toMemoryCapability(caps) {
6
+ const result = {
7
+ capabilities: caps.capabilities,
8
+ complexityThreshold: caps.complexityThreshold,
9
+ concurrentTasks: caps.concurrentTasks,
10
+ };
11
+ if (caps.memorySignals)
12
+ result.memorySignals = caps.memorySignals;
13
+ if (caps.memoryTags)
14
+ result.memoryTags = caps.memoryTags;
15
+ return result;
16
+ }
17
+ export function fromMemoryCapability(caps) {
18
+ const result = {
19
+ capabilities: caps.capabilities,
20
+ complexityThreshold: caps.complexityThreshold,
21
+ concurrentTasks: caps.concurrentTasks,
22
+ };
23
+ if (caps.memorySignals)
24
+ result.memorySignals = caps.memorySignals;
25
+ if (caps.memoryTags)
26
+ result.memoryTags = caps.memoryTags;
27
+ return result;
28
+ }
29
+ export function toMemoryTask(task) {
30
+ const result = {
31
+ id: task.id,
32
+ description: task.description,
33
+ type: task.type,
34
+ };
35
+ if (task.priority)
36
+ result.priority = task.priority;
37
+ if (task.dependencies)
38
+ result.dependencies = task.dependencies;
39
+ if (task.estimatedComplexity !== undefined)
40
+ result.estimatedComplexity = task.estimatedComplexity;
41
+ if (task.metadata)
42
+ result.metadata = task.metadata;
43
+ return result;
44
+ }
45
+ export function fromMemoryTask(task) {
46
+ const result = {
47
+ id: task.id,
48
+ description: task.description,
49
+ type: task.type,
50
+ };
51
+ if (task.priority)
52
+ result.priority = task.priority;
53
+ if (task.dependencies)
54
+ result.dependencies = task.dependencies;
55
+ if (task.estimatedComplexity !== undefined)
56
+ result.estimatedComplexity = task.estimatedComplexity;
57
+ const metadata = task.metadata;
58
+ if (metadata)
59
+ result.metadata = metadata;
60
+ return result;
61
+ }
62
+ export function toMemoryCapabilityMap(caps) {
63
+ return new Map(Array.from(caps.entries()).map(([k, v]) => [k, toMemoryCapability(v)]));
64
+ }
65
+ export function fromMemoryCapabilityMap(caps) {
66
+ return new Map(Array.from(caps.entries()).map(([k, v]) => [k, fromMemoryCapability(v)]));
67
+ }
68
+ export function getProvider() {
69
+ return getMemoryRoutingProviderSync();
70
+ }
@@ -4,6 +4,7 @@
4
4
  * Creates optimized execution plans for orchestration tasks
5
5
  */
6
6
  import { getAgentCapabilitiesManager } from '../config/agent-capabilities.js';
7
+ import { getProvider, toMemoryTask, fromMemoryTask, } from '../config/memory-routing-bridge.js';
7
8
  /**
8
9
  * Execution Planner
9
10
  * Plans and optimizes task execution strategies
@@ -48,26 +49,35 @@ export class ExecutionPlanner {
48
49
  * Create an execution plan based on tasks and mode
49
50
  */
50
51
  async createExecutionPlan(tasks, executionMode) {
52
+ const provider = getProvider();
53
+ const memoryTasks = provider.enrichTasks(tasks.map(toMemoryTask));
54
+ const enrichedTasks = memoryTasks.map(fromMemoryTask);
51
55
  const agentAssignments = new Map();
52
56
  switch (executionMode) {
53
57
  case 'parallel':
54
- this.createParallelPlan(tasks, agentAssignments);
58
+ this.createParallelPlan(enrichedTasks, agentAssignments);
55
59
  break;
56
60
  case 'sequential':
57
- this.createSequentialPlan(tasks, agentAssignments);
61
+ this.createSequentialPlan(enrichedTasks, agentAssignments);
58
62
  break;
59
63
  case 'optimized':
60
64
  default:
61
- await this.createOptimizedPlan(tasks, agentAssignments);
65
+ await this.createOptimizedPlan(enrichedTasks, agentAssignments);
62
66
  break;
63
67
  }
64
68
  const estimatedDuration = this.estimateExecutionDuration(agentAssignments);
65
- return {
66
- tasks,
69
+ const plan = {
70
+ tasks: enrichedTasks,
67
71
  strategy: executionMode,
68
72
  agentAssignments,
69
73
  estimatedDuration,
70
74
  };
75
+ if (provider.id !== 'null') {
76
+ plan.memoryContext = {
77
+ ...provider.buildInheritedContext(memoryTasks),
78
+ };
79
+ }
80
+ return plan;
71
81
  }
72
82
  /**
73
83
  * Create a parallel execution plan
@@ -150,7 +160,11 @@ export class ExecutionPlanner {
150
160
  assignTasksToAgents(tasks, agentAssignments) {
151
161
  for (const task of tasks) {
152
162
  const complexity = task.estimatedComplexity || 30;
153
- const agent = this.capabilitiesManager.selectAgentForTask([task.type], complexity) || 'orchestrator';
163
+ const requiredCaps = [
164
+ task.type,
165
+ ...(task.metadata?.memorySignals ?? []),
166
+ ];
167
+ const agent = this.capabilitiesManager.selectAgentForTask(requiredCaps, complexity, task.description) || 'orchestrator';
154
168
  if (!agentAssignments.has(agent)) {
155
169
  agentAssignments.set(agent, []);
156
170
  }
@@ -188,7 +202,11 @@ export class ExecutionPlanner {
188
202
  category: task.type,
189
203
  });
190
204
  // Assign to agent
191
- const agent = this.capabilitiesManager.selectAgentForTask([task.type], complexity) || 'orchestrator';
205
+ const requiredCaps = [
206
+ task.type,
207
+ ...(task.metadata?.memorySignals ?? []),
208
+ ];
209
+ const agent = this.capabilitiesManager.selectAgentForTask(requiredCaps, complexity, task.description) || 'orchestrator';
192
210
  if (!assignments.has(agent)) {
193
211
  assignments.set(agent, []);
194
212
  }
@@ -6,7 +6,8 @@
6
6
  import { frameworkLogger } from '../../../core/framework-logger.js';
7
7
  import { getExecutionPlanner } from '../execution/execution-planner.js';
8
8
  import { mcpClientManager } from '../../../mcps/mcp-client.js';
9
- import { addObservations, extractOrchestrationObservations } from '../aside-context.js';
9
+ import { addObservations, extractOrchestrationObservations, spawnAside } from '../aside-context.js';
10
+ import { getProvider } from '../config/memory-routing-bridge.js';
10
11
  /**
11
12
  * Task Handler
12
13
  * Processes orchestrate-task requests
@@ -38,8 +39,37 @@ export class TaskHandler {
38
39
  }
39
40
  // Analyze complexity and create execution plan
40
41
  const executionPlan = await this.planner.createExecutionPlan(tasks, executionMode);
42
+ const memoryProvider = getProvider();
43
+ if (memoryProvider.id !== 'null' && executionPlan.memoryContext) {
44
+ await spawnAside({
45
+ description: `Orchestrate: ${description}`,
46
+ sessionId,
47
+ inheritedContext: {
48
+ memoryRouting: executionPlan.memoryContext,
49
+ },
50
+ });
51
+ }
41
52
  // Execute orchestration (simulated for MCP server)
42
53
  const results = await this.executePlan(executionPlan, sessionId, timeout);
54
+ // Feed per-task outcomes back to memory provider (not aggregate session stats)
55
+ if (memoryProvider.ingestFeedback) {
56
+ const outcomeByKey = new Map(results.taskOutcomes.map((o) => [`${o.agent}:${o.taskId}`, o]));
57
+ for (const [agent, assignedTasks] of executionPlan.agentAssignments) {
58
+ for (const task of assignedTasks) {
59
+ const outcome = outcomeByKey.get(`${agent}:${task.id}`);
60
+ memoryProvider.ingestFeedback({
61
+ timestamp: new Date().toISOString(),
62
+ sessionId,
63
+ taskId: task.id,
64
+ assignedAgent: agent,
65
+ memorySignals: task.metadata?.memorySignals ?? [],
66
+ complexity: task.estimatedComplexity ?? 30,
67
+ success: outcome?.success ?? false,
68
+ durationMs: outcome?.durationMs ?? 0,
69
+ });
70
+ }
71
+ }
72
+ }
43
73
  // Update result
44
74
  orchestrationResult.success = results.success;
45
75
  orchestrationResult.completedTasks = results.completedTasks;
@@ -82,6 +112,7 @@ export class TaskHandler {
82
112
  let completedTasks = 0;
83
113
  let failedTasks = 0;
84
114
  const agentOutputs = {};
115
+ const taskOutcomes = [];
85
116
  const skillServers = new Set([
86
117
  'code-review', 'code-reviewer',
87
118
  'security-audit', 'security-auditor',
@@ -96,6 +127,7 @@ export class TaskHandler {
96
127
  agentUtilization[agent] = tasks.length;
97
128
  if (skillServers.has(agent)) {
98
129
  for (const task of tasks) {
130
+ const taskStart = Date.now();
99
131
  try {
100
132
  const toolName = this.mapAgentToTool(agent);
101
133
  const result = await mcpClientManager.callServerTool(agent, toolName, {
@@ -106,10 +138,22 @@ export class TaskHandler {
106
138
  const outputText = this.extractTextFromMcpResult(result);
107
139
  agentOutputs[`${agent}:${task.id}`] = outputText;
108
140
  completedTasks++;
141
+ taskOutcomes.push({
142
+ taskId: task.id,
143
+ agent,
144
+ success: true,
145
+ durationMs: Date.now() - taskStart,
146
+ });
109
147
  }
110
148
  catch (err) {
111
149
  failedTasks++;
112
150
  agentOutputs[`${agent}:${task.id}`] = `Error: ${err instanceof Error ? err.message : String(err)}`;
151
+ taskOutcomes.push({
152
+ taskId: task.id,
153
+ agent,
154
+ success: false,
155
+ durationMs: Date.now() - taskStart,
156
+ });
113
157
  frameworkLogger.log('orchestrator.task-handler', 'task-execution-failed', 'warning', {
114
158
  agent,
115
159
  taskId: task.id,
@@ -120,7 +164,15 @@ export class TaskHandler {
120
164
  }
121
165
  else {
122
166
  // For non-MCP agents we still count them as "assigned" (they will be handled by the caller or legacy path)
123
- completedTasks += tasks.length;
167
+ for (const task of tasks) {
168
+ completedTasks++;
169
+ taskOutcomes.push({
170
+ taskId: task.id,
171
+ agent,
172
+ success: true,
173
+ durationMs: 0,
174
+ });
175
+ }
124
176
  }
125
177
  }
126
178
  const recommendations = [];
@@ -141,6 +193,7 @@ export class TaskHandler {
141
193
  bottlenecks,
142
194
  recommendations,
143
195
  agentOutputs,
196
+ taskOutcomes,
144
197
  };
145
198
  }
146
199
  mapAgentToTool(agent) {
@@ -0,0 +1,4 @@
1
+ export { getMemoryRoutingProvider, getMemoryRoutingProviderSync, getMemoryRoutingConfig, resetMemoryRoutingProvider, initializeMemoryRouting, } from './provider-registry.js';
2
+ export { NullMemoryRoutingProvider, createMemoryRoutingProvider } from './null-provider.js';
3
+ export { loadMemoryRoutingProvider } from './provider-loader.js';
4
+ export { validateMemoryRoutingConfig } from './validate-config.js';
@@ -0,0 +1,51 @@
1
+ const EMPTY_CONTEXT = {
2
+ providerId: 'null',
3
+ matchedSignals: [],
4
+ matchedTags: [],
5
+ flags: {},
6
+ synthesisAvailable: false,
7
+ };
8
+ export class NullMemoryRoutingProvider {
9
+ id = 'null';
10
+ name = 'Null (no memory routing)';
11
+ isAvailable() {
12
+ return true;
13
+ }
14
+ buildRoutingContext() {
15
+ return { ...EMPTY_CONTEXT };
16
+ }
17
+ enhanceAgentCapabilities(base) {
18
+ return new Map(base);
19
+ }
20
+ enrichTasks(tasks) {
21
+ return tasks;
22
+ }
23
+ buildInheritedContext() {
24
+ return { providerId: 'null', matchedSignals: [], flags: {} };
25
+ }
26
+ selectAgent(capabilities, requiredCapabilities, complexity) {
27
+ let bestAgent = null;
28
+ let bestScore = -1;
29
+ for (const [agent, caps] of capabilities) {
30
+ if (complexity > caps.complexityThreshold)
31
+ continue;
32
+ const matchCount = requiredCapabilities.filter((c) => caps.capabilities.includes(c)).length;
33
+ const score = matchCount * 10 + caps.concurrentTasks;
34
+ if (score > bestScore) {
35
+ bestScore = score;
36
+ bestAgent = agent;
37
+ }
38
+ }
39
+ return bestAgent;
40
+ }
41
+ resolveThinDispatch(baseAgent, _operation, complexityScore) {
42
+ return {
43
+ agent: baseAgent,
44
+ adjustedScore: complexityScore,
45
+ context: { ...EMPTY_CONTEXT },
46
+ };
47
+ }
48
+ }
49
+ export function createMemoryRoutingProvider() {
50
+ return new NullMemoryRoutingProvider();
51
+ }
@@ -0,0 +1,91 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { frameworkLogger } from '../core/framework-logger.js';
5
+ import { createMemoryRoutingProvider as createNullProvider } from './null-provider.js';
6
+ import { validateMemoryRoutingConfig } from './validate-config.js';
7
+ const REPERTOIRE_CANDIDATE_PATHS = [
8
+ '../repertoire/dist/provider/memory-routing-provider.js',
9
+ '../../repertoire/dist/provider/memory-routing-provider.js',
10
+ '../../../repertoire/dist/provider/memory-routing-provider.js',
11
+ ];
12
+ /**
13
+ * SECURITY: features.json is a trusted configuration boundary.
14
+ * module_path is resolved from disk and dynamically imported without signature
15
+ * verification. Only grant write access to features.json to trusted operators.
16
+ */
17
+ function resolveModulePath(configuredPath, cwd) {
18
+ if (!configuredPath)
19
+ return null;
20
+ const candidates = [
21
+ resolve(cwd, configuredPath),
22
+ configuredPath,
23
+ ];
24
+ for (const candidate of candidates) {
25
+ if (existsSync(candidate))
26
+ return candidate;
27
+ }
28
+ return null;
29
+ }
30
+ function defaultPathForProvider(provider, cwd) {
31
+ if (provider !== 'repertoire')
32
+ return null;
33
+ for (const rel of REPERTOIRE_CANDIDATE_PATHS) {
34
+ const abs = resolve(cwd, rel);
35
+ if (existsSync(abs))
36
+ return abs;
37
+ }
38
+ return null;
39
+ }
40
+ export async function loadMemoryRoutingProvider(config, cwd = process.cwd()) {
41
+ const validation = validateMemoryRoutingConfig(config);
42
+ if (!validation.valid) {
43
+ await frameworkLogger.log('memory-routing', 'config-invalid', 'error', { errors: validation.errors, provider: config.provider });
44
+ return createNullProvider();
45
+ }
46
+ const effective = validation.normalized;
47
+ if (!effective.enabled || effective.provider === 'null') {
48
+ return createNullProvider();
49
+ }
50
+ const modulePath = resolveModulePath(effective.module_path, cwd) ??
51
+ defaultPathForProvider(effective.provider, cwd);
52
+ if (!modulePath) {
53
+ await frameworkLogger.log('memory-routing', 'provider-not-found', 'error', {
54
+ provider: effective.provider,
55
+ module_path: effective.module_path,
56
+ message: `Provider "${effective.provider}" is configured but module_path could not be resolved. Falling back to null provider.`,
57
+ });
58
+ return createNullProvider();
59
+ }
60
+ try {
61
+ const mod = await import(pathToFileURL(modulePath).href);
62
+ const factory = mod.createMemoryRoutingProvider ??
63
+ mod.default?.createMemoryRoutingProvider;
64
+ if (typeof factory !== 'function') {
65
+ throw new Error(`Module ${modulePath} must export createMemoryRoutingProvider()`);
66
+ }
67
+ const provider = factory((effective.config ?? {}));
68
+ if (!provider?.id || typeof provider.isAvailable !== 'function') {
69
+ throw new Error(`Invalid memory routing provider from ${modulePath}`);
70
+ }
71
+ if (!provider.isAvailable()) {
72
+ await frameworkLogger.log('memory-routing', 'provider-unavailable', 'error', {
73
+ providerId: provider.id,
74
+ modulePath,
75
+ message: `Provider "${provider.id}" loaded but isAvailable() returned false. Falling back to null provider.`,
76
+ });
77
+ return createNullProvider();
78
+ }
79
+ await frameworkLogger.log('memory-routing', 'provider-loaded', 'info', { providerId: provider.id, name: provider.name, modulePath });
80
+ return provider;
81
+ }
82
+ catch (err) {
83
+ await frameworkLogger.log('memory-routing', 'provider-load-failed', 'error', {
84
+ modulePath,
85
+ error: err instanceof Error ? err.message : String(err),
86
+ cwd,
87
+ configDir: dirname(modulePath),
88
+ });
89
+ return createNullProvider();
90
+ }
91
+ }
@@ -0,0 +1,40 @@
1
+ import { featuresConfigLoader } from '../core/features-config.js';
2
+ import { NullMemoryRoutingProvider } from './null-provider.js';
3
+ import { loadMemoryRoutingProvider } from './provider-loader.js';
4
+ import { validateMemoryRoutingConfig } from './validate-config.js';
5
+ let cachedProvider = null;
6
+ let loadPromise = null;
7
+ const nullProviderSingleton = new NullMemoryRoutingProvider();
8
+ export function getMemoryRoutingConfig() {
9
+ const raw = featuresConfigLoader.loadConfig().memory_routing;
10
+ const validation = validateMemoryRoutingConfig(raw ?? { enabled: false, provider: 'null' });
11
+ return validation.normalized;
12
+ }
13
+ export async function getMemoryRoutingProvider(forceReload = false) {
14
+ if (!forceReload && cachedProvider)
15
+ return cachedProvider;
16
+ if (!forceReload && loadPromise)
17
+ return loadPromise;
18
+ const config = getMemoryRoutingConfig();
19
+ loadPromise = loadMemoryRoutingProvider(config).then((provider) => {
20
+ cachedProvider = provider;
21
+ loadPromise = null;
22
+ return provider;
23
+ });
24
+ return loadPromise;
25
+ }
26
+ /** Synchronous accessor — returns shared null singleton until async load completes. */
27
+ export function getMemoryRoutingProviderSync() {
28
+ return cachedProvider ?? nullProviderSingleton;
29
+ }
30
+ export function resetMemoryRoutingProvider() {
31
+ cachedProvider = null;
32
+ loadPromise = null;
33
+ }
34
+ /** Kick off background load at module init. */
35
+ export function initializeMemoryRouting() {
36
+ const config = getMemoryRoutingConfig();
37
+ if (config.enabled) {
38
+ void getMemoryRoutingProvider();
39
+ }
40
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Memory Routing Provider — pluggable contract for long-term memory enrichment.
3
+ *
4
+ * Repertoire is one implementation. Any provider exposing createMemoryRoutingProvider()
5
+ * can be loaded via features.json memory_routing.module_path.
6
+ */
7
+ export {};
@@ -0,0 +1,32 @@
1
+ const VALID_PROVIDERS = new Set(['null', 'repertoire', 'custom']);
2
+ export function validateMemoryRoutingConfig(raw) {
3
+ const errors = [];
4
+ const input = (raw ?? {});
5
+ const enabled = input.enabled === true;
6
+ const provider = typeof input.provider === 'string' ? input.provider : 'null';
7
+ if (!VALID_PROVIDERS.has(provider)) {
8
+ errors.push(`Invalid memory_routing.provider "${provider}". Must be one of: null, repertoire, custom.`);
9
+ }
10
+ if (enabled && provider !== 'null' && !input.module_path) {
11
+ errors.push(`memory_routing.provider "${provider}" requires module_path when enabled.`);
12
+ }
13
+ if (input.module_path !== undefined && typeof input.module_path !== 'string') {
14
+ errors.push('memory_routing.module_path must be a string.');
15
+ }
16
+ if (input.config !== undefined && (typeof input.config !== 'object' || input.config === null)) {
17
+ errors.push('memory_routing.config must be an object.');
18
+ }
19
+ const normalized = {
20
+ enabled,
21
+ provider: VALID_PROVIDERS.has(provider)
22
+ ? provider
23
+ : 'null',
24
+ };
25
+ if (typeof input.module_path === 'string') {
26
+ normalized.module_path = input.module_path;
27
+ }
28
+ if (input.config && typeof input.config === 'object') {
29
+ normalized.config = input.config;
30
+ }
31
+ return { valid: errors.length === 0, errors, normalized };
32
+ }
@@ -9,6 +9,8 @@
9
9
  import { frameworkLogger } from "../core/framework-logger.js";
10
10
  import { getLevelFromScore, getAgentForTier, levelToTier, } from "../delegation/complexity-core.js";
11
11
  import { ComplexityAnalyzer } from "../delegation/complexity-analyzer.js";
12
+ import { getMemoryRoutingProviderSync, initializeMemoryRouting, } from "../memory-routing/index.js";
13
+ initializeMemoryRouting();
12
14
  export const NUCLEUS_THIN_DISPATCH_VERSION = "0.1.0";
13
15
  /**
14
16
  * Score the complexity of an operation given its description and context.
@@ -52,6 +54,32 @@ export function routeToAgent(scoreOrLevel, level) {
52
54
  */
53
55
  export function scoreAndRoute(operation, context, thresholds) {
54
56
  const score = scoreComplexity(operation, context, thresholds);
55
- const agent = routeToAgent(score);
57
+ let agent = routeToAgent(score);
58
+ const provider = getMemoryRoutingProviderSync();
59
+ let memoryRouting;
60
+ if (provider.id !== "null") {
61
+ const resolved = provider.resolveThinDispatch(agent, operation, score.score);
62
+ agent = resolved.agent;
63
+ memoryRouting = {
64
+ providerId: resolved.context.providerId,
65
+ adjustedScore: resolved.adjustedScore,
66
+ signals: resolved.context.matchedSignals,
67
+ };
68
+ const adjustedLevel = getLevelFromScore(resolved.adjustedScore, thresholds);
69
+ frameworkLogger.log("nucleus-thin-dispatch", "memory-routing", "info", {
70
+ providerId: resolved.context.providerId,
71
+ baseAgent: routeToAgent(score),
72
+ resolvedAgent: agent,
73
+ baseScore: score.score,
74
+ adjustedScore: resolved.adjustedScore,
75
+ level: adjustedLevel,
76
+ signals: resolved.context.matchedSignals,
77
+ });
78
+ return {
79
+ score: { ...score, score: resolved.adjustedScore, level: adjustedLevel },
80
+ agent,
81
+ memoryRouting,
82
+ };
83
+ }
56
84
  return { score, agent };
57
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xray",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Multi-agent orchestration and Codex governance for OpenCode, Hermes, Grok Build, and OpenClaw",
5
5
  "readme": "README.md",
6
6
  "license": "MIT",
@@ -1,11 +1,18 @@
1
1
  /**
2
2
  * Agent Capabilities Configuration
3
- *
4
- * Centralized agent capability definitions for orchestration decisions
3
+ *
4
+ * Centralized agent capability definitions for orchestration decisions.
5
+ * Enriched at runtime by the active MemoryRoutingProvider (Repertoire, etc.).
5
6
  */
6
7
 
7
8
  import type { AgentCapability } from '../types.js';
8
9
  import { AGENT_REGISTRY } from "../../../agents/registry.js";
10
+ import { initializeMemoryRouting } from '../../../memory-routing/index.js';
11
+ import {
12
+ getProvider,
13
+ toMemoryCapabilityMap,
14
+ fromMemoryCapabilityMap,
15
+ } from './memory-routing-bridge.js';
9
16
 
10
17
  const DEFAULT_AGENT_CAPABILITIES: Record<string, AgentCapability> = Object.fromEntries(
11
18
  Object.entries(AGENT_REGISTRY).map(([name, entry]) => [
@@ -18,18 +25,31 @@ const DEFAULT_AGENT_CAPABILITIES: Record<string, AgentCapability> = Object.fromE
18
25
  ]),
19
26
  );
20
27
 
28
+ initializeMemoryRouting();
29
+
21
30
  /**
22
31
  * Agent Capabilities Manager
23
32
  * Manages agent capabilities for orchestration decisions
24
33
  */
25
34
  export class AgentCapabilitiesManager {
26
35
  private capabilities: Map<string, AgentCapability> = new Map();
36
+ private enriched = false;
27
37
 
28
38
  constructor() {
29
- // Initialize with default capabilities
30
39
  Object.entries(DEFAULT_AGENT_CAPABILITIES).forEach(([agent, config]) => {
31
40
  this.capabilities.set(agent, config);
32
41
  });
42
+ this.applyMemoryRoutingEnrichment();
43
+ }
44
+
45
+ private applyMemoryRoutingEnrichment(): void {
46
+ const provider = getProvider();
47
+ if (provider.id === 'null') return;
48
+
49
+ const memoryCaps = toMemoryCapabilityMap(this.capabilities);
50
+ const enriched = provider.enhanceAgentCapabilities(memoryCaps);
51
+ this.capabilities = fromMemoryCapabilityMap(enriched);
52
+ this.enriched = true;
33
53
  }
34
54
 
35
55
  /**
@@ -43,6 +63,7 @@ export class AgentCapabilitiesManager {
43
63
  * Get all registered agent capabilities
44
64
  */
45
65
  getAllCapabilities(): Map<string, AgentCapability> {
66
+ if (!this.enriched) this.applyMemoryRoutingEnrichment();
46
67
  return new Map(this.capabilities);
47
68
  }
48
69
 
@@ -54,24 +75,35 @@ export class AgentCapabilitiesManager {
54
75
  }
55
76
 
56
77
  /**
57
- * Select the best agent for a task based on complexity and capabilities
78
+ * Select the best agent for a task based on complexity, capabilities, and memory routing.
58
79
  */
59
- selectAgentForTask(requiredCapabilities: string[], complexity: number): string | null {
80
+ selectAgentForTask(
81
+ requiredCapabilities: string[],
82
+ complexity: number,
83
+ operationDescription = '',
84
+ ): string | null {
85
+ const provider = getProvider();
86
+
87
+ if (provider.id !== 'null' && operationDescription) {
88
+ const memoryCaps = toMemoryCapabilityMap(this.getAllCapabilities());
89
+ return provider.selectAgent(
90
+ memoryCaps,
91
+ requiredCapabilities,
92
+ complexity,
93
+ operationDescription,
94
+ );
95
+ }
96
+
60
97
  let bestAgent: string | null = null;
61
98
  let bestScore = -1;
62
99
 
63
100
  for (const [agent, caps] of this.capabilities) {
64
- // Check if agent can handle the complexity
65
- if (complexity > caps.complexityThreshold) {
66
- continue;
67
- }
101
+ if (complexity > caps.complexityThreshold) continue;
68
102
 
69
- // Calculate capability match score
70
- const matchCount = requiredCapabilities.filter(cap =>
71
- caps.capabilities.includes(cap)
103
+ const matchCount = requiredCapabilities.filter((cap) =>
104
+ caps.capabilities.includes(cap),
72
105
  ).length;
73
106
 
74
- // Prefer agents with more concurrent tasks available
75
107
  const score = matchCount * 10 + caps.concurrentTasks;
76
108
 
77
109
  if (score > bestScore) {
@@ -97,7 +129,6 @@ export class AgentCapabilitiesManager {
97
129
  }
98
130
  }
99
131
 
100
- // Singleton instance
101
132
  let capabilitiesManagerInstance: AgentCapabilitiesManager | null = null;
102
133
 
103
134
  export function getAgentCapabilitiesManager(): AgentCapabilitiesManager {
@@ -106,3 +137,7 @@ export function getAgentCapabilitiesManager(): AgentCapabilitiesManager {
106
137
  }
107
138
  return capabilitiesManagerInstance;
108
139
  }
140
+
141
+ export function resetAgentCapabilitiesManager(): void {
142
+ capabilitiesManagerInstance = null;
143
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Bridge between orchestrator types and the pluggable MemoryRoutingProvider.
3
+ */
4
+
5
+ import {
6
+ getMemoryRoutingProviderSync,
7
+ type MemoryAgentCapability,
8
+ type MemoryOrchestrationTask,
9
+ type MemoryRoutingProvider,
10
+ } from '../../../memory-routing/index.js';
11
+ import type { AgentCapability, OrchestrationTask } from '../types.js';
12
+
13
+ export function toMemoryCapability(caps: AgentCapability): MemoryAgentCapability {
14
+ const result: MemoryAgentCapability = {
15
+ capabilities: caps.capabilities,
16
+ complexityThreshold: caps.complexityThreshold,
17
+ concurrentTasks: caps.concurrentTasks,
18
+ };
19
+ if (caps.memorySignals) result.memorySignals = caps.memorySignals;
20
+ if (caps.memoryTags) result.memoryTags = caps.memoryTags;
21
+ return result;
22
+ }
23
+
24
+ export function fromMemoryCapability(caps: MemoryAgentCapability): AgentCapability {
25
+ const result: AgentCapability = {
26
+ capabilities: caps.capabilities,
27
+ complexityThreshold: caps.complexityThreshold,
28
+ concurrentTasks: caps.concurrentTasks,
29
+ };
30
+ if (caps.memorySignals) result.memorySignals = caps.memorySignals;
31
+ if (caps.memoryTags) result.memoryTags = caps.memoryTags;
32
+ return result;
33
+ }
34
+
35
+ export function toMemoryTask(task: OrchestrationTask): MemoryOrchestrationTask {
36
+ const result: MemoryOrchestrationTask = {
37
+ id: task.id,
38
+ description: task.description,
39
+ type: task.type,
40
+ };
41
+ if (task.priority) result.priority = task.priority;
42
+ if (task.dependencies) result.dependencies = task.dependencies;
43
+ if (task.estimatedComplexity !== undefined) result.estimatedComplexity = task.estimatedComplexity;
44
+ if (task.metadata) result.metadata = task.metadata as Record<string, unknown>;
45
+ return result;
46
+ }
47
+
48
+ export function fromMemoryTask(task: MemoryOrchestrationTask): OrchestrationTask {
49
+ const result: OrchestrationTask = {
50
+ id: task.id,
51
+ description: task.description,
52
+ type: task.type,
53
+ };
54
+ if (task.priority) result.priority = task.priority;
55
+ if (task.dependencies) result.dependencies = task.dependencies;
56
+ if (task.estimatedComplexity !== undefined) result.estimatedComplexity = task.estimatedComplexity;
57
+ const metadata = task.metadata as OrchestrationTask['metadata'];
58
+ if (metadata) result.metadata = metadata;
59
+ return result;
60
+ }
61
+
62
+ export function toMemoryCapabilityMap(
63
+ caps: Map<string, AgentCapability>,
64
+ ): Map<string, MemoryAgentCapability> {
65
+ return new Map(
66
+ Array.from(caps.entries()).map(([k, v]) => [k, toMemoryCapability(v)]),
67
+ );
68
+ }
69
+
70
+ export function fromMemoryCapabilityMap(
71
+ caps: Map<string, MemoryAgentCapability>,
72
+ ): Map<string, AgentCapability> {
73
+ return new Map(
74
+ Array.from(caps.entries()).map(([k, v]) => [k, fromMemoryCapability(v)]),
75
+ );
76
+ }
77
+
78
+ export function getProvider(): MemoryRoutingProvider {
79
+ return getMemoryRoutingProviderSync();
80
+ }
@@ -11,6 +11,11 @@ import type {
11
11
  TaskValidation
12
12
  } from '../types.js';
13
13
  import { getAgentCapabilitiesManager } from '../config/agent-capabilities.js';
14
+ import {
15
+ getProvider,
16
+ toMemoryTask,
17
+ fromMemoryTask,
18
+ } from '../config/memory-routing-bridge.js';
14
19
 
15
20
  /**
16
21
  * Execution Planner
@@ -67,29 +72,41 @@ export class ExecutionPlanner {
67
72
  tasks: OrchestrationTask[],
68
73
  executionMode: string
69
74
  ): Promise<ExecutionPlan> {
75
+ const provider = getProvider();
76
+ const memoryTasks = provider.enrichTasks(tasks.map(toMemoryTask));
77
+ const enrichedTasks = memoryTasks.map(fromMemoryTask);
78
+
70
79
  const agentAssignments = new Map<string, OrchestrationTask[]>();
71
80
 
72
81
  switch (executionMode) {
73
82
  case 'parallel':
74
- this.createParallelPlan(tasks, agentAssignments);
83
+ this.createParallelPlan(enrichedTasks, agentAssignments);
75
84
  break;
76
85
  case 'sequential':
77
- this.createSequentialPlan(tasks, agentAssignments);
86
+ this.createSequentialPlan(enrichedTasks, agentAssignments);
78
87
  break;
79
88
  case 'optimized':
80
89
  default:
81
- await this.createOptimizedPlan(tasks, agentAssignments);
90
+ await this.createOptimizedPlan(enrichedTasks, agentAssignments);
82
91
  break;
83
92
  }
84
93
 
85
94
  const estimatedDuration = this.estimateExecutionDuration(agentAssignments);
86
95
 
87
- return {
88
- tasks,
96
+ const plan: ExecutionPlan = {
97
+ tasks: enrichedTasks,
89
98
  strategy: executionMode as 'parallel' | 'sequential' | 'optimized',
90
99
  agentAssignments,
91
100
  estimatedDuration,
92
101
  };
102
+
103
+ if (provider.id !== 'null') {
104
+ plan.memoryContext = {
105
+ ...provider.buildInheritedContext(memoryTasks),
106
+ } as Record<string, unknown>;
107
+ }
108
+
109
+ return plan;
93
110
  }
94
111
 
95
112
  /**
@@ -197,9 +214,14 @@ export class ExecutionPlanner {
197
214
  ): void {
198
215
  for (const task of tasks) {
199
216
  const complexity = task.estimatedComplexity || 30;
217
+ const requiredCaps = [
218
+ task.type,
219
+ ...(task.metadata?.memorySignals ?? []),
220
+ ];
200
221
  const agent = this.capabilitiesManager.selectAgentForTask(
201
- [task.type],
202
- complexity
222
+ requiredCaps,
223
+ complexity,
224
+ task.description,
203
225
  ) || 'orchestrator';
204
226
 
205
227
  if (!agentAssignments.has(agent)) {
@@ -247,9 +269,14 @@ export class ExecutionPlanner {
247
269
  });
248
270
 
249
271
  // Assign to agent
272
+ const requiredCaps = [
273
+ task.type,
274
+ ...(task.metadata?.memorySignals ?? []),
275
+ ];
250
276
  const agent = this.capabilitiesManager.selectAgentForTask(
251
- [task.type],
252
- complexity
277
+ requiredCaps,
278
+ complexity,
279
+ task.description,
253
280
  ) || 'orchestrator';
254
281
 
255
282
  if (!assignments.has(agent)) {
@@ -7,7 +7,8 @@
7
7
  import { frameworkLogger } from '../../../core/framework-logger.js';
8
8
  import { getExecutionPlanner } from '../execution/execution-planner.js';
9
9
  import { mcpClientManager } from '../../../mcps/mcp-client.js';
10
- import { addObservations, extractOrchestrationObservations } from '../aside-context.js';
10
+ import { addObservations, extractOrchestrationObservations, spawnAside } from '../aside-context.js';
11
+ import { getProvider } from '../config/memory-routing-bridge.js';
11
12
  import type { OrchestrationResult, OrchestrationTask } from '../types.js';
12
13
 
13
14
  export interface TaskHandlerDeps {
@@ -76,9 +77,43 @@ export class TaskHandler {
76
77
  // Analyze complexity and create execution plan
77
78
  const executionPlan = await this.planner.createExecutionPlan(tasks, executionMode);
78
79
 
80
+ const memoryProvider = getProvider();
81
+ if (memoryProvider.id !== 'null' && executionPlan.memoryContext) {
82
+ await spawnAside({
83
+ description: `Orchestrate: ${description}`,
84
+ sessionId,
85
+ inheritedContext: {
86
+ memoryRouting: executionPlan.memoryContext,
87
+ },
88
+ });
89
+ }
90
+
79
91
  // Execute orchestration (simulated for MCP server)
80
92
  const results = await this.executePlan(executionPlan, sessionId, timeout);
81
93
 
94
+ // Feed per-task outcomes back to memory provider (not aggregate session stats)
95
+ if (memoryProvider.ingestFeedback) {
96
+ const outcomeByKey = new Map(
97
+ results.taskOutcomes.map((o) => [`${o.agent}:${o.taskId}`, o]),
98
+ );
99
+
100
+ for (const [agent, assignedTasks] of executionPlan.agentAssignments) {
101
+ for (const task of assignedTasks) {
102
+ const outcome = outcomeByKey.get(`${agent}:${task.id}`);
103
+ memoryProvider.ingestFeedback({
104
+ timestamp: new Date().toISOString(),
105
+ sessionId,
106
+ taskId: task.id,
107
+ assignedAgent: agent,
108
+ memorySignals: task.metadata?.memorySignals ?? [],
109
+ complexity: task.estimatedComplexity ?? 30,
110
+ success: outcome?.success ?? false,
111
+ durationMs: outcome?.durationMs ?? 0,
112
+ });
113
+ }
114
+ }
115
+ }
116
+
82
117
  // Update result
83
118
  orchestrationResult.success = results.success;
84
119
  orchestrationResult.completedTasks = results.completedTasks;
@@ -136,11 +171,23 @@ export class TaskHandler {
136
171
  bottlenecks: string[];
137
172
  recommendations: string[];
138
173
  agentOutputs?: Record<string, string>;
174
+ taskOutcomes: Array<{
175
+ taskId: string;
176
+ agent: string;
177
+ success: boolean;
178
+ durationMs: number;
179
+ }>;
139
180
  }> {
140
181
  const agentUtilization: Record<string, number> = {};
141
182
  let completedTasks = 0;
142
183
  let failedTasks = 0;
143
184
  const agentOutputs: Record<string, string> = {};
185
+ const taskOutcomes: Array<{
186
+ taskId: string;
187
+ agent: string;
188
+ success: boolean;
189
+ durationMs: number;
190
+ }> = [];
144
191
 
145
192
  const skillServers = new Set([
146
193
  'code-review', 'code-reviewer',
@@ -158,6 +205,7 @@ export class TaskHandler {
158
205
 
159
206
  if (skillServers.has(agent)) {
160
207
  for (const task of tasks) {
208
+ const taskStart = Date.now();
161
209
  try {
162
210
  const toolName = this.mapAgentToTool(agent);
163
211
  const result = await mcpClientManager.callServerTool(agent, toolName, {
@@ -169,9 +217,21 @@ export class TaskHandler {
169
217
  const outputText = this.extractTextFromMcpResult(result);
170
218
  agentOutputs[`${agent}:${task.id}`] = outputText;
171
219
  completedTasks++;
220
+ taskOutcomes.push({
221
+ taskId: task.id,
222
+ agent,
223
+ success: true,
224
+ durationMs: Date.now() - taskStart,
225
+ });
172
226
  } catch (err) {
173
227
  failedTasks++;
174
228
  agentOutputs[`${agent}:${task.id}`] = `Error: ${err instanceof Error ? err.message : String(err)}`;
229
+ taskOutcomes.push({
230
+ taskId: task.id,
231
+ agent,
232
+ success: false,
233
+ durationMs: Date.now() - taskStart,
234
+ });
175
235
  frameworkLogger.log('orchestrator.task-handler', 'task-execution-failed', 'warning', {
176
236
  agent,
177
237
  taskId: task.id,
@@ -181,7 +241,15 @@ export class TaskHandler {
181
241
  }
182
242
  } else {
183
243
  // For non-MCP agents we still count them as "assigned" (they will be handled by the caller or legacy path)
184
- completedTasks += tasks.length;
244
+ for (const task of tasks) {
245
+ completedTasks++;
246
+ taskOutcomes.push({
247
+ taskId: task.id,
248
+ agent,
249
+ success: true,
250
+ durationMs: 0,
251
+ });
252
+ }
185
253
  }
186
254
  }
187
255
 
@@ -205,6 +273,7 @@ export class TaskHandler {
205
273
  bottlenecks,
206
274
  recommendations,
207
275
  agentOutputs,
276
+ taskOutcomes,
208
277
  };
209
278
  }
210
279
 
@@ -8,6 +8,17 @@ export interface AgentCapability {
8
8
  capabilities: string[];
9
9
  complexityThreshold: number;
10
10
  concurrentTasks: number;
11
+ /** Populated by active MemoryRoutingProvider (e.g. Repertoire) */
12
+ memorySignals?: string[];
13
+ memoryTags?: string[];
14
+ }
15
+
16
+ export interface OrchestrationTaskMetadata {
17
+ memorySignals?: string[];
18
+ matchedPrimitives?: string[];
19
+ synthesisContext?: string;
20
+ ontologicalTrapDetected?: boolean;
21
+ memoryProviderId?: string;
11
22
  }
12
23
 
13
24
  export interface OrchestrationTask {
@@ -17,6 +28,7 @@ export interface OrchestrationTask {
17
28
  priority?: 'critical' | 'high' | 'medium' | 'low';
18
29
  dependencies?: string[];
19
30
  estimatedComplexity?: number;
31
+ metadata?: OrchestrationTaskMetadata;
20
32
  }
21
33
 
22
34
  export interface ExecutionPlan {
@@ -24,6 +36,7 @@ export interface ExecutionPlan {
24
36
  strategy: 'parallel' | 'sequential' | 'optimized';
25
37
  agentAssignments: Map<string, OrchestrationTask[]>;
26
38
  estimatedDuration: number;
39
+ memoryContext?: Record<string, unknown>;
27
40
  }
28
41
 
29
42
  export interface OrchestrationResult {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.2.0",
2
+ "version": "3.3.0",
3
3
  "terms": [
4
4
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
5
5
  ],