@agentdocumentformat/cli 0.7.2 → 0.7.3
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/README.md +44 -21
- package/dist/adf.mjs +8 -6
- package/dist/chunks/{App-L5L37JI5.mjs → App-QMFRLBPQ.mjs} +1766 -1667
- package/dist/chunks/{adf-schema-JRU2BTOG.mjs → adf-schema-US4NFHMR.mjs} +2 -2
- package/dist/chunks/{chunk-4MQPTCXY.mjs → chunk-2WSQ7V6K.mjs} +1 -1
- package/dist/chunks/{chunk-X34PDRUH.mjs → chunk-3UCKYP7P.mjs} +55 -7
- package/dist/chunks/{chunk-WFQUVXML.mjs → chunk-CD3ATSXE.mjs} +6 -1
- package/dist/chunks/chunk-GKKCMXIZ.mjs +94 -0
- package/dist/chunks/{chunk-HWLWPXQ7.mjs → chunk-HDBPBORT.mjs} +7 -2
- package/dist/chunks/{chunk-3M4ZPOA3.mjs → chunk-J74STFKE.mjs} +35 -6
- package/dist/chunks/{chunk-TMT32MXT.mjs → chunk-TPRZQ7Z4.mjs} +1 -1
- package/dist/chunks/chunk-UEZR2CNS.mjs +65 -0
- package/dist/chunks/{chunk-7MTRVW2U.mjs → chunk-ZROSGV65.mjs} +16 -7
- package/dist/chunks/{cli-TCMBNZF6.mjs → cli-ZGVQRVSQ.mjs} +48 -22
- package/dist/chunks/{commands-DTEKM4ZL.mjs → commands-XNJMCD5L.mjs} +2 -2
- package/dist/chunks/{daemon-ZC3FZ2P4.mjs → daemon-G6OQZER2.mjs} +16380 -3911
- package/dist/chunks/{daemon-control-WDX7PMTC.mjs → daemon-control-HKFVSQTQ.mjs} +27 -9
- package/dist/chunks/{pipeline-executor-BHBSJX2K.mjs → pipeline-executor-U6IMCCP3.mjs} +3 -3
- package/dist/chunks/{store-WR7TZJZS.mjs → store-HUVDJPYN.mjs} +1 -1
- package/dist/chunks/{tui-ODVYUIMT.mjs → tui-LWLJUXZ3.mjs} +8 -7
- package/package.json +1 -1
- package/dist/chunks/chunk-G426FACA.mjs +0 -49
|
@@ -29,10 +29,10 @@ import {
|
|
|
29
29
|
TriggersConfigV3Schema,
|
|
30
30
|
UmbilicalFilterSchema,
|
|
31
31
|
WsConnectionConfigSchema
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-HDBPBORT.mjs";
|
|
33
33
|
import "./chunk-ZJKXHM4Q.mjs";
|
|
34
34
|
import "./chunk-RIX34QHC.mjs";
|
|
35
|
-
import "./chunk-
|
|
35
|
+
import "./chunk-CD3ATSXE.mjs";
|
|
36
36
|
import "./chunk-M2RX3S2T.mjs";
|
|
37
37
|
export {
|
|
38
38
|
AdapterInstanceConfigSchema,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./chunk-SGUTYISF.mjs";
|
|
14
14
|
import {
|
|
15
15
|
daemon_url_exports
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GKKCMXIZ.mjs";
|
|
17
17
|
|
|
18
18
|
// src/main/tui/api/sse.ts
|
|
19
19
|
var EventStream = class {
|
|
@@ -25,6 +25,10 @@ var EventStream = class {
|
|
|
25
25
|
attempt = 0;
|
|
26
26
|
hasOpened = !1;
|
|
27
27
|
lastCursor;
|
|
28
|
+
/** Daemon run the cursor belongs to (`stream.hello`). */
|
|
29
|
+
epoch = null;
|
|
30
|
+
/** This connection resumes a dropped one and has not reported how yet. */
|
|
31
|
+
resumePending = !1;
|
|
28
32
|
seen = /* @__PURE__ */ new Set();
|
|
29
33
|
seenOrder = [];
|
|
30
34
|
idleTimer = null;
|
|
@@ -64,7 +68,7 @@ var EventStream = class {
|
|
|
64
68
|
}
|
|
65
69
|
buildUrl() {
|
|
66
70
|
let params = new URLSearchParams();
|
|
67
|
-
this.options.agentId && params.set("agentId", this.options.agentId), this.lastCursor >= 0 ? params.set("since", String(this.lastCursor)) : this.options.replay || params.set("since", String(Number.MAX_SAFE_INTEGER));
|
|
71
|
+
this.options.agentId && params.set("agentId", this.options.agentId), this.lastCursor >= 0 ? (params.set("since", String(this.lastCursor)), this.epoch && params.set("epoch", this.epoch)) : this.options.replay || params.set("since", String(Number.MAX_SAFE_INTEGER));
|
|
68
72
|
let qs = params.toString();
|
|
69
73
|
return `${this.options.baseUrl}/events${qs ? `?${qs}` : ""}`;
|
|
70
74
|
}
|
|
@@ -83,7 +87,7 @@ var EventStream = class {
|
|
|
83
87
|
});
|
|
84
88
|
if (!response.ok || !response.body)
|
|
85
89
|
throw new Error(`HTTP ${response.status} ${response.statusText}`.trim());
|
|
86
|
-
this.attempt = 0, this.hasOpened = !0, this.setState({ state: "open", attempt: 0, resumed }), this.armIdle(), await this.read(response.body, controller), failure = "stream ended";
|
|
90
|
+
this.attempt = 0, this.resumePending = resumed, this.hasOpened = !0, this.setState({ state: "open", attempt: 0, resumed }), this.armIdle(), await this.read(response.body, controller), failure = "stream ended";
|
|
87
91
|
} catch (err) {
|
|
88
92
|
failure = controller.signal.aborted && this.closed ? void 0 : errorMessage(err);
|
|
89
93
|
} finally {
|
|
@@ -136,14 +140,19 @@ var EventStream = class {
|
|
|
136
140
|
if (controller.signal.aborted) throw controller.signal.reason instanceof Error ? controller.signal.reason : new Error("aborted");
|
|
137
141
|
}
|
|
138
142
|
handleBlock(block) {
|
|
139
|
-
let data = [];
|
|
143
|
+
let data = [], name = "";
|
|
140
144
|
for (let line of block.split(`
|
|
141
145
|
`)) {
|
|
142
146
|
if (!line || line.startsWith(":")) continue;
|
|
143
147
|
let colon = line.indexOf(":"), field = colon < 0 ? line : line.slice(0, colon), value = colon < 0 ? "" : line.slice(colon + 1).replace(/^ /, "");
|
|
144
|
-
field === "data"
|
|
148
|
+
field === "data" ? data.push(value) : field === "event" && (name = value);
|
|
145
149
|
}
|
|
146
150
|
if (data.length === 0) return;
|
|
151
|
+
if (name === "stream.hello" || name === "stream.gap") {
|
|
152
|
+
this.handleControl(name, data.join(`
|
|
153
|
+
`));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
147
156
|
let frame;
|
|
148
157
|
try {
|
|
149
158
|
frame = JSON.parse(data.join(`
|
|
@@ -163,6 +172,41 @@ var EventStream = class {
|
|
|
163
172
|
} catch {
|
|
164
173
|
}
|
|
165
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* `stream.hello` carries enough to judge the resume on its own (so a quiet
|
|
177
|
+
* stream reports at once); `stream.gap` confirms a loss the hello missed.
|
|
178
|
+
*/
|
|
179
|
+
handleControl(name, raw) {
|
|
180
|
+
let data;
|
|
181
|
+
try {
|
|
182
|
+
data = JSON.parse(raw);
|
|
183
|
+
} catch {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
let epoch = typeof data.epoch == "string" ? data.epoch : null;
|
|
187
|
+
if (!epoch) return;
|
|
188
|
+
let previous = this.epoch;
|
|
189
|
+
if (this.epoch = epoch, name === "stream.hello") {
|
|
190
|
+
if (previous && previous !== epoch) {
|
|
191
|
+
this.forgetCursorKeys(), this.lastCursor = -1, this.reportResume({ exact: !1, reason: "epoch_changed", epoch });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
let oldest = typeof data.oldestCursor == "number" ? data.oldestCursor : null, latest = typeof data.latestCursor == "number" ? data.latestCursor : 0, since = this.lastCursor, lost = since >= 0 && since < latest && (oldest === null || since < oldest - 1);
|
|
195
|
+
this.reportResume(lost ? { exact: !1, reason: "evicted", epoch } : { exact: !0, epoch });
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
let reason = data.reason === "epoch_changed" ? "epoch_changed" : "evicted";
|
|
199
|
+
reason === "epoch_changed" && (this.forgetCursorKeys(), this.lastCursor = -1), this.reportResume({ exact: !1, reason, epoch });
|
|
200
|
+
}
|
|
201
|
+
reportResume(info) {
|
|
202
|
+
if (this.resumePending) {
|
|
203
|
+
this.resumePending = !1;
|
|
204
|
+
try {
|
|
205
|
+
this.options.onResume?.(info);
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
166
210
|
remember(key) {
|
|
167
211
|
this.seen.add(key), this.seenOrder.push(key);
|
|
168
212
|
let cap = this.options.dedupeWindow ?? 5e3;
|
|
@@ -209,7 +253,7 @@ function normalizeRuntime(raw) {
|
|
|
209
253
|
}
|
|
210
254
|
|
|
211
255
|
// src/main/tui/api/client.ts
|
|
212
|
-
var { localDaemonToken, resolveDaemonToken, resolveDaemonUrl } = cjs(daemon_url_exports), enc = encodeURIComponent;
|
|
256
|
+
var { localDaemonToken, localProofHeaders, resolveDaemonToken, resolveDaemonUrl } = cjs(daemon_url_exports), enc = encodeURIComponent;
|
|
213
257
|
function sameOrigin(a, b) {
|
|
214
258
|
try {
|
|
215
259
|
return new URL(a).origin === new URL(b).origin;
|
|
@@ -270,7 +314,11 @@ var DaemonClient = class _DaemonClient {
|
|
|
270
314
|
try {
|
|
271
315
|
response = await this.fetchImpl(this.url(path, options.query), {
|
|
272
316
|
method,
|
|
273
|
-
headers: this.headers(
|
|
317
|
+
headers: this.headers({
|
|
318
|
+
...options.body !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
319
|
+
// Proxy-mode daemons (ADF_DAEMON_BEHIND_PROXY) need this machine's proof on local-only routes.
|
|
320
|
+
...this.options.localToken ? localProofHeaders(this.baseUrl, path, this.options.env ?? process.env) : {}
|
|
321
|
+
}),
|
|
274
322
|
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
275
323
|
signal: controller.signal
|
|
276
324
|
});
|
|
@@ -33,7 +33,11 @@ var CODE_EXECUTION_DEFAULTS = {
|
|
|
33
33
|
}, COMPUTE_DEFAULTS = {
|
|
34
34
|
enabled: !1
|
|
35
35
|
};
|
|
36
|
-
var START_IN_STATES = ["active", "idle", "hibernate"]
|
|
36
|
+
var START_IN_STATES = ["active", "idle", "hibernate"];
|
|
37
|
+
function resolveStartInState(config) {
|
|
38
|
+
return config.start_in_state ?? "active";
|
|
39
|
+
}
|
|
40
|
+
var DEFAULT_NEW_LOOP_TOOLS = ["loop_send", "loop_list", "sys_set_state"], LOOP_PROHIBITED_TOOLS = ["sys_update_config", "loop_manage", "sys_create_adf"];
|
|
37
41
|
var META_PROTECTION_LEVELS = ["none", "readonly", "increment"], FILE_PROTECTION_LEVELS = ["read_only", "no_delete", "none"];
|
|
38
42
|
var DEFAULT_TOOLS = [
|
|
39
43
|
{ name: "fs_read", enabled: !0, visible: !0 },
|
|
@@ -282,6 +286,7 @@ export {
|
|
|
282
286
|
RECOVERY_DEFAULTS,
|
|
283
287
|
CODE_EXECUTION_DEFAULTS,
|
|
284
288
|
START_IN_STATES,
|
|
289
|
+
resolveStartInState,
|
|
285
290
|
DEFAULT_NEW_LOOP_TOOLS,
|
|
286
291
|
LOOP_PROHIBITED_TOOLS,
|
|
287
292
|
META_PROTECTION_LEVELS,
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createRequire as __adfCreateRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __adfFileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __adfDirname } from 'node:path';
|
|
4
|
+
const require = __adfCreateRequire(import.meta.url);
|
|
5
|
+
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __adfDirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
readLocalProof
|
|
9
|
+
} from "./chunk-UEZR2CNS.mjs";
|
|
10
|
+
import {
|
|
11
|
+
daemonSettingsDir,
|
|
12
|
+
readDaemonToken
|
|
13
|
+
} from "./chunk-IHDDCZBS.mjs";
|
|
14
|
+
import {
|
|
15
|
+
__export
|
|
16
|
+
} from "./chunk-M2RX3S2T.mjs";
|
|
17
|
+
|
|
18
|
+
// src/main/cli/daemon-url.ts
|
|
19
|
+
var daemon_url_exports = {};
|
|
20
|
+
__export(daemon_url_exports, {
|
|
21
|
+
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
22
|
+
DEFAULT_DAEMON_URL: () => DEFAULT_DAEMON_URL,
|
|
23
|
+
isLocalDaemonUrl: () => isLocalDaemonUrl,
|
|
24
|
+
isLocalOnlyRoute: () => isLocalOnlyRoute,
|
|
25
|
+
localDaemonToken: () => localDaemonToken,
|
|
26
|
+
localProofHeaders: () => localProofHeaders,
|
|
27
|
+
loopbackPort: () => loopbackPort,
|
|
28
|
+
resolveDaemonToken: () => resolveDaemonToken,
|
|
29
|
+
resolveDaemonUrl: () => resolveDaemonUrl,
|
|
30
|
+
tunnelTokenHint: () => tunnelTokenHint
|
|
31
|
+
});
|
|
32
|
+
import { readFileSync } from "node:fs";
|
|
33
|
+
import { join } from "node:path";
|
|
34
|
+
var DEFAULT_DAEMON_PORT = 7385, DEFAULT_DAEMON_URL = `http://127.0.0.1:${DEFAULT_DAEMON_PORT}`;
|
|
35
|
+
function resolveDaemonUrl(explicit, env = process.env) {
|
|
36
|
+
return (explicit ?? env.ADF_DAEMON_URL ?? DEFAULT_DAEMON_URL).replace(/\/+$/, "");
|
|
37
|
+
}
|
|
38
|
+
function loopbackPort(url) {
|
|
39
|
+
try {
|
|
40
|
+
let parsed = new URL(url), host = parsed.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
41
|
+
return host === "localhost" || host === "::1" || /^127\./.test(host) ? parsed.port ? Number(parsed.port) : parsed.protocol === "https:" ? 443 : 80 : null;
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function pidFileAlive(file) {
|
|
47
|
+
try {
|
|
48
|
+
let raw = readFileSync(file, "utf-8").trim(), pid = raw.startsWith("{") ? JSON.parse(raw).pid : Number.parseInt(raw, 10);
|
|
49
|
+
if (typeof pid != "number" || !Number.isFinite(pid) || pid <= 0) return !1;
|
|
50
|
+
try {
|
|
51
|
+
return process.kill(pid, 0), !0;
|
|
52
|
+
} catch (err) {
|
|
53
|
+
return err?.code === "EPERM";
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
return !1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function isLocalDaemonUrl(url, env = process.env) {
|
|
60
|
+
let port = loopbackPort(url);
|
|
61
|
+
return port === null ? !1 : port === DEFAULT_DAEMON_PORT || port === Number(env.ADF_DAEMON_PORT) ? !0 : pidFileAlive(join(daemonSettingsDir(env), `adf-daemon-${port}.pid`));
|
|
62
|
+
}
|
|
63
|
+
function localDaemonToken(url, env = process.env) {
|
|
64
|
+
if (isLocalDaemonUrl(url, env))
|
|
65
|
+
return readDaemonToken(daemonSettingsDir(env)) ?? void 0;
|
|
66
|
+
}
|
|
67
|
+
function tunnelTokenHint(url, explicit, env = process.env) {
|
|
68
|
+
return explicit || env.ADF_DAEMON_TOKEN || loopbackPort(url) === null || isLocalDaemonUrl(url, env) ? null : `${url} is not this machine's daemon port (${Number(env.ADF_DAEMON_PORT) || DEFAULT_DAEMON_PORT}; e.g. an SSH tunnel), so the local token is not sent there. Pass --token or set ADF_DAEMON_TOKEN to the remote daemon's token (print it on that host with: adf daemon token).`;
|
|
69
|
+
}
|
|
70
|
+
function resolveDaemonToken(explicit, env = process.env, url) {
|
|
71
|
+
let token = explicit ?? env.ADF_DAEMON_TOKEN;
|
|
72
|
+
return token || (url ? localDaemonToken(url, env) : void 0);
|
|
73
|
+
}
|
|
74
|
+
function isLocalOnlyRoute(path) {
|
|
75
|
+
let p = path.split("?")[0];
|
|
76
|
+
return p === "/daemon/shutdown" || /^\/identity\/(create|restore|unlock|lock|confirm-backup)$/.test(p);
|
|
77
|
+
}
|
|
78
|
+
function localProofHeaders(url, path, env = process.env) {
|
|
79
|
+
if (!isLocalOnlyRoute(path) || !isLocalDaemonUrl(url, env)) return {};
|
|
80
|
+
let proof = readLocalProof(daemonSettingsDir(env), loopbackPort(url) ?? DEFAULT_DAEMON_PORT);
|
|
81
|
+
return proof ? { "X-ADF-Local-Proof": proof } : {};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
DEFAULT_DAEMON_PORT,
|
|
86
|
+
DEFAULT_DAEMON_URL,
|
|
87
|
+
resolveDaemonUrl,
|
|
88
|
+
loopbackPort,
|
|
89
|
+
isLocalDaemonUrl,
|
|
90
|
+
tunnelTokenHint,
|
|
91
|
+
resolveDaemonToken,
|
|
92
|
+
localProofHeaders,
|
|
93
|
+
daemon_url_exports
|
|
94
|
+
};
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
MESSAGING_MODES,
|
|
14
14
|
RESERVED_AGENT_PATH_SEGMENTS,
|
|
15
15
|
START_IN_STATES
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CD3ATSXE.mjs";
|
|
17
17
|
|
|
18
18
|
// src/shared/types/umbilical-events.ts
|
|
19
19
|
var UMBILICAL_EVENT_TYPES = [
|
|
@@ -30,6 +30,11 @@ var UMBILICAL_EVENT_TYPES = [
|
|
|
30
30
|
"agent.credentials.unlocked",
|
|
31
31
|
// --- turn --------------------------------------------------------------
|
|
32
32
|
"turn.completed",
|
|
33
|
+
// --- owner chats queued behind a running turn ---------------------------
|
|
34
|
+
// delivered → put into a running turn (their ids complete with it);
|
|
35
|
+
// discarded → dropped undelivered by stop/unload/off (never silently).
|
|
36
|
+
"chat.delivered",
|
|
37
|
+
"chat.discarded",
|
|
33
38
|
// --- tools -------------------------------------------------------------
|
|
34
39
|
"tool.started",
|
|
35
40
|
"tool.completed",
|
|
@@ -491,7 +496,7 @@ var StreamBindEndpointSchema = external_exports.union([
|
|
|
491
496
|
}).optional(),
|
|
492
497
|
fetch_middleware: external_exports.array(MiddlewareRefSchema).optional(),
|
|
493
498
|
require_middleware_authorization: external_exports.boolean().default(!0),
|
|
494
|
-
allow_local_fetch: external_exports.boolean().optional().describe("
|
|
499
|
+
allow_local_fetch: external_exports.boolean().optional().describe("Allow sys_fetch/ws_connect to reach private (RFC1918) and CGNAT destinations. When false/absent those are refused, including after DNS resolution and across redirects. Loopback is allowed either way, except the local daemon control API; link-local and cloud-metadata addresses are always refused."),
|
|
495
500
|
table_protections: external_exports.record(external_exports.enum(["none", "append_only", "authorized"])).optional()
|
|
496
501
|
}),
|
|
497
502
|
limits: external_exports.object({
|
|
@@ -268,7 +268,20 @@ function resultText(value) {
|
|
|
268
268
|
}
|
|
269
269
|
return value === void 0 ? void 0 : JSON.stringify(value);
|
|
270
270
|
}
|
|
271
|
+
function markOwnTurns(items, event) {
|
|
272
|
+
let p = event.payload ?? {}, ids = (value) => Array.isArray(value) ? value.filter((id) => typeof id == "string") : [], terminal = event.event_type === "turn.completed" || event.event_type === "agent.error", absorbed = terminal ? ids(p.absorbed_turn_ids) : [], delivered = event.event_type === "chat.delivered" ? ids(p.turn_ids) : [], discarded = event.event_type === "chat.discarded" ? ids(p.turn_ids) : [], cutOff = event.event_type === "chat.discarded" ? ids(p.unanswered_turn_ids) : [];
|
|
273
|
+
if (!event.turn_id && absorbed.length + delivered.length + discarded.length + cutOff.length === 0) return items;
|
|
274
|
+
let answeredNow = event.event_type === "turn.completed" && p.interrupted !== !0, next = null;
|
|
275
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
276
|
+
let item = items[i];
|
|
277
|
+
if (item.kind !== "user" || !item.turnId || item.answered) continue;
|
|
278
|
+
let patch = null;
|
|
279
|
+
absorbed.includes(item.turnId) ? patch = { taken: !0, answered: !0, pending: !1 } : discarded.includes(item.turnId) ? patch = { taken: !0, pending: !1, discarded: !0 } : cutOff.includes(item.turnId) ? patch = { taken: !0, pending: !1 } : delivered.includes(item.turnId) ? patch = item.taken ? null : { taken: !0 } : item.turnId === event.turn_id && (terminal ? patch = answeredNow ? { taken: !0, answered: !0, pending: !1 } : event.event_type === "agent.error" ? { taken: !0, pending: !1 } : null : item.taken || (patch = { taken: !0 })), patch && (next ??= items.slice(), next[i] = { ...item, ...patch });
|
|
280
|
+
}
|
|
281
|
+
return next ?? items;
|
|
282
|
+
}
|
|
271
283
|
function applyEventToItems(items, event) {
|
|
284
|
+
items = markOwnTurns(items, event);
|
|
272
285
|
let p = event.payload ?? {}, at = event.timestamp || Date.now();
|
|
273
286
|
switch (event.event_type) {
|
|
274
287
|
case "turn.delta": {
|
|
@@ -388,6 +401,10 @@ function noticeFor(event) {
|
|
|
388
401
|
return { text: `Model call failed${p.model ? ` (${String(p.model)})` : ""}`, level: "warn" };
|
|
389
402
|
case "error.recovery_suppressed":
|
|
390
403
|
return { text: "Error recovery suppressed \u2014 triggers are being dropped", level: "warn" };
|
|
404
|
+
case "chat.discarded": {
|
|
405
|
+
let count = typeof p.count == "number" ? p.count : 0;
|
|
406
|
+
return count === 0 ? null : { text: `${count} queued message${count === 1 ? "" : "s"} discarded undelivered (${p.reason === "off" ? "agent turned off" : "agent stopped"})`, level: "warn" };
|
|
407
|
+
}
|
|
391
408
|
default:
|
|
392
409
|
return null;
|
|
393
410
|
}
|
|
@@ -669,7 +686,9 @@ var TRANSCRIPT_EVENTS = /* @__PURE__ */ new Set([
|
|
|
669
686
|
"provider.retry_scheduled",
|
|
670
687
|
"provider.retry_cancelled",
|
|
671
688
|
"llm.failed",
|
|
672
|
-
"error.recovery_suppressed"
|
|
689
|
+
"error.recovery_suppressed",
|
|
690
|
+
"chat.delivered",
|
|
691
|
+
"chat.discarded"
|
|
673
692
|
]);
|
|
674
693
|
function applyEvent(state, event) {
|
|
675
694
|
let agentId = event.agent_id ?? null, loop = eventLoop(event), next = {
|
|
@@ -873,9 +892,9 @@ function serverText(server) {
|
|
|
873
892
|
}
|
|
874
893
|
|
|
875
894
|
// src/main/tui/state/store.tsx
|
|
876
|
-
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1), REFRESH_DEBOUNCE_MS = 120, WEB_EVENT_DEBOUNCE_MS = 900, WEB_POLL_MS = 2e4, TRACKED_POLL_MS = 15e3, FOLDER_OVERLAY = "fleet.track", PROMPT_PREFILL_KEY = "shell.prompt.prefill", CHAT_VIEW_ID = "chat";
|
|
895
|
+
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1), REFRESH_DEBOUNCE_MS = 120, WEB_EVENT_DEBOUNCE_MS = 900, RESUME_VERDICT_MS = 1500, WEB_POLL_MS = 2e4, TRACKED_POLL_MS = 15e3, FOLDER_OVERLAY = "fleet.track", PROMPT_PREFILL_KEY = "shell.prompt.prefill", CHAT_VIEW_ID = "chat";
|
|
877
896
|
function createTuiStore(options) {
|
|
878
|
-
let client = options.client, pageSize = options.pageSize ?? 100, state = initialState(client.baseUrl, options.initialView), listeners = /* @__PURE__ */ new Set(), confirmResolvers = /* @__PURE__ */ new Map(), toastTimers = /* @__PURE__ */ new Map(), debounced = /* @__PURE__ */ new Map(), stream = null, webTick = null, trackedTick = null, stopped = !1, needsResync = !1, getState = () => state, dispatch = (action) => {
|
|
897
|
+
let client = options.client, pageSize = options.pageSize ?? 100, state = initialState(client.baseUrl, options.initialView), listeners = /* @__PURE__ */ new Set(), confirmResolvers = /* @__PURE__ */ new Map(), toastTimers = /* @__PURE__ */ new Map(), debounced = /* @__PURE__ */ new Map(), stream = null, webTick = null, trackedTick = null, stopped = !1, needsResync = !1, resumeFallback = null, getState = () => state, dispatch = (action) => {
|
|
879
898
|
let next = tuiReducer(state, action);
|
|
880
899
|
if (next !== state) {
|
|
881
900
|
state = next;
|
|
@@ -1138,7 +1157,8 @@ function createTuiStore(options) {
|
|
|
1138
1157
|
let loop = target.loop ?? selectedLoopOf(agentId), key = transcriptKey(agentId, loop), item = { id: localId(), at: Date.now(), local: !0, kind: "user", text: trimmed, origin: "owner", pending: !0 };
|
|
1139
1158
|
dispatch({ type: "transcript/append", key, item });
|
|
1140
1159
|
try {
|
|
1141
|
-
|
|
1160
|
+
let accepted = await client.chat(agentId, trimmed, loop);
|
|
1161
|
+
return dispatch({ type: "transcript/update", key, id: item.id, patch: { accepted: !0, ...accepted?.turnId ? { turnId: accepted.turnId } : {} } }), !0;
|
|
1142
1162
|
} catch (err) {
|
|
1143
1163
|
return dispatch({ type: "transcript/update", key, id: item.id, patch: { pending: !1 } }), dispatch({ type: "transcript/append", key, item: { id: localId(), at: Date.now(), local: !0, kind: "error", text: `Not sent: ${describe(err)}` } }), !1;
|
|
1144
1164
|
}
|
|
@@ -1369,7 +1389,16 @@ function createTuiStore(options) {
|
|
|
1369
1389
|
options.live !== !1 && (stream = client.events({
|
|
1370
1390
|
onEvent: onFrame,
|
|
1371
1391
|
onState: (info) => {
|
|
1372
|
-
dispatch({ type: "connection", info }), info.state === "reconnecting" && (needsResync = !0, info.error && dispatch({ type: "daemon/reachable", reachable: !1 })), info.state === "open" &&
|
|
1392
|
+
dispatch({ type: "connection", info }), info.state === "reconnecting" && (needsResync = !0, info.error && dispatch({ type: "daemon/reachable", reachable: !1 })), info.state === "open" && info.resumed ? (needsResync = !1, resumeFallback && clearTimeout(resumeFallback), resumeFallback = setTimeout(() => {
|
|
1393
|
+
resumeFallback = null, toast("Reconnected to daemon \u2014 resyncing", "info", 2500), resync();
|
|
1394
|
+
}, RESUME_VERDICT_MS)) : info.state === "open" && needsResync && (needsResync = !1, toast("Connected to daemon", "info", 2500), resync());
|
|
1395
|
+
},
|
|
1396
|
+
onResume: (info) => {
|
|
1397
|
+
if (resumeFallback && (clearTimeout(resumeFallback), resumeFallback = null), info.exact) {
|
|
1398
|
+
toast("Reconnected to daemon \u2014 no events missed", "info", 2500), Promise.all([actions.refreshIdentity(), actions.refreshAuth(), actions.refreshAgents(), actions.refreshWeb()]);
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
toast(info.reason === "epoch_changed" ? "The daemon restarted \u2014 reloading" : "Events were missed while disconnected \u2014 reloading", "warn", 4e3), resync();
|
|
1373
1402
|
}
|
|
1374
1403
|
}).start(), webTick && clearInterval(webTick), webTick = setInterval(() => {
|
|
1375
1404
|
stopped || actions.refreshWeb();
|
|
@@ -1385,7 +1414,7 @@ function createTuiStore(options) {
|
|
|
1385
1414
|
}
|
|
1386
1415
|
}
|
|
1387
1416
|
function stop() {
|
|
1388
|
-
stopped = !0, stream?.close(), stream = null, webTick && (clearInterval(webTick), webTick = null), trackedTick && (clearInterval(trackedTick), trackedTick = null), pendingFrames = [];
|
|
1417
|
+
stopped = !0, stream?.close(), stream = null, resumeFallback && (clearTimeout(resumeFallback), resumeFallback = null), webTick && (clearInterval(webTick), webTick = null), trackedTick && (clearInterval(trackedTick), trackedTick = null), pendingFrames = [];
|
|
1389
1418
|
for (let timer of toastTimers.values()) clearTimeout(timer);
|
|
1390
1419
|
for (let timer of debounced.values()) clearTimeout(timer);
|
|
1391
1420
|
toastTimers.clear(), debounced.clear();
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createRequire as __adfCreateRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __adfFileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __adfDirname } from 'node:path';
|
|
4
|
+
const require = __adfCreateRequire(import.meta.url);
|
|
5
|
+
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __adfDirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
tokensEqual
|
|
9
|
+
} from "./chunk-IHDDCZBS.mjs";
|
|
10
|
+
|
|
11
|
+
// src/main/daemon/local-access.ts
|
|
12
|
+
import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { randomBytes } from "node:crypto";
|
|
15
|
+
var LOCAL_PROOF_FILENAME = "daemon-local-proof", LOCAL_PROOF_HEADER = "x-adf-local-proof", BEHIND_PROXY_ENV = "ADF_DAEMON_BEHIND_PROXY", PROXY_HEADERS = ["forwarded", "x-forwarded-for", "x-forwarded-host", "x-forwarded-proto", "x-real-ip", "via"];
|
|
16
|
+
function isLoopbackAddress(address) {
|
|
17
|
+
return address ? address === "::1" || address.startsWith("127.") || address.startsWith("::ffff:127.") : !1;
|
|
18
|
+
}
|
|
19
|
+
function hasProxyHeaders(headers) {
|
|
20
|
+
return PROXY_HEADERS.some((name) => headers[name] !== void 0);
|
|
21
|
+
}
|
|
22
|
+
function behindProxyFromEnv(env = process.env) {
|
|
23
|
+
return /^(1|true|yes|on)$/i.test((env[BEHIND_PROXY_ENV] ?? "").trim());
|
|
24
|
+
}
|
|
25
|
+
var DEFAULT_PORT = 7385;
|
|
26
|
+
function localProofPath(settingsDir, port = DEFAULT_PORT) {
|
|
27
|
+
return join(settingsDir, port === DEFAULT_PORT ? LOCAL_PROOF_FILENAME : `${LOCAL_PROOF_FILENAME}-${port}`);
|
|
28
|
+
}
|
|
29
|
+
function mintLocalProof(settingsDir, port = DEFAULT_PORT) {
|
|
30
|
+
mkdirSync(settingsDir, { recursive: !0 });
|
|
31
|
+
let proof = randomBytes(32).toString("base64url"), path = localProofPath(settingsDir, port);
|
|
32
|
+
writeFileSync(path, `${proof}
|
|
33
|
+
`, { mode: 384 });
|
|
34
|
+
try {
|
|
35
|
+
chmodSync(path, 384);
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
return { proof, path };
|
|
39
|
+
}
|
|
40
|
+
function readLocalProof(settingsDir, port = DEFAULT_PORT) {
|
|
41
|
+
try {
|
|
42
|
+
let proof = readFileSync(localProofPath(settingsDir, port), "utf-8").trim();
|
|
43
|
+
return /^[A-Za-z0-9_-]{32,}$/.test(proof) ? proof : null;
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function localAccessRefusal(request, opts) {
|
|
49
|
+
if (!isLoopbackAddress(request.remoteAddress)) return "the request did not come from this machine";
|
|
50
|
+
if (hasProxyHeaders(request.headers)) return "the request came through a proxy (forwarded headers)";
|
|
51
|
+
if (opts.behindProxy) {
|
|
52
|
+
let raw = request.headers[LOCAL_PROOF_HEADER], presented = (Array.isArray(raw) ? raw[0] : raw)?.trim();
|
|
53
|
+
if (!presented || !opts.localProof || !tokensEqual(presented, opts.localProof))
|
|
54
|
+
return `the daemon runs behind a proxy (${BEHIND_PROXY_ENV}) and the request lacks this machine's local proof`;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
BEHIND_PROXY_ENV,
|
|
61
|
+
behindProxyFromEnv,
|
|
62
|
+
mintLocalProof,
|
|
63
|
+
readLocalProof,
|
|
64
|
+
localAccessRefusal
|
|
65
|
+
};
|
|
@@ -7,7 +7,7 @@ const __dirname = __adfDirname(__filename);
|
|
|
7
7
|
import {
|
|
8
8
|
META_PROTECTION_LEVELS,
|
|
9
9
|
SETTABLE_STATES
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-CD3ATSXE.mjs";
|
|
11
11
|
import {
|
|
12
12
|
__esm
|
|
13
13
|
} from "./chunk-M2RX3S2T.mjs";
|
|
@@ -15,12 +15,19 @@ import {
|
|
|
15
15
|
// src/main/runtime/execution-context.ts
|
|
16
16
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
17
17
|
function withSource(source, agentIdOrFn, maybeFn) {
|
|
18
|
-
let agentId = typeof agentIdOrFn == "function" ? void 0 : agentIdOrFn, fn = typeof agentIdOrFn == "function" ? agentIdOrFn : maybeFn, parent = store.getStore(),
|
|
19
|
-
return store.run(
|
|
18
|
+
let agentId = typeof agentIdOrFn == "function" ? void 0 : agentIdOrFn, fn = typeof agentIdOrFn == "function" ? agentIdOrFn : maybeFn, parent = store.getStore(), sameAgent = agentId === void 0 || agentId === parent?.agentId, loop = parent?.loop && sameAgent ? parent.loop : void 0, turnId = parent?.turnId && sameAgent ? parent.turnId : void 0;
|
|
19
|
+
return store.run({ source, agentId, ...loop ? { loop } : {}, ...turnId ? { turnId } : {} }, fn);
|
|
20
20
|
}
|
|
21
21
|
function withLoop(loop, fn) {
|
|
22
22
|
let parent = store.getStore();
|
|
23
|
-
return store.run({ source: parent?.source ?? "system:unknown", agentId: parent?.agentId, loop }, fn);
|
|
23
|
+
return store.run({ ...parent, source: parent?.source ?? "system:unknown", agentId: parent?.agentId, loop }, fn);
|
|
24
|
+
}
|
|
25
|
+
function withTurn(turnId, fn) {
|
|
26
|
+
let parent = store.getStore();
|
|
27
|
+
return store.run({ ...parent, source: parent?.source ?? "system:unknown", turnId }, fn);
|
|
28
|
+
}
|
|
29
|
+
function currentTurnId() {
|
|
30
|
+
return store.getStore()?.turnId;
|
|
24
31
|
}
|
|
25
32
|
function currentLoop() {
|
|
26
33
|
return store.getStore()?.loop;
|
|
@@ -1455,7 +1462,7 @@ var xargsHandler = {
|
|
|
1455
1462
|
batchSize = n;
|
|
1456
1463
|
}
|
|
1457
1464
|
if (!text) return ok("");
|
|
1458
|
-
let { parse } = await import("./parser-JVY2PWSM.mjs"), { executeNode } = await import("./pipeline-executor-
|
|
1465
|
+
let { parse } = await import("./parser-JVY2PWSM.mjs"), { executeNode } = await import("./pipeline-executor-U6IMCCP3.mjs"), subCtx = {
|
|
1459
1466
|
workspace: ctx.workspace,
|
|
1460
1467
|
toolRegistry: ctx.toolRegistry,
|
|
1461
1468
|
config: ctx.config,
|
|
@@ -2275,7 +2282,7 @@ async function executeShellScript(path, ctx) {
|
|
|
2275
2282
|
authorized = ctx.workspace.isFileAuthorized(path);
|
|
2276
2283
|
} catch {
|
|
2277
2284
|
}
|
|
2278
|
-
let gate = { ...ctx.gate ?? {}, authorized }, base = baseRegistry(ctx.toolRegistry), toolRegistry = gate.authorized ? authorizedRegistry(base) : base, { parse } = await import("./parser-JVY2PWSM.mjs"), { executeNode, MAX_SHELL_DEPTH } = await import("./pipeline-executor-
|
|
2285
|
+
let gate = { ...ctx.gate ?? {}, authorized }, base = baseRegistry(ctx.toolRegistry), toolRegistry = gate.authorized ? authorizedRegistry(base) : base, { parse } = await import("./parser-JVY2PWSM.mjs"), { executeNode, MAX_SHELL_DEPTH } = await import("./pipeline-executor-U6IMCCP3.mjs"), depth = (ctx.depth ?? 0) + 1;
|
|
2279
2286
|
if (depth > MAX_SHELL_DEPTH)
|
|
2280
2287
|
return err(`./${path}: script nesting too deep (${MAX_SHELL_DEPTH}) \u2014 possible infinite recursion`);
|
|
2281
2288
|
try {
|
|
@@ -3016,7 +3023,7 @@ var CATEGORY_ORDER = [
|
|
|
3016
3023
|
resolvedTools: [],
|
|
3017
3024
|
async execute(ctx) {
|
|
3018
3025
|
if (ctx.args.length > 0) {
|
|
3019
|
-
let { getCommand: getCommand2 } = await import("./commands-
|
|
3026
|
+
let { getCommand: getCommand2 } = await import("./commands-XNJMCD5L.mjs"), handler = getCommand2(ctx.args[0]);
|
|
3020
3027
|
return handler ? ok(handler.helpText) : ok(`Unknown command: ${ctx.args[0]}`);
|
|
3021
3028
|
}
|
|
3022
3029
|
let commands = getAllCommands(), grouped = /* @__PURE__ */ new Map();
|
|
@@ -3076,6 +3083,8 @@ function hasCommand(name) {
|
|
|
3076
3083
|
export {
|
|
3077
3084
|
withSource,
|
|
3078
3085
|
withLoop,
|
|
3086
|
+
withTurn,
|
|
3087
|
+
currentTurnId,
|
|
3079
3088
|
currentLoop,
|
|
3080
3089
|
currentAgentId,
|
|
3081
3090
|
currentSourceOrUnknown,
|