tryassay 0.3.0 → 0.11.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.
Files changed (150) hide show
  1. package/dist/api/pricing-enforcer.d.ts +45 -0
  2. package/dist/api/pricing-enforcer.js +144 -0
  3. package/dist/api/pricing-enforcer.js.map +1 -0
  4. package/dist/api/server.d.ts +28 -0
  5. package/dist/api/server.js +265 -0
  6. package/dist/api/server.js.map +1 -0
  7. package/dist/api/team-session.d.ts +59 -0
  8. package/dist/api/team-session.js +240 -0
  9. package/dist/api/team-session.js.map +1 -0
  10. package/dist/cli.js +142 -2
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/api.d.ts +4 -0
  13. package/dist/commands/api.js +50 -0
  14. package/dist/commands/api.js.map +1 -0
  15. package/dist/commands/runtime.d.ts +69 -0
  16. package/dist/commands/runtime.js +673 -0
  17. package/dist/commands/runtime.js.map +1 -1
  18. package/dist/runtime/agent-loop.d.ts +6 -0
  19. package/dist/runtime/agent-loop.js +87 -5
  20. package/dist/runtime/agent-loop.js.map +1 -1
  21. package/dist/runtime/agent-spawner.d.ts +56 -0
  22. package/dist/runtime/agent-spawner.js +217 -0
  23. package/dist/runtime/agent-spawner.js.map +1 -0
  24. package/dist/runtime/agents/code-agent.d.ts +11 -0
  25. package/dist/runtime/agents/code-agent.js +90 -0
  26. package/dist/runtime/agents/code-agent.js.map +1 -0
  27. package/dist/runtime/agents/coordinator-agent.d.ts +20 -0
  28. package/dist/runtime/agents/coordinator-agent.js +182 -0
  29. package/dist/runtime/agents/coordinator-agent.js.map +1 -0
  30. package/dist/runtime/agents/ops-agent.d.ts +11 -0
  31. package/dist/runtime/agents/ops-agent.js +113 -0
  32. package/dist/runtime/agents/ops-agent.js.map +1 -0
  33. package/dist/runtime/agents/research-agent.d.ts +11 -0
  34. package/dist/runtime/agents/research-agent.js +114 -0
  35. package/dist/runtime/agents/research-agent.js.map +1 -0
  36. package/dist/runtime/agents/review-agent.d.ts +11 -0
  37. package/dist/runtime/agents/review-agent.js +96 -0
  38. package/dist/runtime/agents/review-agent.js.map +1 -0
  39. package/dist/runtime/agents/test-agent.d.ts +11 -0
  40. package/dist/runtime/agents/test-agent.js +114 -0
  41. package/dist/runtime/agents/test-agent.js.map +1 -0
  42. package/dist/runtime/capability-registry.d.ts +62 -0
  43. package/dist/runtime/capability-registry.js +191 -0
  44. package/dist/runtime/capability-registry.js.map +1 -0
  45. package/dist/runtime/collusion-detector.d.ts +35 -0
  46. package/dist/runtime/collusion-detector.js +97 -0
  47. package/dist/runtime/collusion-detector.js.map +1 -0
  48. package/dist/runtime/composition-verifier.d.ts +22 -0
  49. package/dist/runtime/composition-verifier.js +265 -0
  50. package/dist/runtime/composition-verifier.js.map +1 -0
  51. package/dist/runtime/confidence-calibrator.d.ts +10 -0
  52. package/dist/runtime/confidence-calibrator.js +95 -0
  53. package/dist/runtime/confidence-calibrator.js.map +1 -0
  54. package/dist/runtime/domain-coverage-analyzer.d.ts +24 -0
  55. package/dist/runtime/domain-coverage-analyzer.js +178 -0
  56. package/dist/runtime/domain-coverage-analyzer.js.map +1 -0
  57. package/dist/runtime/enriched-prompt-builder.d.ts +25 -0
  58. package/dist/runtime/enriched-prompt-builder.js +173 -0
  59. package/dist/runtime/enriched-prompt-builder.js.map +1 -0
  60. package/dist/runtime/gap-detector.d.ts +6 -0
  61. package/dist/runtime/gap-detector.js +111 -0
  62. package/dist/runtime/gap-detector.js.map +1 -0
  63. package/dist/runtime/human-escalation.d.ts +41 -0
  64. package/dist/runtime/human-escalation.js +122 -0
  65. package/dist/runtime/human-escalation.js.map +1 -0
  66. package/dist/runtime/kill-switch.d.ts +51 -0
  67. package/dist/runtime/kill-switch.js +185 -0
  68. package/dist/runtime/kill-switch.js.map +1 -0
  69. package/dist/runtime/layer2-guardian.d.ts +81 -0
  70. package/dist/runtime/layer2-guardian.js +263 -0
  71. package/dist/runtime/layer2-guardian.js.map +1 -0
  72. package/dist/runtime/message-bus.d.ts +57 -0
  73. package/dist/runtime/message-bus.js +115 -0
  74. package/dist/runtime/message-bus.js.map +1 -0
  75. package/dist/runtime/multi-agent-loop.d.ts +37 -0
  76. package/dist/runtime/multi-agent-loop.js +411 -0
  77. package/dist/runtime/multi-agent-loop.js.map +1 -0
  78. package/dist/runtime/pattern-extractor.d.ts +20 -0
  79. package/dist/runtime/pattern-extractor.js +257 -0
  80. package/dist/runtime/pattern-extractor.js.map +1 -0
  81. package/dist/runtime/planner.d.ts +2 -2
  82. package/dist/runtime/planner.js +10 -7
  83. package/dist/runtime/planner.js.map +1 -1
  84. package/dist/runtime/prompt-safety-analyzer.d.ts +17 -0
  85. package/dist/runtime/prompt-safety-analyzer.js +230 -0
  86. package/dist/runtime/prompt-safety-analyzer.js.map +1 -0
  87. package/dist/runtime/reasoner.d.ts +2 -2
  88. package/dist/runtime/reasoner.js +9 -5
  89. package/dist/runtime/reasoner.js.map +1 -1
  90. package/dist/runtime/reflector.d.ts +7 -1
  91. package/dist/runtime/reflector.js.map +1 -1
  92. package/dist/runtime/rollback-manager.d.ts +50 -0
  93. package/dist/runtime/rollback-manager.js +157 -0
  94. package/dist/runtime/rollback-manager.js.map +1 -0
  95. package/dist/runtime/rule-canary-deployer.d.ts +69 -0
  96. package/dist/runtime/rule-canary-deployer.js +289 -0
  97. package/dist/runtime/rule-canary-deployer.js.map +1 -0
  98. package/dist/runtime/rule-conflict-detector.d.ts +48 -0
  99. package/dist/runtime/rule-conflict-detector.js +214 -0
  100. package/dist/runtime/rule-conflict-detector.js.map +1 -0
  101. package/dist/runtime/rule-meta-verifier.d.ts +18 -0
  102. package/dist/runtime/rule-meta-verifier.js +275 -0
  103. package/dist/runtime/rule-meta-verifier.js.map +1 -0
  104. package/dist/runtime/rule-proposal-manager.d.ts +95 -0
  105. package/dist/runtime/rule-proposal-manager.js +190 -0
  106. package/dist/runtime/rule-proposal-manager.js.map +1 -0
  107. package/dist/runtime/safety-enforcer.d.ts +35 -0
  108. package/dist/runtime/safety-enforcer.js +165 -0
  109. package/dist/runtime/safety-enforcer.js.map +1 -0
  110. package/dist/runtime/safety-status.d.ts +48 -0
  111. package/dist/runtime/safety-status.js +119 -0
  112. package/dist/runtime/safety-status.js.map +1 -0
  113. package/dist/runtime/shadow-runner.d.ts +14 -0
  114. package/dist/runtime/shadow-runner.js +190 -0
  115. package/dist/runtime/shadow-runner.js.map +1 -0
  116. package/dist/runtime/shared-memory.d.ts +47 -0
  117. package/dist/runtime/shared-memory.js +151 -0
  118. package/dist/runtime/shared-memory.js.map +1 -0
  119. package/dist/runtime/specialized-agent.d.ts +72 -0
  120. package/dist/runtime/specialized-agent.js +123 -0
  121. package/dist/runtime/specialized-agent.js.map +1 -0
  122. package/dist/runtime/stall-detector.d.ts +13 -0
  123. package/dist/runtime/stall-detector.js +121 -0
  124. package/dist/runtime/stall-detector.js.map +1 -0
  125. package/dist/runtime/strategy-library.d.ts +11 -0
  126. package/dist/runtime/strategy-library.js +142 -0
  127. package/dist/runtime/strategy-library.js.map +1 -0
  128. package/dist/runtime/supabase-experience-store.d.ts +19 -0
  129. package/dist/runtime/supabase-experience-store.js +215 -0
  130. package/dist/runtime/supabase-experience-store.js.map +1 -0
  131. package/dist/runtime/tool-approval.d.ts +51 -0
  132. package/dist/runtime/tool-approval.js +148 -0
  133. package/dist/runtime/tool-approval.js.map +1 -0
  134. package/dist/runtime/tool-sandbox.d.ts +43 -0
  135. package/dist/runtime/tool-sandbox.js +394 -0
  136. package/dist/runtime/tool-sandbox.js.map +1 -0
  137. package/dist/runtime/tool-verifier.d.ts +18 -0
  138. package/dist/runtime/tool-verifier.js +323 -0
  139. package/dist/runtime/tool-verifier.js.map +1 -0
  140. package/dist/runtime/trust-manager.d.ts +63 -0
  141. package/dist/runtime/trust-manager.js +212 -0
  142. package/dist/runtime/trust-manager.js.map +1 -0
  143. package/dist/runtime/two-agent-loop.d.ts +35 -0
  144. package/dist/runtime/two-agent-loop.js +208 -0
  145. package/dist/runtime/two-agent-loop.js.map +1 -0
  146. package/dist/runtime/types.d.ts +939 -1
  147. package/dist/runtime/verification-intensity.d.ts +34 -0
  148. package/dist/runtime/verification-intensity.js +104 -0
  149. package/dist/runtime/verification-intensity.js.map +1 -0
  150. package/package.json +1 -1
