bazilion 0.11.0 → 0.12.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 +433 -146
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +1382 -232
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +81 -0
- package/dist/web/client/assets/AgentTabs-R6gSjIj3.js +1 -0
- package/dist/web/client/assets/{ProductionTeamPolicyEditor-B6dbpuYy.js → ProductionTeamPolicyEditor-CSL3W7XM.js} +2 -2
- package/dist/web/client/assets/{ProfileCommunicationEditor-Bf8UvmZT.js → ProfileCommunicationEditor-CwU0QkmE.js} +1 -1
- package/dist/web/client/assets/{TeamTabs-sQBHChtd.js → TeamTabs-C1Hakkff.js} +1 -1
- package/dist/web/client/assets/{TemplatesTabs-DPsuwsWB.js → TemplatesTabs-klEydJ8-.js} +1 -1
- package/dist/web/client/assets/{_id-C9rkCclz.js → _id-BOC7ioJu.js} +1 -1
- package/dist/web/client/assets/{_id-DYASsGQ8.js → _id-CnVq-rED.js} +1 -1
- package/dist/web/client/assets/{_id-DE4IY5bL.js → _id-e4u7dmBb.js} +1 -1
- package/dist/web/client/assets/{_id-D65IzC8H.js → _id-wkjjWLz0.js} +1 -1
- package/dist/web/client/assets/{activity-C7o6-xHg.js → activity-uqhwzmiy.js} +1 -1
- package/dist/web/client/assets/{agents-UroO4d25.js → agents-B2usE-L_.js} +1 -1
- package/dist/web/client/assets/{agents-h8yWXQ2H.js → agents-FaQtkAWs.js} +1 -1
- package/dist/web/client/assets/{approvals-DKhF0YLC.js → approvals-DqLE6ttw.js} +1 -1
- package/dist/web/client/assets/attention-CkGozYnJ.js +1 -0
- package/dist/web/client/assets/attention-Gavt2yEp.js +1 -0
- package/dist/web/client/assets/chevron-down-CJk0zGNT.js +1 -0
- package/dist/web/client/assets/{config-q8JDresK.js → config-xrXoDEWM.js} +1 -1
- package/dist/web/client/assets/{context-CBucAoi6.js → context-ZWqx3uiC.js} +1 -1
- package/dist/web/client/assets/inbox-BoIvl9ZF.js +1 -0
- package/dist/web/client/assets/{index-DUXAevpZ.js → index-nb2MV8X1.js} +3 -3
- package/dist/web/client/assets/learning-6_oYn1l7.js +1 -0
- package/dist/web/client/assets/{login-CNAV9Wer.js → login-DM1ytxQL.js} +1 -1
- package/dist/web/client/assets/{mcp-BKdEFwHO.js → mcp-CetZbyUh.js} +1 -1
- package/dist/web/client/assets/{members-BDqZQh26.js → members-DdqWtwZd.js} +1 -1
- package/dist/web/client/assets/{memory-DVdEVr6L.js → memory-FNrxFHmC.js} +1 -1
- package/dist/web/client/assets/plus-C3GroITC.js +1 -0
- package/dist/web/client/assets/{policy-DdDctqvg.js → policy-BKPejYRI.js} +1 -1
- package/dist/web/client/assets/{routes-BEfALSZv.js → routes-CH1ZTTo-.js} +1 -1
- package/dist/web/client/assets/{services-DZP2ybzb.js → services-zk9SqN06.js} +1 -1
- package/dist/web/client/assets/{skills-DoeIjITs.js → skills-tXDpomHW.js} +1 -1
- package/dist/web/client/assets/styles-DMltY3su.css +2 -0
- package/dist/web/client/assets/{teams-W3j-UoJ9.js → teams-BZYjekBN.js} +1 -1
- package/dist/web/client/assets/{teams-DlHRnrQw.js → teams-D1c8zlxs.js} +1 -1
- package/dist/web/client/assets/{telegram-2OdeGv4E.js → telegram-DCe1CWMt.js} +1 -1
- package/dist/web/client/assets/{tokens-MuBfmgue.js → tokens-DAPjRS0N.js} +1 -1
- package/dist/web/client/assets/triggers-D8R-5guA.js +1 -0
- package/dist/web/client/assets/{welcome-CvNr5IMi.js → welcome-CuK0shDJ.js} +1 -1
- package/dist/web/server/assets/{AgentTabs-DoMDJBXH.js → AgentTabs-aXdsiiMp.js} +5 -0
- package/dist/web/server/assets/{_id-Cg7x6q3g.js → _id-BHYLL8M-.js} +2 -2
- package/dist/web/server/assets/{_id-DqON-59C.js → _id-FcHdSocl.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-BXauUXg6.js → _tanstack-start-manifest_v-fLsYERQ-.js} +76 -53
- package/dist/web/server/assets/attention-BW_6ddkj.js +11 -0
- package/dist/web/server/assets/attention-BxkTf337.js +14 -0
- package/dist/web/server/assets/attention-CM-Ks1N9.js +19 -0
- package/dist/web/server/assets/attention-w21GQIGH.js +264 -0
- package/dist/web/server/assets/{inbox-CUIyf9MT.js → inbox-BLUzA5sQ.js} +40 -3
- package/dist/web/server/assets/{inbox-B3-TRsNI.js → inbox-CzlKT9Wg.js} +5 -3
- package/dist/web/server/assets/{inbox-BardsGyy.js → inbox-ZvDNAjaM.js} +1 -1
- package/dist/web/server/assets/learning-8zav4pIT.js +33 -0
- package/dist/web/server/assets/learning-B7PBkvER.js +16 -0
- package/dist/web/server/assets/learning-Cq7K2heb.js +312 -0
- package/dist/web/server/assets/{router-C5_NjTsP.js → router-CQuj7553.js} +80 -47
- package/dist/web/server/assets/{triggers-CBl4yMyw.js → triggers-BZPl5CHs.js} +1 -1
- package/dist/web/server/assets/{triggers-_3rdhwSN.js → triggers-CSNNzRIi.js} +2 -2
- package/dist/web/server/server.js +11 -3
- package/dist/worker.js +166 -36
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/AgentTabs-B3hq5a3e.js +0 -1
- package/dist/web/client/assets/chevron-down-BK6NPMMP.js +0 -1
- package/dist/web/client/assets/inbox-BwoRikj1.js +0 -1
- package/dist/web/client/assets/plus-b4yFXP0O.js +0 -1
- package/dist/web/client/assets/styles-BYM0UGdF.css +0 -2
- package/dist/web/client/assets/triggers-CX7RMQFQ.js +0 -1
package/dist/daemon.js
CHANGED
|
@@ -135,10 +135,10 @@ var require_isexe = __commonJS({
|
|
|
135
135
|
if (typeof Promise !== "function") {
|
|
136
136
|
throw new TypeError("callback not provided");
|
|
137
137
|
}
|
|
138
|
-
return new Promise(function(resolve7,
|
|
138
|
+
return new Promise(function(resolve7, reject2) {
|
|
139
139
|
isexe(path, options || {}, function(er, is) {
|
|
140
140
|
if (er) {
|
|
141
|
-
|
|
141
|
+
reject2(er);
|
|
142
142
|
} else {
|
|
143
143
|
resolve7(is);
|
|
144
144
|
}
|
|
@@ -207,16 +207,16 @@ var require_which = __commonJS({
|
|
|
207
207
|
opt = {};
|
|
208
208
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
209
209
|
const found = [];
|
|
210
|
-
const step = (i) => new Promise((resolve7,
|
|
210
|
+
const step = (i) => new Promise((resolve7, reject2) => {
|
|
211
211
|
if (i === pathEnv.length)
|
|
212
|
-
return opt.all && found.length ? resolve7(found) :
|
|
212
|
+
return opt.all && found.length ? resolve7(found) : reject2(getNotFoundError(cmd));
|
|
213
213
|
const ppRaw = pathEnv[i];
|
|
214
214
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
215
215
|
const pCmd = path.join(pathPart, cmd);
|
|
216
216
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
217
217
|
resolve7(subStep(p, i, 0));
|
|
218
218
|
});
|
|
219
|
-
const subStep = (p, i, ii) => new Promise((resolve7,
|
|
219
|
+
const subStep = (p, i, ii) => new Promise((resolve7, reject2) => {
|
|
220
220
|
if (ii === pathExt.length)
|
|
221
221
|
return resolve7(step(i + 1));
|
|
222
222
|
const ext = pathExt[ii];
|
|
@@ -7796,7 +7796,7 @@ var init_stdio2 = __esm({
|
|
|
7796
7796
|
if (this._process) {
|
|
7797
7797
|
throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
|
|
7798
7798
|
}
|
|
7799
|
-
return new Promise((resolve7,
|
|
7799
|
+
return new Promise((resolve7, reject2) => {
|
|
7800
7800
|
this._process = (0, import_cross_spawn.default)(this._serverParams.command, this._serverParams.args ?? [], {
|
|
7801
7801
|
// merge default env with server env because mcp server needs some env vars
|
|
7802
7802
|
env: {
|
|
@@ -7809,7 +7809,7 @@ var init_stdio2 = __esm({
|
|
|
7809
7809
|
cwd: this._serverParams.cwd
|
|
7810
7810
|
});
|
|
7811
7811
|
this._process.on("error", (error2) => {
|
|
7812
|
-
|
|
7812
|
+
reject2(error2);
|
|
7813
7813
|
this.onerror?.(error2);
|
|
7814
7814
|
});
|
|
7815
7815
|
this._process.on("spawn", () => {
|
|
@@ -9803,7 +9803,7 @@ var init_sse = __esm({
|
|
|
9803
9803
|
}
|
|
9804
9804
|
_startOrAuth() {
|
|
9805
9805
|
const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
|
|
9806
|
-
return new Promise((resolve7,
|
|
9806
|
+
return new Promise((resolve7, reject2) => {
|
|
9807
9807
|
this._eventSource = new EventSource(this._url.href, {
|
|
9808
9808
|
...this._eventSourceInit,
|
|
9809
9809
|
fetch: async (url2, init) => {
|
|
@@ -9824,11 +9824,11 @@ var init_sse = __esm({
|
|
|
9824
9824
|
this._abortController = new AbortController();
|
|
9825
9825
|
this._eventSource.onerror = (event2) => {
|
|
9826
9826
|
if (event2.code === 401 && this._authProvider) {
|
|
9827
|
-
this._authThenStart().then(resolve7,
|
|
9827
|
+
this._authThenStart().then(resolve7, reject2);
|
|
9828
9828
|
return;
|
|
9829
9829
|
}
|
|
9830
9830
|
const error2 = new SseError(event2.code, event2.message, event2);
|
|
9831
|
-
|
|
9831
|
+
reject2(error2);
|
|
9832
9832
|
this.onerror?.(error2);
|
|
9833
9833
|
};
|
|
9834
9834
|
this._eventSource.onopen = () => {
|
|
@@ -9841,7 +9841,7 @@ var init_sse = __esm({
|
|
|
9841
9841
|
throw new Error(`Endpoint origin does not match connection origin: ${this._endpoint.origin}`);
|
|
9842
9842
|
}
|
|
9843
9843
|
} catch (error2) {
|
|
9844
|
-
|
|
9844
|
+
reject2(error2);
|
|
9845
9845
|
this.onerror?.(error2);
|
|
9846
9846
|
void this.close();
|
|
9847
9847
|
return;
|
|
@@ -11033,9 +11033,9 @@ var init_protocol = __esm({
|
|
|
11033
11033
|
*/
|
|
11034
11034
|
request(request2, resultSchema, options) {
|
|
11035
11035
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
11036
|
-
return new Promise((resolve7,
|
|
11036
|
+
return new Promise((resolve7, reject2) => {
|
|
11037
11037
|
const earlyReject = (error2) => {
|
|
11038
|
-
|
|
11038
|
+
reject2(error2);
|
|
11039
11039
|
};
|
|
11040
11040
|
if (!this._transport) {
|
|
11041
11041
|
earlyReject(new Error("Not connected"));
|
|
@@ -11084,7 +11084,7 @@ var init_protocol = __esm({
|
|
|
11084
11084
|
}
|
|
11085
11085
|
};
|
|
11086
11086
|
}
|
|
11087
|
-
const
|
|
11087
|
+
const cancel2 = (reason) => {
|
|
11088
11088
|
this._responseHandlers.delete(messageId);
|
|
11089
11089
|
this._progressHandlers.delete(messageId);
|
|
11090
11090
|
this._cleanupTimeout(messageId);
|
|
@@ -11097,31 +11097,31 @@ var init_protocol = __esm({
|
|
|
11097
11097
|
}
|
|
11098
11098
|
}, { relatedRequestId, resumptionToken, onresumptiontoken }).catch((error3) => this._onerror(new Error(`Failed to send cancellation: ${error3}`)));
|
|
11099
11099
|
const error2 = reason instanceof McpError ? reason : new McpError(ErrorCode.RequestTimeout, String(reason));
|
|
11100
|
-
|
|
11100
|
+
reject2(error2);
|
|
11101
11101
|
};
|
|
11102
11102
|
this._responseHandlers.set(messageId, (response) => {
|
|
11103
11103
|
if (options?.signal?.aborted) {
|
|
11104
11104
|
return;
|
|
11105
11105
|
}
|
|
11106
11106
|
if (response instanceof Error) {
|
|
11107
|
-
return
|
|
11107
|
+
return reject2(response);
|
|
11108
11108
|
}
|
|
11109
11109
|
try {
|
|
11110
11110
|
const parseResult = safeParse3(resultSchema, response.result);
|
|
11111
11111
|
if (!parseResult.success) {
|
|
11112
|
-
|
|
11112
|
+
reject2(parseResult.error);
|
|
11113
11113
|
} else {
|
|
11114
11114
|
resolve7(parseResult.data);
|
|
11115
11115
|
}
|
|
11116
11116
|
} catch (error2) {
|
|
11117
|
-
|
|
11117
|
+
reject2(error2);
|
|
11118
11118
|
}
|
|
11119
11119
|
});
|
|
11120
11120
|
options?.signal?.addEventListener("abort", () => {
|
|
11121
|
-
|
|
11121
|
+
cancel2(options?.signal?.reason);
|
|
11122
11122
|
});
|
|
11123
11123
|
const timeout = options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC;
|
|
11124
|
-
const timeoutHandler = () =>
|
|
11124
|
+
const timeoutHandler = () => cancel2(McpError.fromError(ErrorCode.RequestTimeout, "Request timed out", { timeout }));
|
|
11125
11125
|
this._setupTimeout(messageId, timeout, options?.maxTotalTimeout, timeoutHandler, options?.resetTimeoutOnProgress ?? false);
|
|
11126
11126
|
const relatedTaskId = relatedTask?.taskId;
|
|
11127
11127
|
if (relatedTaskId) {
|
|
@@ -11140,12 +11140,12 @@ var init_protocol = __esm({
|
|
|
11140
11140
|
timestamp: Date.now()
|
|
11141
11141
|
}).catch((error2) => {
|
|
11142
11142
|
this._cleanupTimeout(messageId);
|
|
11143
|
-
|
|
11143
|
+
reject2(error2);
|
|
11144
11144
|
});
|
|
11145
11145
|
} else {
|
|
11146
11146
|
this._transport.send(jsonrpcRequest, { relatedRequestId, resumptionToken, onresumptiontoken }).catch((error2) => {
|
|
11147
11147
|
this._cleanupTimeout(messageId);
|
|
11148
|
-
|
|
11148
|
+
reject2(error2);
|
|
11149
11149
|
});
|
|
11150
11150
|
}
|
|
11151
11151
|
});
|
|
@@ -11372,15 +11372,15 @@ var init_protocol = __esm({
|
|
|
11372
11372
|
}
|
|
11373
11373
|
} catch {
|
|
11374
11374
|
}
|
|
11375
|
-
return new Promise((resolve7,
|
|
11375
|
+
return new Promise((resolve7, reject2) => {
|
|
11376
11376
|
if (signal.aborted) {
|
|
11377
|
-
|
|
11377
|
+
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
11378
11378
|
return;
|
|
11379
11379
|
}
|
|
11380
11380
|
const timeoutId = setTimeout(resolve7, interval);
|
|
11381
11381
|
signal.addEventListener("abort", () => {
|
|
11382
11382
|
clearTimeout(timeoutId);
|
|
11383
|
-
|
|
11383
|
+
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
11384
11384
|
}, { once: true });
|
|
11385
11385
|
});
|
|
11386
11386
|
}
|
|
@@ -13655,8 +13655,8 @@ var require_resolve = __commonJS({
|
|
|
13655
13655
|
}
|
|
13656
13656
|
return count2;
|
|
13657
13657
|
}
|
|
13658
|
-
function getFullPath(resolver, id = "",
|
|
13659
|
-
if (
|
|
13658
|
+
function getFullPath(resolver, id = "", normalize2) {
|
|
13659
|
+
if (normalize2 !== false)
|
|
13660
13660
|
id = normalizeId(id);
|
|
13661
13661
|
const p = resolver.parse(id);
|
|
13662
13662
|
return _getFullPath(resolver, p);
|
|
@@ -15052,7 +15052,7 @@ var require_fast_uri = __commonJS({
|
|
|
15052
15052
|
"use strict";
|
|
15053
15053
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
15054
15054
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
15055
|
-
function
|
|
15055
|
+
function normalize2(uri, options) {
|
|
15056
15056
|
if (typeof uri === "string") {
|
|
15057
15057
|
uri = /** @type {T} */
|
|
15058
15058
|
normalizeString(uri, options);
|
|
@@ -15319,7 +15319,7 @@ var require_fast_uri = __commonJS({
|
|
|
15319
15319
|
}
|
|
15320
15320
|
var fastUri = {
|
|
15321
15321
|
SCHEMES,
|
|
15322
|
-
normalize,
|
|
15322
|
+
normalize: normalize2,
|
|
15323
15323
|
resolve: resolve7,
|
|
15324
15324
|
resolveComponent,
|
|
15325
15325
|
equal,
|
|
@@ -19125,7 +19125,7 @@ var init_client2 = __esm({
|
|
|
19125
19125
|
import { serve } from "@hono/node-server";
|
|
19126
19126
|
|
|
19127
19127
|
// ../daemon/src/app.ts
|
|
19128
|
-
import { Hono as
|
|
19128
|
+
import { Hono as Hono17 } from "hono";
|
|
19129
19129
|
|
|
19130
19130
|
// ../daemon/src/lib/middleware-auth.ts
|
|
19131
19131
|
import { getCookie } from "hono/cookie";
|
|
@@ -19154,6 +19154,7 @@ __export(agents_exports, {
|
|
|
19154
19154
|
setModelOverride: () => setModelOverride,
|
|
19155
19155
|
setName: () => setName,
|
|
19156
19156
|
setReasoningLevel: () => setReasoningLevel,
|
|
19157
|
+
setReviewConfig: () => setReviewConfig,
|
|
19157
19158
|
setStatus: () => setStatus,
|
|
19158
19159
|
setTelegramIconEmoji: () => setTelegramIconEmoji,
|
|
19159
19160
|
setTelegramMirrorMode: () => setTelegramMirrorMode,
|
|
@@ -19167,6 +19168,11 @@ function toAgent(r) {
|
|
|
19167
19168
|
name: r.name,
|
|
19168
19169
|
modelOverride: r.model_override,
|
|
19169
19170
|
reasoningLevel: r.reasoning_level,
|
|
19171
|
+
reviewEnabled: r.review_enabled === 1,
|
|
19172
|
+
reviewEveryNTurns: r.review_every_n_turns,
|
|
19173
|
+
reviewModel: r.review_model,
|
|
19174
|
+
reviewReasoningLevel: r.review_reasoning_level,
|
|
19175
|
+
reviewTurnsSinceLast: r.review_turns_since_last,
|
|
19170
19176
|
status: r.status,
|
|
19171
19177
|
dir: r.dir,
|
|
19172
19178
|
teamId: r.team_id,
|
|
@@ -19201,6 +19207,11 @@ function insert(db, a) {
|
|
|
19201
19207
|
telegramTopicId: null,
|
|
19202
19208
|
telegramMirrorMode: mirrorMode,
|
|
19203
19209
|
telegramIconEmoji: null,
|
|
19210
|
+
reviewEnabled: false,
|
|
19211
|
+
reviewEveryNTurns: 8,
|
|
19212
|
+
reviewModel: null,
|
|
19213
|
+
reviewReasoningLevel: "low",
|
|
19214
|
+
reviewTurnsSinceLast: 0,
|
|
19204
19215
|
createdAt: now,
|
|
19205
19216
|
archivedAt: null
|
|
19206
19217
|
};
|
|
@@ -19211,6 +19222,13 @@ function setReasoningLevel(db, id, level) {
|
|
|
19211
19222
|
function setModelOverride(db, id, model) {
|
|
19212
19223
|
db.raw.run("UPDATE agents SET model_override = ? WHERE id = ?", [model, id]);
|
|
19213
19224
|
}
|
|
19225
|
+
function setReviewConfig(db, id, config2) {
|
|
19226
|
+
db.raw.run(
|
|
19227
|
+
`UPDATE agents SET review_enabled = ?, review_every_n_turns = ?, review_model = ?,
|
|
19228
|
+
review_reasoning_level = ? WHERE id = ?`,
|
|
19229
|
+
[config2.enabled ? 1 : 0, config2.everyNTurns, config2.model, config2.reasoningLevel, id]
|
|
19230
|
+
);
|
|
19231
|
+
}
|
|
19214
19232
|
function setName(db, id, name) {
|
|
19215
19233
|
db.raw.run("UPDATE agents SET name = ? WHERE id = ?", [name, id]);
|
|
19216
19234
|
}
|
|
@@ -20025,12 +20043,123 @@ function loadIdentityFromFile(path) {
|
|
|
20025
20043
|
return identityHasValues(parsed) ? parsed : null;
|
|
20026
20044
|
}
|
|
20027
20045
|
|
|
20046
|
+
// ../daemon/src/core/repos/agentLessonProposals.ts
|
|
20047
|
+
var agentLessonProposals_exports = {};
|
|
20048
|
+
__export(agentLessonProposals_exports, {
|
|
20049
|
+
approve: () => approve,
|
|
20050
|
+
get: () => get4,
|
|
20051
|
+
insert: () => insert3,
|
|
20052
|
+
listForAgent: () => listForAgent,
|
|
20053
|
+
listForReview: () => listForReview,
|
|
20054
|
+
reject: () => reject,
|
|
20055
|
+
revoke: () => revoke,
|
|
20056
|
+
updatePending: () => updatePending
|
|
20057
|
+
});
|
|
20058
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
20059
|
+
function toProposal(row) {
|
|
20060
|
+
return {
|
|
20061
|
+
id: row.id,
|
|
20062
|
+
reviewId: row.review_id,
|
|
20063
|
+
agentId: row.agent_id,
|
|
20064
|
+
scope: row.scope,
|
|
20065
|
+
text: row.text,
|
|
20066
|
+
evidence: JSON.parse(row.evidence_json),
|
|
20067
|
+
status: row.status,
|
|
20068
|
+
version: row.version,
|
|
20069
|
+
decidedAt: row.decided_at,
|
|
20070
|
+
revokedAt: row.revoked_at,
|
|
20071
|
+
appliedKey: row.applied_key,
|
|
20072
|
+
createdAt: row.created_at,
|
|
20073
|
+
updatedAt: row.updated_at
|
|
20074
|
+
};
|
|
20075
|
+
}
|
|
20076
|
+
function insert3(db, input) {
|
|
20077
|
+
const now = input.now ?? Date.now();
|
|
20078
|
+
const id = randomUUID2();
|
|
20079
|
+
db.raw.run(
|
|
20080
|
+
`INSERT INTO agent_lesson_proposals
|
|
20081
|
+
(id, review_id, agent_id, scope, text, evidence_json, status, version, created_at, updated_at)
|
|
20082
|
+
VALUES (?, ?, ?, ?, ?, ?, 'pending', 1, ?, ?)`,
|
|
20083
|
+
[
|
|
20084
|
+
id,
|
|
20085
|
+
input.reviewId,
|
|
20086
|
+
input.agentId,
|
|
20087
|
+
input.scope,
|
|
20088
|
+
input.text.trim(),
|
|
20089
|
+
JSON.stringify(input.evidence),
|
|
20090
|
+
now,
|
|
20091
|
+
now
|
|
20092
|
+
]
|
|
20093
|
+
);
|
|
20094
|
+
const proposal = get4(db, id);
|
|
20095
|
+
if (!proposal) throw new Error("lesson proposal insert failed");
|
|
20096
|
+
return proposal;
|
|
20097
|
+
}
|
|
20098
|
+
function get4(db, id) {
|
|
20099
|
+
const row = db.raw.query("SELECT * FROM agent_lesson_proposals WHERE id = ?").get(id);
|
|
20100
|
+
return row ? toProposal(row) : null;
|
|
20101
|
+
}
|
|
20102
|
+
function listForReview(db, reviewId) {
|
|
20103
|
+
return db.raw.query(
|
|
20104
|
+
"SELECT * FROM agent_lesson_proposals WHERE review_id = ? ORDER BY created_at ASC"
|
|
20105
|
+
).all(reviewId).map(toProposal);
|
|
20106
|
+
}
|
|
20107
|
+
function listForAgent(db, agentId, options = {}) {
|
|
20108
|
+
const limit = options.limit ?? 100;
|
|
20109
|
+
const rows = options.status ? db.raw.query(
|
|
20110
|
+
`SELECT * FROM agent_lesson_proposals WHERE agent_id = ? AND status = ?
|
|
20111
|
+
ORDER BY created_at DESC LIMIT ?`
|
|
20112
|
+
).all(agentId, options.status, limit) : db.raw.query(
|
|
20113
|
+
`SELECT * FROM agent_lesson_proposals WHERE agent_id = ?
|
|
20114
|
+
ORDER BY created_at DESC LIMIT ?`
|
|
20115
|
+
).all(agentId, limit);
|
|
20116
|
+
return rows.map(toProposal);
|
|
20117
|
+
}
|
|
20118
|
+
function changedProposal(db, id, changes) {
|
|
20119
|
+
return changes === 1 ? get4(db, id) : null;
|
|
20120
|
+
}
|
|
20121
|
+
function updatePending(db, id, version2, input, now = Date.now()) {
|
|
20122
|
+
const result = db.raw.run(
|
|
20123
|
+
`UPDATE agent_lesson_proposals SET text = ?, scope = ?, version = version + 1, updated_at = ?
|
|
20124
|
+
WHERE id = ? AND version = ? AND status = 'pending'`,
|
|
20125
|
+
[input.text.trim(), input.scope, now, id, version2]
|
|
20126
|
+
);
|
|
20127
|
+
return changedProposal(db, id, Number(result.changes));
|
|
20128
|
+
}
|
|
20129
|
+
function approve(db, id, version2, appliedKey, now = Date.now()) {
|
|
20130
|
+
const result = db.raw.run(
|
|
20131
|
+
`UPDATE agent_lesson_proposals SET status = 'approved', applied_key = ?, decided_at = ?,
|
|
20132
|
+
version = version + 1, updated_at = ?
|
|
20133
|
+
WHERE id = ? AND version = ? AND status = 'pending'`,
|
|
20134
|
+
[appliedKey, now, now, id, version2]
|
|
20135
|
+
);
|
|
20136
|
+
return changedProposal(db, id, Number(result.changes));
|
|
20137
|
+
}
|
|
20138
|
+
function reject(db, id, version2, now = Date.now()) {
|
|
20139
|
+
const result = db.raw.run(
|
|
20140
|
+
`UPDATE agent_lesson_proposals SET status = 'rejected', decided_at = ?,
|
|
20141
|
+
version = version + 1, updated_at = ?
|
|
20142
|
+
WHERE id = ? AND version = ? AND status = 'pending'`,
|
|
20143
|
+
[now, now, id, version2]
|
|
20144
|
+
);
|
|
20145
|
+
return changedProposal(db, id, Number(result.changes));
|
|
20146
|
+
}
|
|
20147
|
+
function revoke(db, id, version2, now = Date.now()) {
|
|
20148
|
+
const result = db.raw.run(
|
|
20149
|
+
`UPDATE agent_lesson_proposals SET status = 'revoked', revoked_at = ?,
|
|
20150
|
+
version = version + 1, updated_at = ?
|
|
20151
|
+
WHERE id = ? AND version = ? AND status = 'approved'`,
|
|
20152
|
+
[now, now, id, version2]
|
|
20153
|
+
);
|
|
20154
|
+
return changedProposal(db, id, Number(result.changes));
|
|
20155
|
+
}
|
|
20156
|
+
|
|
20028
20157
|
// ../daemon/src/core/repos/profiles.ts
|
|
20029
20158
|
var profiles_exports = {};
|
|
20030
20159
|
__export(profiles_exports, {
|
|
20031
|
-
get: () =>
|
|
20160
|
+
get: () => get5,
|
|
20032
20161
|
getDefaultSkills: () => getDefaultSkills,
|
|
20033
|
-
insert: () =>
|
|
20162
|
+
insert: () => insert4,
|
|
20034
20163
|
list: () => list3,
|
|
20035
20164
|
remove: () => remove3,
|
|
20036
20165
|
setDefaultSkills: () => setDefaultSkills,
|
|
@@ -20047,7 +20176,7 @@ function toProfile(r) {
|
|
|
20047
20176
|
updatedAt: r.updated_at
|
|
20048
20177
|
};
|
|
20049
20178
|
}
|
|
20050
|
-
function
|
|
20179
|
+
function insert4(db, p) {
|
|
20051
20180
|
const now = Date.now();
|
|
20052
20181
|
db.raw.run(
|
|
20053
20182
|
`INSERT INTO profiles (id, name, dir, default_model, skills_mode, created_at, updated_at)
|
|
@@ -20056,7 +20185,7 @@ function insert3(db, p) {
|
|
|
20056
20185
|
);
|
|
20057
20186
|
return { ...p, createdAt: now, updatedAt: now };
|
|
20058
20187
|
}
|
|
20059
|
-
function
|
|
20188
|
+
function get5(db, id) {
|
|
20060
20189
|
const row = db.raw.query("SELECT * FROM profiles WHERE id = ?").get(id);
|
|
20061
20190
|
return row ? toProfile(row) : null;
|
|
20062
20191
|
}
|
|
@@ -20095,7 +20224,7 @@ function resolveAgent(db, paths, agentId) {
|
|
|
20095
20224
|
const agent = get(db, agentId);
|
|
20096
20225
|
if (!agent) throw new Error(`agent not found: ${agentId}`);
|
|
20097
20226
|
agent.identity = loadIdentityFromFile(join2(agent.dir, "IDENTITY.md"));
|
|
20098
|
-
const profile =
|
|
20227
|
+
const profile = get5(db, agent.profileId);
|
|
20099
20228
|
if (!profile) {
|
|
20100
20229
|
throw new Error(`profile not found for agent ${agentId}: ${agent.profileId}`);
|
|
20101
20230
|
}
|
|
@@ -20109,12 +20238,13 @@ function resolveAgent(db, paths, agentId) {
|
|
|
20109
20238
|
model: agent.modelOverride ?? profile.defaultModel,
|
|
20110
20239
|
reasoningLevel: agent.reasoningLevel,
|
|
20111
20240
|
team,
|
|
20112
|
-
skills: listAttachedSkills(db, agentId)
|
|
20241
|
+
skills: listAttachedSkills(db, agentId),
|
|
20242
|
+
privateLessons: listForAgent(db, agent.id, { status: "approved", limit: 100 }).filter((proposal) => proposal.scope === "private").map((proposal) => proposal.text)
|
|
20113
20243
|
};
|
|
20114
20244
|
}
|
|
20115
20245
|
|
|
20116
20246
|
// ../daemon/src/core/agent/spawn.ts
|
|
20117
|
-
import { randomUUID as
|
|
20247
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
20118
20248
|
import { mkdirSync as mkdirSync3, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
20119
20249
|
import { join as join7 } from "path";
|
|
20120
20250
|
|
|
@@ -20125,10 +20255,10 @@ import { join as join3 } from "path";
|
|
|
20125
20255
|
// ../daemon/src/core/repos/profileCommunicationDefaults.ts
|
|
20126
20256
|
var profileCommunicationDefaults_exports = {};
|
|
20127
20257
|
__export(profileCommunicationDefaults_exports, {
|
|
20128
|
-
get: () =>
|
|
20258
|
+
get: () => get6,
|
|
20129
20259
|
set: () => set
|
|
20130
20260
|
});
|
|
20131
|
-
function
|
|
20261
|
+
function get6(db, profileId) {
|
|
20132
20262
|
const row = db.raw.query(
|
|
20133
20263
|
`SELECT user_input, user_output, outside_team_input, outside_team_output, peer_default
|
|
20134
20264
|
FROM profile_communication_defaults WHERE profile_id = ?`
|
|
@@ -20174,7 +20304,7 @@ function readOptional(path) {
|
|
|
20174
20304
|
return existsSync2(path) ? readFileSync3(path, "utf8") : null;
|
|
20175
20305
|
}
|
|
20176
20306
|
function loadProfile(db, id) {
|
|
20177
|
-
const profile =
|
|
20307
|
+
const profile = get5(db, id);
|
|
20178
20308
|
if (!profile) throw new Error(`profile not found: ${id}`);
|
|
20179
20309
|
const soul = readFileSync3(join3(profile.dir, "SOUL.md"), "utf8");
|
|
20180
20310
|
const identityRaw = readFileSync3(join3(profile.dir, "IDENTITY.md"), "utf8");
|
|
@@ -20194,7 +20324,7 @@ function loadProfile(db, id) {
|
|
|
20194
20324
|
tools
|
|
20195
20325
|
},
|
|
20196
20326
|
identity: anyIdentity ? parsedIdentity : null,
|
|
20197
|
-
communicationDefaults:
|
|
20327
|
+
communicationDefaults: get6(db, id)
|
|
20198
20328
|
};
|
|
20199
20329
|
}
|
|
20200
20330
|
|
|
@@ -20376,7 +20506,7 @@ function createProfile(db, paths, input) {
|
|
|
20376
20506
|
};
|
|
20377
20507
|
writeFileSync2(join4(dir, "profile.json"), `${JSON.stringify(profileJson, null, 2)}
|
|
20378
20508
|
`);
|
|
20379
|
-
const profile =
|
|
20509
|
+
const profile = insert4(db, {
|
|
20380
20510
|
id: input.id,
|
|
20381
20511
|
name: profileJson.name,
|
|
20382
20512
|
dir,
|
|
@@ -20422,7 +20552,7 @@ function seedDefaults(db, paths, input) {
|
|
|
20422
20552
|
team = registerTeam(db, { id: DEFAULT_TEAM_ID, name: "Default" }, paths);
|
|
20423
20553
|
teamCreated = true;
|
|
20424
20554
|
}
|
|
20425
|
-
let profile =
|
|
20555
|
+
let profile = get5(db, DEFAULT_PROFILE_ID);
|
|
20426
20556
|
let profileCreated = false;
|
|
20427
20557
|
if (!profile) {
|
|
20428
20558
|
profile = createProfile(db, paths, {
|
|
@@ -20444,7 +20574,7 @@ function seedDefaults(db, paths, input) {
|
|
|
20444
20574
|
}
|
|
20445
20575
|
function ensureSetupSeeded(db, paths) {
|
|
20446
20576
|
if (!isSetupComplete(db)) return null;
|
|
20447
|
-
if (
|
|
20577
|
+
if (get5(db, DEFAULT_PROFILE_ID)) return null;
|
|
20448
20578
|
const first = listAvailableModels(db)[0];
|
|
20449
20579
|
if (!first) return null;
|
|
20450
20580
|
return seedDefaults(db, paths, { model: first.value });
|
|
@@ -20470,7 +20600,7 @@ function discoverSkills(paths) {
|
|
|
20470
20600
|
// ../daemon/src/core/agent/spawn.ts
|
|
20471
20601
|
function spawnAgent(db, paths, input) {
|
|
20472
20602
|
const loaded = loadProfile(db, input.profileId);
|
|
20473
|
-
const id =
|
|
20603
|
+
const id = randomUUID3();
|
|
20474
20604
|
const dir = paths.agentDir(id);
|
|
20475
20605
|
try {
|
|
20476
20606
|
return db.raw.transaction(() => {
|
|
@@ -20557,6 +20687,197 @@ function unarchiveAgent(db, id) {
|
|
|
20557
20687
|
unarchive(db, agent.id);
|
|
20558
20688
|
}
|
|
20559
20689
|
|
|
20690
|
+
// ../daemon/src/core/attention.ts
|
|
20691
|
+
var ATTENTION_KINDS = [
|
|
20692
|
+
"communication_approval",
|
|
20693
|
+
"lesson_proposal",
|
|
20694
|
+
"review_failure",
|
|
20695
|
+
"trigger_failure",
|
|
20696
|
+
"agent_loop_break"
|
|
20697
|
+
];
|
|
20698
|
+
var bounded = (value, fallback) => (value?.trim() || fallback).replace(/(authorization:\s*bearer\s+)[^\s,;]+/gi, "$1[redacted]").replace(/\bsk-[a-z0-9_-]{8,}\b/gi, "[redacted]").replace(/(https?:\/\/)[^\s/@:]+:[^\s/@]+@/gi, "$1[redacted]@").slice(0, 500);
|
|
20699
|
+
var sources = [
|
|
20700
|
+
{
|
|
20701
|
+
kind: "communication_approval",
|
|
20702
|
+
query: (db) => db.raw.query(`SELECT ca.id sourceId, ca.created_at occurredAt, ca.updated_at updatedAt,
|
|
20703
|
+
COALESCE(ca.target_id, ca.source_id) agentId, a.name agentName,
|
|
20704
|
+
COALESCE(ca.target_team_id, ca.source_team_id) teamId, t.name teamName,
|
|
20705
|
+
NULL acknowledged_at
|
|
20706
|
+
FROM communication_approvals ca
|
|
20707
|
+
LEFT JOIN agents a ON a.id = COALESCE(NULLIF(ca.target_id,''), NULLIF(ca.source_id,''))
|
|
20708
|
+
LEFT JOIN teams t ON t.id = COALESCE(ca.target_team_id, ca.source_team_id)
|
|
20709
|
+
WHERE ca.status = 'pending' AND ca.expires_at > CAST(unixepoch('subsec') * 1000 AS INTEGER)`).all().map(
|
|
20710
|
+
(r) => ({
|
|
20711
|
+
...r,
|
|
20712
|
+
kind: "communication_approval",
|
|
20713
|
+
severity: "action_required",
|
|
20714
|
+
title: "Communication approval required",
|
|
20715
|
+
diagnostic: "A policy-protected communication is waiting for an operator decision.",
|
|
20716
|
+
href: "/approvals",
|
|
20717
|
+
acknowledgeable: false
|
|
20718
|
+
})
|
|
20719
|
+
)
|
|
20720
|
+
},
|
|
20721
|
+
{
|
|
20722
|
+
kind: "lesson_proposal",
|
|
20723
|
+
query: (db) => db.raw.query(`SELECT p.id sourceId, p.created_at occurredAt, p.updated_at updatedAt,
|
|
20724
|
+
p.agent_id agentId, a.name agentName, a.team_id teamId, t.name teamName, NULL acknowledged_at
|
|
20725
|
+
FROM agent_lesson_proposals p JOIN agents a ON a.id = p.agent_id
|
|
20726
|
+
JOIN teams t ON t.id = a.team_id
|
|
20727
|
+
WHERE p.status = 'pending'`).all().map(
|
|
20728
|
+
(r) => ({
|
|
20729
|
+
...r,
|
|
20730
|
+
kind: "lesson_proposal",
|
|
20731
|
+
severity: "action_required",
|
|
20732
|
+
title: "Lesson proposal ready",
|
|
20733
|
+
diagnostic: "A reviewed-learning proposal is waiting for approval or rejection.",
|
|
20734
|
+
href: `/agents/${encodeURIComponent(r.agentId ?? "")}/learning`,
|
|
20735
|
+
acknowledgeable: false
|
|
20736
|
+
})
|
|
20737
|
+
)
|
|
20738
|
+
},
|
|
20739
|
+
{
|
|
20740
|
+
kind: "review_failure",
|
|
20741
|
+
query: (db) => db.raw.query(`SELECT r.id sourceId, r.created_at occurredAt, r.updated_at updatedAt,
|
|
20742
|
+
r.agent_id agentId, a.name agentName, a.team_id teamId, t.name teamName,
|
|
20743
|
+
r.status, r.last_error diagnostic, aa.acknowledged_at FROM agent_reviews r
|
|
20744
|
+
JOIN agents a ON a.id = r.agent_id JOIN teams t ON t.id = a.team_id
|
|
20745
|
+
LEFT JOIN attention_acknowledgements aa ON aa.source_kind = 'review_failure' AND aa.source_id = r.id
|
|
20746
|
+
WHERE r.status IN ('failed','cancelled')`).all().map(
|
|
20747
|
+
(r) => ({
|
|
20748
|
+
...r,
|
|
20749
|
+
kind: "review_failure",
|
|
20750
|
+
severity: "error",
|
|
20751
|
+
title: r.status === "cancelled" ? "Agent review cancelled" : "Agent review failed",
|
|
20752
|
+
diagnostic: bounded(r.diagnostic, "The review stopped without completing."),
|
|
20753
|
+
href: `/agents/${encodeURIComponent(r.agentId ?? "")}/learning`,
|
|
20754
|
+
acknowledgeable: true
|
|
20755
|
+
})
|
|
20756
|
+
)
|
|
20757
|
+
},
|
|
20758
|
+
{
|
|
20759
|
+
kind: "trigger_failure",
|
|
20760
|
+
query: (db) => db.raw.query(`SELECT d.id sourceId, d.scheduled_at occurredAt, d.updated_at updatedAt,
|
|
20761
|
+
d.agent_id agentId, a.name agentName, a.team_id teamId, t.name teamName,
|
|
20762
|
+
d.last_error diagnostic, aa.acknowledged_at FROM trigger_dispatches d
|
|
20763
|
+
JOIN agents a ON a.id = d.agent_id JOIN teams t ON t.id = a.team_id
|
|
20764
|
+
LEFT JOIN attention_acknowledgements aa ON aa.source_kind = 'trigger_failure' AND aa.source_id = d.id
|
|
20765
|
+
WHERE d.status = 'failed'`).all().map(
|
|
20766
|
+
(r) => ({
|
|
20767
|
+
...r,
|
|
20768
|
+
kind: "trigger_failure",
|
|
20769
|
+
severity: "error",
|
|
20770
|
+
title: "Scheduled trigger failed",
|
|
20771
|
+
diagnostic: bounded(r.diagnostic, "The scheduled Agent turn exhausted its retries."),
|
|
20772
|
+
href: `/agents/${encodeURIComponent(r.agentId ?? "")}`,
|
|
20773
|
+
acknowledgeable: true
|
|
20774
|
+
})
|
|
20775
|
+
)
|
|
20776
|
+
},
|
|
20777
|
+
{
|
|
20778
|
+
kind: "agent_loop_break",
|
|
20779
|
+
query: (db) => db.raw.query(`SELECT e.id sourceId, e.created_at occurredAt, e.created_at updatedAt,
|
|
20780
|
+
e.from_agent_id agentId, a.name agentName, e.source_team_id teamId, t.name teamName,
|
|
20781
|
+
e.attempted_hop, e.max_hops, aa.acknowledged_at FROM agent_loop_break_events e
|
|
20782
|
+
JOIN agents a ON a.id = e.from_agent_id JOIN teams t ON t.id = e.source_team_id
|
|
20783
|
+
LEFT JOIN attention_acknowledgements aa ON aa.source_kind = 'agent_loop_break' AND aa.source_id = e.id`).all().map(
|
|
20784
|
+
(r) => ({
|
|
20785
|
+
...r,
|
|
20786
|
+
kind: "agent_loop_break",
|
|
20787
|
+
severity: "warning",
|
|
20788
|
+
title: "Agent message loop stopped",
|
|
20789
|
+
diagnostic: `Message chain stopped at hop ${r.attempted_hop} (limit ${r.max_hops}).`,
|
|
20790
|
+
href: `/agents/${encodeURIComponent(r.agentId ?? "")}/inbox`,
|
|
20791
|
+
acknowledgeable: true
|
|
20792
|
+
})
|
|
20793
|
+
)
|
|
20794
|
+
}
|
|
20795
|
+
];
|
|
20796
|
+
function normalize(row) {
|
|
20797
|
+
const { acknowledged_at, ...item } = row;
|
|
20798
|
+
return { ...item, key: `${item.kind}:${item.sourceId}`, acknowledgedAt: acknowledged_at };
|
|
20799
|
+
}
|
|
20800
|
+
function parseAttentionKey(key2) {
|
|
20801
|
+
const at = key2.indexOf(":");
|
|
20802
|
+
const kind = key2.slice(0, at);
|
|
20803
|
+
const sourceId = key2.slice(at + 1);
|
|
20804
|
+
return at > 0 && ATTENTION_KINDS.includes(kind) && sourceId ? { kind, sourceId } : null;
|
|
20805
|
+
}
|
|
20806
|
+
function projectAttention(db, options = {}) {
|
|
20807
|
+
const degraded = [];
|
|
20808
|
+
const items = sources.flatMap((source) => {
|
|
20809
|
+
if (options.kind && source.kind !== options.kind) return [];
|
|
20810
|
+
try {
|
|
20811
|
+
return source.query(db).map(normalize);
|
|
20812
|
+
} catch (error2) {
|
|
20813
|
+
degraded.push({
|
|
20814
|
+
kind: source.kind,
|
|
20815
|
+
error: bounded(error2 instanceof Error ? error2.message : String(error2), "Projection failed")
|
|
20816
|
+
});
|
|
20817
|
+
return [];
|
|
20818
|
+
}
|
|
20819
|
+
});
|
|
20820
|
+
const state3 = options.state ?? "open";
|
|
20821
|
+
return {
|
|
20822
|
+
items: items.filter(
|
|
20823
|
+
(item) => state3 === "all" || (state3 === "acknowledged" ? item.acknowledgedAt !== null : item.acknowledgedAt === null)
|
|
20824
|
+
).sort((a, b2) => b2.updatedAt - a.updatedAt || a.key.localeCompare(b2.key)).slice(0, Math.max(options.limit ?? 100, 1)),
|
|
20825
|
+
degraded
|
|
20826
|
+
};
|
|
20827
|
+
}
|
|
20828
|
+
function attentionSummary(db) {
|
|
20829
|
+
const projected = projectAttention(db, { state: "open", limit: 1e5 });
|
|
20830
|
+
const bySeverity = { action_required: 0, error: 0, warning: 0 };
|
|
20831
|
+
const byKind = Object.fromEntries(ATTENTION_KINDS.map((kind) => [kind, 0]));
|
|
20832
|
+
for (const item of projected.items) {
|
|
20833
|
+
bySeverity[item.severity]++;
|
|
20834
|
+
byKind[item.kind]++;
|
|
20835
|
+
}
|
|
20836
|
+
return { openTotal: projected.items.length, bySeverity, byKind, degraded: projected.degraded };
|
|
20837
|
+
}
|
|
20838
|
+
function acknowledgeAttention(db, key2, acknowledged) {
|
|
20839
|
+
const parsed = parseAttentionKey(key2);
|
|
20840
|
+
if (!parsed) throw new Error("invalid_attention_key");
|
|
20841
|
+
const current = projectAttention(db, {
|
|
20842
|
+
state: "all",
|
|
20843
|
+
kind: parsed.kind,
|
|
20844
|
+
limit: 1e5
|
|
20845
|
+
}).items.find((item) => item.sourceId === parsed.sourceId);
|
|
20846
|
+
if (!current) throw new Error("attention_source_not_found");
|
|
20847
|
+
if (!current.acknowledgeable) throw new Error("attention_action_required");
|
|
20848
|
+
if (acknowledged)
|
|
20849
|
+
db.raw.run(
|
|
20850
|
+
`INSERT INTO attention_acknowledgements (source_kind, source_id, acknowledged_at) VALUES (?, ?, ?) ON CONFLICT(source_kind, source_id) DO NOTHING`,
|
|
20851
|
+
[parsed.kind, parsed.sourceId, Date.now()]
|
|
20852
|
+
);
|
|
20853
|
+
else
|
|
20854
|
+
db.raw.run("DELETE FROM attention_acknowledgements WHERE source_kind = ? AND source_id = ?", [
|
|
20855
|
+
parsed.kind,
|
|
20856
|
+
parsed.sourceId
|
|
20857
|
+
]);
|
|
20858
|
+
const updated = projectAttention(db, {
|
|
20859
|
+
state: "all",
|
|
20860
|
+
kind: parsed.kind,
|
|
20861
|
+
limit: 1e5
|
|
20862
|
+
}).items.find((item) => item.sourceId === parsed.sourceId);
|
|
20863
|
+
if (!updated) throw new Error("attention_source_not_found");
|
|
20864
|
+
return updated;
|
|
20865
|
+
}
|
|
20866
|
+
function acknowledgeAllAttention(db) {
|
|
20867
|
+
return db.raw.transaction(() => {
|
|
20868
|
+
const items = projectAttention(db, { state: "open", limit: 1e5 }).items.filter(
|
|
20869
|
+
(item) => item.acknowledgeable
|
|
20870
|
+
);
|
|
20871
|
+
const now = Date.now();
|
|
20872
|
+
for (const item of items)
|
|
20873
|
+
db.raw.run(
|
|
20874
|
+
`INSERT INTO attention_acknowledgements (source_kind, source_id, acknowledged_at) VALUES (?, ?, ?) ON CONFLICT(source_kind, source_id) DO NOTHING`,
|
|
20875
|
+
[item.kind, item.sourceId, now]
|
|
20876
|
+
);
|
|
20877
|
+
return items.length;
|
|
20878
|
+
})();
|
|
20879
|
+
}
|
|
20880
|
+
|
|
20560
20881
|
// ../daemon/src/core/db/client.ts
|
|
20561
20882
|
import { backup, DatabaseSync } from "node:sqlite";
|
|
20562
20883
|
function wrap(rawDb) {
|
|
@@ -20717,7 +21038,7 @@ __export(teamTemplates_exports, {
|
|
|
20717
21038
|
detail: () => detail2,
|
|
20718
21039
|
edges: () => edges2,
|
|
20719
21040
|
findReferencingProfile: () => findReferencingProfile,
|
|
20720
|
-
get: () =>
|
|
21041
|
+
get: () => get7,
|
|
20721
21042
|
insertCanonical: () => insertCanonical,
|
|
20722
21043
|
insertCanonicalDefinition: () => insertCanonicalDefinition,
|
|
20723
21044
|
list: () => list5,
|
|
@@ -20728,7 +21049,7 @@ __export(teamTemplates_exports, {
|
|
|
20728
21049
|
slots: () => slots,
|
|
20729
21050
|
updateCanonicalMetadata: () => updateCanonicalMetadata
|
|
20730
21051
|
});
|
|
20731
|
-
import { randomUUID as
|
|
21052
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
20732
21053
|
function toTemplate(row) {
|
|
20733
21054
|
return {
|
|
20734
21055
|
id: row.id,
|
|
@@ -20764,7 +21085,7 @@ function toEdge(row) {
|
|
|
20764
21085
|
posture: row.posture
|
|
20765
21086
|
};
|
|
20766
21087
|
}
|
|
20767
|
-
function
|
|
21088
|
+
function get7(db, id) {
|
|
20768
21089
|
const row = db.raw.query("SELECT * FROM team_templates WHERE id = ?").get(id);
|
|
20769
21090
|
return row ? toTemplate(row) : null;
|
|
20770
21091
|
}
|
|
@@ -20772,7 +21093,7 @@ function list5(db) {
|
|
|
20772
21093
|
return db.raw.query("SELECT * FROM team_templates ORDER BY created_at ASC").all().map(toTemplate);
|
|
20773
21094
|
}
|
|
20774
21095
|
function detail2(db, id) {
|
|
20775
|
-
const template =
|
|
21096
|
+
const template = get7(db, id);
|
|
20776
21097
|
if (!template) return null;
|
|
20777
21098
|
const currentSnapshot = revision(db, id, template.currentRevision);
|
|
20778
21099
|
if (!currentSnapshot)
|
|
@@ -20872,7 +21193,7 @@ function replaceCanonicalDefinition(db, templateId, input) {
|
|
|
20872
21193
|
if (resolvedRefs.has(reference)) {
|
|
20873
21194
|
throw new Error(`invalid_template_definition: duplicate slot reference ${reference}`);
|
|
20874
21195
|
}
|
|
20875
|
-
resolvedRefs.set(reference, value.slotId ??
|
|
21196
|
+
resolvedRefs.set(reference, value.slotId ?? randomUUID4());
|
|
20876
21197
|
}
|
|
20877
21198
|
const resolvedEdges = input.edges.map((edge) => ({
|
|
20878
21199
|
...edge,
|
|
@@ -20881,7 +21202,7 @@ function replaceCanonicalDefinition(db, templateId, input) {
|
|
|
20881
21202
|
}));
|
|
20882
21203
|
const resolvedSlots = input.slots.map((slot) => ({
|
|
20883
21204
|
...slot,
|
|
20884
|
-
slotId: slot.slotId ?? (slot.clientKey ? resolvedRefs.get(slot.clientKey) :
|
|
21205
|
+
slotId: slot.slotId ?? (slot.clientKey ? resolvedRefs.get(slot.clientKey) : randomUUID4())
|
|
20885
21206
|
}));
|
|
20886
21207
|
validateCanonicalDefinition(resolvedSlots, resolvedEdges);
|
|
20887
21208
|
const now = Date.now();
|
|
@@ -20893,7 +21214,7 @@ function replaceCanonicalDefinition(db, templateId, input) {
|
|
|
20893
21214
|
for (let position = 0; position < resolvedSlots.length; position++) {
|
|
20894
21215
|
const value = resolvedSlots[position];
|
|
20895
21216
|
if (!value) continue;
|
|
20896
|
-
const slotId = value.slotId ??
|
|
21217
|
+
const slotId = value.slotId ?? randomUUID4();
|
|
20897
21218
|
if (activeIds.has(slotId))
|
|
20898
21219
|
throw new Error(`invalid_template_definition: duplicate slot ${slotId}`);
|
|
20899
21220
|
activeIds.add(slotId);
|
|
@@ -20958,7 +21279,7 @@ function cloneCanonical(db, sourceId, input) {
|
|
|
20958
21279
|
const snapshot = revision(db, sourceId, input.expectedRevision);
|
|
20959
21280
|
if (!snapshot)
|
|
20960
21281
|
throw new Error(`template_snapshot_missing: ${sourceId}@${input.expectedRevision}`);
|
|
20961
|
-
const translated = new Map(snapshot.slots.map((slot) => [slot.slotId,
|
|
21282
|
+
const translated = new Map(snapshot.slots.map((slot) => [slot.slotId, randomUUID4()]));
|
|
20962
21283
|
return insertCanonicalDefinition(db, {
|
|
20963
21284
|
id: input.id,
|
|
20964
21285
|
name: input.name ?? `${source.name} copy`,
|
|
@@ -21044,7 +21365,7 @@ function revision(db, templateId, revisionNumber) {
|
|
|
21044
21365
|
};
|
|
21045
21366
|
}
|
|
21046
21367
|
function snapshotCurrent(db, templateId, revisionNumber, now) {
|
|
21047
|
-
const template =
|
|
21368
|
+
const template = get7(db, templateId);
|
|
21048
21369
|
if (!template) throw new Error(`team template not found: ${templateId}`);
|
|
21049
21370
|
db.raw.run(
|
|
21050
21371
|
`INSERT INTO team_template_revisions (template_id, revision, name, user_md, created_at)
|
|
@@ -21066,7 +21387,7 @@ function snapshotCurrent(db, templateId, revisionNumber, now) {
|
|
|
21066
21387
|
);
|
|
21067
21388
|
}
|
|
21068
21389
|
function pruneRevision(db, templateId, revisionNumber) {
|
|
21069
|
-
const template =
|
|
21390
|
+
const template = get7(db, templateId);
|
|
21070
21391
|
if (!template) throw new Error(`team template not found: ${templateId}`);
|
|
21071
21392
|
if (template.currentRevision === revisionNumber) {
|
|
21072
21393
|
throw new Error(`template_revision_in_use: revision ${revisionNumber} is current`);
|
|
@@ -21101,7 +21422,7 @@ function requireDetail2(db, id) {
|
|
|
21101
21422
|
return found;
|
|
21102
21423
|
}
|
|
21103
21424
|
function requireMutable(db, id) {
|
|
21104
|
-
const template =
|
|
21425
|
+
const template = get7(db, id);
|
|
21105
21426
|
if (!template) throw new Error(`team template not found: ${id}`);
|
|
21106
21427
|
if (template.deletedAt !== null) throw new Error(`template_deleted: ${id}`);
|
|
21107
21428
|
return template;
|
|
@@ -21170,7 +21491,7 @@ function insertTemplateEdge(db, templateId, edge) {
|
|
|
21170
21491
|
|
|
21171
21492
|
// ../daemon/src/core/profile/delete.ts
|
|
21172
21493
|
function deleteProfile(db, id) {
|
|
21173
|
-
const profile =
|
|
21494
|
+
const profile = get5(db, id);
|
|
21174
21495
|
if (!profile) throw new Error(`profile not found: ${id}`);
|
|
21175
21496
|
const agents = list(db, { includeArchived: true }).filter((a) => a.profileId === id);
|
|
21176
21497
|
if (agents.length > 0) {
|
|
@@ -21196,7 +21517,7 @@ function deleteProfile(db, id) {
|
|
|
21196
21517
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
21197
21518
|
import { join as join10 } from "path";
|
|
21198
21519
|
function updateProfile(db, paths, id, input) {
|
|
21199
|
-
const existing =
|
|
21520
|
+
const existing = get5(db, id);
|
|
21200
21521
|
if (!existing) throw new Error(`profile not found: ${id}`);
|
|
21201
21522
|
const nextSkillsMode = input.skillsMode ?? existing.skillsMode;
|
|
21202
21523
|
const next = {
|
|
@@ -21223,14 +21544,197 @@ function updateProfile(db, paths, id, input) {
|
|
|
21223
21544
|
`${JSON.stringify(profileJson, null, 2)}
|
|
21224
21545
|
`
|
|
21225
21546
|
);
|
|
21226
|
-
const updated =
|
|
21547
|
+
const updated = get5(db, id);
|
|
21227
21548
|
if (!updated) throw new Error(`profile vanished after update: ${id}`);
|
|
21228
21549
|
return {
|
|
21229
21550
|
...updated,
|
|
21230
|
-
communicationDefaults:
|
|
21551
|
+
communicationDefaults: get6(db, id)
|
|
21231
21552
|
};
|
|
21232
21553
|
}
|
|
21233
21554
|
|
|
21555
|
+
// ../daemon/src/core/repos/agentReviews.ts
|
|
21556
|
+
var agentReviews_exports = {};
|
|
21557
|
+
__export(agentReviews_exports, {
|
|
21558
|
+
cancel: () => cancel,
|
|
21559
|
+
claim: () => claim,
|
|
21560
|
+
complete: () => complete,
|
|
21561
|
+
defer: () => defer,
|
|
21562
|
+
enqueueManual: () => enqueueManual,
|
|
21563
|
+
fail: () => fail,
|
|
21564
|
+
get: () => get8,
|
|
21565
|
+
getLatestCompleted: () => getLatestCompleted,
|
|
21566
|
+
getOpenForAgent: () => getOpenForAgent,
|
|
21567
|
+
listClaimable: () => listClaimable,
|
|
21568
|
+
listForAgent: () => listForAgent2,
|
|
21569
|
+
recordSuccessfulUserTurn: () => recordSuccessfulUserTurn,
|
|
21570
|
+
setSource: () => setSource
|
|
21571
|
+
});
|
|
21572
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
21573
|
+
function toReview(row) {
|
|
21574
|
+
return {
|
|
21575
|
+
id: row.id,
|
|
21576
|
+
agentId: row.agent_id,
|
|
21577
|
+
status: row.status,
|
|
21578
|
+
trigger: row.trigger_kind,
|
|
21579
|
+
sourceSessionId: row.source_session_id,
|
|
21580
|
+
sourceStartOrdinal: row.source_start_ordinal,
|
|
21581
|
+
sourceEndOrdinal: row.source_end_ordinal,
|
|
21582
|
+
inputCharacters: row.input_characters,
|
|
21583
|
+
turnsReviewed: row.turns_reviewed,
|
|
21584
|
+
proposalCount: row.proposal_count,
|
|
21585
|
+
attemptCount: row.attempt_count,
|
|
21586
|
+
nextAttemptAt: row.next_attempt_at,
|
|
21587
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
21588
|
+
startedAt: row.started_at,
|
|
21589
|
+
finishedAt: row.finished_at,
|
|
21590
|
+
lastError: row.last_error,
|
|
21591
|
+
createdAt: row.created_at,
|
|
21592
|
+
updatedAt: row.updated_at
|
|
21593
|
+
};
|
|
21594
|
+
}
|
|
21595
|
+
function insert5(db, agentId, trigger, now) {
|
|
21596
|
+
const id = randomUUID5();
|
|
21597
|
+
db.raw.run(
|
|
21598
|
+
`INSERT INTO agent_reviews
|
|
21599
|
+
(id, agent_id, status, trigger_kind, input_characters, turns_reviewed,
|
|
21600
|
+
proposal_count, attempt_count, next_attempt_at, created_at, updated_at)
|
|
21601
|
+
VALUES (?, ?, 'pending', ?, 0, 0, 0, 0, ?, ?, ?)`,
|
|
21602
|
+
[id, agentId, trigger, now, now, now]
|
|
21603
|
+
);
|
|
21604
|
+
const review = get8(db, id);
|
|
21605
|
+
if (!review) throw new Error("agent review enqueue failed");
|
|
21606
|
+
return review;
|
|
21607
|
+
}
|
|
21608
|
+
function get8(db, id) {
|
|
21609
|
+
const row = db.raw.query("SELECT * FROM agent_reviews WHERE id = ?").get(id);
|
|
21610
|
+
return row ? toReview(row) : null;
|
|
21611
|
+
}
|
|
21612
|
+
function getOpenForAgent(db, agentId) {
|
|
21613
|
+
const row = db.raw.query(
|
|
21614
|
+
`SELECT * FROM agent_reviews WHERE agent_id = ?
|
|
21615
|
+
AND status IN ('pending','running','retrying') LIMIT 1`
|
|
21616
|
+
).get(agentId);
|
|
21617
|
+
return row ? toReview(row) : null;
|
|
21618
|
+
}
|
|
21619
|
+
function enqueueManual(db, agentId, now = Date.now()) {
|
|
21620
|
+
return db.raw.transaction(
|
|
21621
|
+
() => getOpenForAgent(db, agentId) ?? insert5(db, agentId, "manual", now)
|
|
21622
|
+
)();
|
|
21623
|
+
}
|
|
21624
|
+
function recordSuccessfulUserTurn(db, agentId, now = Date.now()) {
|
|
21625
|
+
return db.raw.transaction(() => {
|
|
21626
|
+
const updated = db.raw.run(
|
|
21627
|
+
`UPDATE agents SET review_turns_since_last = review_turns_since_last + 1
|
|
21628
|
+
WHERE id = ? AND review_enabled = 1`,
|
|
21629
|
+
[agentId]
|
|
21630
|
+
);
|
|
21631
|
+
if (Number(updated.changes) !== 1) return null;
|
|
21632
|
+
const state3 = db.raw.query(
|
|
21633
|
+
`SELECT review_turns_since_last, review_every_n_turns FROM agents WHERE id = ?`
|
|
21634
|
+
).get(agentId);
|
|
21635
|
+
if (!state3 || state3.review_turns_since_last < state3.review_every_n_turns) return null;
|
|
21636
|
+
const open = getOpenForAgent(db, agentId);
|
|
21637
|
+
if (open) return open;
|
|
21638
|
+
const review = insert5(db, agentId, "cadence", now);
|
|
21639
|
+
db.raw.run("UPDATE agents SET review_turns_since_last = 0 WHERE id = ?", [agentId]);
|
|
21640
|
+
return review;
|
|
21641
|
+
})();
|
|
21642
|
+
}
|
|
21643
|
+
function listClaimable(db, now = Date.now()) {
|
|
21644
|
+
return db.raw.query(
|
|
21645
|
+
`SELECT * FROM agent_reviews
|
|
21646
|
+
WHERE (status IN ('pending','retrying') AND next_attempt_at <= ?)
|
|
21647
|
+
OR (status = 'running' AND lease_expires_at <= ?)
|
|
21648
|
+
ORDER BY created_at ASC`
|
|
21649
|
+
).all(now, now).map(toReview);
|
|
21650
|
+
}
|
|
21651
|
+
function claim(db, id, options = {}) {
|
|
21652
|
+
const now = options.now ?? Date.now();
|
|
21653
|
+
const leaseExpiresAt = now + (options.leaseMs ?? 5 * 6e4);
|
|
21654
|
+
return db.raw.transaction(() => {
|
|
21655
|
+
const result = db.raw.run(
|
|
21656
|
+
`UPDATE agent_reviews SET status = 'running', attempt_count = attempt_count + 1,
|
|
21657
|
+
lease_expires_at = ?, started_at = ?, finished_at = NULL, updated_at = ?
|
|
21658
|
+
WHERE id = ? AND (
|
|
21659
|
+
(status IN ('pending','retrying') AND next_attempt_at <= ?)
|
|
21660
|
+
OR (status = 'running' AND lease_expires_at <= ?)
|
|
21661
|
+
)`,
|
|
21662
|
+
[leaseExpiresAt, now, now, id, now, now]
|
|
21663
|
+
);
|
|
21664
|
+
return Number(result.changes) === 1 ? get8(db, id) : null;
|
|
21665
|
+
})();
|
|
21666
|
+
}
|
|
21667
|
+
function defer(db, id, nextAttemptAt = Date.now() + 1e3) {
|
|
21668
|
+
db.raw.run(
|
|
21669
|
+
`UPDATE agent_reviews SET status = 'pending',
|
|
21670
|
+
attempt_count = CASE WHEN attempt_count > 0 THEN attempt_count - 1 ELSE 0 END,
|
|
21671
|
+
next_attempt_at = ?, lease_expires_at = NULL, started_at = NULL, updated_at = ?
|
|
21672
|
+
WHERE id = ? AND status = 'running'`,
|
|
21673
|
+
[nextAttemptAt, Date.now(), id]
|
|
21674
|
+
);
|
|
21675
|
+
}
|
|
21676
|
+
function getLatestCompleted(db, agentId) {
|
|
21677
|
+
const row = db.raw.query(
|
|
21678
|
+
`SELECT * FROM agent_reviews WHERE agent_id = ? AND status = 'completed'
|
|
21679
|
+
ORDER BY finished_at DESC LIMIT 1`
|
|
21680
|
+
).get(agentId);
|
|
21681
|
+
return row ? toReview(row) : null;
|
|
21682
|
+
}
|
|
21683
|
+
function setSource(db, id, source) {
|
|
21684
|
+
db.raw.run(
|
|
21685
|
+
`UPDATE agent_reviews SET source_session_id = ?, source_start_ordinal = ?,
|
|
21686
|
+
source_end_ordinal = ?, input_characters = ?, turns_reviewed = ?, updated_at = ?
|
|
21687
|
+
WHERE id = ? AND status = 'running'`,
|
|
21688
|
+
[
|
|
21689
|
+
source.sessionId,
|
|
21690
|
+
source.startOrdinal,
|
|
21691
|
+
source.endOrdinal,
|
|
21692
|
+
source.inputCharacters,
|
|
21693
|
+
source.turnsReviewed,
|
|
21694
|
+
Date.now(),
|
|
21695
|
+
id
|
|
21696
|
+
]
|
|
21697
|
+
);
|
|
21698
|
+
}
|
|
21699
|
+
function complete(db, id, proposalCount, now = Date.now()) {
|
|
21700
|
+
db.raw.run(
|
|
21701
|
+
`UPDATE agent_reviews SET status = 'completed', proposal_count = ?, lease_expires_at = NULL,
|
|
21702
|
+
finished_at = ?, last_error = NULL, updated_at = ? WHERE id = ? AND status = 'running'`,
|
|
21703
|
+
[proposalCount, now, now, id]
|
|
21704
|
+
);
|
|
21705
|
+
}
|
|
21706
|
+
function cancel(db, id, reason, now = Date.now()) {
|
|
21707
|
+
db.raw.run(
|
|
21708
|
+
`UPDATE agent_reviews SET status = 'cancelled', lease_expires_at = NULL, finished_at = ?,
|
|
21709
|
+
last_error = ?, updated_at = ? WHERE id = ? AND status IN ('pending','running','retrying')`,
|
|
21710
|
+
[now, reason.slice(0, 2e3), now, id]
|
|
21711
|
+
);
|
|
21712
|
+
}
|
|
21713
|
+
function fail(db, id, error2, options = {}) {
|
|
21714
|
+
const now = options.now ?? Date.now();
|
|
21715
|
+
const current = get8(db, id);
|
|
21716
|
+
if (current?.status !== "running") return;
|
|
21717
|
+
const terminal = current.attemptCount >= (options.maxAttempts ?? 3);
|
|
21718
|
+
const retryDelay = (options.retryDelayMs ?? 5e3) * 2 ** Math.max(0, current.attemptCount - 1);
|
|
21719
|
+
db.raw.run(
|
|
21720
|
+
`UPDATE agent_reviews SET status = ?, next_attempt_at = ?, lease_expires_at = NULL,
|
|
21721
|
+
finished_at = ?, last_error = ?, updated_at = ? WHERE id = ? AND status = 'running'`,
|
|
21722
|
+
[
|
|
21723
|
+
terminal ? "failed" : "retrying",
|
|
21724
|
+
terminal ? now : now + retryDelay,
|
|
21725
|
+
terminal ? now : null,
|
|
21726
|
+
error2.slice(0, 2e3),
|
|
21727
|
+
now,
|
|
21728
|
+
id
|
|
21729
|
+
]
|
|
21730
|
+
);
|
|
21731
|
+
}
|
|
21732
|
+
function listForAgent2(db, agentId, limit = 50) {
|
|
21733
|
+
return db.raw.query(
|
|
21734
|
+
"SELECT * FROM agent_reviews WHERE agent_id = ? ORDER BY created_at DESC LIMIT ?"
|
|
21735
|
+
).all(agentId, limit).map(toReview);
|
|
21736
|
+
}
|
|
21737
|
+
|
|
21234
21738
|
// ../daemon/src/core/repos/communicationApprovals.ts
|
|
21235
21739
|
var communicationApprovals_exports = {};
|
|
21236
21740
|
__export(communicationApprovals_exports, {
|
|
@@ -21238,13 +21742,13 @@ __export(communicationApprovals_exports, {
|
|
|
21238
21742
|
decide: () => decide,
|
|
21239
21743
|
expirePending: () => expirePending,
|
|
21240
21744
|
finishDelivery: () => finishDelivery,
|
|
21241
|
-
get: () =>
|
|
21745
|
+
get: () => get9,
|
|
21242
21746
|
getByAttempt: () => getByAttempt,
|
|
21243
21747
|
grantSchedulerTrigger: () => grantSchedulerTrigger,
|
|
21244
21748
|
list: () => list6,
|
|
21245
21749
|
request: () => request
|
|
21246
21750
|
});
|
|
21247
|
-
import { createHash, randomUUID as
|
|
21751
|
+
import { createHash, randomUUID as randomUUID6 } from "crypto";
|
|
21248
21752
|
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
21249
21753
|
function endpoint(kind, id, teamId) {
|
|
21250
21754
|
if (kind === "agent") return { kind, id };
|
|
@@ -21299,7 +21803,7 @@ function appendEvent(db, approvalId, name, actor, detail3 = null, now = Date.now
|
|
|
21299
21803
|
`INSERT INTO communication_approval_events
|
|
21300
21804
|
(id, approval_id, event, actor, detail, created_at)
|
|
21301
21805
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
21302
|
-
[
|
|
21806
|
+
[randomUUID6(), approvalId, name, actor, detail3, now]
|
|
21303
21807
|
);
|
|
21304
21808
|
}
|
|
21305
21809
|
function teams(db, input) {
|
|
@@ -21325,7 +21829,7 @@ function request(db, input, operation, authorization, payloadKind, payload, opti
|
|
|
21325
21829
|
expireOne(db, existing, now);
|
|
21326
21830
|
return toApproval(raw(db, existing.id));
|
|
21327
21831
|
}
|
|
21328
|
-
const id =
|
|
21832
|
+
const id = randomUUID6();
|
|
21329
21833
|
const [sourceGroup, targetGroup] = teams(db, input);
|
|
21330
21834
|
const expiresAt = now + (options.ttlMs ?? DEFAULT_TTL_MS);
|
|
21331
21835
|
db.raw.run(
|
|
@@ -21393,7 +21897,7 @@ function expirePending(db, now = Date.now()) {
|
|
|
21393
21897
|
return rows.length;
|
|
21394
21898
|
})();
|
|
21395
21899
|
}
|
|
21396
|
-
function
|
|
21900
|
+
function get9(db, id, includePayload = false) {
|
|
21397
21901
|
expirePending(db);
|
|
21398
21902
|
const row = raw(db, id);
|
|
21399
21903
|
if (!row) return null;
|
|
@@ -22019,6 +22523,13 @@ var SERVICES = [
|
|
|
22019
22523
|
label: "Extra environment allowlist",
|
|
22020
22524
|
placeholder: "MY_SAFE_VARIABLE,ANOTHER_SAFE_VARIABLE",
|
|
22021
22525
|
description: "Optional comma-separated variable names copied into the container. Provider credentials remain excluded unless explicitly named."
|
|
22526
|
+
},
|
|
22527
|
+
{
|
|
22528
|
+
envVar: "BAZILION_AGENT_LOOP_MAX_HOPS",
|
|
22529
|
+
kind: "config",
|
|
22530
|
+
label: "Agent-message hop limit",
|
|
22531
|
+
placeholder: "8",
|
|
22532
|
+
description: "Maximum causal hops in an agent-to-agent message chain before the daemon stops it. Default 8."
|
|
22022
22533
|
}
|
|
22023
22534
|
]
|
|
22024
22535
|
},
|
|
@@ -22168,16 +22679,16 @@ function openConfig(db) {
|
|
|
22168
22679
|
// ../daemon/src/core/repos/mcpServers.ts
|
|
22169
22680
|
var mcpServers_exports = {};
|
|
22170
22681
|
__export(mcpServers_exports, {
|
|
22171
|
-
get: () =>
|
|
22682
|
+
get: () => get10,
|
|
22172
22683
|
getByName: () => getByName,
|
|
22173
|
-
insert: () =>
|
|
22684
|
+
insert: () => insert6,
|
|
22174
22685
|
list: () => list7,
|
|
22175
22686
|
listEnabled: () => listEnabled2,
|
|
22176
22687
|
remove: () => remove5,
|
|
22177
22688
|
setEnabled: () => setEnabled2,
|
|
22178
22689
|
update: () => update2
|
|
22179
22690
|
});
|
|
22180
|
-
import { randomUUID as
|
|
22691
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
22181
22692
|
function toServer(r) {
|
|
22182
22693
|
let args = [];
|
|
22183
22694
|
try {
|
|
@@ -22198,8 +22709,8 @@ function toServer(r) {
|
|
|
22198
22709
|
updatedAt: r.updated_at
|
|
22199
22710
|
};
|
|
22200
22711
|
}
|
|
22201
|
-
function
|
|
22202
|
-
const id =
|
|
22712
|
+
function insert6(db, input) {
|
|
22713
|
+
const id = randomUUID7();
|
|
22203
22714
|
const now = Date.now();
|
|
22204
22715
|
db.raw.run(
|
|
22205
22716
|
`INSERT INTO mcp_servers (id, name, transport, command, args, url, has_auth, enabled, created_at, updated_at)
|
|
@@ -22217,11 +22728,11 @@ function insert4(db, input) {
|
|
|
22217
22728
|
now
|
|
22218
22729
|
]
|
|
22219
22730
|
);
|
|
22220
|
-
const row =
|
|
22731
|
+
const row = get10(db, id);
|
|
22221
22732
|
if (!row) throw new Error("mcp server insert failed");
|
|
22222
22733
|
return row;
|
|
22223
22734
|
}
|
|
22224
|
-
function
|
|
22735
|
+
function get10(db, id) {
|
|
22225
22736
|
const row = db.raw.query("SELECT * FROM mcp_servers WHERE id = ?").get(id);
|
|
22226
22737
|
return row ? toServer(row) : null;
|
|
22227
22738
|
}
|
|
@@ -22236,7 +22747,7 @@ function listEnabled2(db) {
|
|
|
22236
22747
|
return db.raw.query("SELECT * FROM mcp_servers WHERE enabled = 1 ORDER BY created_at ASC").all().map(toServer);
|
|
22237
22748
|
}
|
|
22238
22749
|
function update2(db, id, input) {
|
|
22239
|
-
const existing =
|
|
22750
|
+
const existing = get10(db, id);
|
|
22240
22751
|
if (!existing) return null;
|
|
22241
22752
|
const next = {
|
|
22242
22753
|
name: input.name ?? existing.name,
|
|
@@ -22263,7 +22774,7 @@ function update2(db, id, input) {
|
|
|
22263
22774
|
id
|
|
22264
22775
|
]
|
|
22265
22776
|
);
|
|
22266
|
-
return
|
|
22777
|
+
return get10(db, id);
|
|
22267
22778
|
}
|
|
22268
22779
|
function setEnabled2(db, id, enabled) {
|
|
22269
22780
|
db.raw.run("UPDATE mcp_servers SET enabled = ?, updated_at = ? WHERE id = ?", [
|
|
@@ -22281,7 +22792,7 @@ var messages_exports = {};
|
|
|
22281
22792
|
__export(messages_exports, {
|
|
22282
22793
|
drainUnreadForAgent: () => drainUnreadForAgent,
|
|
22283
22794
|
findReplies: () => findReplies,
|
|
22284
|
-
get: () =>
|
|
22795
|
+
get: () => get11,
|
|
22285
22796
|
listInbox: () => listInbox,
|
|
22286
22797
|
listInboxForOperator: () => listInboxForOperator,
|
|
22287
22798
|
listRecipientsWithUnread: () => listRecipientsWithUnread,
|
|
@@ -22291,37 +22802,44 @@ __export(messages_exports, {
|
|
|
22291
22802
|
markRead: () => markRead,
|
|
22292
22803
|
send: () => send
|
|
22293
22804
|
});
|
|
22294
|
-
import { randomUUID as
|
|
22805
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
22295
22806
|
function toMessage(r) {
|
|
22296
22807
|
return {
|
|
22297
22808
|
id: r.id,
|
|
22298
22809
|
fromAgentId: r.from_agent_id,
|
|
22299
22810
|
toAgentId: r.to_agent_id,
|
|
22300
22811
|
replyTo: r.reply_to,
|
|
22812
|
+
causalChainId: r.causal_chain_id,
|
|
22813
|
+
causalHop: r.causal_hop,
|
|
22301
22814
|
payload: r.payload,
|
|
22302
22815
|
createdAt: r.created_at,
|
|
22303
22816
|
readAt: r.read_at
|
|
22304
22817
|
};
|
|
22305
22818
|
}
|
|
22306
22819
|
function send(db, input) {
|
|
22307
|
-
const id =
|
|
22820
|
+
const id = randomUUID8();
|
|
22308
22821
|
const now = Date.now();
|
|
22822
|
+
const causalChainId = input.causalChainId ?? id;
|
|
22823
|
+
const causalHop = input.causalHop ?? 0;
|
|
22309
22824
|
db.raw.run(
|
|
22310
|
-
`INSERT INTO messages
|
|
22311
|
-
|
|
22312
|
-
|
|
22825
|
+
`INSERT INTO messages
|
|
22826
|
+
(id, from_agent_id, to_agent_id, reply_to, causal_chain_id, causal_hop, payload, created_at, read_at)
|
|
22827
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)`,
|
|
22828
|
+
[id, input.from, input.to, input.replyTo ?? null, causalChainId, causalHop, input.payload, now]
|
|
22313
22829
|
);
|
|
22314
22830
|
return {
|
|
22315
22831
|
id,
|
|
22316
22832
|
fromAgentId: input.from,
|
|
22317
22833
|
toAgentId: input.to,
|
|
22318
22834
|
replyTo: input.replyTo ?? null,
|
|
22835
|
+
causalChainId,
|
|
22836
|
+
causalHop,
|
|
22319
22837
|
payload: input.payload,
|
|
22320
22838
|
createdAt: now,
|
|
22321
22839
|
readAt: null
|
|
22322
22840
|
};
|
|
22323
22841
|
}
|
|
22324
|
-
function
|
|
22842
|
+
function get11(db, id) {
|
|
22325
22843
|
const row = db.raw.query("SELECT * FROM messages WHERE id = ?").get(id);
|
|
22326
22844
|
return row ? toMessage(row) : null;
|
|
22327
22845
|
}
|
|
@@ -22481,7 +22999,7 @@ function openSecrets(db, password) {
|
|
|
22481
22999
|
// ../daemon/src/core/repos/skillMeta.ts
|
|
22482
23000
|
var skillMeta_exports = {};
|
|
22483
23001
|
__export(skillMeta_exports, {
|
|
22484
|
-
get: () =>
|
|
23002
|
+
get: () => get12,
|
|
22485
23003
|
listAll: () => listAll2,
|
|
22486
23004
|
remove: () => remove6,
|
|
22487
23005
|
upsert: () => upsert
|
|
@@ -22493,7 +23011,7 @@ function toMeta(r) {
|
|
|
22493
23011
|
importedAt: r.imported_at
|
|
22494
23012
|
};
|
|
22495
23013
|
}
|
|
22496
|
-
function
|
|
23014
|
+
function get12(db, name) {
|
|
22497
23015
|
const row = db.raw.query("SELECT * FROM skill_meta WHERE name = ?").get(name);
|
|
22498
23016
|
return row ? toMeta(row) : null;
|
|
22499
23017
|
}
|
|
@@ -22501,7 +23019,7 @@ function listAll2(db) {
|
|
|
22501
23019
|
return db.raw.query("SELECT * FROM skill_meta ORDER BY name ASC").all().map(toMeta);
|
|
22502
23020
|
}
|
|
22503
23021
|
function upsert(db, input) {
|
|
22504
|
-
const existing =
|
|
23022
|
+
const existing = get12(db, input.name);
|
|
22505
23023
|
const source = input.source !== void 0 ? input.source : existing?.source ?? null;
|
|
22506
23024
|
const importedAt = input.importedAt !== void 0 ? input.importedAt : existing?.importedAt ?? null;
|
|
22507
23025
|
db.raw.run(
|
|
@@ -22521,7 +23039,7 @@ var telegram_acl_exports = {};
|
|
|
22521
23039
|
__export(telegram_acl_exports, {
|
|
22522
23040
|
add: () => add,
|
|
22523
23041
|
count: () => count,
|
|
22524
|
-
get: () =>
|
|
23042
|
+
get: () => get13,
|
|
22525
23043
|
isAllowed: () => isAllowed,
|
|
22526
23044
|
list: () => list8,
|
|
22527
23045
|
ownerCount: () => ownerCount,
|
|
@@ -22539,12 +23057,12 @@ function toUser(r) {
|
|
|
22539
23057
|
function list8(db) {
|
|
22540
23058
|
return db.raw.query("SELECT * FROM telegram_allowed_users ORDER BY added_at ASC").all().map(toUser);
|
|
22541
23059
|
}
|
|
22542
|
-
function
|
|
23060
|
+
function get13(db, userId) {
|
|
22543
23061
|
const row = db.raw.query("SELECT * FROM telegram_allowed_users WHERE user_id = ?").get(userId);
|
|
22544
23062
|
return row ? toUser(row) : null;
|
|
22545
23063
|
}
|
|
22546
23064
|
function isAllowed(db, userId) {
|
|
22547
|
-
return
|
|
23065
|
+
return get13(db, userId) !== null;
|
|
22548
23066
|
}
|
|
22549
23067
|
function count(db) {
|
|
22550
23068
|
return db.raw.query("SELECT COUNT(*) as c FROM telegram_allowed_users").get()?.c ?? 0;
|
|
@@ -22563,10 +23081,10 @@ function add(db, input) {
|
|
|
22563
23081
|
ON CONFLICT(user_id) DO UPDATE SET username = excluded.username, label = excluded.label`,
|
|
22564
23082
|
[input.userId, input.username ?? null, input.label ?? null, role, now]
|
|
22565
23083
|
);
|
|
22566
|
-
return
|
|
23084
|
+
return get13(db, input.userId);
|
|
22567
23085
|
}
|
|
22568
23086
|
function remove7(db, userId) {
|
|
22569
|
-
const u =
|
|
23087
|
+
const u = get13(db, userId);
|
|
22570
23088
|
if (!u) return false;
|
|
22571
23089
|
if (u.role === "owner" && ownerCount(db) <= 1) return false;
|
|
22572
23090
|
db.raw.run("DELETE FROM telegram_allowed_users WHERE user_id = ?", [userId]);
|
|
@@ -22578,17 +23096,17 @@ var triggerDispatches_exports = {};
|
|
|
22578
23096
|
__export(triggerDispatches_exports, {
|
|
22579
23097
|
cancelPendingForTrigger: () => cancelPendingForTrigger,
|
|
22580
23098
|
cancelRunning: () => cancelRunning,
|
|
22581
|
-
claim: () =>
|
|
22582
|
-
defer: () =>
|
|
22583
|
-
fail: () =>
|
|
22584
|
-
get: () =>
|
|
23099
|
+
claim: () => claim2,
|
|
23100
|
+
defer: () => defer2,
|
|
23101
|
+
fail: () => fail2,
|
|
23102
|
+
get: () => get14,
|
|
22585
23103
|
hasOpenForTrigger: () => hasOpenForTrigger,
|
|
22586
|
-
listClaimable: () =>
|
|
23104
|
+
listClaimable: () => listClaimable2,
|
|
22587
23105
|
listForTrigger: () => listForTrigger,
|
|
22588
23106
|
materialize: () => materialize,
|
|
22589
23107
|
succeed: () => succeed
|
|
22590
23108
|
});
|
|
22591
|
-
import { randomUUID as
|
|
23109
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
22592
23110
|
function toDispatch(row) {
|
|
22593
23111
|
return {
|
|
22594
23112
|
id: row.id,
|
|
@@ -22614,7 +23132,7 @@ function materialize(db, input) {
|
|
|
22614
23132
|
lease_expires_at, started_at, finished_at, last_error, created_at, updated_at)
|
|
22615
23133
|
VALUES (?, ?, ?, ?, 'pending', 0, ?, NULL, NULL, NULL, NULL, ?, ?)
|
|
22616
23134
|
ON CONFLICT(trigger_id, scheduled_at) DO NOTHING`,
|
|
22617
|
-
[
|
|
23135
|
+
[randomUUID9(), input.triggerId, input.agentId, input.scheduledAt, now, now, now]
|
|
22618
23136
|
);
|
|
22619
23137
|
const row = db.raw.query(
|
|
22620
23138
|
"SELECT * FROM trigger_dispatches WHERE trigger_id = ? AND scheduled_at = ?"
|
|
@@ -22622,11 +23140,11 @@ function materialize(db, input) {
|
|
|
22622
23140
|
if (!row) throw new Error("trigger dispatch materialization failed");
|
|
22623
23141
|
return toDispatch(row);
|
|
22624
23142
|
}
|
|
22625
|
-
function
|
|
23143
|
+
function get14(db, id) {
|
|
22626
23144
|
const row = db.raw.query("SELECT * FROM trigger_dispatches WHERE id = ?").get(id);
|
|
22627
23145
|
return row ? toDispatch(row) : null;
|
|
22628
23146
|
}
|
|
22629
|
-
function
|
|
23147
|
+
function listClaimable2(db, now = Date.now()) {
|
|
22630
23148
|
return db.raw.query(
|
|
22631
23149
|
`SELECT * FROM trigger_dispatches
|
|
22632
23150
|
WHERE (status IN ('pending','retrying') AND next_attempt_at <= ?)
|
|
@@ -22640,7 +23158,7 @@ function hasOpenForTrigger(db, triggerId) {
|
|
|
22640
23158
|
WHERE trigger_id = ? AND status IN ('pending','running','retrying') LIMIT 1`
|
|
22641
23159
|
).get(triggerId) !== null;
|
|
22642
23160
|
}
|
|
22643
|
-
function
|
|
23161
|
+
function claim2(db, id, options = {}) {
|
|
22644
23162
|
const now = options.now ?? Date.now();
|
|
22645
23163
|
const leaseExpiresAt = now + (options.leaseMs ?? 5 * 6e4);
|
|
22646
23164
|
return db.raw.transaction(() => {
|
|
@@ -22666,7 +23184,7 @@ function succeed(db, id, now = Date.now()) {
|
|
|
22666
23184
|
[now, now, id]
|
|
22667
23185
|
);
|
|
22668
23186
|
}
|
|
22669
|
-
function
|
|
23187
|
+
function defer2(db, id, nextAttemptAt = Date.now() + 1e3) {
|
|
22670
23188
|
db.raw.run(
|
|
22671
23189
|
`UPDATE trigger_dispatches SET status = 'pending',
|
|
22672
23190
|
attempt_count = CASE WHEN attempt_count > 0 THEN attempt_count - 1 ELSE 0 END,
|
|
@@ -22682,7 +23200,7 @@ function cancelRunning(db, id, reason, now = Date.now()) {
|
|
|
22682
23200
|
[now, reason.slice(0, 2e3), now, id]
|
|
22683
23201
|
);
|
|
22684
23202
|
}
|
|
22685
|
-
function
|
|
23203
|
+
function fail2(db, id, error2, options = {}) {
|
|
22686
23204
|
const now = options.now ?? Date.now();
|
|
22687
23205
|
const maxAttempts = options.maxAttempts ?? 3;
|
|
22688
23206
|
const retryDelayMs = options.retryDelayMs ?? 5e3;
|
|
@@ -22720,15 +23238,15 @@ function listForTrigger(db, triggerId, limit = 20) {
|
|
|
22720
23238
|
// ../daemon/src/core/repos/triggers.ts
|
|
22721
23239
|
var triggers_exports = {};
|
|
22722
23240
|
__export(triggers_exports, {
|
|
22723
|
-
get: () =>
|
|
22724
|
-
insert: () =>
|
|
23241
|
+
get: () => get15,
|
|
23242
|
+
insert: () => insert7,
|
|
22725
23243
|
listEnabled: () => listEnabled3,
|
|
22726
|
-
listForAgent: () =>
|
|
23244
|
+
listForAgent: () => listForAgent3,
|
|
22727
23245
|
markFired: () => markFired,
|
|
22728
23246
|
remove: () => remove8,
|
|
22729
23247
|
setEnabled: () => setEnabled3
|
|
22730
23248
|
});
|
|
22731
|
-
import { randomUUID as
|
|
23249
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
22732
23250
|
function toTrigger(r) {
|
|
22733
23251
|
return {
|
|
22734
23252
|
id: r.id,
|
|
@@ -22742,8 +23260,8 @@ function toTrigger(r) {
|
|
|
22742
23260
|
createdAt: r.created_at
|
|
22743
23261
|
};
|
|
22744
23262
|
}
|
|
22745
|
-
function
|
|
22746
|
-
const id =
|
|
23263
|
+
function insert7(db, input) {
|
|
23264
|
+
const id = randomUUID10();
|
|
22747
23265
|
const now = Date.now();
|
|
22748
23266
|
const enabled = input.enabled === false ? 0 : 1;
|
|
22749
23267
|
db.raw.run(
|
|
@@ -22764,11 +23282,11 @@ function insert5(db, input) {
|
|
|
22764
23282
|
createdAt: now
|
|
22765
23283
|
};
|
|
22766
23284
|
}
|
|
22767
|
-
function
|
|
23285
|
+
function get15(db, id) {
|
|
22768
23286
|
const row = db.raw.query("SELECT * FROM agent_triggers WHERE id = ?").get(id);
|
|
22769
23287
|
return row ? toTrigger(row) : null;
|
|
22770
23288
|
}
|
|
22771
|
-
function
|
|
23289
|
+
function listForAgent3(db, agentId) {
|
|
22772
23290
|
return db.raw.query(
|
|
22773
23291
|
"SELECT * FROM agent_triggers WHERE agent_id = ? ORDER BY created_at ASC"
|
|
22774
23292
|
).all(agentId).map(toTrigger);
|
|
@@ -22799,13 +23317,13 @@ var webTokens_exports = {};
|
|
|
22799
23317
|
__export(webTokens_exports, {
|
|
22800
23318
|
create: () => create,
|
|
22801
23319
|
findActiveByToken: () => findActiveByToken,
|
|
22802
|
-
get: () =>
|
|
23320
|
+
get: () => get16,
|
|
22803
23321
|
hashToken: () => hashToken,
|
|
22804
23322
|
list: () => list9,
|
|
22805
23323
|
markUsed: () => markUsed,
|
|
22806
|
-
revoke: () =>
|
|
23324
|
+
revoke: () => revoke2
|
|
22807
23325
|
});
|
|
22808
|
-
import { createHash as createHash2, randomBytes as randomBytes2, randomUUID as
|
|
23326
|
+
import { createHash as createHash2, randomBytes as randomBytes2, randomUUID as randomUUID11 } from "crypto";
|
|
22809
23327
|
function toToken(r) {
|
|
22810
23328
|
return {
|
|
22811
23329
|
id: r.id,
|
|
@@ -22819,7 +23337,7 @@ function hashToken(token) {
|
|
|
22819
23337
|
return createHash2("sha256").update(token).digest("hex");
|
|
22820
23338
|
}
|
|
22821
23339
|
function create(db, label) {
|
|
22822
|
-
const id =
|
|
23340
|
+
const id = randomUUID11();
|
|
22823
23341
|
const token = randomBytes2(24).toString("hex");
|
|
22824
23342
|
const tokenHash = hashToken(token);
|
|
22825
23343
|
const now = Date.now();
|
|
@@ -22837,7 +23355,7 @@ function list9(db, opts) {
|
|
|
22837
23355
|
const sql = opts?.includeRevoked ? "SELECT * FROM web_tokens ORDER BY created_at ASC" : "SELECT * FROM web_tokens WHERE revoked_at IS NULL ORDER BY created_at ASC";
|
|
22838
23356
|
return db.raw.query(sql).all().map(toToken);
|
|
22839
23357
|
}
|
|
22840
|
-
function
|
|
23358
|
+
function get16(db, id) {
|
|
22841
23359
|
const row = db.raw.query("SELECT * FROM web_tokens WHERE id = ?").get(id);
|
|
22842
23360
|
return row ? toToken(row) : null;
|
|
22843
23361
|
}
|
|
@@ -22851,7 +23369,7 @@ function findActiveByToken(db, token) {
|
|
|
22851
23369
|
function markUsed(db, id, when = Date.now()) {
|
|
22852
23370
|
db.raw.run("UPDATE web_tokens SET last_used_at = ? WHERE id = ?", [when, id]);
|
|
22853
23371
|
}
|
|
22854
|
-
function
|
|
23372
|
+
function revoke2(db, id, when = Date.now()) {
|
|
22855
23373
|
const res = db.raw.run(
|
|
22856
23374
|
"UPDATE web_tokens SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL",
|
|
22857
23375
|
[when, id]
|
|
@@ -23119,7 +23637,7 @@ function resolveAgentSkills(db, paths, agentId) {
|
|
|
23119
23637
|
}
|
|
23120
23638
|
|
|
23121
23639
|
// ../daemon/src/core/team/delete.ts
|
|
23122
|
-
import { randomUUID as
|
|
23640
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
23123
23641
|
import { existsSync as existsSync9, renameSync as renameSync2, rmSync as rmSync6 } from "fs";
|
|
23124
23642
|
function deleteTeam(db, paths, id, expectedTeamPolicyRevision) {
|
|
23125
23643
|
const g2 = get3(db, id, paths);
|
|
@@ -23138,7 +23656,7 @@ function deleteTeam(db, paths, id, expectedTeamPolicyRevision) {
|
|
|
23138
23656
|
`cannot delete team "${id}": ${members.length} agent(s) still belong to it: ${names}. Move or delete them first.`
|
|
23139
23657
|
);
|
|
23140
23658
|
}
|
|
23141
|
-
const stagedPath = `${g2.path}.deleting-${
|
|
23659
|
+
const stagedPath = `${g2.path}.deleting-${randomUUID12()}`;
|
|
23142
23660
|
const hadSlot = existsSync9(g2.path);
|
|
23143
23661
|
if (hadSlot) renameSync2(g2.path, stagedPath);
|
|
23144
23662
|
try {
|
|
@@ -23162,7 +23680,7 @@ function deleteTeam(db, paths, id, expectedTeamPolicyRevision) {
|
|
|
23162
23680
|
}
|
|
23163
23681
|
|
|
23164
23682
|
// ../daemon/src/core/team-policy/adopt.ts
|
|
23165
|
-
import { randomUUID as
|
|
23683
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
23166
23684
|
function previewTeamPolicyAdoption(db, teamId, input) {
|
|
23167
23685
|
return resolveAdoptionPlan(db, teamId, { ...input, previewEdges: [] }).resolved;
|
|
23168
23686
|
}
|
|
@@ -23174,7 +23692,7 @@ function resolveAdoptionPlan(db, teamId, input) {
|
|
|
23174
23692
|
`team_revision_conflict: expected ${input.teamExpectedRevision}, current ${teamPolicy.revision}`
|
|
23175
23693
|
);
|
|
23176
23694
|
}
|
|
23177
|
-
const template =
|
|
23695
|
+
const template = get7(db, input.templateId);
|
|
23178
23696
|
if (!template) throw new Error(`team template not found: ${input.templateId}`);
|
|
23179
23697
|
if (template.deletedAt !== null) throw new Error(`template_deleted: ${input.templateId}`);
|
|
23180
23698
|
if (template.currentRevision !== input.templateExpectedRevision) {
|
|
@@ -23235,7 +23753,7 @@ function adoptTeamTemplate(db, teamId, input) {
|
|
|
23235
23753
|
);
|
|
23236
23754
|
db.raw.run("DELETE FROM template_instantiations WHERE team_id = ?", [teamId]);
|
|
23237
23755
|
db.raw.run("DELETE FROM team_policy_edges WHERE team_id = ?", [teamId]);
|
|
23238
|
-
const instantiationId =
|
|
23756
|
+
const instantiationId = randomUUID13();
|
|
23239
23757
|
db.raw.run(
|
|
23240
23758
|
`INSERT INTO template_instantiations
|
|
23241
23759
|
(id, team_id, template_id, template_revision, created_at)
|
|
@@ -23333,7 +23851,7 @@ function edgeKey(edge) {
|
|
|
23333
23851
|
}
|
|
23334
23852
|
|
|
23335
23853
|
// ../daemon/src/core/team-policy/authorization.ts
|
|
23336
|
-
import { createHash as createHash3, randomUUID as
|
|
23854
|
+
import { createHash as createHash3, randomUUID as randomUUID14 } from "crypto";
|
|
23337
23855
|
function denied(channel, code, reason) {
|
|
23338
23856
|
return {
|
|
23339
23857
|
decision: "deny",
|
|
@@ -23513,7 +24031,7 @@ function recordDenial(db, input, operation, result) {
|
|
|
23513
24031
|
const sourceGroup = agentGroup(input.source) ?? agentGroup(input.target) ?? ("teamId" in input.source ? input.source.teamId : null);
|
|
23514
24032
|
const targetGroup = agentGroup(input.target) ?? agentGroup(input.source) ?? ("teamId" in input.target ? input.target.teamId : null);
|
|
23515
24033
|
const values = [
|
|
23516
|
-
|
|
24034
|
+
randomUUID14(),
|
|
23517
24035
|
input.attemptKind,
|
|
23518
24036
|
input.attemptId,
|
|
23519
24037
|
operation,
|
|
@@ -23563,7 +24081,7 @@ function recordDenial(db, input, operation, result) {
|
|
|
23563
24081
|
}
|
|
23564
24082
|
|
|
23565
24083
|
// ../daemon/src/core/team-policy/source.ts
|
|
23566
|
-
import { randomUUID as
|
|
24084
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
23567
24085
|
function diffTeamPolicy(db, teamId) {
|
|
23568
24086
|
const detail3 = detail(db, teamId);
|
|
23569
24087
|
if (!detail3) throw new Error(`team_policy_missing: ${teamId}`);
|
|
@@ -23625,13 +24143,13 @@ function saveTeamPolicyAsTemplate(db, paths, teamId, input) {
|
|
|
23625
24143
|
`team_revision_conflict: expected ${input.expectedRevision}, current ${teamPolicy.revision}`
|
|
23626
24144
|
);
|
|
23627
24145
|
}
|
|
23628
|
-
if (
|
|
24146
|
+
if (get7(db, input.id)) {
|
|
23629
24147
|
throw new Error(`team template already exists: ${input.id}`);
|
|
23630
24148
|
}
|
|
23631
24149
|
const team = get3(db, teamId, paths);
|
|
23632
24150
|
if (!team) throw new Error(`team not found: ${teamId}`);
|
|
23633
24151
|
const members = list(db, { includeArchived: true }).filter((agent) => agent.teamId === teamId);
|
|
23634
|
-
const slotByAgent = new Map(members.map((agent) => [agent.id,
|
|
24152
|
+
const slotByAgent = new Map(members.map((agent) => [agent.id, randomUUID15()]));
|
|
23635
24153
|
const stateByAgent = new Map(
|
|
23636
24154
|
agentState(db, teamId).map((state3) => [state3.agentId, state3])
|
|
23637
24155
|
);
|
|
@@ -23673,7 +24191,7 @@ function updateTeamPolicySource(db, teamId, input) {
|
|
|
23673
24191
|
if (!teamPolicy.baselineInstantiationId) throw new Error("baseline_missing: Team has no source");
|
|
23674
24192
|
const baseline = instantiations(db, teamId).find((item) => item.id === teamPolicy.baselineInstantiationId);
|
|
23675
24193
|
if (!baseline) throw new Error("baseline_missing: retained baseline does not exist");
|
|
23676
|
-
const source =
|
|
24194
|
+
const source = get7(db, baseline.templateId);
|
|
23677
24195
|
if (!source) throw new Error(`team template not found: ${baseline.templateId}`);
|
|
23678
24196
|
if (source.deletedAt !== null) throw new Error(`template_deleted: ${source.id}`);
|
|
23679
24197
|
if (source.currentRevision !== baseline.templateRevision) {
|
|
@@ -23707,7 +24225,7 @@ function updateTeamPolicySource(db, teamId, input) {
|
|
|
23707
24225
|
baselineBindings.map((binding) => [binding.agentId, binding.sourceSlotId])
|
|
23708
24226
|
);
|
|
23709
24227
|
for (const id of selectedIds) {
|
|
23710
|
-
if (!slotByAgent.has(id)) slotByAgent.set(id,
|
|
24228
|
+
if (!slotByAgent.has(id)) slotByAgent.set(id, randomUUID15());
|
|
23711
24229
|
}
|
|
23712
24230
|
const previousSlotById = new Map(previous.slots.map((slot) => [slot.slotId, slot]));
|
|
23713
24231
|
const selectedMembers = [...selectedIds].map((id) => {
|
|
@@ -23775,7 +24293,7 @@ function pruneEmptyNonbaselineInstantiation(db, instantiationId, baselineId) {
|
|
|
23775
24293
|
}
|
|
23776
24294
|
|
|
23777
24295
|
// ../daemon/src/core/team-policy/spawn.ts
|
|
23778
|
-
import { randomUUID as
|
|
24296
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
23779
24297
|
import { readdirSync as readdirSync4, rmSync as rmSync8 } from "fs";
|
|
23780
24298
|
|
|
23781
24299
|
// ../daemon/src/core/team-policy/rm-with-retry.ts
|
|
@@ -23800,7 +24318,7 @@ async function rmWithRetry(target, opts = {}) {
|
|
|
23800
24318
|
|
|
23801
24319
|
// ../daemon/src/core/team-policy/spawn.ts
|
|
23802
24320
|
function previewTeamTemplateSpawn(db, paths, input) {
|
|
23803
|
-
const source =
|
|
24321
|
+
const source = get7(db, input.templateId);
|
|
23804
24322
|
if (!source) throw new Error(`team template not found: ${input.templateId}`);
|
|
23805
24323
|
if (source.deletedAt !== null) throw new Error(`template_deleted: ${input.templateId}`);
|
|
23806
24324
|
if (source.currentRevision !== input.templateExpectedRevision) {
|
|
@@ -23866,7 +24384,7 @@ var SpawnTeamTemplateError = class extends Error {
|
|
|
23866
24384
|
}
|
|
23867
24385
|
};
|
|
23868
24386
|
async function spawnTeamTemplate(db, paths, input) {
|
|
23869
|
-
const source =
|
|
24387
|
+
const source = get7(db, input.templateId);
|
|
23870
24388
|
if (!source) throw new Error(`team template not found: ${input.templateId}`);
|
|
23871
24389
|
if (source.deletedAt !== null) throw new Error(`template_deleted: ${input.templateId}`);
|
|
23872
24390
|
if (source.currentRevision !== input.templateExpectedRevision) {
|
|
@@ -23878,7 +24396,7 @@ async function spawnTeamTemplate(db, paths, input) {
|
|
|
23878
24396
|
if (!snapshot)
|
|
23879
24397
|
throw new Error(`template_snapshot_missing: ${source.id}@${source.currentRevision}`);
|
|
23880
24398
|
for (const slot of snapshot.slots) {
|
|
23881
|
-
if (!
|
|
24399
|
+
if (!get5(db, slot.profileId)) {
|
|
23882
24400
|
throw new Error(`profile not found: ${slot.profileId}`);
|
|
23883
24401
|
}
|
|
23884
24402
|
}
|
|
@@ -23891,7 +24409,7 @@ async function spawnTeamTemplate(db, paths, input) {
|
|
|
23891
24409
|
const created = [];
|
|
23892
24410
|
try {
|
|
23893
24411
|
inTx(db, () => {
|
|
23894
|
-
const transactionalSource =
|
|
24412
|
+
const transactionalSource = get7(db, input.templateId);
|
|
23895
24413
|
if (!transactionalSource || transactionalSource.deletedAt !== null) {
|
|
23896
24414
|
throw new Error(`template_deleted: ${input.templateId}`);
|
|
23897
24415
|
}
|
|
@@ -23942,7 +24460,7 @@ async function spawnTeamTemplate(db, paths, input) {
|
|
|
23942
24460
|
})
|
|
23943
24461
|
);
|
|
23944
24462
|
}
|
|
23945
|
-
const instantiationId =
|
|
24463
|
+
const instantiationId = randomUUID16();
|
|
23946
24464
|
db.raw.run(
|
|
23947
24465
|
`INSERT INTO template_instantiations
|
|
23948
24466
|
(id, team_id, template_id, template_revision, created_at)
|
|
@@ -24113,8 +24631,111 @@ async function runAgentLifecycleMutation(agentId, mutation) {
|
|
|
24113
24631
|
}
|
|
24114
24632
|
}
|
|
24115
24633
|
|
|
24634
|
+
// ../daemon/src/lib/agent-loop-guard.ts
|
|
24635
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
24636
|
+
var DEFAULT_MAX_HOPS = 8;
|
|
24637
|
+
function toEvent(row) {
|
|
24638
|
+
return {
|
|
24639
|
+
id: row.id,
|
|
24640
|
+
causalChainId: row.causal_chain_id,
|
|
24641
|
+
parentMessageId: row.parent_message_id,
|
|
24642
|
+
fromAgentId: row.from_agent_id,
|
|
24643
|
+
toAgentId: row.to_agent_id,
|
|
24644
|
+
sourceTeamId: row.source_team_id,
|
|
24645
|
+
targetTeamId: row.target_team_id,
|
|
24646
|
+
attemptedHop: row.attempted_hop,
|
|
24647
|
+
maxHops: row.max_hops,
|
|
24648
|
+
reason: row.reason,
|
|
24649
|
+
origin: row.origin,
|
|
24650
|
+
createdAt: row.created_at
|
|
24651
|
+
};
|
|
24652
|
+
}
|
|
24653
|
+
function agentLoopMaxHops(db, env = process.env) {
|
|
24654
|
+
const raw2 = env.BAZILION_AGENT_LOOP_MAX_HOPS ?? (db ? openConfig(db).get("BAZILION_AGENT_LOOP_MAX_HOPS") : void 0);
|
|
24655
|
+
const parsed = Number(raw2);
|
|
24656
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : DEFAULT_MAX_HOPS;
|
|
24657
|
+
}
|
|
24658
|
+
var AgentLoopLimitError = class extends Error {
|
|
24659
|
+
constructor(event2) {
|
|
24660
|
+
super(
|
|
24661
|
+
`agent message chain ${event2.causalChainId} stopped at hop ${event2.attemptedHop} (limit ${event2.maxHops})`
|
|
24662
|
+
);
|
|
24663
|
+
this.event = event2;
|
|
24664
|
+
this.name = "AgentLoopLimitError";
|
|
24665
|
+
}
|
|
24666
|
+
event;
|
|
24667
|
+
};
|
|
24668
|
+
function resolveMessageCausality(db, input) {
|
|
24669
|
+
const parentMessageId = input.replyTo ?? input.causalParentMessageId ?? null;
|
|
24670
|
+
if (!parentMessageId) return { parentMessageId: null };
|
|
24671
|
+
const parent = messages_exports.get(db, parentMessageId);
|
|
24672
|
+
if (!parent) return { parentMessageId: null };
|
|
24673
|
+
return {
|
|
24674
|
+
causalChainId: parent.causalChainId,
|
|
24675
|
+
causalHop: parent.causalHop + 1,
|
|
24676
|
+
parentMessageId: parent.id
|
|
24677
|
+
};
|
|
24678
|
+
}
|
|
24679
|
+
function enforceMessageCausality(db, input) {
|
|
24680
|
+
const attemptedHop = input.causality.causalHop ?? 0;
|
|
24681
|
+
const maxHops = agentLoopMaxHops(db);
|
|
24682
|
+
if (attemptedHop <= maxHops) return null;
|
|
24683
|
+
const source = agents_exports.get(db, input.from);
|
|
24684
|
+
const target = agents_exports.get(db, input.to);
|
|
24685
|
+
if (!source || !target) return null;
|
|
24686
|
+
const event2 = {
|
|
24687
|
+
id: randomUUID17(),
|
|
24688
|
+
causalChainId: input.causality.causalChainId ?? input.causality.parentMessageId ?? randomUUID17(),
|
|
24689
|
+
parentMessageId: input.causality.parentMessageId,
|
|
24690
|
+
fromAgentId: input.from,
|
|
24691
|
+
toAgentId: input.to,
|
|
24692
|
+
sourceTeamId: source.teamId,
|
|
24693
|
+
targetTeamId: target.teamId,
|
|
24694
|
+
attemptedHop,
|
|
24695
|
+
maxHops,
|
|
24696
|
+
reason: "causal_hop_limit_exceeded",
|
|
24697
|
+
origin: input.origin,
|
|
24698
|
+
createdAt: Date.now()
|
|
24699
|
+
};
|
|
24700
|
+
db.raw.run(
|
|
24701
|
+
`INSERT INTO agent_loop_break_events
|
|
24702
|
+
(id, causal_chain_id, parent_message_id, from_agent_id, to_agent_id,
|
|
24703
|
+
source_team_id, target_team_id, attempted_hop, max_hops, reason, origin, created_at)
|
|
24704
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
24705
|
+
[
|
|
24706
|
+
event2.id,
|
|
24707
|
+
event2.causalChainId,
|
|
24708
|
+
event2.parentMessageId,
|
|
24709
|
+
event2.fromAgentId,
|
|
24710
|
+
event2.toAgentId,
|
|
24711
|
+
event2.sourceTeamId,
|
|
24712
|
+
event2.targetTeamId,
|
|
24713
|
+
event2.attemptedHop,
|
|
24714
|
+
event2.maxHops,
|
|
24715
|
+
event2.reason,
|
|
24716
|
+
event2.origin,
|
|
24717
|
+
event2.createdAt
|
|
24718
|
+
]
|
|
24719
|
+
);
|
|
24720
|
+
return event2;
|
|
24721
|
+
}
|
|
24722
|
+
function listAgentLoopBreaks(db, agentId, limit = 50) {
|
|
24723
|
+
return db.raw.query(
|
|
24724
|
+
`SELECT * FROM agent_loop_break_events
|
|
24725
|
+
WHERE from_agent_id = ? OR to_agent_id = ?
|
|
24726
|
+
ORDER BY created_at DESC, id DESC LIMIT ?`
|
|
24727
|
+
).all(agentId, agentId, Math.max(1, Math.min(limit, 100))).map(toEvent);
|
|
24728
|
+
}
|
|
24729
|
+
function selectCausalParent(messages) {
|
|
24730
|
+
let selected;
|
|
24731
|
+
for (const message of messages) {
|
|
24732
|
+
if (!selected || message.causalHop > selected.causalHop) selected = message;
|
|
24733
|
+
}
|
|
24734
|
+
return selected?.id ?? null;
|
|
24735
|
+
}
|
|
24736
|
+
|
|
24116
24737
|
// ../daemon/src/lib/agent-turn.ts
|
|
24117
|
-
import { randomUUID as
|
|
24738
|
+
import { randomUUID as randomUUID21 } from "crypto";
|
|
24118
24739
|
|
|
24119
24740
|
// ../daemon/src/runtime/auth/openai-codex.ts
|
|
24120
24741
|
import { loginOpenAICodex, refreshOpenAICodexToken } from "@earendil-works/pi-ai/oauth";
|
|
@@ -24896,9 +25517,9 @@ function isRetryableError(err) {
|
|
|
24896
25517
|
return false;
|
|
24897
25518
|
}
|
|
24898
25519
|
function sleepWithAbort(ms, signal) {
|
|
24899
|
-
return new Promise((resolve7,
|
|
25520
|
+
return new Promise((resolve7, reject2) => {
|
|
24900
25521
|
if (signal?.aborted) {
|
|
24901
|
-
|
|
25522
|
+
reject2(new Error("aborted"));
|
|
24902
25523
|
return;
|
|
24903
25524
|
}
|
|
24904
25525
|
const t = setTimeout(() => {
|
|
@@ -24907,7 +25528,7 @@ function sleepWithAbort(ms, signal) {
|
|
|
24907
25528
|
}, ms);
|
|
24908
25529
|
const onAbort = () => {
|
|
24909
25530
|
clearTimeout(t);
|
|
24910
|
-
|
|
25531
|
+
reject2(new Error("aborted"));
|
|
24911
25532
|
};
|
|
24912
25533
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
24913
25534
|
});
|
|
@@ -25418,7 +26039,7 @@ var PROVIDERS = {
|
|
|
25418
26039
|
function createProviderRegistry(config2, opts = {}) {
|
|
25419
26040
|
const cache = /* @__PURE__ */ new Map();
|
|
25420
26041
|
const enabledSet = opts.enabledSet;
|
|
25421
|
-
function
|
|
26042
|
+
function get17(name) {
|
|
25422
26043
|
const cached2 = cache.get(name);
|
|
25423
26044
|
if (cached2) return cached2;
|
|
25424
26045
|
const entry = PROVIDERS[name];
|
|
@@ -25450,7 +26071,7 @@ function createProviderRegistry(config2, opts = {}) {
|
|
|
25450
26071
|
}
|
|
25451
26072
|
const providerName = modelString.slice(0, idx);
|
|
25452
26073
|
const model = modelString.slice(idx + 1);
|
|
25453
|
-
return { provider:
|
|
26074
|
+
return { provider: get17(providerName), model };
|
|
25454
26075
|
},
|
|
25455
26076
|
list() {
|
|
25456
26077
|
return Object.entries(PROVIDERS).filter(([name, entry]) => {
|
|
@@ -25598,11 +26219,34 @@ ${agent.team.userMd.trim()}`
|
|
|
25598
26219
|
This team's USER.md is empty. As you learn STABLE facts about the human (preferences, role, working hours, how they like to be addressed), populate it via \`user_md_get\` then \`user_md_write\` (always get first \u2014 you need the etag). Reserve this for things you're confident are durable \u2014 project knowledge belongs in \`memory_write\`, personal notes about yourself in \`home_write\` on IDENTITY.md. **Do NOT send peer messages announcing USER.md changes \u2014 every agent in the team sees the new content in their system prompt on their next turn automatically.**`
|
|
25599
26220
|
);
|
|
25600
26221
|
}
|
|
26222
|
+
const reviewedLessons = boundReviewedLessons(agent.privateLessons);
|
|
26223
|
+
if (reviewedLessons.length > 0) {
|
|
26224
|
+
parts.push(
|
|
26225
|
+
`# Reviewed lessons
|
|
26226
|
+
|
|
26227
|
+
These private lessons were explicitly approved by the human for your behavior. Follow them when relevant; current user instructions and higher-priority policy still win.
|
|
26228
|
+
|
|
26229
|
+
${reviewedLessons.map((lesson) => `- ${lesson}`).join("\n")}`
|
|
26230
|
+
);
|
|
26231
|
+
}
|
|
25601
26232
|
parts.push(
|
|
25602
26233
|
"# Memory\n\nYou share a persistent memory backend with every other agent in this team. Use `memory_write` to remember things across sessions, and `memory_search` / `memory_read` / `memory_list` to recall them. This memory is for project knowledge \u2014 codebase notes, decisions, things the user told you about the work. For personal notes about yourself (preferences, persona quirks), use `home_write` on IDENTITY.md instead. Always check memory at the start of a session: another agent in the team may have already learned something useful. **Do NOT send peer messages announcing memory writes \u2014 every agent has access to the same store via `memory_search` and will find your note when they need it.**"
|
|
25603
26234
|
);
|
|
25604
26235
|
return parts.join("\n\n---\n\n");
|
|
25605
26236
|
}
|
|
26237
|
+
function boundReviewedLessons(lessons, maxCharacters = 8e3) {
|
|
26238
|
+
const selected = [];
|
|
26239
|
+
let used = 0;
|
|
26240
|
+
for (const raw2 of lessons) {
|
|
26241
|
+
const lesson = raw2.trim();
|
|
26242
|
+
if (!lesson) continue;
|
|
26243
|
+
const remaining = maxCharacters - used;
|
|
26244
|
+
if (remaining <= 0) break;
|
|
26245
|
+
selected.push(lesson.slice(0, remaining));
|
|
26246
|
+
used += Math.min(lesson.length, remaining);
|
|
26247
|
+
}
|
|
26248
|
+
return selected;
|
|
26249
|
+
}
|
|
25606
26250
|
|
|
25607
26251
|
// ../daemon/src/runtime/shell/tooling.ts
|
|
25608
26252
|
import { existsSync as existsSync12, lstatSync as lstatSync2, realpathSync as realpathSync2 } from "fs";
|
|
@@ -25993,7 +26637,7 @@ function createApprovalGatedBashTool(base, host2) {
|
|
|
25993
26637
|
|
|
25994
26638
|
// ../daemon/src/runtime/shell/docker.ts
|
|
25995
26639
|
import { spawn } from "child_process";
|
|
25996
|
-
import { randomUUID as
|
|
26640
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
25997
26641
|
import { closeSync as closeSync2, constants as constants2, mkdtempSync as mkdtempSync2, openSync as openSync2, rmSync as rmSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
25998
26642
|
import { access, realpath, stat } from "fs/promises";
|
|
25999
26643
|
import { tmpdir as tmpdir2 } from "os";
|
|
@@ -26144,7 +26788,7 @@ function createDockerBashOperations(options) {
|
|
|
26144
26788
|
const dockerClientEnv = await resolveLocalDockerClientEnv(dockerPath, hostEnv);
|
|
26145
26789
|
const resolvedImage = await inspectSandboxImage(dockerPath, image, dockerClientEnv);
|
|
26146
26790
|
if (signal?.aborted) throw new Error("aborted");
|
|
26147
|
-
const containerName = `bazilion-bash-${process.pid}-${
|
|
26791
|
+
const containerName = `bazilion-bash-${process.pid}-${randomUUID18().replaceAll("-", "")}`;
|
|
26148
26792
|
const spec = buildDockerRunSpec({
|
|
26149
26793
|
image,
|
|
26150
26794
|
env,
|
|
@@ -26175,7 +26819,7 @@ function executeDockerRun(spec, options) {
|
|
|
26175
26819
|
)
|
|
26176
26820
|
);
|
|
26177
26821
|
}
|
|
26178
|
-
return new Promise((resolve7,
|
|
26822
|
+
return new Promise((resolve7, reject2) => {
|
|
26179
26823
|
const child = spawn(spec.executable, spec.args, {
|
|
26180
26824
|
stdio: ["ignore", "pipe", "pipe", envFileFd ?? "ignore"],
|
|
26181
26825
|
windowsHide: true,
|
|
@@ -26199,23 +26843,23 @@ function executeDockerRun(spec, options) {
|
|
|
26199
26843
|
if (!termination && options.signal?.aborted) termination = "aborted";
|
|
26200
26844
|
if (termination) {
|
|
26201
26845
|
await removeContainer(spec.executable, spec.containerName, spec.processEnv);
|
|
26202
|
-
|
|
26846
|
+
reject2(
|
|
26203
26847
|
termination === "aborted" ? new Error("aborted") : new Error(`timeout:${options.timeout}`)
|
|
26204
26848
|
);
|
|
26205
26849
|
return;
|
|
26206
26850
|
}
|
|
26207
26851
|
if (spawnError) {
|
|
26208
|
-
|
|
26852
|
+
reject2(formatSpawnError(spec.executable, spawnError));
|
|
26209
26853
|
return;
|
|
26210
26854
|
}
|
|
26211
26855
|
if (exitCode === 125) {
|
|
26212
26856
|
await removeContainer(spec.executable, spec.containerName, spec.processEnv);
|
|
26213
|
-
|
|
26857
|
+
reject2(formatDockerRunError(spec, stderr));
|
|
26214
26858
|
return;
|
|
26215
26859
|
}
|
|
26216
26860
|
if (exitCode === null) {
|
|
26217
26861
|
await removeContainer(spec.executable, spec.containerName, spec.processEnv);
|
|
26218
|
-
|
|
26862
|
+
reject2(new Error(`Docker sandbox CLI for container "${spec.containerName}" was killed`));
|
|
26219
26863
|
return;
|
|
26220
26864
|
}
|
|
26221
26865
|
resolve7({ exitCode });
|
|
@@ -26387,7 +27031,7 @@ async function inspectSandboxImage(dockerPath, image, processEnv) {
|
|
|
26387
27031
|
return id;
|
|
26388
27032
|
}
|
|
26389
27033
|
function runDockerInspection(dockerPath, args, processEnv, subject) {
|
|
26390
|
-
return new Promise((resolve7,
|
|
27034
|
+
return new Promise((resolve7, reject2) => {
|
|
26391
27035
|
const child = spawn(dockerPath, args, {
|
|
26392
27036
|
stdio: ["ignore", "pipe", "pipe"],
|
|
26393
27037
|
windowsHide: true,
|
|
@@ -26401,7 +27045,7 @@ function runDockerInspection(dockerPath, args, processEnv, subject) {
|
|
|
26401
27045
|
settled = true;
|
|
26402
27046
|
clearTimeout(timeoutHandle);
|
|
26403
27047
|
if (error2) {
|
|
26404
|
-
|
|
27048
|
+
reject2(error2);
|
|
26405
27049
|
return;
|
|
26406
27050
|
}
|
|
26407
27051
|
resolve7(stdout.trim());
|
|
@@ -27918,7 +28562,8 @@ async function createBazilionSession(opts) {
|
|
|
27918
28562
|
mcpTools,
|
|
27919
28563
|
fileSink,
|
|
27920
28564
|
bashApprovalHost,
|
|
27921
|
-
refreshApiKey
|
|
28565
|
+
refreshApiKey,
|
|
28566
|
+
restricted
|
|
27922
28567
|
} = opts;
|
|
27923
28568
|
const { providerName, modelId } = splitModelString(agent.model);
|
|
27924
28569
|
if (enabledProviders.size > 0 && !enabledProviders.has(providerName)) {
|
|
@@ -27950,9 +28595,9 @@ async function createBazilionSession(opts) {
|
|
|
27950
28595
|
}
|
|
27951
28596
|
const cwd = agent.team.path;
|
|
27952
28597
|
if (!existsSync14(cwd)) mkdirSync6(cwd, { recursive: true });
|
|
27953
|
-
const promptSkills = loadPromptSkills(paths.skillsDir, agent.skills);
|
|
28598
|
+
const promptSkills = restricted ? [] : loadPromptSkills(paths.skillsDir, agent.skills);
|
|
27954
28599
|
const uploadsDir = join19(agent.agent.dir, "uploads");
|
|
27955
|
-
const shellTools = createSessionShellTools(cwd, env, {
|
|
28600
|
+
const shellTools = restricted ? null : createSessionShellTools(cwd, env, {
|
|
27956
28601
|
...existsSync14(uploadsDir) ? { inputsDir: uploadsDir } : {},
|
|
27957
28602
|
skillMounts: promptSkills.map((skill) => ({
|
|
27958
28603
|
source: skill.hostDir,
|
|
@@ -27960,9 +28605,9 @@ async function createBazilionSession(opts) {
|
|
|
27960
28605
|
})),
|
|
27961
28606
|
approvalHost: bashApprovalHost
|
|
27962
28607
|
});
|
|
27963
|
-
const sessionDir = join19(paths.agentDir(agent.agent.id), "sessions");
|
|
28608
|
+
const sessionDir = restricted?.sessionDir ?? join19(paths.agentDir(agent.agent.id), "sessions");
|
|
27964
28609
|
mkdirSync6(sessionDir, { recursive: true });
|
|
27965
|
-
const existing = findMostRecent(sessionDir);
|
|
28610
|
+
const existing = restricted ? null : findMostRecent(sessionDir);
|
|
27966
28611
|
const sessionManager = existing ? SessionManager.open(existing, sessionDir, cwd) : SessionManager.create(cwd, sessionDir);
|
|
27967
28612
|
const settingsManager = SettingsManager.inMemory({
|
|
27968
28613
|
compaction: { enabled: false },
|
|
@@ -27973,13 +28618,13 @@ async function createBazilionSession(opts) {
|
|
|
27973
28618
|
provider: { maxRetryDelayMs: 8e3 }
|
|
27974
28619
|
}
|
|
27975
28620
|
});
|
|
27976
|
-
const bazilionPrompt = buildSystemPrompt(agent, {
|
|
28621
|
+
const bazilionPrompt = restricted?.systemPrompt ?? buildSystemPrompt(agent, {
|
|
27977
28622
|
skills: promptSkills,
|
|
27978
|
-
sandboxMode: shellTools
|
|
28623
|
+
sandboxMode: shellTools?.config.sandboxMode ?? "off"
|
|
27979
28624
|
});
|
|
27980
28625
|
const resourceLoader = createBazilionResourceLoader(bazilionPrompt);
|
|
27981
28626
|
await resourceLoader.reload();
|
|
27982
|
-
const bazilionTools = createBazilionCustomTools({
|
|
28627
|
+
const bazilionTools = restricted ? restricted.tools : createBazilionCustomTools({
|
|
27983
28628
|
agent,
|
|
27984
28629
|
memory,
|
|
27985
28630
|
messagingHost,
|
|
@@ -27990,13 +28635,13 @@ async function createBazilionSession(opts) {
|
|
|
27990
28635
|
fileSink,
|
|
27991
28636
|
env
|
|
27992
28637
|
});
|
|
27993
|
-
const customTools = shellTools
|
|
27994
|
-
const allowedTools = [...shellTools
|
|
28638
|
+
const customTools = shellTools?.customBash ? [...bazilionTools, shellTools.customBash] : bazilionTools;
|
|
28639
|
+
const allowedTools = [...shellTools?.hostToolNames ?? [], ...customTools.map((t) => t.name)];
|
|
27995
28640
|
const { session } = await createAgentSession({
|
|
27996
28641
|
cwd,
|
|
27997
28642
|
agentDir: join19(paths.home, "pi"),
|
|
27998
28643
|
model,
|
|
27999
|
-
thinkingLevel: toPiThinkingLevel(agent.reasoningLevel),
|
|
28644
|
+
thinkingLevel: toPiThinkingLevel(restricted?.reasoningLevel ?? agent.reasoningLevel),
|
|
28000
28645
|
tools: allowedTools,
|
|
28001
28646
|
customTools,
|
|
28002
28647
|
sessionManager,
|
|
@@ -28138,6 +28783,17 @@ function loadInitialMessages(agent, paths) {
|
|
|
28138
28783
|
return [];
|
|
28139
28784
|
}
|
|
28140
28785
|
}
|
|
28786
|
+
function loadSessionMessages(agent, paths, sessionId) {
|
|
28787
|
+
if (!/^[A-Za-z0-9._-]+$/.test(sessionId)) return [];
|
|
28788
|
+
const sessionDir = join19(paths.agentDir(agent.agent.id), "sessions");
|
|
28789
|
+
const file = join19(sessionDir, `${sessionId}.jsonl`);
|
|
28790
|
+
if (!existsSync14(file) || !existsSync14(agent.team.path)) return [];
|
|
28791
|
+
try {
|
|
28792
|
+
return SessionManager.open(file, sessionDir).buildSessionContext().messages;
|
|
28793
|
+
} catch {
|
|
28794
|
+
return [];
|
|
28795
|
+
}
|
|
28796
|
+
}
|
|
28141
28797
|
function loadSessionHead(agent, paths) {
|
|
28142
28798
|
const sessionDir = join19(paths.agentDir(agent.agent.id), "sessions");
|
|
28143
28799
|
if (!existsSync14(sessionDir)) return { file: null, size: 0 };
|
|
@@ -28319,7 +28975,7 @@ function assertOpenAICodexProvider(requested, expected) {
|
|
|
28319
28975
|
}
|
|
28320
28976
|
function waitForRefresh(pending, signal) {
|
|
28321
28977
|
if (!signal) return pending;
|
|
28322
|
-
return new Promise((resolve7,
|
|
28978
|
+
return new Promise((resolve7, reject2) => {
|
|
28323
28979
|
let settled = false;
|
|
28324
28980
|
const finish = (callback) => {
|
|
28325
28981
|
if (settled) return;
|
|
@@ -28327,7 +28983,7 @@ function waitForRefresh(pending, signal) {
|
|
|
28327
28983
|
signal.removeEventListener("abort", onAbort);
|
|
28328
28984
|
callback();
|
|
28329
28985
|
};
|
|
28330
|
-
const onAbort = () => finish(() =>
|
|
28986
|
+
const onAbort = () => finish(() => reject2(refreshCancelledError()));
|
|
28331
28987
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
28332
28988
|
if (signal.aborted) {
|
|
28333
28989
|
onAbort();
|
|
@@ -28335,7 +28991,7 @@ function waitForRefresh(pending, signal) {
|
|
|
28335
28991
|
}
|
|
28336
28992
|
pending.then(
|
|
28337
28993
|
(value) => finish(() => resolve7(value)),
|
|
28338
|
-
(error2) => finish(() =>
|
|
28994
|
+
(error2) => finish(() => reject2(error2))
|
|
28339
28995
|
);
|
|
28340
28996
|
});
|
|
28341
28997
|
}
|
|
@@ -28366,6 +29022,14 @@ function tsxImportSpecifier() {
|
|
|
28366
29022
|
cachedTsxImport = pathToFileURL(req.resolve("tsx")).href;
|
|
28367
29023
|
return cachedTsxImport;
|
|
28368
29024
|
}
|
|
29025
|
+
async function spawnReviewWorker(spec, opts = {}) {
|
|
29026
|
+
for await (const rawFrame of spawnWorkerTurn(spec, opts)) {
|
|
29027
|
+
const frame = rawFrame;
|
|
29028
|
+
if (frame.kind === "review_result") return frame.proposals;
|
|
29029
|
+
if (frame.kind === "fatal") throw new Error(frame.error);
|
|
29030
|
+
}
|
|
29031
|
+
throw new Error("review worker exited without a result");
|
|
29032
|
+
}
|
|
28369
29033
|
async function* spawnWorkerTurn(spec, opts = {}) {
|
|
28370
29034
|
const child = spawn2(process.execPath, workerSpawnArgs(opts.workerEntryPath), {
|
|
28371
29035
|
env: opts.env ?? process.env,
|
|
@@ -28648,7 +29312,7 @@ async function resolveAgentApiKey(db, authToken, agent, opts = {}) {
|
|
|
28648
29312
|
}
|
|
28649
29313
|
|
|
28650
29314
|
// ../daemon/src/lib/attachments.ts
|
|
28651
|
-
import { randomUUID as
|
|
29315
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
28652
29316
|
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync10 } from "fs";
|
|
28653
29317
|
import { join as join20, posix } from "path";
|
|
28654
29318
|
var MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|
@@ -28673,7 +29337,7 @@ function saveInputFiles(agentDir, files, options = {}) {
|
|
|
28673
29337
|
lines.push(`[attachment "${label}" skipped: too large (${fmtBytes(buf.byteLength)} > 25 MB)]`);
|
|
28674
29338
|
continue;
|
|
28675
29339
|
}
|
|
28676
|
-
const filename = `${
|
|
29340
|
+
const filename = `${randomUUID19().slice(0, 8)}-${safeName(label)}`;
|
|
28677
29341
|
const path = join20(dir, filename);
|
|
28678
29342
|
writeFileSync10(path, buf);
|
|
28679
29343
|
const referencePath = options.referenceDir ? posix.join(options.referenceDir, filename) : path;
|
|
@@ -28959,10 +29623,10 @@ async function getSsrfProxy() {
|
|
|
28959
29623
|
if (serverUrl) return serverUrl;
|
|
28960
29624
|
const s = createServer(onRequest);
|
|
28961
29625
|
s.on("connect", onConnect);
|
|
28962
|
-
await new Promise((resolve7,
|
|
28963
|
-
s.once("error",
|
|
29626
|
+
await new Promise((resolve7, reject2) => {
|
|
29627
|
+
s.once("error", reject2);
|
|
28964
29628
|
s.listen(0, "127.0.0.1", () => {
|
|
28965
|
-
s.off("error",
|
|
29629
|
+
s.off("error", reject2);
|
|
28966
29630
|
resolve7();
|
|
28967
29631
|
});
|
|
28968
29632
|
});
|
|
@@ -29358,7 +30022,7 @@ function createBrowserHost(config2) {
|
|
|
29358
30022
|
}
|
|
29359
30023
|
|
|
29360
30024
|
// ../daemon/src/lib/communication.ts
|
|
29361
|
-
import { randomUUID as
|
|
30025
|
+
import { randomUUID as randomUUID20 } from "crypto";
|
|
29362
30026
|
|
|
29363
30027
|
// ../daemon/src/lib/team-policy-contract.ts
|
|
29364
30028
|
var TEAM_POLICY_MANAGEMENT_CONTRACT_VERSION = 1;
|
|
@@ -29503,11 +30167,26 @@ function isUserFacingFrame(frame) {
|
|
|
29503
30167
|
return frame.event.type === "assistant_message" || frame.event.type === "assistant_delta" || frame.event.type === "file" || frame.event.type === "tool_result" && Boolean(frame.event.images?.length) || frame.event.type === "error";
|
|
29504
30168
|
}
|
|
29505
30169
|
function sendAgentMessage(db, input) {
|
|
29506
|
-
if (!teamPolicyEnforcementEnabled()) return messages_exports.send(db, input);
|
|
29507
30170
|
const attemptKind = input.attemptKind ?? "agent_tool";
|
|
29508
|
-
const attemptId = input.attemptId ??
|
|
30171
|
+
const attemptId = input.attemptId ?? randomUUID20();
|
|
29509
30172
|
const outcome = db.raw.transaction(
|
|
29510
30173
|
() => {
|
|
30174
|
+
const causality = resolveMessageCausality(db, input);
|
|
30175
|
+
const loopBreak = enforceMessageCausality(db, {
|
|
30176
|
+
from: input.from,
|
|
30177
|
+
to: input.to,
|
|
30178
|
+
origin: input.origin,
|
|
30179
|
+
causality
|
|
30180
|
+
});
|
|
30181
|
+
if (loopBreak) return { loopBreak };
|
|
30182
|
+
const messageInput = {
|
|
30183
|
+
...input,
|
|
30184
|
+
causalChainId: causality.causalChainId,
|
|
30185
|
+
causalHop: causality.causalHop
|
|
30186
|
+
};
|
|
30187
|
+
if (!teamPolicyEnforcementEnabled()) {
|
|
30188
|
+
return { message: messages_exports.send(db, messageInput) };
|
|
30189
|
+
}
|
|
29511
30190
|
const authorization = {
|
|
29512
30191
|
source: { kind: "agent", id: input.from },
|
|
29513
30192
|
target: { kind: "agent", id: input.to },
|
|
@@ -29523,9 +30202,10 @@ function sendAgentMessage(db, input) {
|
|
|
29523
30202
|
if (result.decision === "approval_required") {
|
|
29524
30203
|
return { approval: { authorization: result, input: authorization } };
|
|
29525
30204
|
}
|
|
29526
|
-
return { message: messages_exports.send(db,
|
|
30205
|
+
return { message: messages_exports.send(db, messageInput) };
|
|
29527
30206
|
}
|
|
29528
30207
|
)();
|
|
30208
|
+
if (outcome.loopBreak) throw new AgentLoopLimitError(outcome.loopBreak);
|
|
29529
30209
|
if (outcome.denial) {
|
|
29530
30210
|
observeDenial(outcome.denial, { origin: input.origin, attemptKind, attemptId });
|
|
29531
30211
|
throw new CommunicationDeniedError(outcome.denial, attemptKind, attemptId);
|
|
@@ -29541,7 +30221,8 @@ function sendAgentMessage(db, input) {
|
|
|
29541
30221
|
from: input.from,
|
|
29542
30222
|
to: input.to,
|
|
29543
30223
|
payload: input.payload,
|
|
29544
|
-
replyTo: input.replyTo ?? null
|
|
30224
|
+
replyTo: input.replyTo ?? null,
|
|
30225
|
+
causalParentMessageId: input.causalParentMessageId ?? null
|
|
29545
30226
|
},
|
|
29546
30227
|
{ requester: input.from }
|
|
29547
30228
|
);
|
|
@@ -29982,17 +30663,21 @@ async function resolveMcpForTurn(db, env, authToken) {
|
|
|
29982
30663
|
}
|
|
29983
30664
|
|
|
29984
30665
|
// ../daemon/src/lib/messaging-host.ts
|
|
29985
|
-
function createDbMessagingHost(db) {
|
|
30666
|
+
function createDbMessagingHost(db, opts = {}) {
|
|
29986
30667
|
return {
|
|
29987
30668
|
agentExists(agentId) {
|
|
29988
30669
|
return agents_exports.get(db, agentId) !== null;
|
|
29989
30670
|
},
|
|
29990
30671
|
sendMessage(input) {
|
|
29991
|
-
const m2 = sendAgentMessage(db, {
|
|
30672
|
+
const m2 = sendAgentMessage(db, {
|
|
30673
|
+
...input,
|
|
30674
|
+
causalParentMessageId: opts.causalParentMessageId,
|
|
30675
|
+
origin: "agent_tool"
|
|
30676
|
+
});
|
|
29992
30677
|
return { messageId: m2.id };
|
|
29993
30678
|
},
|
|
29994
|
-
listInbox(agentId,
|
|
29995
|
-
return deliverableInbox(db, agentId,
|
|
30679
|
+
listInbox(agentId, opts2) {
|
|
30680
|
+
return deliverableInbox(db, agentId, opts2?.unreadOnly === true);
|
|
29996
30681
|
},
|
|
29997
30682
|
markRead(messageId) {
|
|
29998
30683
|
messages_exports.markRead(db, messageId);
|
|
@@ -31965,7 +32650,7 @@ async function* runAgentTurn(agentId, rawMessage, opts = {}) {
|
|
|
31965
32650
|
const authorization = opts.authorization ?? {
|
|
31966
32651
|
origin: "internal_turn",
|
|
31967
32652
|
attemptKind: "turn",
|
|
31968
|
-
attemptId:
|
|
32653
|
+
attemptId: randomUUID21()
|
|
31969
32654
|
};
|
|
31970
32655
|
const releaseLease = opts.acquiredLeaseRelease ?? await acquireAgentLifecycleLease(agentId);
|
|
31971
32656
|
let agent;
|
|
@@ -32009,7 +32694,9 @@ async function* runAgentTurn(agentId, rawMessage, opts = {}) {
|
|
|
32009
32694
|
|
|
32010
32695
|
${fileNote}` : fileNote : rawMessage;
|
|
32011
32696
|
const enabledProviders = Array.from(providerState_exports.listEnabled(db));
|
|
32012
|
-
const messagingHost = createDbMessagingHost(db
|
|
32697
|
+
const messagingHost = createDbMessagingHost(db, {
|
|
32698
|
+
causalParentMessageId: opts.causalParentMessageId
|
|
32699
|
+
});
|
|
32013
32700
|
const userMdHost = createDbUserMdHost(db, paths);
|
|
32014
32701
|
const { apiKey, refreshApiKey } = await resolveAgentApiKey(db, authToken, agent, {
|
|
32015
32702
|
withRefresher: true
|
|
@@ -32019,6 +32706,7 @@ ${fileNote}` : fileNote : rawMessage;
|
|
|
32019
32706
|
const mcp = await resolveMcpForTurn(db, env, authToken);
|
|
32020
32707
|
mirrorTypingStart(agentId, `${authorization.attemptKind}:${authorization.attemptId}:typing`);
|
|
32021
32708
|
let mirrorFrameIndex = 0;
|
|
32709
|
+
let completed = false;
|
|
32022
32710
|
for await (const frame of spawnWorkerTurn(
|
|
32023
32711
|
{
|
|
32024
32712
|
agent,
|
|
@@ -32052,8 +32740,12 @@ ${fileNote}` : fileNote : rawMessage;
|
|
|
32052
32740
|
e instanceof Error ? e.message : String(e)
|
|
32053
32741
|
);
|
|
32054
32742
|
});
|
|
32743
|
+
if (frame.kind === "done") completed = true;
|
|
32055
32744
|
yield frame;
|
|
32056
32745
|
}
|
|
32746
|
+
if (completed && (authorization.origin === "http_chat" || authorization.origin.startsWith("telegram"))) {
|
|
32747
|
+
agentReviews_exports.recordSuccessfulUserTurn(db, agentId);
|
|
32748
|
+
}
|
|
32057
32749
|
} finally {
|
|
32058
32750
|
mirrorTypingStop(agentId);
|
|
32059
32751
|
unregisterAgent(agentId);
|
|
@@ -32131,6 +32823,194 @@ function validateCron(expr) {
|
|
|
32131
32823
|
parseCron(expr);
|
|
32132
32824
|
}
|
|
32133
32825
|
|
|
32826
|
+
// ../daemon/src/lib/review-digest.ts
|
|
32827
|
+
var SECRET_PATTERNS = [
|
|
32828
|
+
/\bBearer\s+[A-Za-z0-9._~+/-]+=*/gi,
|
|
32829
|
+
/\b(?:sk|pk)-[A-Za-z0-9_-]{12,}\b/g,
|
|
32830
|
+
/\b(?:api[_-]?key|token|password)\s*[:=]\s*[^\s,;]+/gi
|
|
32831
|
+
];
|
|
32832
|
+
function redactReviewText(text2) {
|
|
32833
|
+
return SECRET_PATTERNS.reduce((value, pattern) => value.replace(pattern, "[REDACTED]"), text2);
|
|
32834
|
+
}
|
|
32835
|
+
function buildReviewDigest(input, options = {}) {
|
|
32836
|
+
const maxUserTurns = options.maxUserTurns ?? 8;
|
|
32837
|
+
const maxCharacters = options.maxCharacters ?? 4e4;
|
|
32838
|
+
const normalized = input.filter((entry) => !entry.sensitive && entry.ordinal >= 0 && entry.text.trim()).map((entry) => ({
|
|
32839
|
+
...entry,
|
|
32840
|
+
text: entry.role === "tool" ? `[tool:${entry.toolName?.trim() || "unknown"}] completed` : redactReviewText(entry.text.trim())
|
|
32841
|
+
}));
|
|
32842
|
+
if (normalized.length === 0) return null;
|
|
32843
|
+
const selected = [];
|
|
32844
|
+
let userTurns = 0;
|
|
32845
|
+
let characters = 0;
|
|
32846
|
+
for (let index = normalized.length - 1; index >= 0; index -= 1) {
|
|
32847
|
+
const entry = normalized[index];
|
|
32848
|
+
if (!entry) continue;
|
|
32849
|
+
if (entry.role === "user" && userTurns >= maxUserTurns) break;
|
|
32850
|
+
const remaining = maxCharacters - characters;
|
|
32851
|
+
if (remaining <= 0) break;
|
|
32852
|
+
const text2 = entry.text.slice(Math.max(0, entry.text.length - remaining));
|
|
32853
|
+
if (!text2) break;
|
|
32854
|
+
selected.push({ ...entry, text: text2 });
|
|
32855
|
+
characters += text2.length;
|
|
32856
|
+
if (entry.role === "user") userTurns += 1;
|
|
32857
|
+
}
|
|
32858
|
+
selected.reverse();
|
|
32859
|
+
const firstUserIndex = selected.findIndex((entry) => entry.role === "user");
|
|
32860
|
+
const bounded2 = firstUserIndex >= 0 ? selected.slice(firstUserIndex) : selected;
|
|
32861
|
+
characters = bounded2.reduce((total, entry) => total + entry.text.length, 0);
|
|
32862
|
+
const first = bounded2[0];
|
|
32863
|
+
const last = bounded2.at(-1);
|
|
32864
|
+
if (!first || !last) return null;
|
|
32865
|
+
return {
|
|
32866
|
+
sessionId: last.sessionId,
|
|
32867
|
+
startOrdinal: first.ordinal,
|
|
32868
|
+
endOrdinal: last.ordinal,
|
|
32869
|
+
inputCharacters: characters,
|
|
32870
|
+
turnsReviewed: userTurns,
|
|
32871
|
+
entries: bounded2
|
|
32872
|
+
};
|
|
32873
|
+
}
|
|
32874
|
+
|
|
32875
|
+
// ../daemon/src/lib/review-dispatcher.ts
|
|
32876
|
+
function messageText(message) {
|
|
32877
|
+
if (message.role === "tool") return message.toolName ?? "unknown";
|
|
32878
|
+
return message.content;
|
|
32879
|
+
}
|
|
32880
|
+
function transcriptEntries(messages, sessionId) {
|
|
32881
|
+
return messages.flatMap((message, ordinal) => {
|
|
32882
|
+
if (message.role === "system") return [];
|
|
32883
|
+
return [
|
|
32884
|
+
{
|
|
32885
|
+
sessionId,
|
|
32886
|
+
ordinal,
|
|
32887
|
+
role: message.role,
|
|
32888
|
+
text: messageText(message),
|
|
32889
|
+
...message.role === "tool" ? { toolName: message.toolName } : {}
|
|
32890
|
+
}
|
|
32891
|
+
];
|
|
32892
|
+
});
|
|
32893
|
+
}
|
|
32894
|
+
function renderReviewInput(digest, privateLessons, sharedLessonKeys) {
|
|
32895
|
+
const entries = digest.entries.map(
|
|
32896
|
+
(entry) => `[${entry.sessionId}:${entry.ordinal}] ${entry.role.toUpperCase()}: ${entry.text}`
|
|
32897
|
+
).join("\n\n");
|
|
32898
|
+
return `# Transcript digest
|
|
32899
|
+
|
|
32900
|
+
${entries}
|
|
32901
|
+
|
|
32902
|
+
# Existing private lessons
|
|
32903
|
+
${privateLessons.length ? privateLessons.map((text2) => `- ${text2}`).join("\n") : "(none)"}
|
|
32904
|
+
|
|
32905
|
+
# Existing shared lesson keys
|
|
32906
|
+
${sharedLessonKeys.length ? sharedLessonKeys.map((key2) => `- ${key2}`).join("\n") : "(none)"}`;
|
|
32907
|
+
}
|
|
32908
|
+
async function dispatchAgentReview(reviewId) {
|
|
32909
|
+
const { db, paths, authToken } = getCtx();
|
|
32910
|
+
const claimed = agentReviews_exports.claim(db, reviewId);
|
|
32911
|
+
if (!claimed) return;
|
|
32912
|
+
if (isActiveAgent(claimed.agentId)) {
|
|
32913
|
+
agentReviews_exports.defer(db, claimed.id);
|
|
32914
|
+
return;
|
|
32915
|
+
}
|
|
32916
|
+
const releaseLease = await acquireAgentLifecycleLease(claimed.agentId);
|
|
32917
|
+
const controller = new AbortController();
|
|
32918
|
+
let registered = false;
|
|
32919
|
+
try {
|
|
32920
|
+
if (isActiveAgent(claimed.agentId)) {
|
|
32921
|
+
agentReviews_exports.defer(db, claimed.id);
|
|
32922
|
+
return;
|
|
32923
|
+
}
|
|
32924
|
+
registerAgent(claimed.agentId, controller);
|
|
32925
|
+
registered = true;
|
|
32926
|
+
} finally {
|
|
32927
|
+
releaseLease();
|
|
32928
|
+
}
|
|
32929
|
+
try {
|
|
32930
|
+
const resolved = resolveAgent(db, paths, claimed.agentId);
|
|
32931
|
+
const sessionHead = loadSessionHead(resolved, paths);
|
|
32932
|
+
const sessionId = sessionHead.file?.replace(/\.jsonl$/, "") ?? "";
|
|
32933
|
+
const previous = agentReviews_exports.getLatestCompleted(db, claimed.agentId);
|
|
32934
|
+
const messages = piMessagesToProviderView(loadInitialMessages(resolved, paths));
|
|
32935
|
+
const entries = transcriptEntries(messages, sessionId).filter(
|
|
32936
|
+
(entry) => previous?.sourceSessionId !== sessionId || previous.sourceEndOrdinal === null || entry.ordinal > previous.sourceEndOrdinal
|
|
32937
|
+
);
|
|
32938
|
+
const digest = buildReviewDigest(entries);
|
|
32939
|
+
if (!digest) {
|
|
32940
|
+
agentReviews_exports.complete(db, claimed.id, 0);
|
|
32941
|
+
return;
|
|
32942
|
+
}
|
|
32943
|
+
agentReviews_exports.setSource(db, claimed.id, digest);
|
|
32944
|
+
const privateLessons = agentLessonProposals_exports.listForAgent(db, claimed.agentId, { status: "approved" }).filter((proposal) => proposal.scope === "private").map((proposal) => proposal.text);
|
|
32945
|
+
const memory = qmdBackend(`${resolved.team.path}/memory`);
|
|
32946
|
+
await memory.init();
|
|
32947
|
+
const sharedLessonKeys = (await memory.list()).map((entry) => entry.key).filter((key2) => key2.startsWith("lessons/"));
|
|
32948
|
+
const reviewAgent = {
|
|
32949
|
+
...resolved,
|
|
32950
|
+
agent: {
|
|
32951
|
+
...resolved.agent,
|
|
32952
|
+
modelOverride: resolved.agent.reviewModel,
|
|
32953
|
+
reasoningLevel: resolved.agent.reviewReasoningLevel
|
|
32954
|
+
},
|
|
32955
|
+
model: resolved.agent.reviewModel ?? resolved.model,
|
|
32956
|
+
reasoningLevel: resolved.agent.reviewReasoningLevel
|
|
32957
|
+
};
|
|
32958
|
+
const { apiKey, refreshApiKey } = await resolveAgentApiKey(db, authToken, reviewAgent, {
|
|
32959
|
+
withRefresher: true
|
|
32960
|
+
});
|
|
32961
|
+
const env = mergeSecretsIntoEnv(db, authToken);
|
|
32962
|
+
const proposals = await spawnReviewWorker(
|
|
32963
|
+
{
|
|
32964
|
+
mode: "review",
|
|
32965
|
+
review: {
|
|
32966
|
+
reviewId: claimed.id,
|
|
32967
|
+
evidence: digest.entries.map((entry) => ({
|
|
32968
|
+
sessionId: entry.sessionId,
|
|
32969
|
+
entryOrdinal: entry.ordinal
|
|
32970
|
+
}))
|
|
32971
|
+
},
|
|
32972
|
+
agent: reviewAgent,
|
|
32973
|
+
message: renderReviewInput(digest, privateLessons, sharedLessonKeys),
|
|
32974
|
+
enabledProviders: [...providerState_exports.listEnabled(db)],
|
|
32975
|
+
apiKey,
|
|
32976
|
+
turnId: claimed.id,
|
|
32977
|
+
bashApprovalMode: "auto_deny"
|
|
32978
|
+
},
|
|
32979
|
+
{
|
|
32980
|
+
signal: controller.signal,
|
|
32981
|
+
env,
|
|
32982
|
+
apiKeyRefreshHost: refreshApiKey ? { refresh: refreshApiKey } : void 0
|
|
32983
|
+
}
|
|
32984
|
+
);
|
|
32985
|
+
db.raw.transaction(() => {
|
|
32986
|
+
for (const proposal of proposals) {
|
|
32987
|
+
agentLessonProposals_exports.insert(db, {
|
|
32988
|
+
reviewId: claimed.id,
|
|
32989
|
+
agentId: claimed.agentId,
|
|
32990
|
+
scope: proposal.scope,
|
|
32991
|
+
text: proposal.text,
|
|
32992
|
+
evidence: proposal.evidenceEntryIds
|
|
32993
|
+
});
|
|
32994
|
+
}
|
|
32995
|
+
agentReviews_exports.complete(db, claimed.id, proposals.length);
|
|
32996
|
+
})();
|
|
32997
|
+
} catch (error2) {
|
|
32998
|
+
if (controller.signal.aborted) {
|
|
32999
|
+
agentReviews_exports.cancel(db, claimed.id, "cancelled");
|
|
33000
|
+
} else {
|
|
33001
|
+
agentReviews_exports.fail(db, claimed.id, error2 instanceof Error ? error2.message : String(error2));
|
|
33002
|
+
}
|
|
33003
|
+
} finally {
|
|
33004
|
+
if (registered) unregisterAgent(claimed.agentId);
|
|
33005
|
+
}
|
|
33006
|
+
}
|
|
33007
|
+
async function dispatchClaimableReviews(now = Date.now()) {
|
|
33008
|
+
const { db } = getCtx();
|
|
33009
|
+
await Promise.allSettled(
|
|
33010
|
+
agentReviews_exports.listClaimable(db, now).map((review) => dispatchAgentReview(review.id))
|
|
33011
|
+
);
|
|
33012
|
+
}
|
|
33013
|
+
|
|
32134
33014
|
// ../daemon/src/lib/turn-outcome.ts
|
|
32135
33015
|
function turnFrameFailure(frame) {
|
|
32136
33016
|
if (frame.kind === "fatal") return frame.error;
|
|
@@ -32216,7 +33096,7 @@ async function fireTrigger(dispatch2) {
|
|
|
32216
33096
|
const controller = new AbortController();
|
|
32217
33097
|
let registered = false;
|
|
32218
33098
|
try {
|
|
32219
|
-
const
|
|
33099
|
+
const claim3 = claimSchedulerTrigger(ctx.db, {
|
|
32220
33100
|
dispatchId: claimedDispatch.id,
|
|
32221
33101
|
triggerId: t.id,
|
|
32222
33102
|
agentId: t.agentId,
|
|
@@ -32227,21 +33107,21 @@ async function fireTrigger(dispatch2) {
|
|
|
32227
33107
|
registered = true;
|
|
32228
33108
|
}
|
|
32229
33109
|
});
|
|
32230
|
-
if (
|
|
33110
|
+
if (claim3.kind === "already_claimed") {
|
|
32231
33111
|
releaseLease();
|
|
32232
33112
|
triggerDispatches_exports.succeed(ctx.db, claimedDispatch.id);
|
|
32233
33113
|
s.firing.delete(key2);
|
|
32234
33114
|
return;
|
|
32235
33115
|
}
|
|
32236
|
-
if (
|
|
33116
|
+
if (claim3.kind === "approval_pending") {
|
|
32237
33117
|
releaseLease();
|
|
32238
33118
|
triggerDispatches_exports.defer(ctx.db, claimedDispatch.id, Date.now() + TICK_MS);
|
|
32239
33119
|
s.firing.delete(key2);
|
|
32240
33120
|
return;
|
|
32241
33121
|
}
|
|
32242
|
-
if (
|
|
33122
|
+
if (claim3.kind === "approval_terminal") {
|
|
32243
33123
|
releaseLease();
|
|
32244
|
-
triggerDispatches_exports.fail(ctx.db, claimedDispatch.id,
|
|
33124
|
+
triggerDispatches_exports.fail(ctx.db, claimedDispatch.id, claim3.reason, { maxAttempts: 1 });
|
|
32245
33125
|
s.firing.delete(key2);
|
|
32246
33126
|
return;
|
|
32247
33127
|
}
|
|
@@ -32370,7 +33250,8 @@ async function fireInboxWake(agentId) {
|
|
|
32370
33250
|
acquiredLeaseRelease: releaseLease,
|
|
32371
33251
|
controller,
|
|
32372
33252
|
alreadyRegistered: true,
|
|
32373
|
-
bashApprovalMode: "auto_deny"
|
|
33253
|
+
bashApprovalMode: "auto_deny",
|
|
33254
|
+
causalParentMessageId: selectCausalParent(msgs)
|
|
32374
33255
|
})) {
|
|
32375
33256
|
if (frame.kind === "fatal") {
|
|
32376
33257
|
console.error(`[scheduler] inbox wake ${agentId} fatal:`, frame.error);
|
|
@@ -32423,6 +33304,7 @@ async function tick() {
|
|
|
32423
33304
|
for (const agentId of recipients) {
|
|
32424
33305
|
work.push(fireInboxWake(agentId));
|
|
32425
33306
|
}
|
|
33307
|
+
work.push(dispatchClaimableReviews(now));
|
|
32426
33308
|
await Promise.allSettled(work);
|
|
32427
33309
|
}
|
|
32428
33310
|
function startScheduler() {
|
|
@@ -32541,7 +33423,7 @@ async function authMiddleware(c, next) {
|
|
|
32541
33423
|
}
|
|
32542
33424
|
|
|
32543
33425
|
// ../daemon/src/routes/agents.ts
|
|
32544
|
-
import { randomUUID as
|
|
33426
|
+
import { randomUUID as randomUUID22 } from "crypto";
|
|
32545
33427
|
import { existsSync as existsSync17, readdirSync as readdirSync10, readFileSync as readFileSync13, rmSync as rmSync13 } from "fs";
|
|
32546
33428
|
import { join as join21 } from "path";
|
|
32547
33429
|
|
|
@@ -32574,6 +33456,47 @@ function resolveAgentIdParam(db, raw2) {
|
|
|
32574
33456
|
return agents_exports.resolveId(db, raw2) ?? raw2;
|
|
32575
33457
|
}
|
|
32576
33458
|
|
|
33459
|
+
// ../daemon/src/lib/lesson-decisions.ts
|
|
33460
|
+
var LessonProposalConflictError = class extends Error {
|
|
33461
|
+
};
|
|
33462
|
+
function conflict() {
|
|
33463
|
+
throw new LessonProposalConflictError("proposal changed or is no longer eligible");
|
|
33464
|
+
}
|
|
33465
|
+
async function approveLessonProposal(db, memory, id, version2) {
|
|
33466
|
+
const current = agentLessonProposals_exports.get(db, id);
|
|
33467
|
+
if (!current || current.version !== version2 || current.status !== "pending") return conflict();
|
|
33468
|
+
if (current.scope === "private") {
|
|
33469
|
+
return agentLessonProposals_exports.approve(db, id, version2, null) ?? conflict();
|
|
33470
|
+
}
|
|
33471
|
+
const key2 = `lessons/${current.id}.md`;
|
|
33472
|
+
await memory.init();
|
|
33473
|
+
await memory.write(
|
|
33474
|
+
key2,
|
|
33475
|
+
`# Reviewed lesson
|
|
33476
|
+
|
|
33477
|
+
${current.text}
|
|
33478
|
+
|
|
33479
|
+
Source: agent ${current.agentId}, review ${current.reviewId}.
|
|
33480
|
+
`
|
|
33481
|
+
);
|
|
33482
|
+
const approved = agentLessonProposals_exports.approve(db, id, version2, key2);
|
|
33483
|
+
if (approved) return approved;
|
|
33484
|
+
await memory.remove(key2);
|
|
33485
|
+
return conflict();
|
|
33486
|
+
}
|
|
33487
|
+
function rejectLessonProposal(db, id, version2) {
|
|
33488
|
+
return agentLessonProposals_exports.reject(db, id, version2) ?? conflict();
|
|
33489
|
+
}
|
|
33490
|
+
async function revokeLessonProposal(db, memory, id, version2) {
|
|
33491
|
+
const current = agentLessonProposals_exports.get(db, id);
|
|
33492
|
+
if (!current || current.version !== version2 || current.status !== "approved") return conflict();
|
|
33493
|
+
if (current.appliedKey) {
|
|
33494
|
+
await memory.init();
|
|
33495
|
+
await memory.remove(current.appliedKey);
|
|
33496
|
+
}
|
|
33497
|
+
return agentLessonProposals_exports.revoke(db, id, version2) ?? conflict();
|
|
33498
|
+
}
|
|
33499
|
+
|
|
32577
33500
|
// ../daemon/src/lib/telegram/bot.ts
|
|
32578
33501
|
import { Bot, GrammyError } from "grammy";
|
|
32579
33502
|
|
|
@@ -34548,13 +35471,13 @@ agentsRouter.post("/", async (c) => {
|
|
|
34548
35471
|
return c.json({ agent, team: teamPolicies_exports.detail(db, agent.teamId) }, 201);
|
|
34549
35472
|
} catch (err) {
|
|
34550
35473
|
const message = err.message;
|
|
34551
|
-
const
|
|
35474
|
+
const conflict2 = message.startsWith("placement_required") || message.startsWith("team_policy_invalid") || message.startsWith("team_revision_conflict");
|
|
34552
35475
|
return c.json(
|
|
34553
35476
|
{
|
|
34554
35477
|
error: message,
|
|
34555
35478
|
...message.startsWith("placement_required") ? { code: "placement_required" } : message.startsWith("team_revision_conflict") ? { code: "team_revision_conflict" } : message.startsWith("team_policy_invalid") ? { code: "team_policy_invalid" } : {}
|
|
34556
35479
|
},
|
|
34557
|
-
|
|
35480
|
+
conflict2 ? 409 : 400
|
|
34558
35481
|
);
|
|
34559
35482
|
}
|
|
34560
35483
|
});
|
|
@@ -34844,13 +35767,13 @@ agentsRouter.patch("/:id/team", async (c) => {
|
|
|
34844
35767
|
});
|
|
34845
35768
|
} catch (err) {
|
|
34846
35769
|
const message = err.message;
|
|
34847
|
-
const
|
|
35770
|
+
const conflict2 = message.startsWith("agent_turn_active") || message.startsWith("placement_required") || message.startsWith("team_policy_invalid") || message.includes("team_revision_conflict");
|
|
34848
35771
|
return c.json(
|
|
34849
35772
|
{
|
|
34850
35773
|
error: message,
|
|
34851
35774
|
...message.startsWith("agent_turn_active") ? { code: "agent_turn_active" } : message.startsWith("placement_required") ? { code: "placement_required" } : message.includes("team_revision_conflict") ? { code: message.split(":")[0] } : message.startsWith("team_policy_invalid") ? { code: "team_policy_invalid" } : {}
|
|
34852
35775
|
},
|
|
34853
|
-
|
|
35776
|
+
conflict2 ? 409 : 400
|
|
34854
35777
|
);
|
|
34855
35778
|
}
|
|
34856
35779
|
});
|
|
@@ -34908,6 +35831,149 @@ agentsRouter.delete("/:id/skills/:name", (c) => {
|
|
|
34908
35831
|
agents_exports.detachSkill(db, id, c.req.param("name"));
|
|
34909
35832
|
return c.body(null, 204);
|
|
34910
35833
|
});
|
|
35834
|
+
agentsRouter.get("/:id/review-config", (c) => {
|
|
35835
|
+
const { db } = getCtx();
|
|
35836
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35837
|
+
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
35838
|
+
return c.json({
|
|
35839
|
+
enabled: agent.reviewEnabled,
|
|
35840
|
+
everyNTurns: agent.reviewEveryNTurns,
|
|
35841
|
+
model: agent.reviewModel,
|
|
35842
|
+
reasoningLevel: agent.reviewReasoningLevel,
|
|
35843
|
+
turnsSinceLast: agent.reviewTurnsSinceLast
|
|
35844
|
+
});
|
|
35845
|
+
});
|
|
35846
|
+
agentsRouter.patch("/:id/review-config", async (c) => {
|
|
35847
|
+
const body = await c.req.json().catch(() => null);
|
|
35848
|
+
if (!body) return c.json({ error: "invalid JSON body" }, 400);
|
|
35849
|
+
const { db } = getCtx();
|
|
35850
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35851
|
+
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
35852
|
+
const everyNTurns = body.everyNTurns ?? agent.reviewEveryNTurns;
|
|
35853
|
+
const reasoningLevel = body.reasoningLevel ?? agent.reviewReasoningLevel;
|
|
35854
|
+
if (!Number.isInteger(everyNTurns) || everyNTurns < 1 || everyNTurns > 100) {
|
|
35855
|
+
return c.json({ error: "everyNTurns must be an integer from 1 to 100" }, 400);
|
|
35856
|
+
}
|
|
35857
|
+
if (!REASONING_LEVELS.includes(reasoningLevel)) {
|
|
35858
|
+
return c.json({ error: `invalid reasoningLevel: ${reasoningLevel}` }, 400);
|
|
35859
|
+
}
|
|
35860
|
+
if (body.model !== void 0 && body.model !== null && !body.model.includes(":")) {
|
|
35861
|
+
return c.json({ error: "model must use provider:model format" }, 400);
|
|
35862
|
+
}
|
|
35863
|
+
agents_exports.setReviewConfig(db, agent.id, {
|
|
35864
|
+
enabled: body.enabled ?? agent.reviewEnabled,
|
|
35865
|
+
everyNTurns,
|
|
35866
|
+
model: body.model === void 0 ? agent.reviewModel : body.model,
|
|
35867
|
+
reasoningLevel
|
|
35868
|
+
});
|
|
35869
|
+
const updated = agents_exports.get(db, agent.id);
|
|
35870
|
+
if (!updated) return c.json({ error: "agent disappeared" }, 500);
|
|
35871
|
+
return c.json({
|
|
35872
|
+
enabled: updated.reviewEnabled,
|
|
35873
|
+
everyNTurns: updated.reviewEveryNTurns,
|
|
35874
|
+
model: updated.reviewModel,
|
|
35875
|
+
reasoningLevel: updated.reviewReasoningLevel,
|
|
35876
|
+
turnsSinceLast: updated.reviewTurnsSinceLast
|
|
35877
|
+
});
|
|
35878
|
+
});
|
|
35879
|
+
agentsRouter.post("/:id/reviews", (c) => {
|
|
35880
|
+
const { db } = getCtx();
|
|
35881
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35882
|
+
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
35883
|
+
return c.json(
|
|
35884
|
+
{ review: agentReviews_exports.enqueueManual(db, agent.id) },
|
|
35885
|
+
202
|
|
35886
|
+
);
|
|
35887
|
+
});
|
|
35888
|
+
agentsRouter.get("/:id/reviews", (c) => {
|
|
35889
|
+
const { db } = getCtx();
|
|
35890
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35891
|
+
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
35892
|
+
return c.json({
|
|
35893
|
+
reviews: agentReviews_exports.listForAgent(db, agent.id)
|
|
35894
|
+
});
|
|
35895
|
+
});
|
|
35896
|
+
agentsRouter.get("/:id/reviews/:reviewId", (c) => {
|
|
35897
|
+
const { db, paths } = getCtx();
|
|
35898
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35899
|
+
const review = agentReviews_exports.get(db, c.req.param("reviewId"));
|
|
35900
|
+
if (!agent || !review || review.agentId !== agent.id)
|
|
35901
|
+
return c.json({ error: "review not found" }, 404);
|
|
35902
|
+
return c.json({
|
|
35903
|
+
review,
|
|
35904
|
+
proposals: enrichProposalEvidence(
|
|
35905
|
+
agentLessonProposals_exports.listForReview(db, review.id),
|
|
35906
|
+
resolveAgent(db, paths, agent.id),
|
|
35907
|
+
paths
|
|
35908
|
+
)
|
|
35909
|
+
});
|
|
35910
|
+
});
|
|
35911
|
+
agentsRouter.get("/:id/lesson-proposals", (c) => {
|
|
35912
|
+
const { db, paths } = getCtx();
|
|
35913
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35914
|
+
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
35915
|
+
const rawStatus = c.req.query("status");
|
|
35916
|
+
const statuses = ["pending", "approved", "rejected", "revoked"];
|
|
35917
|
+
if (rawStatus && !statuses.includes(rawStatus)) {
|
|
35918
|
+
return c.json({ error: `invalid status: ${rawStatus}` }, 400);
|
|
35919
|
+
}
|
|
35920
|
+
return c.json({
|
|
35921
|
+
proposals: enrichProposalEvidence(
|
|
35922
|
+
agentLessonProposals_exports.listForAgent(db, agent.id, {
|
|
35923
|
+
status: rawStatus
|
|
35924
|
+
}),
|
|
35925
|
+
resolveAgent(db, paths, agent.id),
|
|
35926
|
+
paths
|
|
35927
|
+
)
|
|
35928
|
+
});
|
|
35929
|
+
});
|
|
35930
|
+
agentsRouter.patch("/:id/lesson-proposals/:proposalId", async (c) => {
|
|
35931
|
+
const body = await c.req.json().catch(() => null);
|
|
35932
|
+
if (!body || !Number.isInteger(body.version)) return c.json({ error: "version is required" }, 400);
|
|
35933
|
+
const { db } = getCtx();
|
|
35934
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35935
|
+
const current = agentLessonProposals_exports.get(db, c.req.param("proposalId"));
|
|
35936
|
+
if (!agent || !current || current.agentId !== agent.id)
|
|
35937
|
+
return c.json({ error: "proposal not found" }, 404);
|
|
35938
|
+
const text2 = body.text?.trim() ?? current.text;
|
|
35939
|
+
const scope = body.scope ?? current.scope;
|
|
35940
|
+
if (!text2 || text2.length > 500) return c.json({ error: "text must be 1-500 characters" }, 400);
|
|
35941
|
+
if (!["private", "shared"].includes(scope)) {
|
|
35942
|
+
return c.json({ error: `invalid scope: ${scope}` }, 400);
|
|
35943
|
+
}
|
|
35944
|
+
const proposal = agentLessonProposals_exports.updatePending(db, current.id, body.version, {
|
|
35945
|
+
text: text2,
|
|
35946
|
+
scope
|
|
35947
|
+
});
|
|
35948
|
+
return proposal ? c.json({ proposal }) : c.json({ error: "proposal changed or is no longer pending" }, 409);
|
|
35949
|
+
});
|
|
35950
|
+
for (const decision of ["approve", "reject", "revoke"]) {
|
|
35951
|
+
agentsRouter.post(`/:id/lesson-proposals/:proposalId/${decision}`, async (c) => {
|
|
35952
|
+
const body = await c.req.json().catch(() => null);
|
|
35953
|
+
if (!body || !Number.isInteger(body.version))
|
|
35954
|
+
return c.json({ error: "version is required" }, 400);
|
|
35955
|
+
const { db, paths } = getCtx();
|
|
35956
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
35957
|
+
const current = agentLessonProposals_exports.get(db, c.req.param("proposalId"));
|
|
35958
|
+
if (!agent || !current || current.agentId !== agent.id)
|
|
35959
|
+
return c.json({ error: "proposal not found" }, 404);
|
|
35960
|
+
const team = teams_exports.get(db, agent.teamId, paths);
|
|
35961
|
+
if (!team) return c.json({ error: `team not found: ${agent.teamId}` }, 404);
|
|
35962
|
+
try {
|
|
35963
|
+
const proposal = await runAgentLifecycleMutation(agent.id, async () => {
|
|
35964
|
+
const memory = qmdBackend(join21(team.path, "memory"));
|
|
35965
|
+
if (decision === "approve")
|
|
35966
|
+
return approveLessonProposal(db, memory, current.id, body.version);
|
|
35967
|
+
if (decision === "reject") return rejectLessonProposal(db, current.id, body.version);
|
|
35968
|
+
return revokeLessonProposal(db, memory, current.id, body.version);
|
|
35969
|
+
});
|
|
35970
|
+
return c.json({ proposal });
|
|
35971
|
+
} catch (error2) {
|
|
35972
|
+
if (error2 instanceof LessonProposalConflictError) return c.json({ error: error2.message }, 409);
|
|
35973
|
+
throw error2;
|
|
35974
|
+
}
|
|
35975
|
+
});
|
|
35976
|
+
}
|
|
34911
35977
|
agentsRouter.get("/:id/triggers", (c) => {
|
|
34912
35978
|
const { db, paths, authToken } = getCtx();
|
|
34913
35979
|
const agent = agents_exports.get(db, c.req.param("id"));
|
|
@@ -34974,6 +36040,13 @@ agentsRouter.get("/:id/messages", (c) => {
|
|
|
34974
36040
|
};
|
|
34975
36041
|
return c.json(body);
|
|
34976
36042
|
});
|
|
36043
|
+
agentsRouter.get("/:id/loop-breaks", (c) => {
|
|
36044
|
+
const { db } = getCtx();
|
|
36045
|
+
const agent = agents_exports.get(db, c.req.param("id"));
|
|
36046
|
+
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
36047
|
+
const limit = Math.min(Math.max(Number(c.req.query("limit")) || 25, 1), 100);
|
|
36048
|
+
return c.json({ events: listAgentLoopBreaks(db, agent.id, limit) });
|
|
36049
|
+
});
|
|
34977
36050
|
agentsRouter.post("/:id/messages", async (c) => {
|
|
34978
36051
|
const body = await c.req.json().catch(() => null);
|
|
34979
36052
|
if (!body || typeof body.from !== "string" || !body.from || !body.payload || typeof body.payload.text !== "string") {
|
|
@@ -34999,6 +36072,9 @@ agentsRouter.post("/:id/messages", async (c) => {
|
|
|
34999
36072
|
});
|
|
35000
36073
|
return c.json(msg, 201);
|
|
35001
36074
|
} catch (error2) {
|
|
36075
|
+
if (error2 instanceof AgentLoopLimitError) {
|
|
36076
|
+
return c.json({ error: error2.message, code: "agent_loop_limit", event: error2.event }, 429);
|
|
36077
|
+
}
|
|
35002
36078
|
if (error2 instanceof CommunicationDeniedError) {
|
|
35003
36079
|
return c.json(
|
|
35004
36080
|
{ ...error2.result, attemptKind: error2.attemptKind, attemptId: error2.attemptId },
|
|
@@ -35070,7 +36146,7 @@ agentsRouter.post("/:id/chat", async (c) => {
|
|
|
35070
36146
|
if (!message && attachments.length === 0) {
|
|
35071
36147
|
return c.json({ error: "message or an attachment is required" }, 400);
|
|
35072
36148
|
}
|
|
35073
|
-
const requestAttemptId = c.req.header("x-request-id") ??
|
|
36149
|
+
const requestAttemptId = c.req.header("x-request-id") ?? randomUUID22();
|
|
35074
36150
|
try {
|
|
35075
36151
|
authorizeUserIngress(db, id, {
|
|
35076
36152
|
origin: "http_chat",
|
|
@@ -35451,6 +36527,24 @@ function countProperties(schema) {
|
|
|
35451
36527
|
if (!props || typeof props !== "object") return null;
|
|
35452
36528
|
return Object.keys(props).length;
|
|
35453
36529
|
}
|
|
36530
|
+
function enrichProposalEvidence(proposals, agent, paths) {
|
|
36531
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
36532
|
+
return proposals.map((proposal) => ({
|
|
36533
|
+
...proposal,
|
|
36534
|
+
evidence: proposal.evidence.map((evidence) => {
|
|
36535
|
+
let messages = sessions.get(evidence.sessionId);
|
|
36536
|
+
if (!messages) {
|
|
36537
|
+
messages = piMessagesToProviderView(loadSessionMessages(agent, paths, evidence.sessionId));
|
|
36538
|
+
sessions.set(evidence.sessionId, messages);
|
|
36539
|
+
}
|
|
36540
|
+
const message = messages[evidence.entryOrdinal];
|
|
36541
|
+
const excerpt = message ? redactReviewText(
|
|
36542
|
+
message.role === "tool" ? `[tool:${message.toolName ?? "unknown"}] completed` : message.content
|
|
36543
|
+
).replace(/\s+/g, " ").slice(0, 240) : void 0;
|
|
36544
|
+
return { ...evidence, ...excerpt ? { excerpt } : {} };
|
|
36545
|
+
})
|
|
36546
|
+
}));
|
|
36547
|
+
}
|
|
35454
36548
|
|
|
35455
36549
|
// ../daemon/src/routes/approvals.ts
|
|
35456
36550
|
import { Bot as Bot2, InputFile as InputFile2 } from "grammy";
|
|
@@ -35598,7 +36692,19 @@ function validateSchedulerGrant(db, approval) {
|
|
|
35598
36692
|
async function deliver(approval) {
|
|
35599
36693
|
if (approval.payloadKind === "agent_message") {
|
|
35600
36694
|
const payload = approval.payload;
|
|
35601
|
-
|
|
36695
|
+
const causality = resolveMessageCausality(getCtx().db, payload);
|
|
36696
|
+
const loopBreak = enforceMessageCausality(getCtx().db, {
|
|
36697
|
+
from: payload.from,
|
|
36698
|
+
to: payload.to,
|
|
36699
|
+
origin: "communication_approval_delivery",
|
|
36700
|
+
causality
|
|
36701
|
+
});
|
|
36702
|
+
if (loopBreak) throw new AgentLoopLimitError(loopBreak);
|
|
36703
|
+
messages_exports.send(getCtx().db, {
|
|
36704
|
+
...payload,
|
|
36705
|
+
causalChainId: causality.causalChainId,
|
|
36706
|
+
causalHop: causality.causalHop
|
|
36707
|
+
});
|
|
35602
36708
|
return;
|
|
35603
36709
|
}
|
|
35604
36710
|
if (approval.payloadKind === "scheduler_trigger") {
|
|
@@ -35734,11 +36840,54 @@ function approvalError(error2) {
|
|
|
35734
36840
|
return Response.json({ error: message }, { status: 400 });
|
|
35735
36841
|
}
|
|
35736
36842
|
|
|
36843
|
+
// ../daemon/src/routes/attention.ts
|
|
36844
|
+
import { Hono as Hono3 } from "hono";
|
|
36845
|
+
var attentionRouter = new Hono3();
|
|
36846
|
+
attentionRouter.get("/", (c) => {
|
|
36847
|
+
const state3 = c.req.query("state") ?? "open";
|
|
36848
|
+
if (!["open", "acknowledged", "all"].includes(state3))
|
|
36849
|
+
return c.json({ error: "invalid attention state", code: "invalid_attention_state" }, 400);
|
|
36850
|
+
const kind = c.req.query("kind");
|
|
36851
|
+
if (kind && !ATTENTION_KINDS.includes(kind))
|
|
36852
|
+
return c.json({ error: "invalid attention kind", code: "invalid_attention_kind" }, 400);
|
|
36853
|
+
const rawLimit = c.req.query("limit");
|
|
36854
|
+
const limit = rawLimit === void 0 ? 100 : Number(rawLimit);
|
|
36855
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 200)
|
|
36856
|
+
return c.json(
|
|
36857
|
+
{ error: "attention limit must be between 1 and 200", code: "invalid_attention_limit" },
|
|
36858
|
+
400
|
|
36859
|
+
);
|
|
36860
|
+
return c.json(projectAttention(getCtx().db, { state: state3, kind, limit }));
|
|
36861
|
+
});
|
|
36862
|
+
attentionRouter.get("/summary", (c) => c.json(attentionSummary(getCtx().db)));
|
|
36863
|
+
attentionRouter.post(
|
|
36864
|
+
"/acknowledge-all",
|
|
36865
|
+
(c) => c.json({ acknowledged: acknowledgeAllAttention(getCtx().db) })
|
|
36866
|
+
);
|
|
36867
|
+
attentionRouter.post("/:key/acknowledge", (c) => mutate(c, true));
|
|
36868
|
+
attentionRouter.delete("/:key/acknowledgement", (c) => mutate(c, false));
|
|
36869
|
+
function mutate(c, acknowledged) {
|
|
36870
|
+
try {
|
|
36871
|
+
return c.json({
|
|
36872
|
+
item: acknowledgeAttention(getCtx().db, c.req.param("key") ?? "", acknowledged)
|
|
36873
|
+
});
|
|
36874
|
+
} catch (error2) {
|
|
36875
|
+
const code = error2 instanceof Error ? error2.message : "attention_error";
|
|
36876
|
+
if (code === "invalid_attention_key")
|
|
36877
|
+
return c.json({ error: "invalid attention key", code }, 400);
|
|
36878
|
+
if (code === "attention_action_required")
|
|
36879
|
+
return c.json({ error: "action-required items must be resolved at their source", code }, 409);
|
|
36880
|
+
if (code === "attention_source_not_found")
|
|
36881
|
+
return c.json({ error: "attention source not found or no longer eligible", code }, 404);
|
|
36882
|
+
throw error2;
|
|
36883
|
+
}
|
|
36884
|
+
}
|
|
36885
|
+
|
|
35737
36886
|
// ../daemon/src/routes/auth-login.ts
|
|
35738
36887
|
import { spawn as spawn4 } from "child_process";
|
|
35739
|
-
import { Hono as
|
|
36888
|
+
import { Hono as Hono4 } from "hono";
|
|
35740
36889
|
import { setCookie } from "hono/cookie";
|
|
35741
|
-
var authRouter = new
|
|
36890
|
+
var authRouter = new Hono4();
|
|
35742
36891
|
authRouter.get("/auth/me", (c) => {
|
|
35743
36892
|
const { db } = getCtx();
|
|
35744
36893
|
return c.json({ authed: true, setupComplete: isSetupComplete(db) });
|
|
@@ -35852,8 +37001,8 @@ function openBrowser(url2) {
|
|
|
35852
37001
|
}
|
|
35853
37002
|
|
|
35854
37003
|
// ../daemon/src/routes/communication.ts
|
|
35855
|
-
import { Hono as
|
|
35856
|
-
var communicationRouter = new
|
|
37004
|
+
import { Hono as Hono5 } from "hono";
|
|
37005
|
+
var communicationRouter = new Hono5();
|
|
35857
37006
|
communicationRouter.post("/evaluate", async (c) => {
|
|
35858
37007
|
const input = await c.req.json().catch(() => null);
|
|
35859
37008
|
if (!input || !input.source || !input.target || typeof input.origin !== "string" || typeof input.attemptKind !== "string" || typeof input.attemptId !== "string") {
|
|
@@ -35863,8 +37012,8 @@ communicationRouter.post("/evaluate", async (c) => {
|
|
|
35863
37012
|
});
|
|
35864
37013
|
|
|
35865
37014
|
// ../daemon/src/routes/config.ts
|
|
35866
|
-
import { Hono as
|
|
35867
|
-
var configRouter = new
|
|
37015
|
+
import { Hono as Hono6 } from "hono";
|
|
37016
|
+
var configRouter = new Hono6();
|
|
35868
37017
|
configRouter.get("/providers", async (c) => {
|
|
35869
37018
|
const { db, paths, authToken } = getCtx();
|
|
35870
37019
|
const env = mergeSecretsIntoEnv(db, authToken);
|
|
@@ -36043,8 +37192,8 @@ function knownProviderRegistryNames() {
|
|
|
36043
37192
|
}
|
|
36044
37193
|
|
|
36045
37194
|
// ../daemon/src/routes/mcp.ts
|
|
36046
|
-
import { Hono as
|
|
36047
|
-
var mcpRouter = new
|
|
37195
|
+
import { Hono as Hono7 } from "hono";
|
|
37196
|
+
var mcpRouter = new Hono7();
|
|
36048
37197
|
var TRANSPORTS = /* @__PURE__ */ new Set(["stdio", "http", "sse"]);
|
|
36049
37198
|
function validate(input) {
|
|
36050
37199
|
if (!input.name || !/^[a-zA-Z0-9_]+$/.test(input.name)) {
|
|
@@ -36173,8 +37322,8 @@ mcpRouter.post("/:id/test", async (c) => {
|
|
|
36173
37322
|
});
|
|
36174
37323
|
|
|
36175
37324
|
// ../daemon/src/routes/messages.ts
|
|
36176
|
-
import { Hono as
|
|
36177
|
-
var messagesRouter = new
|
|
37325
|
+
import { Hono as Hono8 } from "hono";
|
|
37326
|
+
var messagesRouter = new Hono8();
|
|
36178
37327
|
messagesRouter.get("/:id", (c) => {
|
|
36179
37328
|
const { db } = getCtx();
|
|
36180
37329
|
const msg = messages_exports.get(db, c.req.param("id"));
|
|
@@ -36198,7 +37347,7 @@ messagesRouter.patch("/:id", async (c) => {
|
|
|
36198
37347
|
import { existsSync as existsSync18 } from "fs";
|
|
36199
37348
|
import { homedir as homedir2 } from "os";
|
|
36200
37349
|
import { join as join24 } from "path";
|
|
36201
|
-
import { Hono as
|
|
37350
|
+
import { Hono as Hono9 } from "hono";
|
|
36202
37351
|
|
|
36203
37352
|
// ../daemon/src/lib/backup.ts
|
|
36204
37353
|
import { mkdtempSync as mkdtempSync3, rmSync as rmSync14 } from "fs";
|
|
@@ -36293,7 +37442,7 @@ function createBackupArchive(paths, snapshot) {
|
|
|
36293
37442
|
}
|
|
36294
37443
|
|
|
36295
37444
|
// ../daemon/src/lib/daemon-liveness.ts
|
|
36296
|
-
import { createHash as createHash5, randomUUID as
|
|
37445
|
+
import { createHash as createHash5, randomUUID as randomUUID23 } from "crypto";
|
|
36297
37446
|
import {
|
|
36298
37447
|
chmodSync as chmodSync2,
|
|
36299
37448
|
closeSync as closeSync4,
|
|
@@ -36419,9 +37568,9 @@ function pidIsAlive(pid) {
|
|
|
36419
37568
|
}
|
|
36420
37569
|
function reclaimStaleRecord(path, existing) {
|
|
36421
37570
|
const identity = createHash5("sha256").update(existing.instanceId ?? existing.raw).update(`\0${existing.stat.dev}\0${existing.stat.ino}`).digest("hex").slice(0, 24);
|
|
36422
|
-
const
|
|
37571
|
+
const claim3 = `${path}.reclaim-${identity}`;
|
|
36423
37572
|
try {
|
|
36424
|
-
mkdirSync9(
|
|
37573
|
+
mkdirSync9(claim3, { mode: 448 });
|
|
36425
37574
|
} catch (error2) {
|
|
36426
37575
|
if (errorCode(error2) === "EEXIST") return null;
|
|
36427
37576
|
throw error2;
|
|
@@ -36431,8 +37580,8 @@ function reclaimStaleRecord(path, existing) {
|
|
|
36431
37580
|
if (!current || !sameFile(current.stat, existing.stat) || current.raw !== existing.raw) {
|
|
36432
37581
|
return null;
|
|
36433
37582
|
}
|
|
36434
|
-
renameSync3(path, join23(
|
|
36435
|
-
return
|
|
37583
|
+
renameSync3(path, join23(claim3, "stale-record.json"));
|
|
37584
|
+
return claim3;
|
|
36436
37585
|
} catch (error2) {
|
|
36437
37586
|
if (!["ENOENT", "EEXIST"].includes(errorCode(error2) ?? "")) throw error2;
|
|
36438
37587
|
return null;
|
|
@@ -36460,7 +37609,7 @@ function acquireDaemonLiveness(paths) {
|
|
|
36460
37609
|
mkdirSync9(dirname5(resolve6(paths.home)), { recursive: true });
|
|
36461
37610
|
const path = daemonLivenessPath(paths.home);
|
|
36462
37611
|
mkdirSync9(dirname5(path), { recursive: true });
|
|
36463
|
-
const instanceId =
|
|
37612
|
+
const instanceId = randomUUID23();
|
|
36464
37613
|
const startedAt = Date.now();
|
|
36465
37614
|
let fd = null;
|
|
36466
37615
|
let reclaimClaim = null;
|
|
@@ -36494,8 +37643,8 @@ function acquireDaemonLiveness(paths) {
|
|
|
36494
37643
|
`another Bazilion daemon owns this home${owner}; stop it before starting another`
|
|
36495
37644
|
);
|
|
36496
37645
|
}
|
|
36497
|
-
const
|
|
36498
|
-
if (
|
|
37646
|
+
const claim3 = reclaimStaleRecord(path, existing);
|
|
37647
|
+
if (claim3) reclaimClaim = claim3;
|
|
36499
37648
|
}
|
|
36500
37649
|
}
|
|
36501
37650
|
if (fd === null) {
|
|
@@ -36580,7 +37729,7 @@ function acquireDaemonLiveness(paths) {
|
|
|
36580
37729
|
}
|
|
36581
37730
|
|
|
36582
37731
|
// ../daemon/src/routes/misc.ts
|
|
36583
|
-
var miscRouter = new
|
|
37732
|
+
var miscRouter = new Hono9();
|
|
36584
37733
|
miscRouter.get("/health", (c) => {
|
|
36585
37734
|
const instanceId = getDaemonInstanceId();
|
|
36586
37735
|
if (instanceId) c.header("x-bazilion-daemon-instance", instanceId);
|
|
@@ -36802,8 +37951,8 @@ miscRouter.delete("/tokens/:id", (c) => {
|
|
|
36802
37951
|
// ../daemon/src/routes/profiles.ts
|
|
36803
37952
|
import { existsSync as existsSync19, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "fs";
|
|
36804
37953
|
import { join as join25 } from "path";
|
|
36805
|
-
import { Hono as
|
|
36806
|
-
var profilesRouter = new
|
|
37954
|
+
import { Hono as Hono10 } from "hono";
|
|
37955
|
+
var profilesRouter = new Hono10();
|
|
36807
37956
|
profilesRouter.get("/", (c) => {
|
|
36808
37957
|
const { db } = getCtx();
|
|
36809
37958
|
const profiles = profiles_exports.list(db);
|
|
@@ -36982,8 +38131,8 @@ function parseCommunicationDefaults(value) {
|
|
|
36982
38131
|
}
|
|
36983
38132
|
|
|
36984
38133
|
// ../daemon/src/routes/shell-approvals.ts
|
|
36985
|
-
import { Hono as
|
|
36986
|
-
var shellApprovalsRouter = new
|
|
38134
|
+
import { Hono as Hono11 } from "hono";
|
|
38135
|
+
var shellApprovalsRouter = new Hono11();
|
|
36987
38136
|
shellApprovalsRouter.get("/", (c) => {
|
|
36988
38137
|
const agentId = c.req.query("agentId")?.trim();
|
|
36989
38138
|
if (!agentId) return c.json({ error: "agentId query parameter is required" }, 400);
|
|
@@ -37018,9 +38167,9 @@ shellApprovalsRouter.post("/:id", async (c) => {
|
|
|
37018
38167
|
import { existsSync as existsSync20, mkdtempSync as mkdtempSync4, rmSync as rmSync16, writeFileSync as writeFileSync13 } from "fs";
|
|
37019
38168
|
import { homedir as homedir3, tmpdir as tmpdir4 } from "os";
|
|
37020
38169
|
import { join as join26 } from "path";
|
|
37021
|
-
import { Hono as
|
|
38170
|
+
import { Hono as Hono12 } from "hono";
|
|
37022
38171
|
var MAX_ZIP_BYTES = 50 * 1024 * 1024;
|
|
37023
|
-
var skillsRouter = new
|
|
38172
|
+
var skillsRouter = new Hono12();
|
|
37024
38173
|
skillsRouter.get("/", (c) => {
|
|
37025
38174
|
const { db, paths } = getCtx();
|
|
37026
38175
|
const out = [];
|
|
@@ -37137,9 +38286,9 @@ async function parseImportInput(request2) {
|
|
|
37137
38286
|
}
|
|
37138
38287
|
|
|
37139
38288
|
// ../daemon/src/routes/team-templates.ts
|
|
37140
|
-
import { randomUUID as
|
|
37141
|
-
import { Hono as
|
|
37142
|
-
var teamTemplatesRouter = new
|
|
38289
|
+
import { randomUUID as randomUUID24 } from "crypto";
|
|
38290
|
+
import { Hono as Hono13 } from "hono";
|
|
38291
|
+
var teamTemplatesRouter = new Hono13();
|
|
37143
38292
|
teamTemplatesRouter.get("/", (c) => {
|
|
37144
38293
|
const { db } = getCtx();
|
|
37145
38294
|
return c.json(
|
|
@@ -37177,7 +38326,7 @@ teamTemplatesRouter.post("/import", async (c) => {
|
|
|
37177
38326
|
if (!profiles_exports.get(db, parsed.profileId)) {
|
|
37178
38327
|
throw new Error(`profile not found: ${parsed.profileId}`);
|
|
37179
38328
|
}
|
|
37180
|
-
const slotId =
|
|
38329
|
+
const slotId = randomUUID24();
|
|
37181
38330
|
keyToSlot.set(clientKey, slotId);
|
|
37182
38331
|
return { ...parsed, slotId };
|
|
37183
38332
|
});
|
|
@@ -37470,9 +38619,9 @@ function canonicalError(c, error2) {
|
|
|
37470
38619
|
|
|
37471
38620
|
// ../daemon/src/routes/teams.ts
|
|
37472
38621
|
import { join as join27 } from "path";
|
|
37473
|
-
import { Hono as
|
|
38622
|
+
import { Hono as Hono14 } from "hono";
|
|
37474
38623
|
var USER_MD_MAX_BYTES2 = 12e3;
|
|
37475
|
-
var teamsRouter = new
|
|
38624
|
+
var teamsRouter = new Hono14();
|
|
37476
38625
|
teamsRouter.get("/", (c) => {
|
|
37477
38626
|
const { db, paths } = getCtx();
|
|
37478
38627
|
return c.json(teams_exports.list(db, paths));
|
|
@@ -37841,7 +38990,7 @@ function teamPolicyError(c, error2) {
|
|
|
37841
38990
|
}
|
|
37842
38991
|
|
|
37843
38992
|
// ../daemon/src/routes/telegram.ts
|
|
37844
|
-
import { Hono as
|
|
38993
|
+
import { Hono as Hono15 } from "hono";
|
|
37845
38994
|
|
|
37846
38995
|
// ../daemon/src/lib/telegram/preflight.ts
|
|
37847
38996
|
var TELEGRAM_API_BASE = "https://api.telegram.org";
|
|
@@ -37870,7 +39019,7 @@ async function runPreflight(args) {
|
|
|
37870
39019
|
clearTimeout(t);
|
|
37871
39020
|
}
|
|
37872
39021
|
};
|
|
37873
|
-
const
|
|
39022
|
+
const fail3 = (step, message) => ({
|
|
37874
39023
|
configured: true,
|
|
37875
39024
|
preflight: null,
|
|
37876
39025
|
error: { step, message },
|
|
@@ -37880,13 +39029,13 @@ async function runPreflight(args) {
|
|
|
37880
39029
|
try {
|
|
37881
39030
|
me2 = await call("getMe", {});
|
|
37882
39031
|
} catch (e) {
|
|
37883
|
-
return
|
|
39032
|
+
return fail3("getMe", errorMessage(e));
|
|
37884
39033
|
}
|
|
37885
39034
|
let chat;
|
|
37886
39035
|
try {
|
|
37887
39036
|
chat = await call("getChat", { chat_id: chatId(args.chatId) });
|
|
37888
39037
|
} catch (e) {
|
|
37889
|
-
return
|
|
39038
|
+
return fail3("getChat", errorMessage(e));
|
|
37890
39039
|
}
|
|
37891
39040
|
let member;
|
|
37892
39041
|
try {
|
|
@@ -37895,7 +39044,7 @@ async function runPreflight(args) {
|
|
|
37895
39044
|
user_id: me2.id
|
|
37896
39045
|
});
|
|
37897
39046
|
} catch (e) {
|
|
37898
|
-
return
|
|
39047
|
+
return fail3("getChatMember", errorMessage(e));
|
|
37899
39048
|
}
|
|
37900
39049
|
const hasManageTopics = member.status === "creator" || member.can_manage_topics === true;
|
|
37901
39050
|
const preflight = {
|
|
@@ -37935,7 +39084,7 @@ var DERIVED_STATE_KEYS = [
|
|
|
37935
39084
|
"TELEGRAM_DIRECTORY_MESSAGE_ID",
|
|
37936
39085
|
MIGRATED_CHAT_ID_KEY
|
|
37937
39086
|
];
|
|
37938
|
-
var telegramRouter = new
|
|
39087
|
+
var telegramRouter = new Hono15();
|
|
37939
39088
|
telegramRouter.get("/", (c) => {
|
|
37940
39089
|
const { db, authToken } = getCtx();
|
|
37941
39090
|
return c.json(readState(db, authToken));
|
|
@@ -38074,8 +39223,8 @@ function maskBotToken(t) {
|
|
|
38074
39223
|
}
|
|
38075
39224
|
|
|
38076
39225
|
// ../daemon/src/routes/triggers.ts
|
|
38077
|
-
import { Hono as
|
|
38078
|
-
var triggersRouter = new
|
|
39226
|
+
import { Hono as Hono16 } from "hono";
|
|
39227
|
+
var triggersRouter = new Hono16();
|
|
38079
39228
|
triggersRouter.get("/:id/dispatches", (c) => {
|
|
38080
39229
|
const { db } = getCtx();
|
|
38081
39230
|
const id = c.req.param("id");
|
|
@@ -38108,9 +39257,10 @@ triggersRouter.patch("/:id", async (c) => {
|
|
|
38108
39257
|
|
|
38109
39258
|
// ../daemon/src/app.ts
|
|
38110
39259
|
function createApp() {
|
|
38111
|
-
const app2 = new
|
|
39260
|
+
const app2 = new Hono17();
|
|
38112
39261
|
app2.use("*", authMiddleware);
|
|
38113
39262
|
app2.route("/api/agents", agentsRouter);
|
|
39263
|
+
app2.route("/api/attention", attentionRouter);
|
|
38114
39264
|
app2.route("/api/approvals", approvalsRouter);
|
|
38115
39265
|
app2.route("/api/shell-approvals", shellApprovalsRouter);
|
|
38116
39266
|
app2.route("/api/teams", teamsRouter);
|