@holoscript/framework 6.0.3 → 6.0.4
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 +1 -2
- package/ROADMAP.md +68 -66
- package/dist/{InvisibleWallet-BB6tFvRA.d.cts → InvisibleWallet-EFiuaLn3.d.cts} +1 -1
- package/dist/{OrchestratorAgent-BvWgf9uw.d.cts → OrchestratorAgent-CrLDGNL6.d.cts} +1 -1
- package/dist/agents/index.cjs +11 -10
- package/dist/agents/index.d.cts +4 -16
- package/dist/ai/index.cjs +2 -2
- package/dist/behavior.cjs +10 -0
- package/dist/economy/index.cjs +4 -4
- package/dist/economy/index.d.cts +2 -2
- package/dist/index.cjs +33 -11
- package/dist/index.d.cts +3 -3
- package/dist/swarm/index.cjs +3 -0
- package/package.json +14 -9
- package/src/__tests__/bounty-marketplace.test.ts +53 -21
- package/src/__tests__/delegation.test.ts +1 -4
- package/src/__tests__/done-log-audit.test.ts +38 -46
- package/src/__tests__/framework.test.ts +172 -53
- package/src/__tests__/goal-synthesizer.test.ts +9 -6
- package/src/__tests__/presence.test.ts +1 -1
- package/src/__tests__/protocol-agent.test.ts +12 -11
- package/src/__tests__/revenue-splitter.test.ts +22 -15
- package/src/__tests__/scenario-driven-todo.test.ts +55 -35
- package/src/__tests__/self-improve.test.ts +28 -9
- package/src/__tests__/service-lifecycle.test.ts +9 -3
- package/src/__tests__/skill-router.test.ts +3 -3
- package/src/agents/CulturalMemory.ts +6 -6
- package/src/agents/DelegationTraceHooks.ts +560 -0
- package/src/agents/FederatedRegistryAdapter.ts +1 -1
- package/src/agents/NormEngine.ts +3 -8
- package/src/agents/OrchestratorAgent.ts +1 -1
- package/src/agents/TaskDelegationService.ts +5 -9
- package/src/agents/__tests__/AgentWalletRegistry.test.ts +5 -4
- package/src/agents/__tests__/CrossRealityHandoff.test.ts +9 -3
- package/src/agents/__tests__/DelegationTraceHooks.test.ts +390 -0
- package/src/agents/__tests__/TaskDelegationService.test.ts +4 -2
- package/src/agents/spatial-comms/Layer1RealTime.ts +36 -19
- package/src/agents/spatial-comms/Layer2A2A.ts +1 -3
- package/src/agents/spatial-comms/Layer3MCP.ts +13 -4
- package/src/agents/spatial-comms/ProtocolTypes.ts +5 -2
- package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +2 -2
- package/src/ai/HoloScriptGenerator.ts +2 -2
- package/src/ai/__tests__/PerceptionSystem.prod.test.ts +1 -1
- package/src/ai/__tests__/PerceptionSystem.test.ts +14 -14
- package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +1 -1
- package/src/ai/index.ts +5 -1
- package/src/board/audit.ts +17 -6
- package/src/board/board-ops.ts +45 -15
- package/src/board/board-types.ts +94 -20
- package/src/delegation.ts +5 -3
- package/src/distributed-claimer.ts +13 -2
- package/src/economy/BountyManager.ts +40 -18
- package/src/economy/KnowledgeMarketplace.ts +27 -8
- package/src/economy/PaymentWebhookService.ts +0 -1
- package/src/economy/RevenueSplitter.ts +2 -4
- package/src/economy/UnifiedBudgetOptimizer.ts +8 -9
- package/src/economy/_core-stubs.ts +1 -1
- package/src/economy/x402-facilitator.ts +17 -8
- package/src/index.ts +16 -12
- package/src/knowledge/__tests__/knowledge-consolidator.test.ts +138 -89
- package/src/knowledge/__tests__/knowledge-store-vector.test.ts +59 -16
- package/src/knowledge/brain.ts +7 -7
- package/src/knowledge/consolidation.ts +16 -16
- package/src/knowledge/knowledge-consolidator.ts +60 -30
- package/src/knowledge/knowledge-store.ts +83 -45
- package/src/learning/ProceduralCompiler.ts +6 -1
- package/src/learning/learning/MemoryConsolidator.ts +102 -0
- package/src/learning/learning/MemoryScorer.ts +69 -0
- package/src/learning/learning/ProceduralCompiler.ts +45 -0
- package/src/learning/learning/SemanticClusterer.ts +66 -0
- package/src/llm/llm-adapter.ts +24 -10
- package/src/mesh/index.ts +37 -17
- package/src/protocol/goal-synthesizer.ts +24 -34
- package/src/protocol/implementations.ts +91 -22
- package/src/protocol/micro-phase-decomposer.ts +25 -17
- package/src/protocol/micro-step-decomposer.test.ts +104 -39
- package/src/protocol-agent.test.ts +17 -7
- package/src/protocol-agent.ts +45 -42
- package/src/self-improve/absorb-scanner.ts +9 -6
- package/src/self-improve/evolution-engine.ts +36 -18
- package/src/self-improve/framework-absorber.ts +21 -16
- package/src/self-improve/index.ts +2 -10
- package/src/self-improve/prompt-optimizer.ts +31 -19
- package/src/self-improve/test-generator.ts +16 -12
- package/src/skill-router.ts +7 -6
- package/src/swarm/messaging/GossipProtocol.ts +1 -1
- package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +31 -9
- package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +21 -7
- package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +24 -8
- package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +6 -2
- package/src/team.ts +277 -122
- package/src/training/scripts/generate-spatial-dataset.ts +1 -1
- package/src/training/training/LRScheduler.ts +377 -0
- package/src/training/training/QualityScoringPipeline.ts +139 -0
- package/src/training/training/SoftDedup.ts +461 -0
- package/src/training/training/SparsityMonitor.ts +685 -0
- package/src/training/training/SparsityMonitorTypes.ts +209 -0
- package/src/training/training/SpatialTrainingDataGenerator.ts +1526 -0
- package/src/training/training/SpatialTrainingDataTypes.ts +216 -0
- package/src/training/training/TrainingPipelineConfig.ts +215 -0
- package/src/training/training/__tests__/CorpusValidation.test.ts +87 -0
- package/src/training/training/__tests__/LRScheduler.test.ts +592 -0
- package/src/training/training/__tests__/SoftDedup.test.ts +415 -0
- package/src/training/training/__tests__/SparsityMonitor.test.ts +1623 -0
- package/src/training/training/__tests__/SpatialCorpusValidation.test.ts +72 -0
- package/src/training/training/__tests__/SpatialTrainingDataGenerator.test.ts +1244 -0
- package/src/training/training/__tests__/TrainingMonkeyIntegration.test.ts +897 -0
- package/src/training/training/__tests__/TrainingPipelineConfig.test.ts +202 -0
- package/src/training/training/__tests__/schema.test.ts +72 -0
- package/src/training/training/__tests__/training-constants.test.ts +106 -0
- package/src/training/training/__tests__/trait-mappings.test.ts +81 -0
- package/src/training/training/constants.ts +94 -0
- package/src/training/training/index.ts +17 -0
- package/src/training/training/schema.ts +147 -0
- package/src/training/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
- package/src/training/training/scripts/generate-spatial-dataset.ts +521 -0
- package/src/training/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
- package/src/training/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
- package/src/training/training/trainingmonkey/index.ts +26 -0
- package/src/training/training/trait-mappings.ts +157 -0
- package/src/types.ts +2 -7
- package/ALL-test-results.json +0 -1
- package/LICENSE +0 -21
- package/dist/AgentManifest-CB4xM-Ma.d.ts +0 -704
- package/dist/BehaviorTree-BrBFECv5.d.ts +0 -103
- package/dist/InvisibleWallet-rtRrBOA8.d.ts +0 -1732
- package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +0 -798
- package/dist/agents/index.d.ts +0 -1788
- package/dist/agents/index.js +0 -4695
- package/dist/ai/index.d.ts +0 -1753
- package/dist/ai/index.js +0 -5244
- package/dist/behavior.d.ts +0 -130
- package/dist/behavior.js +0 -407
- package/dist/economy/index.d.ts +0 -747
- package/dist/economy/index.js +0 -3617
- package/dist/implementations-D9T3un9D.d.ts +0 -236
- package/dist/index.d.ts +0 -1729
- package/dist/index.js +0 -24277
- package/dist/learning/index.d.ts +0 -104
- package/dist/learning/index.js +0 -189
- package/dist/negotiation/index.d.ts +0 -610
- package/dist/negotiation/index.js +0 -931
- package/dist/skills/index.d.ts +0 -289
- package/dist/skills/index.js +0 -1079
- package/dist/swarm/index.d.ts +0 -2433
- package/dist/swarm/index.js +0 -5221
- package/dist/training/index.d.ts +0 -1734
- package/dist/training/index.js +0 -2687
- package/extract-failures.js +0 -10
- package/src/training/training/data/novel-use-cases.jsonl +0 -153
- package/src/training/training/data/spatial-reasoning-10k.jsonl +0 -9354
- package/src/types/core-stubs.d.ts +0 -113
- package/test-output.txt +0 -0
- package/test-result.json +0 -1
- package/tsc-errors.txt +0 -4
- package/tsc_output.txt +0 -0
- package/typescript-errors-2.txt +0 -0
- package/typescript-errors.txt +0 -22
- package/vitest-log-utf8.txt +0 -268
- package/vitest-log.txt +0 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegation Trace & Replay Hooks
|
|
3
|
+
*
|
|
4
|
+
* Enables tracing which agent delegated work to which other agent,
|
|
5
|
+
* and replaying those delegation chains for debugging.
|
|
6
|
+
*
|
|
7
|
+
* Builds on top of TaskDelegationService's per-task trace events
|
|
8
|
+
* to provide a cross-agent delegation tree view.
|
|
9
|
+
*
|
|
10
|
+
* Part of HoloScript v6.0 Agent Orchestration.
|
|
11
|
+
*
|
|
12
|
+
* @module DelegationTraceHooks
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// TYPES
|
|
17
|
+
// =============================================================================
|
|
18
|
+
|
|
19
|
+
/** A single delegation event in the agent-to-agent chain. */
|
|
20
|
+
export interface DelegationEvent {
|
|
21
|
+
/** Unique ID for this delegation event */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Agent that initiated the delegation */
|
|
24
|
+
fromAgent: string;
|
|
25
|
+
/** Agent that received the delegation */
|
|
26
|
+
toAgent: string;
|
|
27
|
+
/** Task ID associated with this delegation */
|
|
28
|
+
taskId: string;
|
|
29
|
+
/** ISO-8601 timestamp of the delegation */
|
|
30
|
+
timestamp: string;
|
|
31
|
+
/** Arbitrary payload carried with the delegation (skill, args, etc.) */
|
|
32
|
+
payload: Record<string, unknown>;
|
|
33
|
+
/** ID of the parent DelegationEvent (null for root delegations) */
|
|
34
|
+
parentDelegation: string | null;
|
|
35
|
+
/** Current status of this delegation */
|
|
36
|
+
status: DelegationEventStatus;
|
|
37
|
+
/** Duration in ms (set after completion/failure) */
|
|
38
|
+
durationMs?: number;
|
|
39
|
+
/** Error message if the delegation failed */
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type DelegationEventStatus =
|
|
44
|
+
| 'pending'
|
|
45
|
+
| 'in_progress'
|
|
46
|
+
| 'completed'
|
|
47
|
+
| 'failed'
|
|
48
|
+
| 'timeout'
|
|
49
|
+
| 'replaying';
|
|
50
|
+
|
|
51
|
+
/** A full delegation trace — a tree of DelegationEvents with a single root. */
|
|
52
|
+
export interface DelegationTrace {
|
|
53
|
+
/** The root delegation event ID */
|
|
54
|
+
rootId: string;
|
|
55
|
+
/** All events in this trace, keyed by event ID */
|
|
56
|
+
events: Map<string, DelegationEvent>;
|
|
57
|
+
/** Timestamp when the trace was created */
|
|
58
|
+
createdAt: string;
|
|
59
|
+
/** Timestamp of the most recent event */
|
|
60
|
+
lastUpdated: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Summary of a delegation chain from root to leaf. */
|
|
64
|
+
export interface DelegationChainEntry {
|
|
65
|
+
/** The delegation event */
|
|
66
|
+
event: DelegationEvent;
|
|
67
|
+
/** Depth in the chain (0 = root) */
|
|
68
|
+
depth: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Subscriber callback for delegation events. */
|
|
72
|
+
export type DelegationHookFn = (event: DelegationEvent, trace: DelegationTrace) => void;
|
|
73
|
+
|
|
74
|
+
/** Options for replaying a delegation trace. */
|
|
75
|
+
export interface ReplayOptions {
|
|
76
|
+
/** If true, invoke the executor for each event. If false (default), dry-run only. */
|
|
77
|
+
execute?: boolean;
|
|
78
|
+
/** Optional delay between replay steps in ms (for visualization). */
|
|
79
|
+
stepDelayMs?: number;
|
|
80
|
+
/** Override payloads for specific event IDs during replay. */
|
|
81
|
+
payloadOverrides?: Map<string, Record<string, unknown>>;
|
|
82
|
+
/** Callback invoked before each replay step. Return false to skip. */
|
|
83
|
+
beforeStep?: (event: DelegationEvent, depth: number) => boolean | Promise<boolean>;
|
|
84
|
+
/** Callback invoked after each replay step. */
|
|
85
|
+
afterStep?: (event: DelegationEvent, result: ReplayStepResult) => void | Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Result of replaying a single delegation step. */
|
|
89
|
+
export interface ReplayStepResult {
|
|
90
|
+
eventId: string;
|
|
91
|
+
status: 'executed' | 'skipped' | 'dry_run' | 'failed';
|
|
92
|
+
result?: unknown;
|
|
93
|
+
error?: string;
|
|
94
|
+
durationMs: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Full result of replaying an entire trace. */
|
|
98
|
+
export interface ReplayResult {
|
|
99
|
+
traceId: string;
|
|
100
|
+
steps: ReplayStepResult[];
|
|
101
|
+
totalDurationMs: number;
|
|
102
|
+
status: 'completed' | 'partial' | 'failed';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Executor function for replay — called for each event when execute=true. */
|
|
106
|
+
export type DelegationExecutor = (
|
|
107
|
+
fromAgent: string,
|
|
108
|
+
toAgent: string,
|
|
109
|
+
taskId: string,
|
|
110
|
+
payload: Record<string, unknown>
|
|
111
|
+
) => Promise<unknown>;
|
|
112
|
+
|
|
113
|
+
// =============================================================================
|
|
114
|
+
// DELEGATION TRACE STORE
|
|
115
|
+
// =============================================================================
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* In-memory store for delegation traces with hooks support.
|
|
119
|
+
*
|
|
120
|
+
* Tracks agent-to-agent delegation chains, supports subscribing to
|
|
121
|
+
* delegation events, and enables replaying traces for debugging.
|
|
122
|
+
*/
|
|
123
|
+
export class DelegationTraceStore {
|
|
124
|
+
private traces: Map<string, DelegationTrace> = new Map();
|
|
125
|
+
private eventToTrace: Map<string, string> = new Map();
|
|
126
|
+
private hooks: DelegationHookFn[] = [];
|
|
127
|
+
private maxTraces: number;
|
|
128
|
+
private idCounter = 0;
|
|
129
|
+
|
|
130
|
+
constructor(options?: { maxTraces?: number }) {
|
|
131
|
+
this.maxTraces = options?.maxTraces ?? 10_000;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ===========================================================================
|
|
135
|
+
// TRACE DELEGATION
|
|
136
|
+
// ===========================================================================
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Record a new delegation event. Creates a new trace if no parent,
|
|
140
|
+
* or appends to an existing trace via parentDelegation.
|
|
141
|
+
*/
|
|
142
|
+
traceDelegation(
|
|
143
|
+
fromAgent: string,
|
|
144
|
+
toAgent: string,
|
|
145
|
+
taskId: string,
|
|
146
|
+
payload: Record<string, unknown> = {},
|
|
147
|
+
parentDelegation: string | null = null
|
|
148
|
+
): DelegationEvent {
|
|
149
|
+
const now = new Date().toISOString();
|
|
150
|
+
const id = this.generateId();
|
|
151
|
+
|
|
152
|
+
const event: DelegationEvent = {
|
|
153
|
+
id,
|
|
154
|
+
fromAgent,
|
|
155
|
+
toAgent,
|
|
156
|
+
taskId,
|
|
157
|
+
timestamp: now,
|
|
158
|
+
payload: { ...payload },
|
|
159
|
+
parentDelegation,
|
|
160
|
+
status: 'pending',
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
if (parentDelegation) {
|
|
164
|
+
// Append to existing trace
|
|
165
|
+
const traceId = this.eventToTrace.get(parentDelegation);
|
|
166
|
+
if (traceId) {
|
|
167
|
+
const trace = this.traces.get(traceId);
|
|
168
|
+
if (trace) {
|
|
169
|
+
trace.events.set(id, event);
|
|
170
|
+
trace.lastUpdated = now;
|
|
171
|
+
this.eventToTrace.set(id, traceId);
|
|
172
|
+
this.notifyHooks(event, trace);
|
|
173
|
+
return event;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Parent not found — create a new trace anyway (orphaned delegation)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// New root trace
|
|
180
|
+
const trace: DelegationTrace = {
|
|
181
|
+
rootId: id,
|
|
182
|
+
events: new Map([[id, event]]),
|
|
183
|
+
createdAt: now,
|
|
184
|
+
lastUpdated: now,
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
this.traces.set(id, trace);
|
|
188
|
+
this.eventToTrace.set(id, id);
|
|
189
|
+
this.evictIfNeeded();
|
|
190
|
+
this.notifyHooks(event, trace);
|
|
191
|
+
|
|
192
|
+
return event;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ===========================================================================
|
|
196
|
+
// UPDATE STATUS
|
|
197
|
+
// ===========================================================================
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Update the status of a delegation event.
|
|
201
|
+
*/
|
|
202
|
+
updateStatus(
|
|
203
|
+
eventId: string,
|
|
204
|
+
status: DelegationEventStatus,
|
|
205
|
+
details?: { durationMs?: number; error?: string }
|
|
206
|
+
): boolean {
|
|
207
|
+
const traceId = this.eventToTrace.get(eventId);
|
|
208
|
+
if (!traceId) return false;
|
|
209
|
+
|
|
210
|
+
const trace = this.traces.get(traceId);
|
|
211
|
+
if (!trace) return false;
|
|
212
|
+
|
|
213
|
+
const event = trace.events.get(eventId);
|
|
214
|
+
if (!event) return false;
|
|
215
|
+
|
|
216
|
+
event.status = status;
|
|
217
|
+
if (details?.durationMs !== undefined) event.durationMs = details.durationMs;
|
|
218
|
+
if (details?.error !== undefined) event.error = details.error;
|
|
219
|
+
trace.lastUpdated = new Date().toISOString();
|
|
220
|
+
|
|
221
|
+
this.notifyHooks(event, trace);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ===========================================================================
|
|
226
|
+
// GET DELEGATION CHAIN
|
|
227
|
+
// ===========================================================================
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Walk up the parent chain from a given event to the root.
|
|
231
|
+
* Returns the chain from root (depth 0) to the given event.
|
|
232
|
+
*/
|
|
233
|
+
getDelegationChain(eventId: string): DelegationChainEntry[] {
|
|
234
|
+
const traceId = this.eventToTrace.get(eventId);
|
|
235
|
+
if (!traceId) return [];
|
|
236
|
+
|
|
237
|
+
const trace = this.traces.get(traceId);
|
|
238
|
+
if (!trace) return [];
|
|
239
|
+
|
|
240
|
+
// Walk up from eventId to root
|
|
241
|
+
const chain: DelegationEvent[] = [];
|
|
242
|
+
let currentId: string | null = eventId;
|
|
243
|
+
|
|
244
|
+
while (currentId) {
|
|
245
|
+
const event = trace.events.get(currentId);
|
|
246
|
+
if (!event) break;
|
|
247
|
+
chain.push(event);
|
|
248
|
+
currentId = event.parentDelegation;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Reverse so root is first (depth 0)
|
|
252
|
+
chain.reverse();
|
|
253
|
+
return chain.map((event, index) => ({ event, depth: index }));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ===========================================================================
|
|
257
|
+
// GET CHILDREN
|
|
258
|
+
// ===========================================================================
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Get direct children of a delegation event.
|
|
262
|
+
*/
|
|
263
|
+
getChildren(eventId: string): DelegationEvent[] {
|
|
264
|
+
const traceId = this.eventToTrace.get(eventId);
|
|
265
|
+
if (!traceId) return [];
|
|
266
|
+
|
|
267
|
+
const trace = this.traces.get(traceId);
|
|
268
|
+
if (!trace) return [];
|
|
269
|
+
|
|
270
|
+
const children: DelegationEvent[] = [];
|
|
271
|
+
for (const event of trace.events.values()) {
|
|
272
|
+
if (event.parentDelegation === eventId) {
|
|
273
|
+
children.push(event);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return children;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// ===========================================================================
|
|
280
|
+
// REPLAY DELEGATION
|
|
281
|
+
// ===========================================================================
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Replay a delegation trace for debugging.
|
|
285
|
+
*
|
|
286
|
+
* Walks the trace tree in depth-first order and optionally re-executes
|
|
287
|
+
* each delegation step via the provided executor.
|
|
288
|
+
*/
|
|
289
|
+
async replayDelegation(
|
|
290
|
+
traceId: string,
|
|
291
|
+
executor?: DelegationExecutor,
|
|
292
|
+
options: ReplayOptions = {}
|
|
293
|
+
): Promise<ReplayResult> {
|
|
294
|
+
const trace = this.traces.get(traceId);
|
|
295
|
+
if (!trace) {
|
|
296
|
+
return {
|
|
297
|
+
traceId,
|
|
298
|
+
steps: [],
|
|
299
|
+
totalDurationMs: 0,
|
|
300
|
+
status: 'failed',
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const totalStart = Date.now();
|
|
305
|
+
const steps: ReplayStepResult[] = [];
|
|
306
|
+
const shouldExecute = options.execute && executor;
|
|
307
|
+
|
|
308
|
+
// DFS traversal from root
|
|
309
|
+
const visited = new Set<string>();
|
|
310
|
+
const stack: Array<{ eventId: string; depth: number }> = [
|
|
311
|
+
{ eventId: trace.rootId, depth: 0 },
|
|
312
|
+
];
|
|
313
|
+
|
|
314
|
+
while (stack.length > 0) {
|
|
315
|
+
const { eventId, depth } = stack.pop()!;
|
|
316
|
+
if (visited.has(eventId)) continue;
|
|
317
|
+
visited.add(eventId);
|
|
318
|
+
|
|
319
|
+
const event = trace.events.get(eventId);
|
|
320
|
+
if (!event) continue;
|
|
321
|
+
|
|
322
|
+
// beforeStep hook
|
|
323
|
+
if (options.beforeStep) {
|
|
324
|
+
const proceed = await options.beforeStep(event, depth);
|
|
325
|
+
if (!proceed) {
|
|
326
|
+
const stepResult: ReplayStepResult = {
|
|
327
|
+
eventId,
|
|
328
|
+
status: 'skipped',
|
|
329
|
+
durationMs: 0,
|
|
330
|
+
};
|
|
331
|
+
steps.push(stepResult);
|
|
332
|
+
if (options.afterStep) await options.afterStep(event, stepResult);
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Optional delay for visualization
|
|
338
|
+
if (options.stepDelayMs && options.stepDelayMs > 0) {
|
|
339
|
+
await new Promise<void>((resolve) => setTimeout(resolve, options.stepDelayMs));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const stepStart = Date.now();
|
|
343
|
+
let stepResult: ReplayStepResult;
|
|
344
|
+
|
|
345
|
+
if (shouldExecute) {
|
|
346
|
+
try {
|
|
347
|
+
const payload = options.payloadOverrides?.get(eventId) ?? event.payload;
|
|
348
|
+
const result = await executor(event.fromAgent, event.toAgent, event.taskId, payload);
|
|
349
|
+
stepResult = {
|
|
350
|
+
eventId,
|
|
351
|
+
status: 'executed',
|
|
352
|
+
result,
|
|
353
|
+
durationMs: Date.now() - stepStart,
|
|
354
|
+
};
|
|
355
|
+
} catch (err) {
|
|
356
|
+
stepResult = {
|
|
357
|
+
eventId,
|
|
358
|
+
status: 'failed',
|
|
359
|
+
error: err instanceof Error ? err.message : String(err),
|
|
360
|
+
durationMs: Date.now() - stepStart,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
stepResult = {
|
|
365
|
+
eventId,
|
|
366
|
+
status: 'dry_run',
|
|
367
|
+
durationMs: Date.now() - stepStart,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
steps.push(stepResult);
|
|
372
|
+
if (options.afterStep) await options.afterStep(event, stepResult);
|
|
373
|
+
|
|
374
|
+
// Push children (reverse order so first child is processed first in DFS)
|
|
375
|
+
const children = this.getChildren(eventId);
|
|
376
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
377
|
+
stack.push({ eventId: children[i].id, depth: depth + 1 });
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const totalDurationMs = Date.now() - totalStart;
|
|
382
|
+
const hasFailed = steps.some((s) => s.status === 'failed');
|
|
383
|
+
const allExecuted = steps.every((s) => s.status === 'executed' || s.status === 'dry_run');
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
traceId,
|
|
387
|
+
steps,
|
|
388
|
+
totalDurationMs,
|
|
389
|
+
status: hasFailed ? (allExecuted ? 'failed' : 'partial') : 'completed',
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// ===========================================================================
|
|
394
|
+
// HOOKS (subscribe/unsubscribe)
|
|
395
|
+
// ===========================================================================
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Subscribe to delegation events. Returns an unsubscribe function.
|
|
399
|
+
*/
|
|
400
|
+
onDelegation(hook: DelegationHookFn): () => void {
|
|
401
|
+
this.hooks.push(hook);
|
|
402
|
+
return () => {
|
|
403
|
+
const idx = this.hooks.indexOf(hook);
|
|
404
|
+
if (idx >= 0) this.hooks.splice(idx, 1);
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// ===========================================================================
|
|
409
|
+
// QUERY
|
|
410
|
+
// ===========================================================================
|
|
411
|
+
|
|
412
|
+
/** Get a trace by its root event ID. */
|
|
413
|
+
getTrace(traceId: string): DelegationTrace | undefined {
|
|
414
|
+
return this.traces.get(traceId);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/** Get a specific delegation event by ID. */
|
|
418
|
+
getEvent(eventId: string): DelegationEvent | undefined {
|
|
419
|
+
const traceId = this.eventToTrace.get(eventId);
|
|
420
|
+
if (!traceId) return undefined;
|
|
421
|
+
return this.traces.get(traceId)?.events.get(eventId);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/** Get all traces (most recent first). */
|
|
425
|
+
getAllTraces(): DelegationTrace[] {
|
|
426
|
+
return [...this.traces.values()].sort(
|
|
427
|
+
(a, b) => new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime()
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/** Get traces involving a specific agent (as source or target). */
|
|
432
|
+
getTracesForAgent(agentId: string): DelegationTrace[] {
|
|
433
|
+
const result: DelegationTrace[] = [];
|
|
434
|
+
for (const trace of this.traces.values()) {
|
|
435
|
+
for (const event of trace.events.values()) {
|
|
436
|
+
if (event.fromAgent === agentId || event.toAgent === agentId) {
|
|
437
|
+
result.push(trace);
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return result;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** Get the total number of tracked traces. */
|
|
446
|
+
get size(): number {
|
|
447
|
+
return this.traces.size;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** Clear all traces. */
|
|
451
|
+
clear(): void {
|
|
452
|
+
this.traces.clear();
|
|
453
|
+
this.eventToTrace.clear();
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ===========================================================================
|
|
457
|
+
// PRIVATE
|
|
458
|
+
// ===========================================================================
|
|
459
|
+
|
|
460
|
+
private generateId(): string {
|
|
461
|
+
this.idCounter++;
|
|
462
|
+
return `deleg-${Date.now()}-${this.idCounter}`;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
private notifyHooks(event: DelegationEvent, trace: DelegationTrace): void {
|
|
466
|
+
for (const hook of this.hooks) {
|
|
467
|
+
try {
|
|
468
|
+
hook(event, trace);
|
|
469
|
+
} catch {
|
|
470
|
+
// Hooks must not break the delegation flow
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
private evictIfNeeded(): void {
|
|
476
|
+
while (this.traces.size > this.maxTraces) {
|
|
477
|
+
// Evict oldest trace
|
|
478
|
+
let oldestKey: string | undefined;
|
|
479
|
+
let oldestTime = Infinity;
|
|
480
|
+
for (const [key, trace] of this.traces) {
|
|
481
|
+
const time = new Date(trace.createdAt).getTime();
|
|
482
|
+
if (time < oldestTime) {
|
|
483
|
+
oldestTime = time;
|
|
484
|
+
oldestKey = key;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (oldestKey) {
|
|
488
|
+
const trace = this.traces.get(oldestKey);
|
|
489
|
+
if (trace) {
|
|
490
|
+
for (const eventId of trace.events.keys()) {
|
|
491
|
+
this.eventToTrace.delete(eventId);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
this.traces.delete(oldestKey);
|
|
495
|
+
} else {
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// =============================================================================
|
|
503
|
+
// CONVENIENCE FUNCTIONS (module-level, use a shared store)
|
|
504
|
+
// =============================================================================
|
|
505
|
+
|
|
506
|
+
let defaultStore: DelegationTraceStore | undefined;
|
|
507
|
+
|
|
508
|
+
/** Get or create the default (singleton) DelegationTraceStore. */
|
|
509
|
+
export function getDefaultTraceStore(): DelegationTraceStore {
|
|
510
|
+
if (!defaultStore) {
|
|
511
|
+
defaultStore = new DelegationTraceStore();
|
|
512
|
+
}
|
|
513
|
+
return defaultStore;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/** Reset the default store (for testing). */
|
|
517
|
+
export function resetDefaultTraceStore(): void {
|
|
518
|
+
defaultStore?.clear();
|
|
519
|
+
defaultStore = undefined;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Record a delegation event in the default store.
|
|
524
|
+
* Convenience wrapper around DelegationTraceStore.traceDelegation().
|
|
525
|
+
*/
|
|
526
|
+
export function traceDelegation(
|
|
527
|
+
fromAgent: string,
|
|
528
|
+
toAgent: string,
|
|
529
|
+
taskId: string,
|
|
530
|
+
payload?: Record<string, unknown>,
|
|
531
|
+
parentDelegation?: string | null
|
|
532
|
+
): DelegationEvent {
|
|
533
|
+
return getDefaultTraceStore().traceDelegation(
|
|
534
|
+
fromAgent,
|
|
535
|
+
toAgent,
|
|
536
|
+
taskId,
|
|
537
|
+
payload,
|
|
538
|
+
parentDelegation ?? null
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Replay a delegation trace from the default store.
|
|
544
|
+
* Convenience wrapper around DelegationTraceStore.replayDelegation().
|
|
545
|
+
*/
|
|
546
|
+
export async function replayDelegation(
|
|
547
|
+
traceId: string,
|
|
548
|
+
executor?: DelegationExecutor,
|
|
549
|
+
options?: ReplayOptions
|
|
550
|
+
): Promise<ReplayResult> {
|
|
551
|
+
return getDefaultTraceStore().replayDelegation(traceId, executor, options);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Get the delegation chain (root to leaf) for an event in the default store.
|
|
556
|
+
* Convenience wrapper around DelegationTraceStore.getDelegationChain().
|
|
557
|
+
*/
|
|
558
|
+
export function getDelegationChain(eventId: string): DelegationChainEntry[] {
|
|
559
|
+
return getDefaultTraceStore().getDelegationChain(eventId);
|
|
560
|
+
}
|
|
@@ -170,7 +170,7 @@ export class FederatedRegistryAdapter {
|
|
|
170
170
|
let updated = 0;
|
|
171
171
|
const failed: string[] = [];
|
|
172
172
|
|
|
173
|
-
const
|
|
173
|
+
const _results = await Promise.allSettled(
|
|
174
174
|
this.config.seedUrls.map(async (url) => {
|
|
175
175
|
const wasKnown = this.isKnownUrl(url);
|
|
176
176
|
const manifest = await this.fetchAndRegister(url);
|
package/src/agents/NormEngine.ts
CHANGED
|
@@ -18,12 +18,7 @@
|
|
|
18
18
|
* @version 1.0.0
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type {
|
|
22
|
-
NormEnforcement,
|
|
23
|
-
NormScope,
|
|
24
|
-
NormCategory,
|
|
25
|
-
CulturalNorm,
|
|
26
|
-
} from '@holoscript/core';
|
|
21
|
+
import type { NormEnforcement, NormScope, NormCategory, CulturalNorm } from '@holoscript/core';
|
|
27
22
|
|
|
28
23
|
export const BUILTIN_NORMS: CulturalNorm[] = [
|
|
29
24
|
{
|
|
@@ -58,7 +53,7 @@ export const BUILTIN_NORMS: CulturalNorm[] = [
|
|
|
58
53
|
activationThreshold: 0.3,
|
|
59
54
|
strength: 'weak',
|
|
60
55
|
forbiddenEffects: ['trade:scam', 'trade:extort'],
|
|
61
|
-
}
|
|
56
|
+
},
|
|
62
57
|
];
|
|
63
58
|
|
|
64
59
|
export function criticalMassForChange(norm: CulturalNorm, populationSize: number): number {
|
|
@@ -442,7 +437,7 @@ export class NormEngine {
|
|
|
442
437
|
return state;
|
|
443
438
|
}
|
|
444
439
|
|
|
445
|
-
private witnessesIn(
|
|
440
|
+
private witnessesIn(_zoneId?: string): string[] {
|
|
446
441
|
// In a full implementation, this would check spatial proximity.
|
|
447
442
|
// For now, return all agents as potential witnesses.
|
|
448
443
|
return [...this.agents.keys()].slice(0, 5);
|
|
@@ -306,7 +306,7 @@ export class OrchestratorAgent extends BaseAgent {
|
|
|
306
306
|
// PHASE 6: EVOLVE — Optimize routing preferences
|
|
307
307
|
// ===========================================================================
|
|
308
308
|
|
|
309
|
-
async evolve(
|
|
309
|
+
async evolve(_adaptations: unknown): Promise<PhaseResult> {
|
|
310
310
|
const startTime = Date.now();
|
|
311
311
|
|
|
312
312
|
// Update routing preferences based on patterns
|
|
@@ -231,14 +231,7 @@ export class TaskDelegationService {
|
|
|
231
231
|
|
|
232
232
|
try {
|
|
233
233
|
const result = await this.executeWithTimeout(
|
|
234
|
-
() =>
|
|
235
|
-
this.executeOnAgent(
|
|
236
|
-
manifest,
|
|
237
|
-
request.skillId,
|
|
238
|
-
request.arguments,
|
|
239
|
-
taskId,
|
|
240
|
-
attempt
|
|
241
|
-
),
|
|
234
|
+
() => this.executeOnAgent(manifest, request.skillId, request.arguments, taskId, attempt),
|
|
242
235
|
timeout
|
|
243
236
|
);
|
|
244
237
|
|
|
@@ -346,7 +339,10 @@ export class TaskDelegationService {
|
|
|
346
339
|
/**
|
|
347
340
|
* Replay a previously delegated task using its original request payload.
|
|
348
341
|
*/
|
|
349
|
-
async replay(
|
|
342
|
+
async replay(
|
|
343
|
+
taskId: string,
|
|
344
|
+
overrides: Partial<DelegationRequest> = {}
|
|
345
|
+
): Promise<DelegationResult> {
|
|
350
346
|
const original = this.requestHistory.get(taskId);
|
|
351
347
|
if (!original) {
|
|
352
348
|
throw new Error(`Replay unavailable for taskId: ${taskId}`);
|
|
@@ -96,7 +96,10 @@ describe('AgentWalletRegistry', () => {
|
|
|
96
96
|
describe('authorizeTransaction', () => {
|
|
97
97
|
it('returns a hex signature for a registered agent', async () => {
|
|
98
98
|
registry.registerWallet('agent-1', '0xABC');
|
|
99
|
-
const sig = await registry.authorizeTransaction('agent-1', {
|
|
99
|
+
const sig = await registry.authorizeTransaction('agent-1', {
|
|
100
|
+
action: 'buy',
|
|
101
|
+
traitId: 'T.001',
|
|
102
|
+
});
|
|
100
103
|
expect(sig).toMatch(/^0x[0-9a-f]+$/);
|
|
101
104
|
});
|
|
102
105
|
|
|
@@ -144,9 +147,7 @@ describe('AgentWalletRegistry', () => {
|
|
|
144
147
|
// Unregister
|
|
145
148
|
registry.unregisterWallet('agent-3');
|
|
146
149
|
// Should fail
|
|
147
|
-
await expect(
|
|
148
|
-
registry.authorizeTransaction('agent-3', { action: 'test' })
|
|
149
|
-
).rejects.toThrow();
|
|
150
|
+
await expect(registry.authorizeTransaction('agent-3', { action: 'test' })).rejects.toThrow();
|
|
150
151
|
});
|
|
151
152
|
});
|
|
152
153
|
});
|
|
@@ -32,10 +32,16 @@ import {
|
|
|
32
32
|
import type { PlatformCapabilities } from '../CrossRealityHandoff';
|
|
33
33
|
|
|
34
34
|
const PLATFORM_CAPABILITIES: Record<string, PlatformCapabilities> = {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
quest3: { spatialTracking: true, handTracking: true, gpu3D: true, spatialAudio: true },
|
|
36
|
+
android: { gps: true, camera: true, touchScreen: true, gpu3D: true },
|
|
37
37
|
'android-auto': { gps: true, spatialAudio: true, voiceControl: true },
|
|
38
|
-
|
|
38
|
+
pcvr: {
|
|
39
|
+
spatialTracking: true,
|
|
40
|
+
handTracking: true,
|
|
41
|
+
gpu3D: true,
|
|
42
|
+
spatialAudio: true,
|
|
43
|
+
highFidelity: true,
|
|
44
|
+
},
|
|
39
45
|
};
|
|
40
46
|
|
|
41
47
|
// ── Test Fixtures ──────────────────────────────────────────────────────────
|