@songsid/agend 2.2.0-beta.9 → 2.2.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/README.md +40 -24
- package/README.zh-TW.md +40 -24
- package/dist/agent-endpoint.js +3 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-whats-new.js +7 -1
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.d.ts +3 -1
- package/dist/auth-api.js +15 -1
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/antigravity.d.ts +33 -0
- package/dist/backend/antigravity.js +126 -18
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +3 -0
- package/dist/backend/claude-code.js +9 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +33 -0
- package/dist/backend/codex-metadata.js +122 -18
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex.d.ts +3 -0
- package/dist/backend/codex.js +17 -1
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/effort-metadata.d.ts +37 -1
- package/dist/backend/effort-metadata.js +86 -15
- package/dist/backend/effort-metadata.js.map +1 -1
- package/dist/backend/grok.d.ts +3 -0
- package/dist/backend/grok.js +9 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -1
- package/dist/backend/kiro.js +7 -3
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/launch-effort.d.ts +61 -0
- package/dist/backend/launch-effort.js +170 -0
- package/dist/backend/launch-effort.js.map +1 -0
- package/dist/backend/types.d.ts +24 -0
- package/dist/backend/types.js +12 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-command.d.ts +91 -0
- package/dist/backend-command.js +122 -0
- package/dist/backend-command.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +12 -0
- package/dist/channel/adapters/discord.js +49 -2
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +18 -0
- package/dist/channel/adapters/telegram.js +24 -3
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.d.ts +2 -0
- package/dist/channel/tool-router.js +1 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/channel/types.d.ts +16 -0
- package/dist/cli.js +124 -24
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +2 -2
- package/dist/command-table.js +5 -2
- package/dist/command-table.js.map +1 -1
- package/dist/compact-watch.d.ts +86 -0
- package/dist/compact-watch.js +288 -0
- package/dist/compact-watch.js.map +1 -0
- package/dist/config-validator.js +39 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +9 -0
- package/dist/daemon.js +150 -9
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +8 -1
- package/dist/delivery-outbox.js +6 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/doctor.js +7 -0
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-context.d.ts +7 -0
- package/dist/fleet-manager.d.ts +158 -9
- package/dist/fleet-manager.js +827 -118
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +4 -3
- package/dist/forged-envelope-scan.js +4 -3
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +4 -1
- package/dist/install-lock.d.ts +18 -1
- package/dist/install-lock.js +30 -3
- package/dist/install-lock.js.map +1 -1
- package/dist/instance-avatar.d.ts +5 -4
- package/dist/instance-avatar.js +12 -8
- package/dist/instance-avatar.js.map +1 -1
- package/dist/instructions.js +2 -2
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-compact-pane.d.ts +38 -0
- package/dist/kiro-compact-pane.js +57 -0
- package/dist/kiro-compact-pane.js.map +1 -0
- package/dist/launchd-handoff.d.ts +43 -0
- package/dist/launchd-handoff.js +56 -0
- package/dist/launchd-handoff.js.map +1 -0
- package/dist/locale.js +202 -30
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +10 -2
- package/dist/log-service.js.map +1 -1
- package/dist/login-shell.d.ts +21 -0
- package/dist/login-shell.js +98 -0
- package/dist/login-shell.js.map +1 -0
- package/dist/outbound-handlers.d.ts +27 -0
- package/dist/outbound-handlers.js +120 -36
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +12 -0
- package/dist/outbound-schemas.js +15 -4
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/provider-probe.d.ts +29 -0
- package/dist/provider-probe.js +198 -2
- package/dist/provider-probe.js.map +1 -1
- package/dist/public-web-gateway.d.ts +2 -0
- package/dist/public-web-gateway.js +11 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +1 -1
- package/dist/quickstart-api.js +8 -6
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +12 -0
- package/dist/quickstart.js +36 -6
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +86 -5
- package/dist/reply-buttons-controller.js +271 -7
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-buttons.d.ts +48 -3
- package/dist/reply-buttons.js +105 -10
- package/dist/reply-buttons.js.map +1 -1
- package/dist/reply-polls.d.ts +85 -0
- package/dist/reply-polls.js +154 -0
- package/dist/reply-polls.js.map +1 -0
- package/dist/restart-guard.d.ts +6 -3
- package/dist/restart-guard.js +6 -3
- package/dist/restart-guard.js.map +1 -1
- package/dist/restart-progress.d.ts +0 -2
- package/dist/restart-progress.js +0 -2
- package/dist/restart-progress.js.map +1 -1
- package/dist/sd-notify.d.ts +22 -1
- package/dist/sd-notify.js +63 -10
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-activation.d.ts +15 -7
- package/dist/service-activation.js +42 -26
- package/dist/service-activation.js.map +1 -1
- package/dist/service-installer.d.ts +24 -0
- package/dist/service-installer.js +49 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +11 -0
- package/dist/service-plan.js +23 -0
- package/dist/service-plan.js.map +1 -1
- package/dist/systemd-peer-bus.d.ts +95 -0
- package/dist/systemd-peer-bus.js +430 -0
- package/dist/systemd-peer-bus.js.map +1 -0
- package/dist/systemd-runtime.d.ts +27 -1
- package/dist/systemd-runtime.js +69 -7
- package/dist/systemd-runtime.js.map +1 -1
- package/dist/tool-permissions.js +3 -3
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +68 -2
- package/dist/topic-commands.js +141 -27
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-jsonl.d.ts +7 -2
- package/dist/transcript-jsonl.js +13 -7
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-sources.js +6 -1
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/ui/chat-commands.js +1 -0
- package/dist/ui/chat-render.js +55 -10
- package/dist/ui/chat-store.js +69 -5
- package/dist/ui/chat-strings.js +28 -16
- package/dist/ui/chat-thread.js +132 -14
- package/dist/ui/chat-tour.js +17 -14
- package/dist/ui/panel-chat.js +16 -10
- package/dist/ui/panel-fleet.js +15 -2
- package/dist/ui/panel-log.js +4 -4
- package/dist/ui/panel-needs.js +10 -7
- package/dist/ui/panel-settings.js +58 -7
- package/dist/ui/settings-dialogs.js +11 -6
- package/dist/ui/settings-model.js +3 -1
- package/dist/ui/settings-strings.js +24 -10
- package/dist/ui/settings-token.js +7 -0
- package/dist/ui/settings-wizard.js +5 -3
- package/dist/ui/shared/app-i18n.js +1 -1
- package/dist/ui/shared/app-stream.js +4 -1
- package/dist/ui/shared/app.css +52 -10
- package/dist/ui/shared/header-tools.js +34 -14
- package/dist/ui/shared/instance-switch.js +5 -2
- package/dist/ui/shared/panel-view.js +15 -4
- package/dist/ui/shared/signin.js +15 -9
- package/dist/ui/shared/ui-icons.js +1 -0
- package/dist/ui/shared/view-strings.js +10 -2
- package/dist/ui/signin.html +8 -3
- package/dist/update-check.d.ts +31 -0
- package/dist/update-check.js +47 -0
- package/dist/update-check.js.map +1 -1
- package/dist/update-launch.d.ts +48 -1
- package/dist/update-launch.js +159 -5
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/providers.d.ts +28 -8
- package/dist/usage/providers.js +96 -41
- package/dist/usage/providers.js.map +1 -1
- package/dist/view-api.js +26 -9
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +44 -2
- package/dist/web-api.js +265 -57
- package/dist/web-api.js.map +1 -1
- package/dist/web-chat-history.d.ts +26 -1
- package/dist/web-chat-history.js +47 -8
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +39 -3
- package/dist/web-commands.js +22 -5
- package/dist/web-commands.js.map +1 -1
- package/dist/web-login.d.ts +14 -0
- package/dist/web-login.js +4 -2
- package/dist/web-login.js.map +1 -1
- package/dist/web-prefs.d.ts +18 -0
- package/dist/web-prefs.js +36 -4
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-profile.d.ts +32 -0
- package/dist/web-profile.js +132 -0
- package/dist/web-profile.js.map +1 -0
- package/dist/web-session.d.ts +14 -0
- package/dist/web-session.js +10 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-upload.d.ts +119 -4
- package/dist/web-upload.js +252 -39
- package/dist/web-upload.js.map +1 -1
- package/launcher/install-admission.cjs +61 -6
- package/package.json +3 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { validateFleetConfig } from "./config-validator.js";
|
|
1
|
+
import { KNOWN_BACKENDS, validateFleetConfig } from "./config-validator.js";
|
|
2
2
|
import { resolve as pathResolve, isAbsolute } from "node:path";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { deliveryContentDigest, deliveryStatusSelector } from "./delivery-outbox.js";
|
|
6
6
|
import { GENERAL_PAUSE_ERROR, isGeneralInstance } from "./general-instance.js";
|
|
7
|
-
import { DEFAULT_MAX_CROSS_INSTANCE_MESSAGE_BYTES, DEFAULT_LIST_INSTANCES_OUTPUT_BUDGET, MAX_INSTANCE_LOG_LINES } from "./config.js";
|
|
7
|
+
import { DEFAULT_MAX_CROSS_INSTANCE_MESSAGE_BYTES, DEFAULT_LIST_INSTANCES_OUTPUT_BUDGET, MAX_INSTANCE_LOG_LINES, getEffectiveInstanceDefaults } from "./config.js";
|
|
8
8
|
import { t } from "./locale.js";
|
|
9
9
|
import { presentationState, interactionSummary } from "./interaction-observation.js";
|
|
10
10
|
import { truncatePreview } from "./channel/markdown-chunk.js";
|
|
@@ -14,7 +14,7 @@ import { assignDisplayLabels, displayInstanceName, readStatuslineModel } from ".
|
|
|
14
14
|
import { CHAT_PROFILE_LOGIN_BACKENDS, credentialProfileLogin, credentialSwitchCarriesConversation, credentialSwitchStartsFresh, instanceCredentialProfile } from "./backend/credential-profile.js";
|
|
15
15
|
import { kiroEngineCandidates, kiroEngineStatus } from "./kiro-engine-status.js";
|
|
16
16
|
import { formatCrossInstanceInboundMessage, MAX_ASSEMBLED_CROSS_INSTANCE_MESSAGE_BYTES, } from "./cross-instance-envelope.js";
|
|
17
|
-
import { BroadcastArgs, CreateInstanceArgs, CreateTeamArgs, DelegateTaskArgs, DeleteInstanceArgs, DeleteTeamArgs, DeployTemplateArgs, DescribeInstanceArgs, ListDeploymentsArgs, ListInstancesArgs, ListTeamsArgs, ReplaceInstanceArgs, ReportResultArgs, DeliveryStatusArgs, RequestInformationArgs, RestartInstanceArgs, SendToInstanceArgs, PauseInstanceArgs, WakeInstanceArgs, StopInstanceArgs, GetInstanceLogsArgs, GetEffortArgs, KiroEngineStatusArgs, GetUsageArgs, ListModelsArgs, GetFleetConfigArgs, UpdateInstanceConfigArgs, UpdateFleetDefaultsArgs, StartInstanceArgs, TeardownDeploymentArgs, UpdateTeamArgs, validateArgs, } from "./outbound-schemas.js";
|
|
17
|
+
import { BroadcastArgs, CreateInstanceArgs, CreateTeamArgs, DelegateTaskArgs, DeleteInstanceArgs, DeleteTeamArgs, DeployTemplateArgs, DescribeInstanceArgs, ListDeploymentsArgs, ListInstancesArgs, ListTeamsArgs, ReplaceInstanceArgs, ReportResultArgs, DeliveryStatusArgs, RequestInformationArgs, RestartInstanceArgs, SendToInstanceArgs, PauseInstanceArgs, WakeInstanceArgs, StopInstanceArgs, GetInstanceLogsArgs, GetEffortArgs, ClosePollArgs, KiroEngineStatusArgs, GetUsageArgs, ListModelsArgs, GetFleetConfigArgs, UpdateInstanceConfigArgs, UpdateFleetDefaultsArgs, StartInstanceArgs, TeardownDeploymentArgs, UpdateTeamArgs, validateArgs, } from "./outbound-schemas.js";
|
|
18
18
|
const HOME_DIR = homedir();
|
|
19
19
|
function formatByteSize(bytes) {
|
|
20
20
|
if (bytes < 1024)
|
|
@@ -787,6 +787,25 @@ const kiroEngineStatusHandler = (ctx, rawArgs, respond) => {
|
|
|
787
787
|
}
|
|
788
788
|
respond(status);
|
|
789
789
|
};
|
|
790
|
+
/** #1823: close one of the caller's own polls before its deadline; its results then go out as at the deadline. */
|
|
791
|
+
const closePoll = async (ctx, rawArgs, respond, meta) => {
|
|
792
|
+
const v = validateArgs(ClosePollArgs, rawArgs, "close_poll");
|
|
793
|
+
if (!v.ok) {
|
|
794
|
+
respond(null, v.error);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
const fm = ctx;
|
|
798
|
+
const instance = meta?.instanceName; // whose polls: the instance's (as the reply recorded)
|
|
799
|
+
if (!instance || !fm.closePollEarly) {
|
|
800
|
+
respond(null, "close_poll is not available here");
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
const r = await fm.closePollEarly(instance, v.data.poll_id);
|
|
804
|
+
if (r.ok)
|
|
805
|
+
respond({ closed: true, poll_id: v.data.poll_id, voted: r.voted });
|
|
806
|
+
else
|
|
807
|
+
respond(null, `close_poll: ${r.error}`);
|
|
808
|
+
};
|
|
790
809
|
const getEffort = (ctx, rawArgs, respond, meta) => {
|
|
791
810
|
const v = validateArgs(GetEffortArgs, rawArgs, "get_effort");
|
|
792
811
|
if (!v.ok) {
|
|
@@ -945,31 +964,86 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
945
964
|
respond(null, v.error);
|
|
946
965
|
return;
|
|
947
966
|
}
|
|
948
|
-
|
|
967
|
+
applyInstanceConfigPatch(ctx, v.data.name, v.data.config, respond);
|
|
968
|
+
};
|
|
969
|
+
/**
|
|
970
|
+
* update_instance_config's write: one validated config write, rolled back whole on a refusal, then one relaunch when
|
|
971
|
+
* the backend (fresh, #1217), a credential profile or backend_options changed. Answers through `respond` like the tool.
|
|
972
|
+
*/
|
|
973
|
+
export function applyInstanceConfigPatch(ctx, name, patch, respond) {
|
|
974
|
+
const inst = ctx.fleetConfig?.instances[name];
|
|
949
975
|
if (!inst) {
|
|
950
976
|
const isClassic = (ctx.classicChannels?.getAll() ?? [])
|
|
951
|
-
.some(channel => channel.instanceName ===
|
|
977
|
+
.some(channel => channel.instanceName === name);
|
|
952
978
|
respond(null, isClassic
|
|
953
979
|
? "This is a ClassicBot instance (managed in classicBot.yaml). Use set_display_name or set_description to configure it."
|
|
954
|
-
: `Instance '${
|
|
980
|
+
: `Instance '${name}' not found in fleet config`);
|
|
955
981
|
return;
|
|
956
982
|
}
|
|
957
|
-
const patch = v.data.config;
|
|
958
983
|
// Read before anything is mutated: the switch is what decides whether the
|
|
959
984
|
// next launch may resume, and by then `inst` already holds the new value.
|
|
960
|
-
|
|
985
|
+
// The backend an instance runs: its own, else the fleet default (#1815 review: a Settings-created entry may omit it).
|
|
986
|
+
const effectiveBackend = () => inst.backend ?? ctx.fleetConfig?.defaults?.backend ?? "claude-code";
|
|
987
|
+
const backendBefore = effectiveBackend();
|
|
988
|
+
// #1808: a model and an effort name the backend they were chosen for. On a switch the new backend gets the ones
|
|
989
|
+
// given — if it takes them, refused here before anything is written — or none of the instance's own (the inherited
|
|
990
|
+
// value, else the CLI's default). Never the old backend's: codex launched with `--model opus` fails every turn.
|
|
991
|
+
if (patch.backend !== undefined && patch.backend !== backendBefore) {
|
|
992
|
+
const backendNew = patch.backend;
|
|
993
|
+
// Only a backend AgEnD knows gets these checks; any other name is refused by validation below, as before (and a
|
|
994
|
+
// "__proto__" or "toString" never reaches a lookup keyed by backend name).
|
|
995
|
+
const known = KNOWN_BACKENDS.includes(backendNew);
|
|
996
|
+
// The provider the new backend will run on (#1815 review): this patch's backend_options over the instance's, else
|
|
997
|
+
// the fleet defaults' — a custom provider has its own catalog, which the account's list says nothing about.
|
|
998
|
+
const options = mergeBackendOptions(inst.backend_options, patch.backend_options ?? {})[backendNew]
|
|
999
|
+
?? ctx.fleetConfig?.defaults?.backend_options?.[backendNew];
|
|
1000
|
+
const rawProvider = options?.provider;
|
|
1001
|
+
const provider = typeof rawProvider === "string" && rawProvider.trim() ? rawProvider.trim() : null;
|
|
1002
|
+
if (known && typeof patch.model === "string") {
|
|
1003
|
+
const verdict = ctx.backendModelVerdict?.(name, backendNew, patch.model, { provider });
|
|
1004
|
+
if (verdict && !verdict.ok) {
|
|
1005
|
+
respond(null, `Rejected: ${backendNew} does not take the model "${patch.model}". ${verdict.choices.length
|
|
1006
|
+
? `Choose one of: ${verdict.choices.join(", ")}` : `No ${backendNew} model list is known yet`} — or leave model out for its default.`);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
if (known && typeof patch.effort === "string") {
|
|
1011
|
+
// The levels of the model that will run there (codex's differ per model): the one given, else the inherited one.
|
|
1012
|
+
const inheritedModel = getEffectiveInstanceDefaults(ctx.fleetConfig?.defaults).model;
|
|
1013
|
+
const runs = typeof patch.model === "string" ? patch.model : typeof inheritedModel === "string" ? inheritedModel : null;
|
|
1014
|
+
const levels = ctx.backendEffortLevels?.(name, backendNew, runs);
|
|
1015
|
+
if (levels && !levels.includes(patch.effort)) {
|
|
1016
|
+
respond(null, levels.length
|
|
1017
|
+
? `Rejected: ${backendNew} takes no effort "${patch.effort}" at launch on this host. Choose one of: ${levels.join(", ")} — or leave effort out for its default.`
|
|
1018
|
+
: `Rejected: ${backendNew} takes no effort at launch on this host — leave effort out.`);
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
patch = { ...patch, model: patch.model === undefined ? null : patch.model, effort: patch.effort === undefined ? null : patch.effort };
|
|
1023
|
+
}
|
|
961
1024
|
const profileBefore = instanceCredentialProfile(inst, ctx.fleetConfig?.defaults, backendBefore);
|
|
962
1025
|
// Snapshot enough to undo the whole patch if validation refuses it.
|
|
963
1026
|
const beforeEdit = validateFleetConfig(ctx.fleetConfig);
|
|
964
1027
|
const beforeFields = {};
|
|
965
|
-
for (const key of ["backend", "model", "auto_pause_after", "display_name", "description"]) {
|
|
1028
|
+
for (const key of ["backend", "model", "effort", "auto_pause_after", "display_name", "description"]) {
|
|
966
1029
|
if (patch[key] !== undefined)
|
|
967
1030
|
beforeFields[key] = inst[key];
|
|
968
1031
|
}
|
|
969
1032
|
if (patch.backend !== undefined)
|
|
970
1033
|
inst.backend = patch.backend;
|
|
971
|
-
|
|
972
|
-
|
|
1034
|
+
// null: the value this instance would have with no override of its own — what loading fleet.yaml gives it.
|
|
1035
|
+
const inherited = getEffectiveInstanceDefaults(ctx.fleetConfig?.defaults);
|
|
1036
|
+
for (const key of ["model", "effort"]) {
|
|
1037
|
+
const value = patch[key];
|
|
1038
|
+
if (value === undefined)
|
|
1039
|
+
continue;
|
|
1040
|
+
if (value !== null)
|
|
1041
|
+
inst[key] = value;
|
|
1042
|
+
else if (inherited[key] !== undefined)
|
|
1043
|
+
inst[key] = inherited[key];
|
|
1044
|
+
else
|
|
1045
|
+
delete inst[key];
|
|
1046
|
+
}
|
|
973
1047
|
if (patch.auto_pause_after !== undefined)
|
|
974
1048
|
inst.auto_pause_after = patch.auto_pause_after;
|
|
975
1049
|
if (patch.display_name !== undefined)
|
|
@@ -983,20 +1057,7 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
983
1057
|
let relaunchNeeded = false;
|
|
984
1058
|
if (patch.backend_options !== undefined) {
|
|
985
1059
|
const before = JSON.stringify(previousOptions ?? {});
|
|
986
|
-
const merged =
|
|
987
|
-
for (const [backendName, options] of Object.entries(patch.backend_options)) {
|
|
988
|
-
const namespace = { ...(merged[backendName] ?? {}), ...options };
|
|
989
|
-
// A merge cannot express removal, so null (or "") means "drop this key"
|
|
990
|
-
// — that is how an agent goes back to the fleet's default login.
|
|
991
|
-
for (const [key, value] of Object.entries(options)) {
|
|
992
|
-
if (value === null || value === "")
|
|
993
|
-
delete namespace[key];
|
|
994
|
-
}
|
|
995
|
-
if (Object.keys(namespace).length)
|
|
996
|
-
merged[backendName] = namespace;
|
|
997
|
-
else
|
|
998
|
-
delete merged[backendName];
|
|
999
|
-
}
|
|
1060
|
+
const merged = mergeBackendOptions(previousOptions, patch.backend_options);
|
|
1000
1061
|
inst.backend_options = merged;
|
|
1001
1062
|
relaunchNeeded = JSON.stringify(merged) !== before;
|
|
1002
1063
|
}
|
|
@@ -1024,7 +1085,7 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
1024
1085
|
respond(null, `Rejected: ${introduced.map(issue => `${issue.path}: ${issue.message}`).join("; ")}`);
|
|
1025
1086
|
return;
|
|
1026
1087
|
}
|
|
1027
|
-
const backendAfter =
|
|
1088
|
+
const backendAfter = effectiveBackend();
|
|
1028
1089
|
const profileAfter = instanceCredentialProfile(inst, ctx.fleetConfig?.defaults, backendAfter);
|
|
1029
1090
|
const profileSwitched = profileAfter !== profileBefore;
|
|
1030
1091
|
// #1217: a running CLI is the backend it was launched as. Saving a new
|
|
@@ -1047,7 +1108,9 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
1047
1108
|
// the escape hatch from a bad switch and must never be the thing that is
|
|
1048
1109
|
// blocked, and an unlogged shared store means the CLI was never set up at
|
|
1049
1110
|
// all — a state that predates this feature.
|
|
1050
|
-
|
|
1111
|
+
// #1806 review: a profile is a login of ONE backend — the same name under another backend is another store, so a
|
|
1112
|
+
// backend switch onto a named profile is checked too (claude-code "personal" says nothing about kiro-cli "personal").
|
|
1113
|
+
if ((profileSwitched || backendSwitched) && profileAfter) {
|
|
1051
1114
|
// The same root the launcher resolves the profile under, so the store this
|
|
1052
1115
|
// probes is the store the CLI will be pointed at.
|
|
1053
1116
|
const login = credentialProfileLogin(ctx.dataDir, backendAfter, profileAfter);
|
|
@@ -1068,18 +1131,18 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
1068
1131
|
return;
|
|
1069
1132
|
}
|
|
1070
1133
|
if (!relaunchNeeded) {
|
|
1071
|
-
respond({ success: true, name
|
|
1134
|
+
respond({ success: true, name, applied: patch });
|
|
1072
1135
|
return;
|
|
1073
1136
|
}
|
|
1074
1137
|
// Only a running instance is restarted. Switching the subscription of a
|
|
1075
1138
|
// paused or stopped agent must not start it — restartSingleInstance is
|
|
1076
1139
|
// stop-then-start and would — so the new credentials are read whenever it
|
|
1077
1140
|
// next comes up on its own.
|
|
1078
|
-
const status = targetState(ctx,
|
|
1141
|
+
const status = targetState(ctx, name);
|
|
1079
1142
|
if (status !== "running") {
|
|
1080
1143
|
respond({
|
|
1081
1144
|
success: true,
|
|
1082
|
-
name
|
|
1145
|
+
name,
|
|
1083
1146
|
applied: patch,
|
|
1084
1147
|
restarted: false,
|
|
1085
1148
|
note: `Instance is ${status}; the new ${backendSwitched ? "backend" : "backend_options"} apply when it next starts.`,
|
|
@@ -1106,19 +1169,19 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
1106
1169
|
? { backend: backendAfter, from: profileBefore, to: profileAfter, result: null }
|
|
1107
1170
|
: null;
|
|
1108
1171
|
const handover = switchLosesConversation
|
|
1109
|
-
? (ctx.lifecycle.daemons.get(
|
|
1172
|
+
? (ctx.lifecycle.daemons.get(name)?.collectHandoverContext() ?? "")
|
|
1110
1173
|
: "";
|
|
1111
1174
|
// Saving without restarting would report a subscription switch that has not
|
|
1112
1175
|
// happened — the running CLI keeps the credentials it was launched with.
|
|
1113
1176
|
// A switch that cannot take the conversation along starts fresh: the new store
|
|
1114
1177
|
// has no conversation for this directory, so resuming can only spend the
|
|
1115
1178
|
// resume startup budget waiting for something that is not there.
|
|
1116
|
-
ctx.restartSingleInstance(
|
|
1179
|
+
ctx.restartSingleInstance(name, carry ? { carry } : switchLosesConversation || backendSwitched ? { freshStart: true } : undefined).then(async () => {
|
|
1117
1180
|
const carried = carry?.result?.carried === true;
|
|
1118
|
-
const handoverChars = carried ? 0 : await deliverProfileHandover(ctx,
|
|
1181
|
+
const handoverChars = carried ? 0 : await deliverProfileHandover(ctx, name, profileBefore, profileAfter, handover);
|
|
1119
1182
|
respond({
|
|
1120
1183
|
success: true,
|
|
1121
|
-
name
|
|
1184
|
+
name,
|
|
1122
1185
|
applied: patch,
|
|
1123
1186
|
restarted: true,
|
|
1124
1187
|
...(backendSwitched ? { backend_switched: true, conversation_carried_over: false } : {}),
|
|
@@ -1140,12 +1203,32 @@ const updateInstanceConfig = (ctx, rawArgs, respond) => {
|
|
|
1140
1203
|
});
|
|
1141
1204
|
}, (err) => respond({
|
|
1142
1205
|
success: true,
|
|
1143
|
-
name
|
|
1206
|
+
name,
|
|
1144
1207
|
applied: patch,
|
|
1145
1208
|
restarted: false,
|
|
1146
1209
|
warning: `Config saved, but the restart failed: ${err.message}. The new backend_options take effect on the next start.`,
|
|
1147
1210
|
}));
|
|
1148
|
-
}
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* backend_options merged per backend namespace, so setting a kiro option cannot silently drop a codex one. A merge
|
|
1214
|
+
* cannot express removal, so null (or "") means "drop this key" — that is how an agent goes back to the fleet's
|
|
1215
|
+
* default login.
|
|
1216
|
+
*/
|
|
1217
|
+
function mergeBackendOptions(previous, patch) {
|
|
1218
|
+
const merged = { ...(previous ?? {}) };
|
|
1219
|
+
for (const [backendName, options] of Object.entries(patch)) {
|
|
1220
|
+
const namespace = { ...(merged[backendName] ?? {}), ...options };
|
|
1221
|
+
for (const [key, value] of Object.entries(options)) {
|
|
1222
|
+
if (value === null || value === "")
|
|
1223
|
+
delete namespace[key];
|
|
1224
|
+
}
|
|
1225
|
+
if (Object.keys(namespace).length)
|
|
1226
|
+
merged[backendName] = namespace;
|
|
1227
|
+
else
|
|
1228
|
+
delete merged[backendName];
|
|
1229
|
+
}
|
|
1230
|
+
return merged;
|
|
1231
|
+
}
|
|
1149
1232
|
/** Long enough for the relaunched CLI to be listening; matches replace_instance. */
|
|
1150
1233
|
export const PROFILE_HANDOVER_SETTLE_MS = 3_000;
|
|
1151
1234
|
/**
|
|
@@ -1886,6 +1969,7 @@ export const outboundHandlers = new Map([
|
|
|
1886
1969
|
["stop_instance", stopInstance],
|
|
1887
1970
|
["get_fleet_status", getFleetStatus],
|
|
1888
1971
|
["get_effort", getEffort],
|
|
1972
|
+
["close_poll", closePoll],
|
|
1889
1973
|
["kiro_engine_status", kiroEngineStatusHandler],
|
|
1890
1974
|
["get_usage", getUsage],
|
|
1891
1975
|
["list_models", listModels],
|