tryassay 0.2.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +41 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/runtime.d.ts +20 -0
- package/dist/commands/runtime.js +192 -6
- package/dist/commands/runtime.js.map +1 -1
- package/dist/runtime/agent-loop.d.ts +16 -1
- package/dist/runtime/agent-loop.js +197 -32
- package/dist/runtime/agent-loop.js.map +1 -1
- package/dist/runtime/agents/code-agent.d.ts +11 -0
- package/dist/runtime/agents/code-agent.js +90 -0
- package/dist/runtime/agents/code-agent.js.map +1 -0
- package/dist/runtime/agents/review-agent.d.ts +11 -0
- package/dist/runtime/agents/review-agent.js +96 -0
- package/dist/runtime/agents/review-agent.js.map +1 -0
- package/dist/runtime/audit-log.d.ts +35 -0
- package/dist/runtime/audit-log.js +115 -0
- package/dist/runtime/audit-log.js.map +1 -0
- package/dist/runtime/composition-verifier.d.ts +22 -0
- package/dist/runtime/composition-verifier.js +265 -0
- package/dist/runtime/composition-verifier.js.map +1 -0
- package/dist/runtime/confidence-calibrator.d.ts +10 -0
- package/dist/runtime/confidence-calibrator.js +95 -0
- package/dist/runtime/confidence-calibrator.js.map +1 -0
- package/dist/runtime/config-loader.d.ts +41 -0
- package/dist/runtime/config-loader.js +116 -0
- package/dist/runtime/config-loader.js.map +1 -0
- package/dist/runtime/control-server.d.ts +25 -0
- package/dist/runtime/control-server.js +83 -0
- package/dist/runtime/control-server.js.map +1 -0
- package/dist/runtime/enriched-prompt-builder.d.ts +25 -0
- package/dist/runtime/enriched-prompt-builder.js +173 -0
- package/dist/runtime/enriched-prompt-builder.js.map +1 -0
- package/dist/runtime/gap-detector.d.ts +6 -0
- package/dist/runtime/gap-detector.js +111 -0
- package/dist/runtime/gap-detector.js.map +1 -0
- package/dist/runtime/logger.d.ts +20 -0
- package/dist/runtime/logger.js +73 -0
- package/dist/runtime/logger.js.map +1 -0
- package/dist/runtime/message-bus.d.ts +57 -0
- package/dist/runtime/message-bus.js +115 -0
- package/dist/runtime/message-bus.js.map +1 -0
- package/dist/runtime/observer.d.ts +5 -1
- package/dist/runtime/observer.js +61 -14
- package/dist/runtime/observer.js.map +1 -1
- package/dist/runtime/pattern-extractor.d.ts +20 -0
- package/dist/runtime/pattern-extractor.js +257 -0
- package/dist/runtime/pattern-extractor.js.map +1 -0
- package/dist/runtime/planner.d.ts +2 -2
- package/dist/runtime/planner.js +10 -7
- package/dist/runtime/planner.js.map +1 -1
- package/dist/runtime/reasoner.d.ts +2 -2
- package/dist/runtime/reasoner.js +22 -7
- package/dist/runtime/reasoner.js.map +1 -1
- package/dist/runtime/reflector.d.ts +7 -1
- package/dist/runtime/reflector.js.map +1 -1
- package/dist/runtime/shadow-runner.d.ts +14 -0
- package/dist/runtime/shadow-runner.js +190 -0
- package/dist/runtime/shadow-runner.js.map +1 -0
- package/dist/runtime/specialized-agent.d.ts +67 -0
- package/dist/runtime/specialized-agent.js +86 -0
- package/dist/runtime/specialized-agent.js.map +1 -0
- package/dist/runtime/strategy-library.d.ts +11 -0
- package/dist/runtime/strategy-library.js +142 -0
- package/dist/runtime/strategy-library.js.map +1 -0
- package/dist/runtime/supabase-experience-store.d.ts +19 -0
- package/dist/runtime/supabase-experience-store.js +215 -0
- package/dist/runtime/supabase-experience-store.js.map +1 -0
- package/dist/runtime/trust-manager.d.ts +33 -0
- package/dist/runtime/trust-manager.js +110 -0
- package/dist/runtime/trust-manager.js.map +1 -0
- package/dist/runtime/two-agent-loop.d.ts +35 -0
- package/dist/runtime/two-agent-loop.js +208 -0
- package/dist/runtime/two-agent-loop.js.map +1 -0
- package/dist/runtime/types.d.ts +291 -1
- package/package.json +1 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Supabase Experience Store
|
|
3
|
+
// Replaces NDJSON file with Supabase pgvector for semantic search.
|
|
4
|
+
// Falls back to local file when Supabase is unreachable.
|
|
5
|
+
// ============================================================
|
|
6
|
+
import { createClient } from '@supabase/supabase-js';
|
|
7
|
+
import { ExperienceStore } from './reflector.js';
|
|
8
|
+
// ── Embedding ─────────────────────────────────────────────────
|
|
9
|
+
function buildEmbeddingText(exp) {
|
|
10
|
+
const parts = [
|
|
11
|
+
exp.domain,
|
|
12
|
+
exp.decision.reasoning.slice(0, 300),
|
|
13
|
+
exp.lessons.join('. '),
|
|
14
|
+
exp.outcome,
|
|
15
|
+
exp.delta?.slice(0, 200) ?? '',
|
|
16
|
+
];
|
|
17
|
+
return parts.filter(Boolean).join(' | ');
|
|
18
|
+
}
|
|
19
|
+
async function computeEmbedding(text) {
|
|
20
|
+
// Use Anthropic's message API to generate a pseudo-embedding
|
|
21
|
+
// by hashing the semantic content. For production, swap to
|
|
22
|
+
// a dedicated embedding model (OpenAI text-embedding-3-small
|
|
23
|
+
// or Voyage AI). For now, use OpenAI since it's already a dep.
|
|
24
|
+
const { default: OpenAI } = await import('openai');
|
|
25
|
+
const client = new OpenAI();
|
|
26
|
+
const response = await client.embeddings.create({
|
|
27
|
+
model: 'text-embedding-3-small',
|
|
28
|
+
input: text.slice(0, 8000),
|
|
29
|
+
});
|
|
30
|
+
return response.data[0].embedding;
|
|
31
|
+
}
|
|
32
|
+
// ── SupabaseExperienceStore ──────────────────────────────────
|
|
33
|
+
export class SupabaseExperienceStore {
|
|
34
|
+
supabase;
|
|
35
|
+
localFallback;
|
|
36
|
+
online = true;
|
|
37
|
+
constructor(supabaseUrl, supabaseKey, localFallbackPath) {
|
|
38
|
+
this.supabase = createClient(supabaseUrl, supabaseKey);
|
|
39
|
+
this.localFallback = new ExperienceStore(localFallbackPath);
|
|
40
|
+
}
|
|
41
|
+
async save(experience) {
|
|
42
|
+
// Always write to local fallback
|
|
43
|
+
await this.localFallback.save(experience);
|
|
44
|
+
// Try Supabase
|
|
45
|
+
try {
|
|
46
|
+
const embeddingText = buildEmbeddingText(experience);
|
|
47
|
+
const embedding = await computeEmbedding(embeddingText);
|
|
48
|
+
const { error } = await this.supabase.from('experiences').insert({
|
|
49
|
+
id: experience.id,
|
|
50
|
+
agent_name: experience.observation.source === 'filesystem'
|
|
51
|
+
? 'default'
|
|
52
|
+
: 'default',
|
|
53
|
+
domain: experience.domain,
|
|
54
|
+
outcome: experience.outcome,
|
|
55
|
+
delta: experience.delta,
|
|
56
|
+
lessons: experience.lessons,
|
|
57
|
+
tags: experience.tags,
|
|
58
|
+
timestamp: experience.timestamp,
|
|
59
|
+
observation: experience.observation,
|
|
60
|
+
decision: experience.decision,
|
|
61
|
+
plan: experience.plan,
|
|
62
|
+
verification: experience.verification,
|
|
63
|
+
execution: experience.execution,
|
|
64
|
+
embedding: embedding,
|
|
65
|
+
});
|
|
66
|
+
if (error) {
|
|
67
|
+
console.error(`[SupabaseStore] Insert error: ${error.message}`);
|
|
68
|
+
this.online = false;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.online = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
76
|
+
console.error(`[SupabaseStore] Save failed, using local only: ${msg}`);
|
|
77
|
+
this.online = false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async search(query, limit = 5) {
|
|
81
|
+
if (!this.online) {
|
|
82
|
+
return this.fallbackSearch(query, limit);
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const queryEmbedding = await computeEmbedding(query);
|
|
86
|
+
const { data, error } = await this.supabase.rpc('match_experiences', {
|
|
87
|
+
query_embedding: queryEmbedding,
|
|
88
|
+
match_threshold: 0.3,
|
|
89
|
+
match_count: limit,
|
|
90
|
+
});
|
|
91
|
+
if (error || !data) {
|
|
92
|
+
console.error(`[SupabaseStore] Search error: ${error?.message}`);
|
|
93
|
+
return this.fallbackSearch(query, limit);
|
|
94
|
+
}
|
|
95
|
+
return data.map((row) => ({
|
|
96
|
+
experience: this.rowToExperience(row),
|
|
97
|
+
similarity: row.similarity,
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
102
|
+
console.error(`[SupabaseStore] Search failed, using fallback: ${msg}`);
|
|
103
|
+
this.online = false;
|
|
104
|
+
return this.fallbackSearch(query, limit);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async getByDomain(domain, limit = 50) {
|
|
108
|
+
if (!this.online) {
|
|
109
|
+
return this.localFallback.getByDomain(domain);
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const { data, error } = await this.supabase
|
|
113
|
+
.from('experiences')
|
|
114
|
+
.select('*')
|
|
115
|
+
.eq('domain', domain)
|
|
116
|
+
.order('timestamp', { ascending: false })
|
|
117
|
+
.limit(limit);
|
|
118
|
+
if (error || !data) {
|
|
119
|
+
return this.localFallback.getByDomain(domain);
|
|
120
|
+
}
|
|
121
|
+
return data.map((row) => this.rowToExperience(row));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return this.localFallback.getByDomain(domain);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async getByOutcome(outcome, limit = 50) {
|
|
128
|
+
if (!this.online) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const { data, error } = await this.supabase
|
|
133
|
+
.from('experiences')
|
|
134
|
+
.select('*')
|
|
135
|
+
.eq('outcome', outcome)
|
|
136
|
+
.order('timestamp', { ascending: false })
|
|
137
|
+
.limit(limit);
|
|
138
|
+
if (error || !data)
|
|
139
|
+
return [];
|
|
140
|
+
return data.map((row) => this.rowToExperience(row));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async getRecent(limit = 10) {
|
|
147
|
+
if (!this.online) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const { data, error } = await this.supabase
|
|
152
|
+
.from('experiences')
|
|
153
|
+
.select('*')
|
|
154
|
+
.order('timestamp', { ascending: false })
|
|
155
|
+
.limit(limit);
|
|
156
|
+
if (error || !data)
|
|
157
|
+
return [];
|
|
158
|
+
return data.map((row) => this.rowToExperience(row));
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async count() {
|
|
165
|
+
if (!this.online)
|
|
166
|
+
return 0;
|
|
167
|
+
try {
|
|
168
|
+
const { count, error } = await this.supabase
|
|
169
|
+
.from('experiences')
|
|
170
|
+
.select('*', { count: 'exact', head: true });
|
|
171
|
+
if (error || count === null)
|
|
172
|
+
return 0;
|
|
173
|
+
return count;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return 0;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async getStats() {
|
|
180
|
+
return this.localFallback.getStats();
|
|
181
|
+
}
|
|
182
|
+
// Interface compatibility method
|
|
183
|
+
async getRelevantExperiences(context, limit = 5) {
|
|
184
|
+
const scored = await this.search(context, limit);
|
|
185
|
+
return scored.map(s => s.experience);
|
|
186
|
+
}
|
|
187
|
+
isOnline() {
|
|
188
|
+
return this.online;
|
|
189
|
+
}
|
|
190
|
+
// ── Helpers ─────────────────────────────────────────────────
|
|
191
|
+
async fallbackSearch(query, limit) {
|
|
192
|
+
const results = await this.localFallback.getRelevantExperiences(query, limit);
|
|
193
|
+
return results.map((exp, i) => ({
|
|
194
|
+
experience: exp,
|
|
195
|
+
similarity: 1 - (i * 0.1), // approximate ranking
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
rowToExperience(row) {
|
|
199
|
+
return {
|
|
200
|
+
id: row.id,
|
|
201
|
+
observation: row.observation,
|
|
202
|
+
decision: row.decision,
|
|
203
|
+
plan: row.plan,
|
|
204
|
+
verification: row.verification,
|
|
205
|
+
execution: row.execution,
|
|
206
|
+
outcome: row.outcome,
|
|
207
|
+
delta: row.delta ?? '',
|
|
208
|
+
lessons: row.lessons ?? [],
|
|
209
|
+
domain: row.domain,
|
|
210
|
+
tags: row.tags ?? [],
|
|
211
|
+
timestamp: row.timestamp,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=supabase-experience-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase-experience-store.js","sourceRoot":"","sources":["../../src/runtime/supabase-experience-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AgentIdentity, TrustLevel, BoundaryVerificationResult, SafetyPolicy } from './types.js';
|
|
2
|
+
export declare class TrustManager {
|
|
3
|
+
private agents;
|
|
4
|
+
private policy;
|
|
5
|
+
private trustDemotionOnOverride;
|
|
6
|
+
private sessionOverrides;
|
|
7
|
+
private sessionDemotions;
|
|
8
|
+
constructor(policy: SafetyPolicy, opts?: {
|
|
9
|
+
trustDemotionOnOverride?: boolean;
|
|
10
|
+
});
|
|
11
|
+
/** Register an agent with its initial identity. */
|
|
12
|
+
register(agent: AgentIdentity): void;
|
|
13
|
+
/** Get an agent's current identity (with updated trust). */
|
|
14
|
+
getAgent(agentId: string): AgentIdentity | undefined;
|
|
15
|
+
/** Get all registered agents. */
|
|
16
|
+
getAllAgents(): AgentIdentity[];
|
|
17
|
+
/**
|
|
18
|
+
* Update trust based on a boundary verification result.
|
|
19
|
+
* Returns the updated trust level and whether the agent was demoted.
|
|
20
|
+
*/
|
|
21
|
+
updateTrust(agentId: string, result: BoundaryVerificationResult): {
|
|
22
|
+
newTrust: TrustLevel;
|
|
23
|
+
demoted: boolean;
|
|
24
|
+
shouldHalt: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** Get session-level stats for an agent. */
|
|
27
|
+
getSessionStats(agentId: string): {
|
|
28
|
+
overrides: number;
|
|
29
|
+
demotions: number;
|
|
30
|
+
};
|
|
31
|
+
private demoteTrust;
|
|
32
|
+
private computePassRate;
|
|
33
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Trust Manager
|
|
3
|
+
// Manages agent trust levels based on verification history
|
|
4
|
+
// ============================================================
|
|
5
|
+
// ── Trust Manager ───────────────────────────────────────────
|
|
6
|
+
export class TrustManager {
|
|
7
|
+
agents = new Map();
|
|
8
|
+
policy;
|
|
9
|
+
trustDemotionOnOverride;
|
|
10
|
+
sessionOverrides = new Map(); // agent -> override count this session
|
|
11
|
+
sessionDemotions = new Map(); // agent -> demotion count this session
|
|
12
|
+
constructor(policy, opts) {
|
|
13
|
+
this.policy = policy;
|
|
14
|
+
this.trustDemotionOnOverride = opts?.trustDemotionOnOverride ?? true;
|
|
15
|
+
}
|
|
16
|
+
/** Register an agent with its initial identity. */
|
|
17
|
+
register(agent) {
|
|
18
|
+
this.agents.set(agent.id, agent);
|
|
19
|
+
this.sessionOverrides.set(agent.id, 0);
|
|
20
|
+
this.sessionDemotions.set(agent.id, 0);
|
|
21
|
+
}
|
|
22
|
+
/** Get an agent's current identity (with updated trust). */
|
|
23
|
+
getAgent(agentId) {
|
|
24
|
+
return this.agents.get(agentId);
|
|
25
|
+
}
|
|
26
|
+
/** Get all registered agents. */
|
|
27
|
+
getAllAgents() {
|
|
28
|
+
return Array.from(this.agents.values());
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Update trust based on a boundary verification result.
|
|
32
|
+
* Returns the updated trust level and whether the agent was demoted.
|
|
33
|
+
*/
|
|
34
|
+
updateTrust(agentId, result) {
|
|
35
|
+
const agent = this.agents.get(agentId);
|
|
36
|
+
if (!agent)
|
|
37
|
+
return { newTrust: 'untrusted', demoted: false, shouldHalt: false };
|
|
38
|
+
const oldTrust = agent.trustLevel;
|
|
39
|
+
let newTrust = oldTrust;
|
|
40
|
+
let demoted = false;
|
|
41
|
+
// Check for formal overrides
|
|
42
|
+
if (result.formalStats.formalOverrides > 0 && this.trustDemotionOnOverride) {
|
|
43
|
+
// A single formal override drops trust by one level
|
|
44
|
+
newTrust = this.demoteTrust(oldTrust);
|
|
45
|
+
demoted = newTrust !== oldTrust;
|
|
46
|
+
if (demoted) {
|
|
47
|
+
const overrides = (this.sessionOverrides.get(agentId) ?? 0) + result.formalStats.formalOverrides;
|
|
48
|
+
this.sessionOverrides.set(agentId, overrides);
|
|
49
|
+
const demotions = (this.sessionDemotions.get(agentId) ?? 0) + 1;
|
|
50
|
+
this.sessionDemotions.set(agentId, demotions);
|
|
51
|
+
// Two formal overrides in a session → drop to untrusted
|
|
52
|
+
if (overrides >= 2) {
|
|
53
|
+
newTrust = 'untrusted';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Check for promotion
|
|
58
|
+
if (!demoted && result.verdict === 'PASS') {
|
|
59
|
+
const history = agent.verificationHistory;
|
|
60
|
+
const newTotal = history.totalHandoffs + 1;
|
|
61
|
+
const newPassRate = (history.passRate * history.totalHandoffs + 1) / newTotal;
|
|
62
|
+
// Promote if enough clean handoffs
|
|
63
|
+
if (oldTrust === 'untrusted' && newTotal >= 10 && newPassRate >= 0.9) {
|
|
64
|
+
newTrust = 'provisional';
|
|
65
|
+
}
|
|
66
|
+
else if (oldTrust === 'provisional' && newTotal >= 50 && newPassRate >= 0.95) {
|
|
67
|
+
newTrust = 'trusted';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Update the agent's identity
|
|
71
|
+
const updatedHistory = {
|
|
72
|
+
totalHandoffs: agent.verificationHistory.totalHandoffs + 1,
|
|
73
|
+
passRate: this.computePassRate(agent, result),
|
|
74
|
+
formalOverrides: agent.verificationHistory.formalOverrides + result.formalStats.formalOverrides,
|
|
75
|
+
};
|
|
76
|
+
const updatedAgent = {
|
|
77
|
+
...agent,
|
|
78
|
+
trustLevel: newTrust,
|
|
79
|
+
verificationHistory: updatedHistory,
|
|
80
|
+
};
|
|
81
|
+
this.agents.set(agentId, updatedAgent);
|
|
82
|
+
// Check if we should halt
|
|
83
|
+
const shouldHalt = (this.sessionOverrides.get(agentId) ?? 0) >= this.policy.escalationRules.maxFormalOverridesBeforeHalt ||
|
|
84
|
+
(this.sessionDemotions.get(agentId) ?? 0) >= this.policy.escalationRules.maxTrustDemotions;
|
|
85
|
+
return { newTrust, demoted, shouldHalt };
|
|
86
|
+
}
|
|
87
|
+
/** Get session-level stats for an agent. */
|
|
88
|
+
getSessionStats(agentId) {
|
|
89
|
+
return {
|
|
90
|
+
overrides: this.sessionOverrides.get(agentId) ?? 0,
|
|
91
|
+
demotions: this.sessionDemotions.get(agentId) ?? 0,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// ── Private helpers ─────────────────────────────────────
|
|
95
|
+
demoteTrust(current) {
|
|
96
|
+
switch (current) {
|
|
97
|
+
case 'trusted': return 'provisional';
|
|
98
|
+
case 'provisional': return 'untrusted';
|
|
99
|
+
case 'untrusted': return 'untrusted';
|
|
100
|
+
case 'formal': return 'formal'; // formal agents can't be demoted
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
computePassRate(agent, result) {
|
|
104
|
+
const oldTotal = agent.verificationHistory.totalHandoffs;
|
|
105
|
+
const oldRate = agent.verificationHistory.passRate;
|
|
106
|
+
const passed = result.verdict === 'PASS' ? 1 : 0;
|
|
107
|
+
return (oldRate * oldTotal + passed) / (oldTotal + 1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=trust-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-manager.js","sourceRoot":"","sources":["../../src/runtime/trust-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { TaskAssignmentPayload } from './specialized-agent.js';
|
|
3
|
+
import type { SafetyPolicy, VerifiedHandoff, BoundaryArtifact, AuditEntry } from './types.js';
|
|
4
|
+
export interface TwoAgentResult {
|
|
5
|
+
readonly taskId: string;
|
|
6
|
+
readonly status: 'completed' | 'rejected' | 'escalated' | 'failed';
|
|
7
|
+
readonly codeArtifacts: readonly BoundaryArtifact[];
|
|
8
|
+
readonly reviewArtifact: BoundaryArtifact | null;
|
|
9
|
+
readonly codeHandoff: VerifiedHandoff | null;
|
|
10
|
+
readonly reviewHandoff: VerifiedHandoff | null;
|
|
11
|
+
readonly attempts: number;
|
|
12
|
+
readonly auditTrail: readonly AuditEntry[];
|
|
13
|
+
}
|
|
14
|
+
export declare class TwoAgentLoop extends EventEmitter {
|
|
15
|
+
private messageBus;
|
|
16
|
+
private compositionVerifier;
|
|
17
|
+
private trustManager;
|
|
18
|
+
private codeAgent;
|
|
19
|
+
private reviewAgent;
|
|
20
|
+
private auditTrail;
|
|
21
|
+
constructor(codebaseRoot: string, opts?: {
|
|
22
|
+
codeModel?: string;
|
|
23
|
+
reviewModel?: string;
|
|
24
|
+
safetyPolicy?: SafetyPolicy;
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Run the two-agent loop on a task.
|
|
28
|
+
* Code Agent writes -> Assay verifies -> Review Agent reviews -> Assay verifies.
|
|
29
|
+
* If rejected at any boundary, Code Agent gets feedback and retries.
|
|
30
|
+
*/
|
|
31
|
+
run(task: TaskAssignmentPayload, maxAttempts?: number): Promise<TwoAgentResult>;
|
|
32
|
+
/** Get the current audit trail. */
|
|
33
|
+
getAuditTrail(): readonly AuditEntry[];
|
|
34
|
+
private audit;
|
|
35
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Two-Agent Loop
|
|
3
|
+
// M1 deliverable: Code + Review with boundary verification
|
|
4
|
+
// ============================================================
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { EventEmitter } from 'node:events';
|
|
7
|
+
import { MessageBus } from './message-bus.js';
|
|
8
|
+
import { CompositionVerifier } from './composition-verifier.js';
|
|
9
|
+
import { TrustManager } from './trust-manager.js';
|
|
10
|
+
import { CodeAgent } from './agents/code-agent.js';
|
|
11
|
+
import { ReviewAgent } from './agents/review-agent.js';
|
|
12
|
+
// ── Default safety policy ───────────────────────────────────
|
|
13
|
+
const DEFAULT_SAFETY = {
|
|
14
|
+
formalOverridesConsensus: true,
|
|
15
|
+
noSelfVerification: true,
|
|
16
|
+
criticalClaimsRequireFormal: true,
|
|
17
|
+
escalationRules: {
|
|
18
|
+
maxFormalOverridesBeforeHalt: 3,
|
|
19
|
+
maxTrustDemotions: 2,
|
|
20
|
+
maxRejectCyclesPerTask: 3,
|
|
21
|
+
},
|
|
22
|
+
preferModelDiversity: false,
|
|
23
|
+
};
|
|
24
|
+
// ── Two-Agent Loop ──────────────────────────────────────────
|
|
25
|
+
export class TwoAgentLoop extends EventEmitter {
|
|
26
|
+
messageBus;
|
|
27
|
+
compositionVerifier;
|
|
28
|
+
trustManager;
|
|
29
|
+
codeAgent;
|
|
30
|
+
reviewAgent;
|
|
31
|
+
auditTrail = [];
|
|
32
|
+
constructor(codebaseRoot, opts) {
|
|
33
|
+
super();
|
|
34
|
+
this.messageBus = new MessageBus();
|
|
35
|
+
this.compositionVerifier = new CompositionVerifier(codebaseRoot);
|
|
36
|
+
this.trustManager = new TrustManager(opts?.safetyPolicy ?? DEFAULT_SAFETY);
|
|
37
|
+
this.codeAgent = new CodeAgent(this.messageBus, { model: opts?.codeModel });
|
|
38
|
+
this.reviewAgent = new ReviewAgent(this.messageBus, { model: opts?.reviewModel });
|
|
39
|
+
// Register agents with trust manager
|
|
40
|
+
this.trustManager.register(this.codeAgent.getIdentity());
|
|
41
|
+
this.trustManager.register(this.reviewAgent.getIdentity());
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Run the two-agent loop on a task.
|
|
45
|
+
* Code Agent writes -> Assay verifies -> Review Agent reviews -> Assay verifies.
|
|
46
|
+
* If rejected at any boundary, Code Agent gets feedback and retries.
|
|
47
|
+
*/
|
|
48
|
+
async run(task, maxAttempts = 3) {
|
|
49
|
+
const taskId = task.taskId;
|
|
50
|
+
let attempts = 0;
|
|
51
|
+
let currentTask = task;
|
|
52
|
+
let lastCodeArtifacts = [];
|
|
53
|
+
let lastReviewArtifact = null;
|
|
54
|
+
let lastCodeHandoff = null;
|
|
55
|
+
let lastReviewHandoff = null;
|
|
56
|
+
while (attempts < maxAttempts) {
|
|
57
|
+
attempts++;
|
|
58
|
+
this.audit('task_status_change', { taskId, status: 'in_progress', attempt: attempts });
|
|
59
|
+
// Step 1: Code Agent writes code
|
|
60
|
+
const codeResult = await this.codeAgent.executeTask(currentTask);
|
|
61
|
+
this.audit('message_sent', {
|
|
62
|
+
from: this.codeAgent.getIdentity().name,
|
|
63
|
+
type: 'task_result',
|
|
64
|
+
status: codeResult.status,
|
|
65
|
+
artifactCount: codeResult.artifacts.length,
|
|
66
|
+
});
|
|
67
|
+
if (codeResult.status === 'failed') {
|
|
68
|
+
this.audit('task_status_change', { taskId, status: 'failed', reason: codeResult.summary });
|
|
69
|
+
return {
|
|
70
|
+
taskId,
|
|
71
|
+
status: 'failed',
|
|
72
|
+
codeArtifacts: [],
|
|
73
|
+
reviewArtifact: null,
|
|
74
|
+
codeHandoff: null,
|
|
75
|
+
reviewHandoff: null,
|
|
76
|
+
attempts,
|
|
77
|
+
auditTrail: this.auditTrail,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
lastCodeArtifacts = [...codeResult.artifacts];
|
|
81
|
+
let boundaryRejected = false;
|
|
82
|
+
// Step 2: Verify Code Agent output at boundary
|
|
83
|
+
for (const artifact of codeResult.artifacts) {
|
|
84
|
+
const handoff = await this.compositionVerifier.verifyHandoff(this.codeAgent.getIdentity(), this.reviewAgent.getIdentity(), artifact);
|
|
85
|
+
lastCodeHandoff = handoff;
|
|
86
|
+
this.audit('verification_run', {
|
|
87
|
+
boundary: `${this.codeAgent.getIdentity().name} -> ${this.reviewAgent.getIdentity().name}`,
|
|
88
|
+
verdict: handoff.verificationResult.verdict,
|
|
89
|
+
claims: handoff.verificationResult.total,
|
|
90
|
+
passed: handoff.verificationResult.passed,
|
|
91
|
+
failed: handoff.verificationResult.failed,
|
|
92
|
+
});
|
|
93
|
+
// Update trust
|
|
94
|
+
const trustResult = this.trustManager.updateTrust(this.codeAgent.getIdentity().id, handoff.verificationResult);
|
|
95
|
+
if (trustResult.demoted) {
|
|
96
|
+
this.audit('trust_change', {
|
|
97
|
+
agent: this.codeAgent.getIdentity().name,
|
|
98
|
+
newTrust: trustResult.newTrust,
|
|
99
|
+
reason: 'formal_override',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (trustResult.shouldHalt) {
|
|
103
|
+
this.audit('escalation', { reason: 'trust_threshold_exceeded', agent: this.codeAgent.getIdentity().name });
|
|
104
|
+
return {
|
|
105
|
+
taskId,
|
|
106
|
+
status: 'escalated',
|
|
107
|
+
codeArtifacts: lastCodeArtifacts,
|
|
108
|
+
reviewArtifact: null,
|
|
109
|
+
codeHandoff: lastCodeHandoff,
|
|
110
|
+
reviewHandoff: null,
|
|
111
|
+
attempts,
|
|
112
|
+
auditTrail: this.auditTrail,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// If code boundary fails, feed back to code agent and retry
|
|
116
|
+
if (handoff.decision.action === 'reject') {
|
|
117
|
+
this.audit('handoff_decision', { decision: 'reject', boundary: 'code->review' });
|
|
118
|
+
// Update task with rejection feedback
|
|
119
|
+
currentTask = {
|
|
120
|
+
...currentTask,
|
|
121
|
+
constraints: [
|
|
122
|
+
...currentTask.constraints,
|
|
123
|
+
`Previous attempt rejected. Issues: ${handoff.verificationResult.blockers.map(b => b.text).join('; ')}`,
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
boundaryRejected = true;
|
|
127
|
+
break; // retry from step 1
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (boundaryRejected) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Step 3: Review Agent reviews the code
|
|
134
|
+
const reviewTask = {
|
|
135
|
+
taskId: `${taskId}-review`,
|
|
136
|
+
goal: `Review the code produced for: ${currentTask.goal}`,
|
|
137
|
+
constraints: ['Be thorough', 'Check for security, correctness, and edge cases'],
|
|
138
|
+
dependencies: [],
|
|
139
|
+
contextRefs: codeResult.artifacts.map(a => ({
|
|
140
|
+
summary: a.path ?? 'code patch',
|
|
141
|
+
content: a.content,
|
|
142
|
+
})),
|
|
143
|
+
};
|
|
144
|
+
const reviewResult = await this.reviewAgent.executeTask(reviewTask);
|
|
145
|
+
this.audit('message_sent', {
|
|
146
|
+
from: this.reviewAgent.getIdentity().name,
|
|
147
|
+
type: 'task_result',
|
|
148
|
+
status: reviewResult.status,
|
|
149
|
+
});
|
|
150
|
+
if (reviewResult.artifacts.length > 0) {
|
|
151
|
+
lastReviewArtifact = reviewResult.artifacts[0];
|
|
152
|
+
// Step 4: Verify Review Agent output at boundary
|
|
153
|
+
const reviewHandoff = await this.compositionVerifier.verifyHandoff(this.reviewAgent.getIdentity(), this.codeAgent.getIdentity(), // review flows back to code
|
|
154
|
+
lastReviewArtifact);
|
|
155
|
+
lastReviewHandoff = reviewHandoff;
|
|
156
|
+
this.audit('verification_run', {
|
|
157
|
+
boundary: `${this.reviewAgent.getIdentity().name} -> ${this.codeAgent.getIdentity().name}`,
|
|
158
|
+
verdict: reviewHandoff.verificationResult.verdict,
|
|
159
|
+
claims: reviewHandoff.verificationResult.total,
|
|
160
|
+
});
|
|
161
|
+
// Update review agent trust
|
|
162
|
+
this.trustManager.updateTrust(this.reviewAgent.getIdentity().id, reviewHandoff.verificationResult);
|
|
163
|
+
}
|
|
164
|
+
// If we got here without a reject, the task is complete
|
|
165
|
+
this.audit('task_status_change', { taskId, status: 'completed', attempts });
|
|
166
|
+
return {
|
|
167
|
+
taskId,
|
|
168
|
+
status: 'completed',
|
|
169
|
+
codeArtifacts: lastCodeArtifacts,
|
|
170
|
+
reviewArtifact: lastReviewArtifact,
|
|
171
|
+
codeHandoff: lastCodeHandoff,
|
|
172
|
+
reviewHandoff: lastReviewHandoff,
|
|
173
|
+
attempts,
|
|
174
|
+
auditTrail: this.auditTrail,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// Exhausted max attempts
|
|
178
|
+
this.audit('task_status_change', { taskId, status: 'rejected', reason: 'max_attempts_exceeded' });
|
|
179
|
+
return {
|
|
180
|
+
taskId,
|
|
181
|
+
status: 'rejected',
|
|
182
|
+
codeArtifacts: lastCodeArtifacts,
|
|
183
|
+
reviewArtifact: lastReviewArtifact,
|
|
184
|
+
codeHandoff: lastCodeHandoff,
|
|
185
|
+
reviewHandoff: lastReviewHandoff,
|
|
186
|
+
attempts,
|
|
187
|
+
auditTrail: this.auditTrail,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/** Get the current audit trail. */
|
|
191
|
+
getAuditTrail() {
|
|
192
|
+
return this.auditTrail;
|
|
193
|
+
}
|
|
194
|
+
// ── Private ─────────────────────────────────────────────
|
|
195
|
+
audit(eventType, details) {
|
|
196
|
+
const entry = {
|
|
197
|
+
id: randomUUID(),
|
|
198
|
+
eventType,
|
|
199
|
+
agentName: 'two-agent-loop',
|
|
200
|
+
timestamp: new Date().toISOString(),
|
|
201
|
+
details,
|
|
202
|
+
relatedIds: {},
|
|
203
|
+
};
|
|
204
|
+
this.auditTrail.push(entry);
|
|
205
|
+
this.emit('audit', entry);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=two-agent-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"two-agent-loop.js","sourceRoot":"","sources":["../../src/runtime/two-agent-loop.ts"],"names":[],"mappings":"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"}
|