@@ -0,0 +1,151 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Shared Memory Store
3
+ // Append-only shared state with conflict detection.
4
+ // Agents write facts, decisions, conventions, findings.
5
+ // No mutable shared state — conflicts are detected, not hidden.
6
+ // ============================================================
7
+ import { randomUUID } from 'node:crypto';
8
+ // ── Shared Memory Store ────────────────────────────────────
9
+ export class SharedMemoryStore {
10
+ entries = [];
11
+ conflicts = [];
12
+ /**
13
+ * Add a new entry to shared memory.
14
+ * Checks for conflicts with existing entries by the same tags.
15
+ * Returns the entry ID and any detected conflicts.
16
+ */
17
+ add(type, content, author, opts) {
18
+ const entry = {
19
+ id: randomUUID(),
20
+ type,
21
+ content,
22
+ author,
23
+ tags: opts?.tags ?? [],
24
+ verificationStatus: opts?.verificationStatus ?? 'unverified',
25
+ claims: opts?.claims ?? [],
26
+ confidence: opts?.confidence ?? 0.5,
27
+ createdAt: new Date().toISOString(),
28
+ supersedes: opts?.supersedes,
29
+ };
30
+ this.entries.push(entry);
31
+ // Detect conflicts: entries with overlapping tags that make contradictory claims
32
+ const newConflicts = this.detectConflicts(entry);
33
+ this.conflicts.push(...newConflicts);
34
+ return { entryId: entry.id, conflicts: newConflicts };
35
+ }
36
+ /**
37
+ * Query entries by filter criteria.
38
+ */
39
+ query(filter) {
40
+ return this.entries.filter(entry => {
41
+ if (filter.type && entry.type !== filter.type)
42
+ return false;
43
+ if (filter.tags && filter.tags.length > 0) {
44
+ const hasTag = filter.tags.some(t => entry.tags.includes(t));
45
+ if (!hasTag)
46
+ return false;
47
+ }
48
+ if (filter.minConfidence !== undefined && entry.confidence < filter.minConfidence)
49
+ return false;
50
+ if (filter.verificationStatus && entry.verificationStatus !== filter.verificationStatus)
51
+ return false;
52
+ if (filter.author && entry.author !== filter.author)
53
+ return false;
54
+ if (filter.since && entry.createdAt < filter.since)
55
+ return false;
56
+ return true;
57
+ });
58
+ }
59
+ /** Get entries by tag. */
60
+ getByTag(tag) {
61
+ return this.entries.filter(e => e.tags.includes(tag));
62
+ }
63
+ /** Get entries by author agent ID. */
64
+ getByAgent(agentId) {
65
+ return this.entries.filter(e => e.author === agentId);
66
+ }
67
+ /** Get only entries where all claims passed verification. */
68
+ getVerified() {
69
+ return this.entries.filter(e => e.verificationStatus === 'verified' || e.verificationStatus === 'formally_verified');
70
+ }
71
+ /** Get all detected conflicts. */
72
+ getConflicts() {
73
+ return this.conflicts;
74
+ }
75
+ /** Get only open (unresolved) conflicts. */
76
+ getOpenConflicts() {
77
+ return this.conflicts.filter(c => c.status === 'open');
78
+ }
79
+ /** Resolve a conflict. */
80
+ resolveConflict(conflictId, resolution) {
81
+ const conflict = this.conflicts.find(c => c.id === conflictId);
82
+ if (!conflict || conflict.status !== 'open')
83
+ return false;
84
+ // Mutate the conflict record (conflicts are mutable tracking state)
85
+ conflict.resolution = resolution;
86
+ conflict.status = 'resolved';
87
+ return true;
88
+ }
89
+ /** Escalate a conflict for human resolution. */
90
+ escalateConflict(conflictId) {
91
+ const conflict = this.conflicts.find(c => c.id === conflictId);
92
+ if (!conflict || conflict.status !== 'open')
93
+ return false;
94
+ conflict.status = 'escalated';
95
+ return true;
96
+ }
97
+ /** Get all entries (for snapshots and audit). */
98
+ getAllEntries() {
99
+ return this.entries;
100
+ }
101
+ /** Get entry by ID. */
102
+ getEntry(entryId) {
103
+ return this.entries.find(e => e.id === entryId);
104
+ }
105
+ /** Get the entry that superseded a given entry. */
106
+ getSuperseding(entryId) {
107
+ return this.entries.find(e => e.supersedes === entryId);
108
+ }
109
+ /** Update verification status of an entry after boundary verification. */
110
+ updateVerification(entryId, status, claims, confidence) {
111
+ const entry = this.entries.find(e => e.id === entryId);
112
+ if (!entry)
113
+ return;
114
+ entry.verificationStatus = status;
115
+ if (claims) {
116
+ entry.claims = claims;
117
+ }
118
+ if (confidence !== undefined) {
119
+ entry.confidence = confidence;
120
+ }
121
+ }
122
+ // ── Private ─────────────────────────────────────────────
123
+ detectConflicts(newEntry) {
124
+ const detected = [];
125
+ // Only check entries with overlapping tags
126
+ if (newEntry.tags.length === 0)
127
+ return detected;
128
+ // Find entries that share tags and are the same type
129
+ const candidates = this.entries.filter(existing => existing.id !== newEntry.id &&
130
+ existing.type === newEntry.type &&
131
+ existing.tags.some(t => newEntry.tags.includes(t)) &&
132
+ !existing.supersedes && // Don't conflict with superseded entries
133
+ !newEntry.supersedes // If new entry supersedes something, that's resolution, not conflict
134
+ );
135
+ for (const candidate of candidates) {
136
+ // Simple heuristic: if two entries of the same type with the same tags
137
+ // have different content and are from different authors, flag as potential conflict
138
+ if (candidate.author !== newEntry.author &&
139
+ candidate.content !== newEntry.content) {
140
+ detected.push({
141
+ id: randomUUID(),
142
+ entries: [candidate, newEntry],
143
+ detectedBy: 'assay',
144
+ status: 'open',
145
+ });
146
+ }
147
+ }
148
+ return detected;
149
+ }
150
+ }
151
+ //# sourceMappingURL=shared-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-memory.js","sourceRoot":"","sources":["../../src/runtime/shared-memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import type { AgentIdentity, AgentSpecialization, AgentCapability, TrustLevel, BoundaryArtifact, AgentMessage } from './types.js';
2
+ import type { MessageBus } from './message-bus.js';
3
+ export interface TaskAssignmentPayload {
4
+ readonly taskId: string;
5
+ readonly goal: string;
6
+ readonly constraints: readonly string[];
7
+ readonly dependencies: readonly string[];
8
+ readonly contextRefs: readonly {
9
+ summary: string;
10
+ content?: string;
11
+ }[];
12
+ }
13
+ export interface TaskResultPayload {
14
+ readonly taskId: string;
15
+ readonly status: 'completed' | 'blocked' | 'failed';
16
+ readonly artifacts: readonly BoundaryArtifact[];
17
+ readonly summary: string;
18
+ readonly claimsAboutArtifacts: readonly string[];
19
+ readonly blockers?: readonly string[];
20
+ }
21
+ export interface FindingPayload {
22
+ readonly severity: 'critical' | 'high' | 'medium' | 'low';
23
+ readonly category: string;
24
+ readonly description: string;
25
+ readonly evidence: string;
26
+ readonly suggestedFix?: string;
27
+ readonly affectedFiles: readonly string[];
28
+ }
29
+ export declare abstract class SpecializedAgent {
30
+ readonly identity: AgentIdentity;
31
+ protected messageBus: MessageBus;
32
+ protected modelId: string;
33
+ constructor(name: string, specialization: AgentSpecialization, capabilities: AgentCapability[], messageBus: MessageBus, opts?: {
34
+ model?: string;
35
+ initialTrust?: TrustLevel;
36
+ });
37
+ /** Handle an incoming message. Subclasses override for specific behavior. */
38
+ protected abstract onMessage(message: AgentMessage): void;
39
+ /**
40
+ * Execute a task assignment. Returns the result as artifacts.
41
+ * Each agent role implements this differently.
42
+ */
43
+ abstract executeTask(task: TaskAssignmentPayload): Promise<TaskResultPayload>;
44
+ /** Get the agent's identity. */
45
+ getIdentity(): AgentIdentity;
46
+ /**
47
+ * Call Claude with a system prompt and user prompt.
48
+ * Returns the raw response text and token usage.
49
+ */
50
+ protected callClaude(systemPrompt: string, userPrompt: string): Promise<{
51
+ content: string;
52
+ inputTokens: number;
53
+ outputTokens: number;
54
+ }>;
55
+ /** Send a task result back to the coordinator. */
56
+ protected sendResult(result: TaskResultPayload, threadId: string): void;
57
+ /** Send a finding to another agent or coordinator. */
58
+ protected sendFinding(recipient: string, finding: FindingPayload, threadId: string): void;
59
+ /** Send an escalation to the coordinator. */
60
+ protected sendEscalation(reason: string, context: string, attemptsMade: string[], threadId: string): void;
61
+ /** Create a BoundaryArtifact from produced output. */
62
+ protected makeArtifact(type: BoundaryArtifact['type'], content: string, opts?: {
63
+ path?: string;
64
+ language?: string;
65
+ metadata?: Record<string, unknown>;
66
+ }): BoundaryArtifact;
67
+ }
68
+ export declare function checkModelDiversity(agents: AgentIdentity[]): {
69
+ diverse: boolean;
70
+ providers: Map<string, string[]>;
71
+ recommendation: string | null;
72
+ };
@@ -0,0 +1,123 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Specialized Agent
3
+ // Base class for all agent roles. Handles Claude API calls,
4
+ // message receiving, and artifact production.
5
+ // ============================================================
6
+ import { randomUUID } from 'node:crypto';
7
+ import { getClient, MODEL } from '../lib/anthropic.js';
8
+ // ── Specialized Agent ───────────────────────────────────────
9
+ export class SpecializedAgent {
10
+ identity;
11
+ messageBus;
12
+ modelId;
13
+ constructor(name, specialization, capabilities, messageBus, opts) {
14
+ this.identity = {
15
+ id: randomUUID(),
16
+ name,
17
+ specialization,
18
+ capabilities,
19
+ trustLevel: opts?.initialTrust ?? 'untrusted',
20
+ model: opts?.model ?? MODEL,
21
+ spawnedAt: new Date().toISOString(),
22
+ verificationHistory: {
23
+ totalHandoffs: 0,
24
+ passRate: 0,
25
+ formalOverrides: 0,
26
+ },
27
+ };
28
+ this.messageBus = messageBus;
29
+ this.modelId = opts?.model ?? MODEL;
30
+ // Listen for messages addressed to this agent
31
+ messageBus.on(`message:${this.identity.id}`, (msg) => {
32
+ this.onMessage(msg);
33
+ });
34
+ }
35
+ /** Get the agent's identity. */
36
+ getIdentity() {
37
+ return this.identity;
38
+ }
39
+ // ── Protected helpers for subclasses ──────────────────────
40
+ /**
41
+ * Call Claude with a system prompt and user prompt.
42
+ * Returns the raw response text and token usage.
43
+ */
44
+ async callClaude(systemPrompt, userPrompt) {
45
+ const client = getClient();
46
+ let content = '';
47
+ const stream = client.messages.stream({
48
+ model: this.modelId,
49
+ max_tokens: 8_000,
50
+ system: systemPrompt,
51
+ messages: [{ role: 'user', content: userPrompt }],
52
+ });
53
+ stream.on('text', (text) => {
54
+ content += text;
55
+ });
56
+ const finalMessage = await stream.finalMessage();
57
+ return {
58
+ content,
59
+ inputTokens: finalMessage.usage.input_tokens,
60
+ outputTokens: finalMessage.usage.output_tokens,
61
+ };
62
+ }
63
+ /** Send a task result back to the coordinator. */
64
+ sendResult(result, threadId) {
65
+ this.messageBus.send(this.identity.id, 'coordinator', 'task_result', result, { threadId });
66
+ }
67
+ /** Send a finding to another agent or coordinator. */
68
+ sendFinding(recipient, finding, threadId) {
69
+ this.messageBus.send(this.identity.id, recipient, 'finding', finding, { threadId });
70
+ }
71
+ /** Send an escalation to the coordinator. */
72
+ sendEscalation(reason, context, attemptsMade, threadId) {
73
+ this.messageBus.send(this.identity.id, 'coordinator', 'escalation', { reason, context, attemptsMade }, { threadId });
74
+ }
75
+ /** Create a BoundaryArtifact from produced output. */
76
+ makeArtifact(type, content, opts) {
77
+ return {
78
+ type,
79
+ content,
80
+ path: opts?.path,
81
+ language: opts?.language,
82
+ metadata: opts?.metadata ?? {},
83
+ };
84
+ }
85
+ }
86
+ // ── Model Diversity Checker ────────────────────────────────
87
+ export function checkModelDiversity(agents) {
88
+ const providers = new Map();
89
+ for (const agent of agents) {
90
+ // Extract provider from model name (e.g., "claude-sonnet-4-5" -> "anthropic")
91
+ const provider = inferProvider(agent.model);
92
+ const existing = providers.get(provider) ?? [];
93
+ existing.push(agent.name);
94
+ providers.set(provider, existing);
95
+ }
96
+ // Model diversity is satisfied if agents that verify each other
97
+ // use different providers
98
+ const allSameProvider = providers.size === 1;
99
+ const recommendation = allSameProvider
100
+ ? 'All agents use the same provider. Consider using different providers for Code and Review agents to reduce correlated failures.'
101
+ : null;
102
+ return {
103
+ diverse: !allSameProvider,
104
+ providers,
105
+ recommendation,
106
+ };
107
+ }
108
+ function inferProvider(model) {
109
+ if (model.startsWith('claude') || model.includes('anthropic'))
110
+ return 'anthropic';
111
+ if (model.startsWith('gpt') || model.includes('openai'))
112
+ return 'openai';
113
+ if (model.startsWith('gemini') || model.includes('google'))
114
+ return 'google';
115
+ if (model.startsWith('llama') || model.includes('meta'))
116
+ return 'meta';
117
+ if (model.startsWith('mistral'))
118
+ return 'mistral';
119
+ if (model.startsWith('deepseek'))
120
+ return 'deepseek';
121
+ return 'unknown';
122
+ }
123
+ //# sourceMappingURL=specialized-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specialized-agent.js","sourceRoot":"","sources":["../../src/runtime/specialized-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { TaskGraph, StallReport } from './types.js';
2
+ export declare class StallDetector {
3
+ /**
4
+ * Detect stalls in a task graph.
5
+ * Returns stall reports for any problematic tasks.
6
+ */
7
+ detectStalls(graph: TaskGraph, thresholdMs: number): StallReport[];
8
+ /**
9
+ * Detect circular dependencies in the task graph.
10
+ * Returns task IDs involved in deadlock cycles.
11
+ */
12
+ private detectDeadlocks;
13
+ }
@@ -0,0 +1,121 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Stall Detector
3
+ // Monitors task graph for timeouts, reject loops,
4
+ // dependency deadlocks, and resource contention.
5
+ // ============================================================
6
+ // ── Stall Detector ─────────────────────────────────────────
7
+ export class StallDetector {
8
+ /**
9
+ * Detect stalls in a task graph.
10
+ * Returns stall reports for any problematic tasks.
11
+ */
12
+ detectStalls(graph, thresholdMs) {
13
+ const reports = [];
14
+ const now = Date.now();
15
+ for (const task of graph.tasks) {
16
+ // Skip completed or failed tasks
17
+ if (task.status === 'completed' || task.status === 'failed')
18
+ continue;
19
+ // Check for timeout: task in progress for too long
20
+ if (task.status === 'in_progress' || task.status === 'assigned') {
21
+ const taskStart = new Date(task.createdAt).getTime();
22
+ const elapsed = now - taskStart;
23
+ if (elapsed > thresholdMs) {
24
+ reports.push({
25
+ taskId: task.id,
26
+ type: 'timeout',
27
+ duration: elapsed,
28
+ attempts: task.attempts,
29
+ suggestedAction: task.attempts >= task.maxAttempts ? 'escalate' : 'reassign',
30
+ });
31
+ }
32
+ }
33
+ // Check for reject loop: task rejected too many times
34
+ if (task.status === 'rejected' && task.attempts >= task.maxAttempts) {
35
+ reports.push({
36
+ taskId: task.id,
37
+ type: 'reject_loop',
38
+ duration: now - new Date(task.createdAt).getTime(),
39
+ attempts: task.attempts,
40
+ suggestedAction: task.attempts >= task.maxAttempts ? 'escalate' : 'simplify',
41
+ });
42
+ }
43
+ // Check for resource contention: multiple tasks waiting for the same specialization
44
+ if (task.status === 'ready' || task.status === 'pending') {
45
+ const waitingForSameSpec = graph.tasks.filter(t => t.id !== task.id &&
46
+ t.specialization === task.specialization &&
47
+ (t.status === 'in_progress' || t.status === 'assigned'));
48
+ if (waitingForSameSpec.length >= 2) {
49
+ reports.push({
50
+ taskId: task.id,
51
+ type: 'resource_contention',
52
+ duration: now - new Date(task.createdAt).getTime(),
53
+ attempts: task.attempts,
54
+ suggestedAction: 'reassign',
55
+ });
56
+ }
57
+ }
58
+ }
59
+ // Check for dependency deadlocks: circular dependencies
60
+ const deadlockTasks = this.detectDeadlocks(graph);
61
+ for (const taskId of deadlockTasks) {
62
+ const task = graph.tasks.find(t => t.id === taskId);
63
+ if (task) {
64
+ reports.push({
65
+ taskId: task.id,
66
+ type: 'dependency_deadlock',
67
+ duration: now - new Date(task.createdAt).getTime(),
68
+ attempts: task.attempts,
69
+ suggestedAction: 'abort',
70
+ });
71
+ }
72
+ }
73
+ return reports;
74
+ }
75
+ /**
76
+ * Detect circular dependencies in the task graph.
77
+ * Returns task IDs involved in deadlock cycles.
78
+ */
79
+ detectDeadlocks(graph) {
80
+ const deadlocked = new Set();
81
+ // Build adjacency list from blocking edges
82
+ const blockingEdges = graph.edges.filter(e => e.type === 'blocks');
83
+ const adjacency = new Map();
84
+ for (const edge of blockingEdges) {
85
+ const existing = adjacency.get(edge.from) ?? [];
86
+ existing.push(edge.to);
87
+ adjacency.set(edge.from, existing);
88
+ }
89
+ // DFS-based cycle detection
90
+ const visited = new Set();
91
+ const inStack = new Set();
92
+ const dfs = (taskId) => {
93
+ if (inStack.has(taskId)) {
94
+ // Found a cycle — collect all tasks in the cycle
95
+ deadlocked.add(taskId);
96
+ return true;
97
+ }
98
+ if (visited.has(taskId))
99
+ return false;
100
+ visited.add(taskId);
101
+ inStack.add(taskId);
102
+ const neighbors = adjacency.get(taskId) ?? [];
103
+ for (const neighbor of neighbors) {
104
+ if (dfs(neighbor)) {
105
+ deadlocked.add(taskId);
106
+ }
107
+ }
108
+ inStack.delete(taskId);
109
+ return false;
110
+ };
111
+ // Only check tasks that are not yet completed
112
+ const activeTasks = graph.tasks
113
+ .filter(t => t.status !== 'completed' && t.status !== 'failed')
114
+ .map(t => t.id);
115
+ for (const taskId of activeTasks) {
116
+ dfs(taskId);
117
+ }
118
+ return Array.from(deadlocked);
119
+ }
120
+ }
121
+ //# sourceMappingURL=stall-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stall-detector.js","sourceRoot":"","sources":["../../src/runtime/stall-detector.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gDAAgD;AAChD,kDAAkD;AAClD,iDAAiD;AACjD,+DAA+D;AAQ/D,8DAA8D;AAE9D,MAAM,OAAO,aAAa;IACxB;;;OAGG;IACH,YAAY,CAAC,KAAgB,EAAE,WAAmB;QAChD,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,iCAAiC;YACjC,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAAE,SAAS;YAEtE,mDAAmD;YACnD,IAAI,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBAChE,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;gBACrD,MAAM,OAAO,GAAG,GAAG,GAAG,SAAS,CAAC;gBAChC,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;oBAC1B,OAAO,CAAC,IAAI,CAAC;wBACX,MAAM,EAAE,IAAI,CAAC,EAAE;wBACf,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,OAAO;wBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,eAAe,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;qBAC7E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,sDAAsD;YACtD,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACpE,OAAO,CAAC,IAAI,CAAC;oBACX,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,IAAI,EAAE,aAAa;oBACnB,QAAQ,EAAE,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;oBAClD,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,eAAe,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;iBAC7E,CAAC,CAAC;YACL,CAAC;YAED,oFAAoF;YACpF,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzD,MAAM,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAChD,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;oBAChB,CAAC,CAAC,cAAc,KAAK,IAAI,CAAC,cAAc;oBACxC,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CACxD,CAAC;gBACF,IAAI,kBAAkB,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBACnC,OAAO,CAAC,IAAI,CAAC;wBACX,MAAM,EAAE,IAAI,CAAC,EAAE;wBACf,IAAI,EAAE,qBAAqB;wBAC3B,QAAQ,EAAE,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;wBAClD,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,eAAe,EAAE,UAAU;qBAC5B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAClD,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;YACpD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC;oBACX,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,IAAI,EAAE,qBAAqB;oBAC3B,QAAQ,EAAE,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;oBAClD,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,eAAe,EAAE,OAAO;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,KAAgB;QACtC,MAAM,UAAU,GAAgB,IAAI,GAAG,EAAE,CAAC;QAE1C,2CAA2C;QAC3C,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;QAED,4BAA4B;QAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAElC,MAAM,GAAG,GAAG,CAAC,MAAc,EAAW,EAAE;YACtC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,iDAAiD;gBACjD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;YAEtC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAEpB,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAClB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,8CAA8C;QAC9C,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK;aAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAElB,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,GAAG,CAAC,MAAM,CAAC,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { Strategy, Experience, ExperienceOutcome, OperationType } from './types.js';
2
+ export declare class StrategyLibrary {
3
+ private strategies;
4
+ constructor(initial?: Strategy[]);
5
+ rank(domain: string, operationType: OperationType): Promise<Strategy[]>;
6
+ recordOutcome(strategyId: string, outcome: ExperienceOutcome, verificationPassRate: number, durationMs: number): Promise<void>;
7
+ discover(experiences: Experience[]): Promise<Strategy[]>;
8
+ getAll(): Strategy[];
9
+ load(strategies: Strategy[]): void;
10
+ private proposeStrategy;
11
+ }
@@ -0,0 +1,142 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Strategy Library
3
+ // Maintains named strategies per domain/operation type,
4
+ // ranked by historical success rate.
5
+ // ============================================================
6
+ import { randomUUID } from 'node:crypto';
7
+ import { getClient, MODEL } from '../lib/anthropic.js';
8
+ export class StrategyLibrary {
9
+ strategies = new Map();
10
+ constructor(initial) {
11
+ if (initial) {
12
+ for (const s of initial) {
13
+ this.strategies.set(s.id, s);
14
+ }
15
+ }
16
+ }
17
+ async rank(domain, operationType) {
18
+ const matches = Array.from(this.strategies.values())
19
+ .filter(s => s.domain === domain && s.operationType === operationType)
20
+ .filter(s => s.timesUsed >= 5) // only rank strategies with enough data
21
+ .filter(s => s.successRate >= 0.3) // exclude deprecated strategies
22
+ .sort((a, b) => b.successRate - a.successRate);
23
+ return matches;
24
+ }
25
+ async recordOutcome(strategyId, outcome, verificationPassRate, durationMs) {
26
+ const strategy = this.strategies.get(strategyId);
27
+ if (!strategy)
28
+ return;
29
+ strategy.timesUsed++;
30
+ if (outcome === 'success')
31
+ strategy.timesSucceeded++;
32
+ strategy.successRate = strategy.timesUsed > 0
33
+ ? strategy.timesSucceeded / strategy.timesUsed
34
+ : 0;
35
+ // Running average for verification pass rate
36
+ const prevTotal = strategy.avgVerificationPassRate * (strategy.timesUsed - 1);
37
+ strategy.avgVerificationPassRate = (prevTotal + verificationPassRate) / strategy.timesUsed;
38
+ // Running average for duration
39
+ const prevDurTotal = strategy.avgDurationMs * (strategy.timesUsed - 1);
40
+ strategy.avgDurationMs = (prevDurTotal + durationMs) / strategy.timesUsed;
41
+ strategy.lastUsed = new Date().toISOString();
42
+ }
43
+ async discover(experiences) {
44
+ // Group successful experiences by domain + operation type
45
+ const groups = new Map();
46
+ for (const exp of experiences) {
47
+ if (exp.outcome !== 'success')
48
+ continue;
49
+ for (const step of exp.plan.steps) {
50
+ const key = `${exp.domain}:${step.operation.type}`;
51
+ const group = groups.get(key) ?? [];
52
+ group.push(exp);
53
+ groups.set(key, group);
54
+ }
55
+ }
56
+ const newStrategies = [];
57
+ for (const [key, exps] of groups) {
58
+ if (exps.length < 3)
59
+ continue; // need at least 3 examples
60
+ const [domain, opType] = key.split(':');
61
+ // Check if we already have strategies for this combination
62
+ const existing = Array.from(this.strategies.values())
63
+ .filter(s => s.domain === domain && s.operationType === opType);
64
+ if (existing.length >= 5)
65
+ continue; // enough strategies already
66
+ try {
67
+ const strategy = await this.proposeStrategy(domain, opType, exps);
68
+ if (strategy) {
69
+ this.strategies.set(strategy.id, strategy);
70
+ newStrategies.push(strategy);
71
+ }
72
+ }
73
+ catch {
74
+ // Skip on failure — strategy discovery is best-effort
75
+ }
76
+ }
77
+ return newStrategies;
78
+ }
79
+ getAll() {
80
+ return Array.from(this.strategies.values());
81
+ }
82
+ load(strategies) {
83
+ for (const s of strategies) {
84
+ this.strategies.set(s.id, s);
85
+ }
86
+ }
87
+ async proposeStrategy(domain, operationType, experiences) {
88
+ const summaries = experiences.slice(0, 5).map(e => ({
89
+ lessons: e.lessons,
90
+ planSteps: e.plan.steps.map(s => s.description),
91
+ duration: e.execution.totalDurationMs,
92
+ }));
93
+ const client = getClient();
94
+ const response = await client.messages.create({
95
+ model: MODEL,
96
+ max_tokens: 1024,
97
+ system: 'Extract a named strategy from successful agent experiences. Respond with ONLY JSON, no markdown.',
98
+ messages: [{
99
+ role: 'user',
100
+ content: `These ${experiences.length} successful experiences in "${domain}" (operation: ${operationType}) share a common approach. Name and describe the strategy.
101
+
102
+ EXAMPLES:
103
+ ${JSON.stringify(summaries, null, 2)}
104
+
105
+ Respond:
106
+ {
107
+ "name": "short-kebab-case-name",
108
+ "description": "when to use this strategy",
109
+ "planTemplate": "natural language template for the planner"
110
+ }`,
111
+ }],
112
+ });
113
+ const text = response.content[0].type === 'text' ? response.content[0].text : '';
114
+ try {
115
+ let cleaned = text.trim();
116
+ if (cleaned.startsWith('```')) {
117
+ cleaned = cleaned.replace(/^```(?:json)?\s*/, '').replace(/\s*```$/, '');
118
+ }
119
+ const parsed = JSON.parse(cleaned);
120
+ return {
121
+ id: randomUUID(),
122
+ domain,
123
+ operationType,
124
+ name: parsed.name,
125
+ description: parsed.description,
126
+ planTemplate: parsed.planTemplate,
127
+ timesUsed: 0,
128
+ timesSucceeded: 0,
129
+ successRate: 0,
130
+ avgVerificationPassRate: 0,
131
+ avgDurationMs: 0,
132
+ lastUsed: '',
133
+ discoveredFrom: experiences.map(e => e.id),
134
+ createdAt: new Date().toISOString(),
135
+ };
136
+ }
137
+ catch {
138
+ return null;
139
+ }
140
+ }
141
+ }
142
+ //# sourceMappingURL=strategy-library.js.map