0agent 1.0.14 → 1.0.16
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/daemon.mjs +206 -1
- package/package.json +1 -1
package/dist/daemon.mjs
CHANGED
|
@@ -989,9 +989,24 @@ var init_TraceStore = __esm({
|
|
|
989
989
|
});
|
|
990
990
|
|
|
991
991
|
// packages/core/src/storage/WeightEventLog.ts
|
|
992
|
+
var WeightEventLog;
|
|
992
993
|
var init_WeightEventLog = __esm({
|
|
993
994
|
"packages/core/src/storage/WeightEventLog.ts"() {
|
|
994
995
|
"use strict";
|
|
996
|
+
WeightEventLog = class {
|
|
997
|
+
constructor(adapter) {
|
|
998
|
+
this.adapter = adapter;
|
|
999
|
+
}
|
|
1000
|
+
append(event) {
|
|
1001
|
+
this.adapter.insertWeightEvent(event);
|
|
1002
|
+
}
|
|
1003
|
+
getByEdge(edgeId) {
|
|
1004
|
+
return this.adapter.getWeightEvents(edgeId);
|
|
1005
|
+
}
|
|
1006
|
+
getByTrace(traceId) {
|
|
1007
|
+
return this.adapter.getWeightEventsByTrace(traceId);
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
995
1010
|
}
|
|
996
1011
|
});
|
|
997
1012
|
|
|
@@ -1426,9 +1441,58 @@ var init_ArchivalMemory = __esm({
|
|
|
1426
1441
|
});
|
|
1427
1442
|
|
|
1428
1443
|
// packages/core/src/concurrency/EdgeWeightUpdater.ts
|
|
1444
|
+
var EdgeWeightUpdater;
|
|
1429
1445
|
var init_EdgeWeightUpdater = __esm({
|
|
1430
1446
|
"packages/core/src/concurrency/EdgeWeightUpdater.ts"() {
|
|
1431
1447
|
"use strict";
|
|
1448
|
+
EdgeWeightUpdater = class {
|
|
1449
|
+
constructor(adapter, weightLog) {
|
|
1450
|
+
this.adapter = adapter;
|
|
1451
|
+
this.weightLog = weightLog;
|
|
1452
|
+
}
|
|
1453
|
+
/**
|
|
1454
|
+
* Update edge weight with optimistic concurrency control.
|
|
1455
|
+
* Retries up to 3 times with exponential backoff (1ms, 2ms, 4ms).
|
|
1456
|
+
* On 3rd failure: LWW (last-write-wins) fallback.
|
|
1457
|
+
*/
|
|
1458
|
+
async update(edgeId, expectedWeight, newWeight, reason, traceId) {
|
|
1459
|
+
const delays = [1, 2, 4];
|
|
1460
|
+
let currentExpected = expectedWeight;
|
|
1461
|
+
for (let attempt = 0; attempt <= 2; attempt++) {
|
|
1462
|
+
const success = this.adapter.updateEdgeWeight(edgeId, newWeight, currentExpected);
|
|
1463
|
+
if (success) {
|
|
1464
|
+
this.logEvent(edgeId, currentExpected, newWeight, reason, traceId);
|
|
1465
|
+
return true;
|
|
1466
|
+
}
|
|
1467
|
+
const edge = this.adapter.getEdge(edgeId);
|
|
1468
|
+
if (!edge) return false;
|
|
1469
|
+
currentExpected = edge.weight;
|
|
1470
|
+
if (attempt < 2) {
|
|
1471
|
+
await this.sleep(delays[attempt]);
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
console.warn(`OCC conflict on edge ${edgeId} after 3 retries \u2014 LWW fallback`);
|
|
1475
|
+
this.adapter.forceUpdateEdgeWeight(edgeId, newWeight);
|
|
1476
|
+
this.logEvent(edgeId, currentExpected, newWeight, `${reason}:lww_fallback`, traceId);
|
|
1477
|
+
return true;
|
|
1478
|
+
}
|
|
1479
|
+
logEvent(edgeId, oldWeight, newWeight, reason, traceId) {
|
|
1480
|
+
const event = {
|
|
1481
|
+
id: crypto.randomUUID(),
|
|
1482
|
+
edge_id: edgeId,
|
|
1483
|
+
old_weight: oldWeight,
|
|
1484
|
+
new_weight: newWeight,
|
|
1485
|
+
delta: newWeight - oldWeight,
|
|
1486
|
+
reason,
|
|
1487
|
+
trace_id: traceId ?? null,
|
|
1488
|
+
created_at: Date.now()
|
|
1489
|
+
};
|
|
1490
|
+
this.weightLog.append(event);
|
|
1491
|
+
}
|
|
1492
|
+
sleep(ms) {
|
|
1493
|
+
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
1494
|
+
}
|
|
1495
|
+
};
|
|
1432
1496
|
}
|
|
1433
1497
|
});
|
|
1434
1498
|
|
|
@@ -3166,6 +3230,9 @@ ${issues}`);
|
|
|
3166
3230
|
return result.data;
|
|
3167
3231
|
}
|
|
3168
3232
|
|
|
3233
|
+
// packages/daemon/src/SessionManager.ts
|
|
3234
|
+
init_src();
|
|
3235
|
+
|
|
3169
3236
|
// packages/daemon/src/EntityScopedContext.ts
|
|
3170
3237
|
init_src();
|
|
3171
3238
|
var EntityScopedContextLoader = class {
|
|
@@ -3501,6 +3568,61 @@ var ProjectScanner = class {
|
|
|
3501
3568
|
}
|
|
3502
3569
|
};
|
|
3503
3570
|
|
|
3571
|
+
// packages/daemon/src/ConversationStore.ts
|
|
3572
|
+
var CREATE_TABLE = `
|
|
3573
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
3574
|
+
id TEXT PRIMARY KEY,
|
|
3575
|
+
session_id TEXT NOT NULL,
|
|
3576
|
+
user_entity_id TEXT NOT NULL,
|
|
3577
|
+
role TEXT NOT NULL,
|
|
3578
|
+
content TEXT NOT NULL,
|
|
3579
|
+
created_at INTEGER NOT NULL
|
|
3580
|
+
);
|
|
3581
|
+
CREATE INDEX IF NOT EXISTS idx_conv_user ON conversations(user_entity_id, created_at);
|
|
3582
|
+
`;
|
|
3583
|
+
var ConversationStore = class {
|
|
3584
|
+
constructor(adapter) {
|
|
3585
|
+
this.adapter = adapter;
|
|
3586
|
+
}
|
|
3587
|
+
initialised = false;
|
|
3588
|
+
init() {
|
|
3589
|
+
if (this.initialised) return;
|
|
3590
|
+
this.adapter.db.exec(CREATE_TABLE);
|
|
3591
|
+
this.initialised = true;
|
|
3592
|
+
}
|
|
3593
|
+
append(msg) {
|
|
3594
|
+
this.init();
|
|
3595
|
+
const db = this.adapter.db;
|
|
3596
|
+
db.prepare(
|
|
3597
|
+
`INSERT INTO conversations (id, session_id, user_entity_id, role, content, created_at)
|
|
3598
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
3599
|
+
).run(msg.id, msg.session_id, msg.user_entity_id, msg.role, msg.content, msg.created_at);
|
|
3600
|
+
}
|
|
3601
|
+
getHistory(userEntityId, limit = 20) {
|
|
3602
|
+
this.init();
|
|
3603
|
+
const db = this.adapter.db;
|
|
3604
|
+
const rows = db.prepare(
|
|
3605
|
+
`SELECT * FROM conversations WHERE user_entity_id = ?
|
|
3606
|
+
ORDER BY created_at DESC LIMIT ?`
|
|
3607
|
+
).all(userEntityId, limit);
|
|
3608
|
+
return rows.reverse();
|
|
3609
|
+
}
|
|
3610
|
+
/**
|
|
3611
|
+
* Build conversation history as LLM messages for context injection.
|
|
3612
|
+
*/
|
|
3613
|
+
buildContextMessages(userEntityId, limit = 10) {
|
|
3614
|
+
return this.getHistory(userEntityId, limit).map((m) => ({
|
|
3615
|
+
role: m.role,
|
|
3616
|
+
content: m.content
|
|
3617
|
+
}));
|
|
3618
|
+
}
|
|
3619
|
+
clearHistory(userEntityId) {
|
|
3620
|
+
this.init();
|
|
3621
|
+
const db = this.adapter.db;
|
|
3622
|
+
db.prepare(`DELETE FROM conversations WHERE user_entity_id = ?`).run(userEntityId);
|
|
3623
|
+
}
|
|
3624
|
+
};
|
|
3625
|
+
|
|
3504
3626
|
// packages/daemon/src/SessionManager.ts
|
|
3505
3627
|
var SessionManager = class {
|
|
3506
3628
|
sessions = /* @__PURE__ */ new Map();
|
|
@@ -3511,6 +3633,8 @@ var SessionManager = class {
|
|
|
3511
3633
|
cwd;
|
|
3512
3634
|
identity;
|
|
3513
3635
|
projectContext;
|
|
3636
|
+
conversationStore;
|
|
3637
|
+
weightUpdater;
|
|
3514
3638
|
anthropicFetcher = new AnthropicSkillFetcher();
|
|
3515
3639
|
constructor(deps = {}) {
|
|
3516
3640
|
this.inferenceEngine = deps.inferenceEngine;
|
|
@@ -3520,6 +3644,12 @@ var SessionManager = class {
|
|
|
3520
3644
|
this.cwd = deps.cwd ?? process.cwd();
|
|
3521
3645
|
this.identity = deps.identity;
|
|
3522
3646
|
this.projectContext = deps.projectContext;
|
|
3647
|
+
if (deps.adapter) {
|
|
3648
|
+
this.conversationStore = new ConversationStore(deps.adapter);
|
|
3649
|
+
this.conversationStore.init();
|
|
3650
|
+
const wLog = new WeightEventLog(deps.adapter);
|
|
3651
|
+
this.weightUpdater = new EdgeWeightUpdater(deps.adapter, wLog);
|
|
3652
|
+
}
|
|
3523
3653
|
}
|
|
3524
3654
|
/**
|
|
3525
3655
|
* Create a new session with status 'pending'.
|
|
@@ -3707,9 +3837,22 @@ var SessionManager = class {
|
|
|
3707
3837
|
);
|
|
3708
3838
|
const identityContext = this.identity ? `You are talking to ${this.identity.name} (device: ${this.identity.device_id}, timezone: ${this.identity.timezone}).` : void 0;
|
|
3709
3839
|
const projectCtx = this.projectContext ? ProjectScanner.buildContextPrompt(this.projectContext) : void 0;
|
|
3840
|
+
const userEntityId = enrichedReq.entity_id ?? this.identity?.entity_node_id;
|
|
3841
|
+
let conversationHistory;
|
|
3842
|
+
if (this.conversationStore && userEntityId) {
|
|
3843
|
+
const history = this.conversationStore.buildContextMessages(userEntityId, 8);
|
|
3844
|
+
if (history.length > 0) {
|
|
3845
|
+
const historyStr = history.map((m) => `${m.role === "user" ? "User" : "Agent"}: ${m.content.slice(0, 400)}`).join("\n");
|
|
3846
|
+
conversationHistory = `CONVERSATION HISTORY (use this for context on follow-up requests):
|
|
3847
|
+
${historyStr}
|
|
3848
|
+
|
|
3849
|
+
Current task:`;
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3710
3852
|
const systemContext = [
|
|
3711
3853
|
identityContext,
|
|
3712
3854
|
projectCtx,
|
|
3855
|
+
conversationHistory,
|
|
3713
3856
|
anthropicContext,
|
|
3714
3857
|
enrichedReq.context?.system_context ? String(enrichedReq.context.system_context) : void 0
|
|
3715
3858
|
].filter(Boolean).join("\n\n") || void 0;
|
|
@@ -3726,6 +3869,49 @@ var SessionManager = class {
|
|
|
3726
3869
|
} catch {
|
|
3727
3870
|
agentResult = await executor.execute(enrichedReq.task, systemContext);
|
|
3728
3871
|
}
|
|
3872
|
+
if (this.conversationStore && userEntityId) {
|
|
3873
|
+
const sessionId = session.id;
|
|
3874
|
+
const now = Date.now();
|
|
3875
|
+
this.conversationStore.append({
|
|
3876
|
+
id: crypto.randomUUID(),
|
|
3877
|
+
session_id: sessionId,
|
|
3878
|
+
user_entity_id: userEntityId,
|
|
3879
|
+
role: "user",
|
|
3880
|
+
content: enrichedReq.task,
|
|
3881
|
+
created_at: now
|
|
3882
|
+
});
|
|
3883
|
+
this.conversationStore.append({
|
|
3884
|
+
id: crypto.randomUUID(),
|
|
3885
|
+
session_id: sessionId,
|
|
3886
|
+
user_entity_id: userEntityId,
|
|
3887
|
+
role: "assistant",
|
|
3888
|
+
content: agentResult.output.slice(0, 1e3),
|
|
3889
|
+
// cap stored output length
|
|
3890
|
+
created_at: now + 1
|
|
3891
|
+
});
|
|
3892
|
+
}
|
|
3893
|
+
const selectedEdgeId = session.plan?.selected_edge?.edge_id;
|
|
3894
|
+
if (selectedEdgeId && this.weightUpdater && this.graph) {
|
|
3895
|
+
const outcomeSignal = this.computeOutcomeSignal(agentResult);
|
|
3896
|
+
if (outcomeSignal !== 0) {
|
|
3897
|
+
const edge = this.graph.getEdge(selectedEdgeId);
|
|
3898
|
+
if (edge && !edge.locked) {
|
|
3899
|
+
const newWeight = Math.max(0, Math.min(
|
|
3900
|
+
1,
|
|
3901
|
+
edge.weight + outcomeSignal * 0.1
|
|
3902
|
+
// learning rate 0.1
|
|
3903
|
+
));
|
|
3904
|
+
await this.weightUpdater.update(
|
|
3905
|
+
edge.id,
|
|
3906
|
+
edge.weight,
|
|
3907
|
+
newWeight,
|
|
3908
|
+
outcomeSignal > 0 ? "task_outcome_positive" : "task_outcome_negative",
|
|
3909
|
+
session.id
|
|
3910
|
+
);
|
|
3911
|
+
this.emit({ type: "graph.weight_updated", edge_id: edge.id, old_weight: edge.weight, new_weight: newWeight });
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
}
|
|
3729
3915
|
if (agentResult.files_written.length > 0) {
|
|
3730
3916
|
this.addStep(session.id, `Files written: ${agentResult.files_written.join(", ")}`);
|
|
3731
3917
|
}
|
|
@@ -3774,6 +3960,23 @@ var SessionManager = class {
|
|
|
3774
3960
|
this.eventBus.emit(event);
|
|
3775
3961
|
}
|
|
3776
3962
|
}
|
|
3963
|
+
/**
|
|
3964
|
+
* Convert a task result into a weight signal for the knowledge graph.
|
|
3965
|
+
*
|
|
3966
|
+
* Signal scale: -0.3 (failed after retries) to +0.3 (verified success first try).
|
|
3967
|
+
* Neutral (0) when no verification was possible — don't penalise unverifiable tasks.
|
|
3968
|
+
*/
|
|
3969
|
+
computeOutcomeSignal(result) {
|
|
3970
|
+
const healAttempts = result["heal_attempts"];
|
|
3971
|
+
if (!healAttempts || healAttempts.length === 0) return 0;
|
|
3972
|
+
const last = healAttempts[healAttempts.length - 1];
|
|
3973
|
+
const verification = last?.["verification"];
|
|
3974
|
+
if (!verification || verification["method"] === "none") return 0;
|
|
3975
|
+
const success = verification["success"] === true;
|
|
3976
|
+
const healed = result["healed"] === true;
|
|
3977
|
+
if (success) return healed ? 0.1 : 0.3;
|
|
3978
|
+
return -0.2;
|
|
3979
|
+
}
|
|
3777
3980
|
};
|
|
3778
3981
|
|
|
3779
3982
|
// packages/daemon/src/WebSocketEvents.ts
|
|
@@ -5013,7 +5216,9 @@ var ZeroAgentDaemon = class {
|
|
|
5013
5216
|
llm: llmExecutor,
|
|
5014
5217
|
cwd,
|
|
5015
5218
|
identity: identity ?? void 0,
|
|
5016
|
-
projectContext: projectContext ?? void 0
|
|
5219
|
+
projectContext: projectContext ?? void 0,
|
|
5220
|
+
adapter: this.adapter
|
|
5221
|
+
// enables ConversationStore + weight feedback
|
|
5017
5222
|
});
|
|
5018
5223
|
const teamSync = identity && teams.length > 0 ? new TeamSync(teamManager, this.adapter, identity.entity_node_id) : null;
|
|
5019
5224
|
let proactiveSurface = null;
|