@songsid/agend 2.1.11-beta.6 → 2.1.12-beta.1
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 +23 -15
- package/README.zh-TW.md +50 -11
- package/dist/backend/claude-code.d.ts +2 -0
- package/dist/backend/claude-code.js +63 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/types.d.ts +25 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/classic-bindings.d.ts +48 -0
- package/dist/classic-bindings.js +128 -0
- package/dist/classic-bindings.js.map +1 -0
- package/dist/classic-channel-manager.d.ts +21 -0
- package/dist/classic-channel-manager.js +31 -0
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/daemon.d.ts +41 -0
- package/dist/daemon.js +299 -16
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +13 -0
- package/dist/delivery-reconciliation.js +71 -7
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/delivery-reconciliation.test.js +115 -2
- package/dist/delivery-reconciliation.test.js.map +1 -1
- package/dist/fleet-manager.d.ts +14 -1
- package/dist/fleet-manager.js +75 -8
- package/dist/fleet-manager.js.map +1 -1
- package/dist/instance-lifecycle.js +4 -2
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/interaction-observation.d.ts +32 -0
- package/dist/interaction-observation.js +118 -0
- package/dist/interaction-observation.js.map +1 -0
- package/dist/kiro-engine-status.d.ts +2 -0
- package/dist/kiro-engine-status.js +3 -1
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/locale.js +22 -0
- package/dist/locale.js.map +1 -1
- package/dist/outbound-handlers.d.ts +2 -0
- package/dist/outbound-handlers.js +28 -11
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/output-log-tail.d.ts +21 -0
- package/dist/output-log-tail.js +89 -0
- package/dist/output-log-tail.js.map +1 -0
- package/dist/usage/providers.d.ts +11 -0
- package/dist/usage/providers.js +34 -7
- package/dist/usage/providers.js.map +1 -1
- package/package.json +1 -1
package/dist/fleet-manager.js
CHANGED
|
@@ -75,6 +75,7 @@ import { handleAgentRequest, ToolNotPermittedError } from "./agent-endpoint.js";
|
|
|
75
75
|
import { ClassicChannelManager, getClassicBackendChoices, isSelectableClassicBackend, readClassicLastActivityAt } from "./classic-channel-manager.js";
|
|
76
76
|
import { assertExplicitInstanceRemoval } from "./instance-removal.js";
|
|
77
77
|
import { validateFleetConfig } from "./config-validator.js";
|
|
78
|
+
import { presentationState, interactionSummary } from "./interaction-observation.js";
|
|
78
79
|
import { readLastInboundAt } from "./daemon.js";
|
|
79
80
|
import { clearPausedMarker, readPausedAt, readPauseReason, writePausedMarker } from "./pause-marker.js";
|
|
80
81
|
import { DEFAULT_WARM_OVERFLOW, WakeCoordinator } from "./wake-coordinator.js";
|
|
@@ -97,7 +98,8 @@ import { PROVIDER_SECRET_SPECS, providerSecretSpec, providerRegistryEnvKeys, isR
|
|
|
97
98
|
/** A self-restart is a whole service restart; 120s is the apply budget, not this. */
|
|
98
99
|
const SELF_RESTART_DEADLINE_MS = 300_000;
|
|
99
100
|
import { APPLY_FLEET_TARGET, ApplyJobStore, viewOf, } from "./apply-job.js";
|
|
100
|
-
import { instanceCredentialProfile } from "./backend/credential-profile.js";
|
|
101
|
+
import { credentialSwitchStartsFresh, instanceCredentialProfile } from "./backend/credential-profile.js";
|
|
102
|
+
import { mergeBackendOptions, profileKey, profileName, profileOf } from "./classic-bindings.js";
|
|
101
103
|
import { classifyInstanceChange, CLASSIC_HOT_CONFIG_KEYS, HOT_INSTANCE_CONFIG_KEYS, hotConfigUpdate, } from "./instance-config-impact.js";
|
|
102
104
|
import { formatRestartProgressCompletion, RESTART_PROGRESS_TERMINAL_TIMEOUT_MS, RestartProgress, } from "./restart-progress.js";
|
|
103
105
|
import { launchFullRestartHelper } from "./full-restart.js";
|
|
@@ -1774,6 +1776,21 @@ export class FleetManager {
|
|
|
1774
1776
|
return null;
|
|
1775
1777
|
return this.instanceStateCache.get(name)?.state ?? null;
|
|
1776
1778
|
}
|
|
1779
|
+
/** Pure read of the single daemon-owned observation; no probe/capture or second tracker. */
|
|
1780
|
+
getInstanceInteraction(name) {
|
|
1781
|
+
if (this.lifecycle.isPaused(name) || this.instanceProcessStatus.has(name))
|
|
1782
|
+
return null;
|
|
1783
|
+
const daemon = this.lifecycle.daemons.get(name);
|
|
1784
|
+
if (daemon?.getProcessStatus?.() !== "running")
|
|
1785
|
+
return null;
|
|
1786
|
+
return daemon.getInteractionSnapshot?.() ?? null;
|
|
1787
|
+
}
|
|
1788
|
+
instancePresentation(name) {
|
|
1789
|
+
const execution_state = this.getInstanceExecutionState(name);
|
|
1790
|
+
const interaction = this.getInstanceInteraction(name);
|
|
1791
|
+
return { state: presentationState(execution_state, interaction), execution_state,
|
|
1792
|
+
interaction, interaction_summary: interactionSummary(interaction) };
|
|
1793
|
+
}
|
|
1777
1794
|
/**
|
|
1778
1795
|
* Subscription providers currently relevant to this fleet. Stopped/crashed
|
|
1779
1796
|
* rows do not keep a usage card alive, while persisted paused instances do.
|
|
@@ -1805,6 +1822,34 @@ export class FleetManager {
|
|
|
1805
1822
|
}
|
|
1806
1823
|
return providers;
|
|
1807
1824
|
}
|
|
1825
|
+
/** #1220: the login a running classic instance was launched on, from its own config; null when not running. */
|
|
1826
|
+
classicLaunchedProfile(name) {
|
|
1827
|
+
const launched = this.daemons.get(name)?.getConfigSnapshot?.();
|
|
1828
|
+
return launched ? profileOf(launched.backend_options, launched.backend ?? "claude-code") : null;
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* #1220: whether a running classic instance's login differs from what its
|
|
1832
|
+
* configuration now says — compared with what it was launched on, not with an
|
|
1833
|
+
* earlier reading of the config (a reload consumes that), and with an invalid
|
|
1834
|
+
* setting as a value of its own rather than the shared login it would fall to.
|
|
1835
|
+
* A switch on the same backend that loses the conversation (kiro) starts fresh.
|
|
1836
|
+
*/
|
|
1837
|
+
classicProfileChange(name, backendChanged) {
|
|
1838
|
+
const launched = this.classicLaunchedProfile(name);
|
|
1839
|
+
if (!launched || !this.classicChannels)
|
|
1840
|
+
return { changed: false, startsFresh: false };
|
|
1841
|
+
const next = this.classicChannels.getCredentialProfileByInstance(name, this.fleetConfig?.defaults);
|
|
1842
|
+
if (profileKey(launched) === profileKey(next))
|
|
1843
|
+
return { changed: false, startsFresh: false };
|
|
1844
|
+
const backend = this.classicChannels.getBackendByInstance(name, this.fleetConfig?.defaults?.backend);
|
|
1845
|
+
return {
|
|
1846
|
+
changed: true,
|
|
1847
|
+
// A backend change keeps its own (existing) restart semantics.
|
|
1848
|
+
startsFresh: !backendChanged && credentialSwitchStartsFresh(backend),
|
|
1849
|
+
from: profileKey(launched),
|
|
1850
|
+
to: profileKey(next),
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1808
1853
|
/** `[instance, effective backend, credential profile]` for everything that is
|
|
1809
1854
|
* running or paused — the one place both usage views agree on who is live. */
|
|
1810
1855
|
activeBackendBindings() {
|
|
@@ -1823,8 +1868,9 @@ export class FleetManager {
|
|
|
1823
1868
|
}
|
|
1824
1869
|
for (const channel of this.classicChannels?.getAll() ?? []) {
|
|
1825
1870
|
const backend = this.classicChannels?.getBackendByInstance(channel.instanceName, this.fleetConfig?.defaults?.backend);
|
|
1826
|
-
//
|
|
1827
|
-
add(channel.instanceName, backend,
|
|
1871
|
+
// The login it was launched on; before a launch, the one it would get (#1220).
|
|
1872
|
+
add(channel.instanceName, backend, profileName(this.classicLaunchedProfile(channel.instanceName)
|
|
1873
|
+
?? this.classicChannels.getCredentialProfileByInstance(channel.instanceName, this.fleetConfig?.defaults)));
|
|
1828
1874
|
}
|
|
1829
1875
|
return bindings;
|
|
1830
1876
|
}
|
|
@@ -2693,9 +2739,15 @@ export class FleetManager {
|
|
|
2693
2739
|
const backendChanged = oldBackends.get(ch.instanceName) !== newBackend;
|
|
2694
2740
|
const modelChanged = oldModels.get(ch.instanceName) !== newModel;
|
|
2695
2741
|
const autoPauseChanged = oldAutoPause.get(ch.instanceName) !== newAutoPause;
|
|
2696
|
-
|
|
2697
|
-
|
|
2742
|
+
// #1220: a running CLI keeps the login it was launched with, so a new
|
|
2743
|
+
// credential_profile only takes effect through a restart.
|
|
2744
|
+
const { changed: profileChanged, startsFresh: profileSwitchStartsFresh, from: profileFrom, to: profileTo } = this.classicProfileChange(ch.instanceName, backendChanged);
|
|
2745
|
+
if (this.daemons.has(ch.instanceName) && (backendChanged || modelChanged || autoPauseChanged || profileChanged)) {
|
|
2746
|
+
this.logger.info({ instanceName: ch.instanceName, backendFrom: oldBackends.get(ch.instanceName), backendTo: newBackend, modelFrom: oldModels.get(ch.instanceName), modelTo: newModel,
|
|
2747
|
+
...(profileChanged ? { profileFrom, profileTo } : {}) }, "Backend/model/profile changed — restarting");
|
|
2698
2748
|
await this.stopInstance(ch.instanceName).catch(() => { });
|
|
2749
|
+
if (profileSwitchStartsFresh)
|
|
2750
|
+
this.writeFreshStartMarker(ch.instanceName);
|
|
2699
2751
|
// Small delay to let tmux window clean up
|
|
2700
2752
|
await new Promise(r => setTimeout(r, 2000));
|
|
2701
2753
|
// The manager already holds the new backend/model/auto-pause; the
|
|
@@ -12123,6 +12175,17 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
12123
12175
|
...(autoPauseAfter !== undefined ? { auto_pause_after: autoPauseAfter } : {}),
|
|
12124
12176
|
...(preTaskCommand ? { pre_task_command: preTaskCommand } : {}),
|
|
12125
12177
|
};
|
|
12178
|
+
// #1220: a channel's own backend_options (credential_profile) override the
|
|
12179
|
+
// fleet defaults' per backend, as a fleet.yaml instance's do.
|
|
12180
|
+
config.backend_options = mergeBackendOptions(config.backend_options, classicIdentity?.backendOptions);
|
|
12181
|
+
// ClassicBot has no validator in front of its launch, and a backend that
|
|
12182
|
+
// cannot read a profile name falls back to the shared login. Refuse here,
|
|
12183
|
+
// so a bad name never runs the agent on the wrong subscription.
|
|
12184
|
+
const profile = profileOf(config.backend_options, config.backend ?? "claude-code");
|
|
12185
|
+
if (profile.state === "invalid") {
|
|
12186
|
+
throw new Error(`Classic instance '${instanceName}' has an invalid credential_profile (${profile.reason}) — `
|
|
12187
|
+
+ "fix it in classicBot.yaml; it will not start on another login");
|
|
12188
|
+
}
|
|
12126
12189
|
const topicMode = this.fleetConfig?.channel?.mode === "topic";
|
|
12127
12190
|
await this.startInstance(instanceName, config, topicMode, "classic", false, transition);
|
|
12128
12191
|
}
|
|
@@ -12631,10 +12694,13 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
12631
12694
|
const backend = this.classicChannels.getBackend(ch.channelId, ch.adapterId, this.fleetConfig?.defaults?.backend);
|
|
12632
12695
|
const model = this.classicChannels.getModel(ch.channelId, ch.adapterId, this.fleetConfig?.defaults?.model);
|
|
12633
12696
|
const autoPauseAfter = this.classicChannels.getAutoPauseAfter(ch.channelId, ch.adapterId, this.fleetConfig?.defaults?.auto_pause_after);
|
|
12634
|
-
|
|
12635
|
-
|
|
12697
|
+
const profile = this.classicProfileChange(ch.instanceName, old.backend !== backend);
|
|
12698
|
+
if (old.backend !== backend || old.model !== model || old.autoPauseAfter !== autoPauseAfter || profile.changed) {
|
|
12699
|
+
this.logger.info({ instanceName: ch.instanceName, ...(profile.changed ? { profileFrom: profile.from, profileTo: profile.to } : {}) }, "Classic cold config changed — restarting");
|
|
12636
12700
|
observe?.(ch.instanceName, "restart", "running");
|
|
12637
12701
|
await this.stopInstance(ch.instanceName).catch(() => { });
|
|
12702
|
+
if (profile.startsFresh)
|
|
12703
|
+
this.writeFreshStartMarker(ch.instanceName);
|
|
12638
12704
|
await this.startClassicInstanceUnattended(ch, "classic instance after fleet reload");
|
|
12639
12705
|
observe?.(ch.instanceName, "restart", "done");
|
|
12640
12706
|
continue;
|
|
@@ -14247,7 +14313,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
14247
14313
|
lastActivity,
|
|
14248
14314
|
currentTask,
|
|
14249
14315
|
idle: this.getInstanceIdle(inst.name),
|
|
14250
|
-
|
|
14316
|
+
...this.instancePresentation(inst.name),
|
|
14251
14317
|
};
|
|
14252
14318
|
});
|
|
14253
14319
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -14504,6 +14570,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
14504
14570
|
backend,
|
|
14505
14571
|
effort,
|
|
14506
14572
|
effort_source,
|
|
14573
|
+
...this.instancePresentation(name),
|
|
14507
14574
|
};
|
|
14508
14575
|
});
|
|
14509
14576
|
return {
|