@songsid/agend 2.1.12-beta.3 → 2.1.12-beta.5
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 +54 -8
- package/README.zh-TW.md +104 -11
- package/dist/agent-endpoint.d.ts +2 -0
- package/dist/agent-endpoint.js +38 -29
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/factory.js +5 -5
- package/dist/backend/factory.js.map +1 -1
- package/dist/backend/index.d.ts +0 -1
- package/dist/backend/index.js +0 -1
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/kiro.d.ts +10 -1
- package/dist/backend/kiro.js +13 -0
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/mock.d.ts +1 -1
- package/dist/backend/mock.js +1 -1
- package/dist/backend/muse.d.ts +14 -0
- package/dist/backend/muse.js +60 -11
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/removed.d.ts +12 -0
- package/dist/backend/removed.js +18 -0
- package/dist/backend/removed.js.map +1 -0
- package/dist/backend/session-signals.js +5 -10
- package/dist/backend/session-signals.js.map +1 -1
- package/dist/backend/types.d.ts +1 -1
- package/dist/backend/types.js +0 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.js +9 -0
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +14 -8
- package/dist/channel/adapters/telegram.js +80 -26
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -2
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/classic-channel-manager.js +2 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +27 -53
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +1 -1
- package/dist/command-table.js +4 -2
- package/dist/command-table.js.map +1 -1
- package/dist/config-validator.js +82 -10
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +7 -5
- package/dist/config.js.map +1 -1
- package/dist/context-guardian.d.ts +1 -1
- package/dist/context-guardian.js +1 -1
- package/dist/cross-instance-notice.d.ts +39 -0
- package/dist/cross-instance-notice.js +84 -0
- package/dist/cross-instance-notice.js.map +1 -0
- package/dist/daemon.d.ts +6 -0
- package/dist/daemon.js +54 -42
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js +0 -3
- package/dist/daily-summary.js.map +1 -1
- package/dist/fleet-manager.d.ts +16 -3
- package/dist/fleet-manager.js +110 -53
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -1
- package/dist/instance-config-impact.js +3 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +9 -1
- package/dist/instance-lifecycle.js +66 -7
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +28 -2
- package/dist/locale.js.map +1 -1
- package/dist/memory-pressure.d.ts +8 -2
- package/dist/memory-pressure.js +10 -4
- package/dist/memory-pressure.js.map +1 -1
- package/dist/outbound-handlers.js +36 -23
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +0 -1
- package/dist/outbound-schemas.js +4 -4
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/prompt-file-ref.d.ts +42 -0
- package/dist/prompt-file-ref.js +118 -0
- package/dist/prompt-file-ref.js.map +1 -0
- package/dist/reply-dedup.d.ts +5 -0
- package/dist/reply-dedup.js +9 -0
- package/dist/reply-dedup.js.map +1 -1
- package/dist/settings-api.js +5 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/setup-wizard.js +0 -4
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.js +4 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/target-queue-worker.d.ts +1 -1
- package/dist/topic-commands.d.ts +64 -5
- package/dist/topic-commands.js +172 -14
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-jsonl.d.ts +12 -0
- package/dist/transcript-jsonl.js +37 -0
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-monitor.js +10 -7
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -1
- package/dist/transcript-sources.js +29 -11
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +13 -4
- package/dist/ui/dashboard.html +3 -3
- package/dist/ui/settings.html +58 -16
- package/dist/update-check.d.ts +15 -6
- package/dist/update-check.js +20 -7
- package/dist/update-check.js.map +1 -1
- package/dist/wake-coordinator.js +1 -1
- package/dist/web-api.js +1 -2
- package/dist/web-api.js.map +1 -1
- package/package.json +1 -1
- package/dist/backend/gemini-cli.d.ts +0 -20
- package/dist/backend/gemini-cli.js +0 -169
- package/dist/backend/gemini-cli.js.map +0 -1
package/dist/daemon.js
CHANGED
|
@@ -16,6 +16,8 @@ import { resolveToolSet } from "./tool-permissions.js";
|
|
|
16
16
|
import { getAgendHome } from "./paths.js";
|
|
17
17
|
import { LOGIN_FLOWS } from "./login-flows.js";
|
|
18
18
|
import { ProgressAccumulator, summarizeProgress } from "./tool-progress.js";
|
|
19
|
+
import { assembleSystemPrompt, resolveWorkflowText } from "./prompt-file-ref.js";
|
|
20
|
+
import { isCrossInstanceVisibility } from "./cross-instance-notice.js";
|
|
19
21
|
import { ContextGuardian } from "./context-guardian.js";
|
|
20
22
|
import { IpcServer } from "./channel/ipc-bridge.js";
|
|
21
23
|
import { daemonBudgetMs } from "./channel/ipc-timeouts.js";
|
|
@@ -73,9 +75,7 @@ export function buildInstructionReloadNotice(binaryName, instanceName, instanceD
|
|
|
73
75
|
? `.kiro/steering/agend-${instanceName}.md`
|
|
74
76
|
: binaryName === "agy"
|
|
75
77
|
? ".agents/agents.md"
|
|
76
|
-
:
|
|
77
|
-
? "GEMINI.md"
|
|
78
|
-
: join(instanceDir, "fleet-instructions.md");
|
|
78
|
+
: join(instanceDir, "fleet-instructions.md");
|
|
79
79
|
return `[system] Your AgEnD instructions have been updated. Reload only ${source}; do not scan other instruction directories. Do not reply to this message.`;
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
@@ -1006,6 +1006,8 @@ export class Daemon extends EventEmitter {
|
|
|
1006
1006
|
spawnGate;
|
|
1007
1007
|
stormWindow;
|
|
1008
1008
|
backendOutage;
|
|
1009
|
+
/** #1314: fleet-directory fallbacks already reported to the topic (once per daemon, per field and path). */
|
|
1010
|
+
promptFileFallbackNoticed = new Set();
|
|
1009
1011
|
/** Identity of this live Daemon object; changes on object stop/restart. */
|
|
1010
1012
|
bootId = randomUUID();
|
|
1011
1013
|
deliveryOutbox;
|
|
@@ -2112,7 +2114,7 @@ export class Daemon extends EventEmitter {
|
|
|
2112
2114
|
}
|
|
2113
2115
|
// 8. Context guardian
|
|
2114
2116
|
const statusFile = join(this.instanceDir, "statusline.json");
|
|
2115
|
-
this.guardian = new ContextGuardian(this.config.context_guardian, this.logger, statusFile);
|
|
2117
|
+
this.guardian = new ContextGuardian(this.config.context_guardian ?? {}, this.logger, statusFile);
|
|
2116
2118
|
this.guardian.startWatching();
|
|
2117
2119
|
this.guardian.on("status_update", () => {
|
|
2118
2120
|
this.saveSessionId();
|
|
@@ -3981,8 +3983,20 @@ export class Daemon extends EventEmitter {
|
|
|
3981
3983
|
getInteractionSnapshot() {
|
|
3982
3984
|
return this.interactionObservation.snapshot(this.interactionOwner());
|
|
3983
3985
|
}
|
|
3986
|
+
/** Key of the last interaction snapshot actually emitted + broadcast (#1219). */
|
|
3987
|
+
lastPublishedInteractionKey = null;
|
|
3984
3988
|
publishInteraction() {
|
|
3985
3989
|
const interaction = this.getInteractionSnapshot();
|
|
3990
|
+
// The runtime monitor and every state capture observe the same unchanged
|
|
3991
|
+
// dialog for minutes; re-emitting an identical snapshot each time is
|
|
3992
|
+
// needless IPC traffic. Skip only exact duplicates — any change in the
|
|
3993
|
+
// presentation-relevant fields publishes, so the final state is never
|
|
3994
|
+
// lost (clocks like ageMs are excluded on purpose: they always change).
|
|
3995
|
+
const key = JSON.stringify([interaction.phase, interaction.kind, interaction.reason,
|
|
3996
|
+
interaction.episode, interaction.stale, interaction.suspected]);
|
|
3997
|
+
if (key === this.lastPublishedInteractionKey)
|
|
3998
|
+
return;
|
|
3999
|
+
this.lastPublishedInteractionKey = key;
|
|
3986
4000
|
// Presentation telemetry must not interrupt the execution-state/hold path.
|
|
3987
4001
|
try {
|
|
3988
4002
|
this.emit("instance_interaction", { name: this.name, interaction });
|
|
@@ -5079,15 +5093,14 @@ export class Daemon extends EventEmitter {
|
|
|
5079
5093
|
? await this.tmux.capturePane(1_000) : await this.tmux.capturePane();
|
|
5080
5094
|
if (!currentDeliveryCapture() || !sameInteractionOwner(interactionOwner, this.interactionOwner()))
|
|
5081
5095
|
return;
|
|
5082
|
-
// An old capture must not retire a new launch's transient guard either.
|
|
5083
|
-
if (reason === "delivery_idle_gate" && !currentDeliveryCapture()) {
|
|
5084
|
-
this.resetFooterFallback();
|
|
5085
|
-
return;
|
|
5086
|
-
}
|
|
5087
5096
|
// Delivery's unknown-footer proof also awaits the TTY mode. Validate
|
|
5088
5097
|
// output and launch freshness AFTER both awaits, before accepting it.
|
|
5089
5098
|
const deliveryCandidate = reason === "delivery_idle_gate"
|
|
5090
5099
|
? await this.probeDeliveryIdleFallback(pane) : null;
|
|
5100
|
+
// An old capture must not retire a new launch's transient guard either.
|
|
5101
|
+
// This check is only live here, after the probe's await: the identical
|
|
5102
|
+
// check before the probe was dead (no await in between, so the early
|
|
5103
|
+
// return above had already settled it) and is gone (#1219).
|
|
5091
5104
|
if (reason === "delivery_idle_gate" && !currentDeliveryCapture()) {
|
|
5092
5105
|
this.resetFooterFallback();
|
|
5093
5106
|
return;
|
|
@@ -5583,6 +5596,10 @@ export class Daemon extends EventEmitter {
|
|
|
5583
5596
|
this.config.tags = [...update.tags];
|
|
5584
5597
|
else if (update.tags === null)
|
|
5585
5598
|
delete this.config.tags;
|
|
5599
|
+
if (isCrossInstanceVisibility(update.cross_instance_visibility))
|
|
5600
|
+
this.config.cross_instance_visibility = update.cross_instance_visibility;
|
|
5601
|
+
else if (update.cross_instance_visibility === null)
|
|
5602
|
+
delete this.config.cross_instance_visibility;
|
|
5586
5603
|
if (["trace", "debug", "info", "warn", "error"].includes(String(update.log_level))) {
|
|
5587
5604
|
const level = update.log_level;
|
|
5588
5605
|
if (this.config.log_level !== level) {
|
|
@@ -8583,6 +8600,26 @@ export class Daemon extends EventEmitter {
|
|
|
8583
8600
|
respond(null, `Unknown tool: ${tool}`);
|
|
8584
8601
|
}
|
|
8585
8602
|
}
|
|
8603
|
+
/** Where this instance's `file:` refs resolve, and what a problem with one reports — never the file's contents. */
|
|
8604
|
+
promptFileContext() {
|
|
8605
|
+
return {
|
|
8606
|
+
workingDirectory: this.config.working_directory,
|
|
8607
|
+
// The only reader of the fleet's cwd: the one-release fallback to where these refs used to resolve.
|
|
8608
|
+
fleetCwd: process.cwd(),
|
|
8609
|
+
onWarning: (warning) => {
|
|
8610
|
+
if (warning.problem === "fleet_dir_fallback") {
|
|
8611
|
+
this.logger.warn({ field: warning.field, path: warning.path, legacyPath: warning.legacyPath }, `${warning.field} file: ref is not under the instance's working directory (${warning.path}); read ${warning.legacyPath} from the fleet directory instead — make the path absolute or move the file. The fallback is removed in 2.2.`);
|
|
8612
|
+
const key = `${warning.field}:${warning.path}`;
|
|
8613
|
+
if (!this.promptFileFallbackNoticed.has(key)) {
|
|
8614
|
+
this.promptFileFallbackNoticed.add(key);
|
|
8615
|
+
this.emit("prompt_file_fallback", { name: this.name, field: warning.field, path: warning.path, legacyPath: warning.legacyPath });
|
|
8616
|
+
}
|
|
8617
|
+
return;
|
|
8618
|
+
}
|
|
8619
|
+
this.logger.warn({ field: warning.field, path: warning.path, problem: warning.problem, code: warning.code }, `${warning.field} file: ref gives nothing (${warning.problem}${warning.code ? ` ${warning.code}` : ""}): ${warning.path}`);
|
|
8620
|
+
},
|
|
8621
|
+
};
|
|
8622
|
+
}
|
|
8586
8623
|
/** Build config object for the CLI backend */
|
|
8587
8624
|
buildBackendConfig() {
|
|
8588
8625
|
// Antigravity 1.1.17 has no per-workspace MCP config, but its global MCP
|
|
@@ -8595,44 +8632,19 @@ export class Daemon extends EventEmitter {
|
|
|
8595
8632
|
serverJs = join(__dirname, "..", "dist", "channel", "mcp-server.js");
|
|
8596
8633
|
}
|
|
8597
8634
|
// ── Resolve workflow and systemPrompt once, share between MCP env and instructions ──
|
|
8635
|
+
// #1314: `file:` refs are relative to this instance's working directory (src/prompt-file-ref.ts).
|
|
8636
|
+
const promptFiles = this.promptFileContext();
|
|
8598
8637
|
let resolvedWorkflow;
|
|
8599
8638
|
if (this.config.workflow === false) {
|
|
8600
8639
|
resolvedWorkflow = false;
|
|
8601
8640
|
}
|
|
8602
8641
|
else {
|
|
8603
8642
|
const wf = this.config.workflow ?? "builtin";
|
|
8604
|
-
if (wf !== "builtin")
|
|
8605
|
-
|
|
8606
|
-
if (content.startsWith("file:")) {
|
|
8607
|
-
try {
|
|
8608
|
-
content = readFileSync(content.slice(5), "utf-8");
|
|
8609
|
-
}
|
|
8610
|
-
catch {
|
|
8611
|
-
content = "";
|
|
8612
|
-
}
|
|
8613
|
-
}
|
|
8614
|
-
resolvedWorkflow = content || undefined;
|
|
8615
|
-
}
|
|
8616
|
-
}
|
|
8617
|
-
let resolvedCustomPrompt;
|
|
8618
|
-
if (this.config.systemPrompt) {
|
|
8619
|
-
// Support comma-separated file: paths for prompt modularization:
|
|
8620
|
-
// systemPrompt: "file:prompts/role.md, file:prompts/rules.md, file:prompts/context.md"
|
|
8621
|
-
const parts = this.config.systemPrompt.split(",").map((s) => s.trim());
|
|
8622
|
-
const resolved = parts.map((part) => {
|
|
8623
|
-
if (part.startsWith("file:")) {
|
|
8624
|
-
try {
|
|
8625
|
-
return readFileSync(part.slice(5), "utf-8");
|
|
8626
|
-
}
|
|
8627
|
-
catch {
|
|
8628
|
-
return "";
|
|
8629
|
-
}
|
|
8630
|
-
}
|
|
8631
|
-
return part;
|
|
8632
|
-
}).filter(Boolean);
|
|
8633
|
-
if (resolved.length > 0)
|
|
8634
|
-
resolvedCustomPrompt = resolved.join("\n\n");
|
|
8643
|
+
if (wf !== "builtin")
|
|
8644
|
+
resolvedWorkflow = resolveWorkflowText(wf, promptFiles) || undefined;
|
|
8635
8645
|
}
|
|
8646
|
+
// Comma-separated parts (`file:role.md, file:rules.md`) only when a part is a file ref; otherwise one inline prompt.
|
|
8647
|
+
const resolvedCustomPrompt = this.config.systemPrompt ? assembleSystemPrompt(this.config.systemPrompt, promptFiles) : undefined;
|
|
8636
8648
|
let decisions;
|
|
8637
8649
|
if (process.env.AGEND_DECISIONS) {
|
|
8638
8650
|
try {
|
|
@@ -9494,8 +9506,8 @@ export class Daemon extends EventEmitter {
|
|
|
9494
9506
|
else {
|
|
9495
9507
|
this.warmupNeeded = !!backendConfig.instructions && prev !== backendConfig.instructions;
|
|
9496
9508
|
}
|
|
9497
|
-
// For backends that don't re-read instructions on resume (kiro/codex
|
|
9498
|
-
//
|
|
9509
|
+
// For backends that don't re-read instructions on resume (kiro/codex),
|
|
9510
|
+
// also notify the agent on next message instead of forcing a new
|
|
9499
9511
|
// session. Resume is preserved so context isn't lost.
|
|
9500
9512
|
if (!backendConfig.skipResume && backendNeedsPaneReloadNotice(this.backend) && this.warmupNeeded) {
|
|
9501
9513
|
if (prev) {
|