@moxt-ai/mobius 0.0.16 → 0.0.18
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/acp/session-config/grok-build-session-config.d.ts +10 -0
- package/dist/acp/session-config/grok-build-session-config.d.ts.map +1 -0
- package/dist/acp/session-config/grok-build-session-config.js +202 -0
- package/dist/acp/session-config/grok-build-session-config.js.map +1 -0
- package/dist/acp/session-config/session-config-protocol.d.ts +32 -0
- package/dist/acp/session-config/session-config-protocol.d.ts.map +1 -0
- package/dist/acp/session-config/session-config-protocol.js +237 -0
- package/dist/acp/session-config/session-config-protocol.js.map +1 -0
- package/dist/acp/session-config/session-config-registry.d.ts +3 -0
- package/dist/acp/session-config/session-config-registry.d.ts.map +1 -0
- package/dist/acp/session-config/session-config-registry.js +8 -0
- package/dist/acp/session-config/session-config-registry.js.map +1 -0
- package/dist/acp/session-manager.d.ts.map +1 -1
- package/dist/acp/session-manager.js +29 -155
- package/dist/acp/session-manager.js.map +1 -1
- package/dist/agent-catalog/agent-discovery.d.ts +19 -9
- package/dist/agent-catalog/agent-discovery.d.ts.map +1 -1
- package/dist/agent-catalog/agent-discovery.js +32 -16
- package/dist/agent-catalog/agent-discovery.js.map +1 -1
- package/dist/agent-catalog/agent-specification.d.ts +0 -1
- package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
- package/dist/agent-catalog/agent-specification.js +0 -2
- package/dist/agent-catalog/agent-specification.js.map +1 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.d.ts +0 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.d.ts.map +1 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.js +0 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.js.map +1 -1
- package/dist/agent-catalog/discover-agent.d.ts.map +1 -1
- package/dist/agent-catalog/discover-agent.js +30 -21
- package/dist/agent-catalog/discover-agent.js.map +1 -1
- package/dist/agent-catalog/discover-local-agents.d.ts +0 -1
- package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
- package/dist/agent-catalog/discover-local-agents.js +1 -1
- package/dist/agent-catalog/discover-local-agents.js.map +1 -1
- package/dist/agent-catalog/local-agent.d.ts +12 -1
- package/dist/agent-catalog/local-agent.d.ts.map +1 -1
- package/dist/agent-catalog/local-agent.js +16 -0
- package/dist/agent-catalog/local-agent.js.map +1 -1
- package/dist/agent-catalog/publish-agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog/publish-agent-catalog.js +3 -4
- package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
- package/dist/agent-installation/agent-installation-manager.d.ts.map +1 -1
- package/dist/agent-installation/agent-installation-manager.js +6 -7
- package/dist/agent-installation/agent-installation-manager.js.map +1 -1
- package/dist/agent-installation/fixed-installation-executor.d.ts +2 -3
- package/dist/agent-installation/fixed-installation-executor.d.ts.map +1 -1
- package/dist/agent-installation/fixed-installation-executor.js +47 -67
- package/dist/agent-installation/fixed-installation-executor.js.map +1 -1
- package/dist/agent-installation/managed-agent-archive.d.ts +2 -5
- package/dist/agent-installation/managed-agent-archive.d.ts.map +1 -1
- package/dist/agent-installation/managed-agent-archive.js +1 -1
- package/dist/agent-installation/managed-agent-archive.js.map +1 -1
- package/dist/agent-installation/verified-download.d.ts +0 -4
- package/dist/agent-installation/verified-download.d.ts.map +1 -1
- package/dist/agent-installation/verified-download.js +1 -1
- package/dist/agent-installation/verified-download.js.map +1 -1
- package/dist/cli.js +1128 -1782
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1129 -1783
- package/dist/index.js.map +4 -4
- package/dist/pairing/pair-local-machine.d.ts.map +1 -1
- package/dist/pairing/pair-local-machine.js +4 -5
- package/dist/pairing/pair-local-machine.js.map +1 -1
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +162 -57
- package/dist/run-daemon.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent-installation/automatic-adapter-provisioner.d.ts +0 -19
- package/dist/agent-installation/automatic-adapter-provisioner.d.ts.map +0 -1
- package/dist/agent-installation/automatic-adapter-provisioner.js +0 -125
- package/dist/agent-installation/automatic-adapter-provisioner.js.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipe.d.ts +0 -20
- package/dist/agent-installation/fixed-agent-install-recipe.d.ts.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipe.js +0 -18
- package/dist/agent-installation/fixed-agent-install-recipe.js.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts +0 -26
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipes.js +0 -301
- package/dist/agent-installation/fixed-agent-install-recipes.js.map +0 -1
- package/dist/agent-installation/grok-build-install-recipe.d.ts +0 -12
- package/dist/agent-installation/grok-build-install-recipe.d.ts.map +0 -1
- package/dist/agent-installation/grok-build-install-recipe.js +0 -102
- package/dist/agent-installation/grok-build-install-recipe.js.map +0 -1
- package/dist/agent-installation/workbuddy-install-recipe.d.ts +0 -12
- package/dist/agent-installation/workbuddy-install-recipe.d.ts.map +0 -1
- package/dist/agent-installation/workbuddy-install-recipe.js +0 -51
- package/dist/agent-installation/workbuddy-install-recipe.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2007,8 +2007,8 @@ function emoji() {
|
|
|
2007
2007
|
}
|
|
2008
2008
|
var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
2009
2009
|
var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
|
|
2010
|
-
var mac = (
|
|
2011
|
-
const escapedDelim = escapeRegex(
|
|
2010
|
+
var mac = (delimiter2) => {
|
|
2011
|
+
const escapedDelim = escapeRegex(delimiter2 ?? ":");
|
|
2012
2012
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
2013
2013
|
};
|
|
2014
2014
|
var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -18981,13 +18981,13 @@ var SESSION_ELICITATION_RESPOND_KIND = "session.elicitation.respond";
|
|
|
18981
18981
|
var SESSION_ELICITATION_RESOLVED_KIND = "session.elicitation.resolved";
|
|
18982
18982
|
var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
|
|
18983
18983
|
var AGENT_CONTENT_KIND = "agent.content";
|
|
18984
|
-
var AGENT_INSTALL_REQUEST_KIND = "agent.install.request";
|
|
18985
|
-
var AGENT_INSTALL_CANCEL_KIND = "agent.install.cancel";
|
|
18986
|
-
var AGENT_INSTALL_STARTED_KIND = "agent.install.started";
|
|
18987
|
-
var AGENT_INSTALL_PROGRESS_KIND = "agent.install.progress";
|
|
18988
|
-
var AGENT_INSTALL_COMPLETED_KIND = "agent.install.completed";
|
|
18989
|
-
var AGENT_INSTALL_FAILED_KIND = "agent.install.failed";
|
|
18990
|
-
var AGENT_INSTALL_CANCELLED_KIND = "agent.install.cancelled";
|
|
18984
|
+
var AGENT_INSTALL_REQUEST_KIND = "agent.integration.install.request";
|
|
18985
|
+
var AGENT_INSTALL_CANCEL_KIND = "agent.integration.install.cancel";
|
|
18986
|
+
var AGENT_INSTALL_STARTED_KIND = "agent.integration.install.started";
|
|
18987
|
+
var AGENT_INSTALL_PROGRESS_KIND = "agent.integration.install.progress";
|
|
18988
|
+
var AGENT_INSTALL_COMPLETED_KIND = "agent.integration.install.completed";
|
|
18989
|
+
var AGENT_INSTALL_FAILED_KIND = "agent.integration.install.failed";
|
|
18990
|
+
var AGENT_INSTALL_CANCELLED_KIND = "agent.integration.install.cancelled";
|
|
18991
18991
|
var IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
18992
18992
|
var DIRECTORY_IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
|
|
18993
18993
|
var IDENTIFIER = external_exports.string().min(1).max(128).regex(IDENTIFIER_PATTERN);
|
|
@@ -21025,6 +21025,22 @@ var InstallableAgentDefinition = class {
|
|
|
21025
21025
|
this.label = label;
|
|
21026
21026
|
}
|
|
21027
21027
|
};
|
|
21028
|
+
var MissingAgentDefinition = class extends InstallableAgentDefinition {
|
|
21029
|
+
status = "agent_not_installed";
|
|
21030
|
+
constructor(id, label) {
|
|
21031
|
+
super(id, label);
|
|
21032
|
+
}
|
|
21033
|
+
};
|
|
21034
|
+
var AgentIntegrationDefinition = class extends InstallableAgentDefinition {
|
|
21035
|
+
agentPath;
|
|
21036
|
+
agentVersion;
|
|
21037
|
+
status = "integration_not_installed";
|
|
21038
|
+
constructor(id, label, agentPath, agentVersion) {
|
|
21039
|
+
super(id, label);
|
|
21040
|
+
this.agentPath = agentPath;
|
|
21041
|
+
this.agentVersion = agentVersion;
|
|
21042
|
+
}
|
|
21043
|
+
};
|
|
21028
21044
|
var LocalAgentCatalogSnapshot = class {
|
|
21029
21045
|
agents;
|
|
21030
21046
|
installableAgents;
|
|
@@ -21139,7 +21155,7 @@ function loadDaemonConfig() {
|
|
|
21139
21155
|
// src/acp/session-manager.ts
|
|
21140
21156
|
import { spawn as spawn2 } from "node:child_process";
|
|
21141
21157
|
import {
|
|
21142
|
-
methods as
|
|
21158
|
+
methods as methods3,
|
|
21143
21159
|
ndJsonStream,
|
|
21144
21160
|
PROTOCOL_VERSION,
|
|
21145
21161
|
RequestError
|
|
@@ -21653,6 +21669,491 @@ var nativeSessionPageSchema = external_exports.object({
|
|
|
21653
21669
|
nextCursor: external_exports.string().min(1).max(4096).nullish()
|
|
21654
21670
|
}).readonly();
|
|
21655
21671
|
|
|
21672
|
+
// src/acp/session-config/session-config-protocol.ts
|
|
21673
|
+
import { methods as methods2 } from "@agentclientprotocol/sdk";
|
|
21674
|
+
var AGENT_DEFAULT_REASONING_EFFORT = "agent_default";
|
|
21675
|
+
var MAXIMUM_CONFIG_OPTIONS = 100;
|
|
21676
|
+
var SessionConfigProtocolError = class extends Error {
|
|
21677
|
+
code = "invalid_session_configuration_response";
|
|
21678
|
+
constructor(message, options = {}) {
|
|
21679
|
+
super(message, options);
|
|
21680
|
+
this.name = "SessionConfigProtocolError";
|
|
21681
|
+
}
|
|
21682
|
+
};
|
|
21683
|
+
function isRecord3(value) {
|
|
21684
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21685
|
+
}
|
|
21686
|
+
function readString2(value, fallback = "") {
|
|
21687
|
+
return typeof value === "string" ? value : fallback;
|
|
21688
|
+
}
|
|
21689
|
+
function truncate2(value, maximum) {
|
|
21690
|
+
return value.length <= maximum ? value : value.slice(0, maximum);
|
|
21691
|
+
}
|
|
21692
|
+
function readBoolean(value, fallback = false) {
|
|
21693
|
+
return typeof value === "boolean" ? value : fallback;
|
|
21694
|
+
}
|
|
21695
|
+
function normalizeConfigValue(option, groupId = "", groupName = "") {
|
|
21696
|
+
return {
|
|
21697
|
+
description: truncate2(readString2(option["description"]), 500),
|
|
21698
|
+
groupId: truncate2(groupId, 128),
|
|
21699
|
+
groupName: truncate2(groupName, 255),
|
|
21700
|
+
name: truncate2(
|
|
21701
|
+
readString2(option["name"], readString2(option["value"])),
|
|
21702
|
+
255
|
|
21703
|
+
),
|
|
21704
|
+
value: truncate2(readString2(option["value"]), 500)
|
|
21705
|
+
};
|
|
21706
|
+
}
|
|
21707
|
+
function normalizeConfigValues(value) {
|
|
21708
|
+
if (!Array.isArray(value)) {
|
|
21709
|
+
return [];
|
|
21710
|
+
}
|
|
21711
|
+
const normalized = [];
|
|
21712
|
+
for (const entry of value) {
|
|
21713
|
+
if (!isRecord3(entry)) {
|
|
21714
|
+
continue;
|
|
21715
|
+
}
|
|
21716
|
+
const groupedOptions = entry["options"];
|
|
21717
|
+
if (Array.isArray(groupedOptions)) {
|
|
21718
|
+
const groupId = readString2(entry["group"]);
|
|
21719
|
+
const groupName = readString2(entry["name"]);
|
|
21720
|
+
for (const groupedOption of groupedOptions) {
|
|
21721
|
+
if (isRecord3(groupedOption)) {
|
|
21722
|
+
normalized.push(
|
|
21723
|
+
normalizeConfigValue(groupedOption, groupId, groupName)
|
|
21724
|
+
);
|
|
21725
|
+
}
|
|
21726
|
+
}
|
|
21727
|
+
continue;
|
|
21728
|
+
}
|
|
21729
|
+
normalized.push(normalizeConfigValue(entry));
|
|
21730
|
+
}
|
|
21731
|
+
return normalized.filter((entry) => entry.value.length > 0).slice(0, 500);
|
|
21732
|
+
}
|
|
21733
|
+
function normalizeConfigOptions(value, modes) {
|
|
21734
|
+
const normalized = [];
|
|
21735
|
+
if (Array.isArray(value)) {
|
|
21736
|
+
for (const option of value) {
|
|
21737
|
+
if (!isRecord3(option)) {
|
|
21738
|
+
continue;
|
|
21739
|
+
}
|
|
21740
|
+
const id = truncate2(readString2(option["id"]), 128);
|
|
21741
|
+
const name = truncate2(readString2(option["name"], id), 255);
|
|
21742
|
+
if (id.length === 0 || name.length === 0) {
|
|
21743
|
+
continue;
|
|
21744
|
+
}
|
|
21745
|
+
if (option["type"] === "boolean") {
|
|
21746
|
+
normalized.push({
|
|
21747
|
+
booleanValue: readBoolean(option["currentValue"]),
|
|
21748
|
+
category: truncate2(readString2(option["category"]), 128),
|
|
21749
|
+
currentValue: "",
|
|
21750
|
+
description: truncate2(readString2(option["description"]), 500),
|
|
21751
|
+
id,
|
|
21752
|
+
name,
|
|
21753
|
+
type: "boolean",
|
|
21754
|
+
values: []
|
|
21755
|
+
});
|
|
21756
|
+
continue;
|
|
21757
|
+
}
|
|
21758
|
+
if (option["type"] === "select") {
|
|
21759
|
+
const values = normalizeConfigValues(option["options"]);
|
|
21760
|
+
const currentValue = truncate2(readString2(option["currentValue"]), 500);
|
|
21761
|
+
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue)) {
|
|
21762
|
+
normalized.push({
|
|
21763
|
+
booleanValue: false,
|
|
21764
|
+
category: truncate2(readString2(option["category"]), 128),
|
|
21765
|
+
currentValue,
|
|
21766
|
+
description: truncate2(readString2(option["description"]), 500),
|
|
21767
|
+
id,
|
|
21768
|
+
name,
|
|
21769
|
+
type: "select",
|
|
21770
|
+
values
|
|
21771
|
+
});
|
|
21772
|
+
}
|
|
21773
|
+
}
|
|
21774
|
+
}
|
|
21775
|
+
}
|
|
21776
|
+
if (isRecord3(modes)) {
|
|
21777
|
+
const values = [];
|
|
21778
|
+
const availableModes = modes["availableModes"];
|
|
21779
|
+
if (Array.isArray(availableModes)) {
|
|
21780
|
+
for (const mode of availableModes) {
|
|
21781
|
+
if (!isRecord3(mode)) {
|
|
21782
|
+
continue;
|
|
21783
|
+
}
|
|
21784
|
+
const id = truncate2(readString2(mode["id"]), 500);
|
|
21785
|
+
if (id.length === 0) {
|
|
21786
|
+
continue;
|
|
21787
|
+
}
|
|
21788
|
+
values.push({
|
|
21789
|
+
description: truncate2(readString2(mode["description"]), 500),
|
|
21790
|
+
groupId: "",
|
|
21791
|
+
groupName: "",
|
|
21792
|
+
name: truncate2(readString2(mode["name"], id), 255),
|
|
21793
|
+
value: id
|
|
21794
|
+
});
|
|
21795
|
+
}
|
|
21796
|
+
}
|
|
21797
|
+
const currentValue = truncate2(readString2(modes["currentModeId"]), 500);
|
|
21798
|
+
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue) && !normalized.some((entry) => entry.category === "mode")) {
|
|
21799
|
+
normalized.unshift({
|
|
21800
|
+
booleanValue: false,
|
|
21801
|
+
category: "mode",
|
|
21802
|
+
currentValue,
|
|
21803
|
+
description: "Agent session mode",
|
|
21804
|
+
id: "mode",
|
|
21805
|
+
name: "Mode",
|
|
21806
|
+
type: "select",
|
|
21807
|
+
values
|
|
21808
|
+
});
|
|
21809
|
+
}
|
|
21810
|
+
}
|
|
21811
|
+
return normalized.slice(0, 100);
|
|
21812
|
+
}
|
|
21813
|
+
function ensureReasoningEffortOption(current) {
|
|
21814
|
+
if (current.some((option) => option.category === "thought_level")) {
|
|
21815
|
+
return current;
|
|
21816
|
+
}
|
|
21817
|
+
const unavailable = {
|
|
21818
|
+
booleanValue: false,
|
|
21819
|
+
category: "thought_level",
|
|
21820
|
+
currentValue: AGENT_DEFAULT_REASONING_EFFORT,
|
|
21821
|
+
description: "This Agent does not expose adjustable reasoning effort for the selected model.",
|
|
21822
|
+
id: "reasoning_effort",
|
|
21823
|
+
name: "Reasoning effort",
|
|
21824
|
+
type: "select",
|
|
21825
|
+
values: [
|
|
21826
|
+
{
|
|
21827
|
+
description: "Selected by the Agent",
|
|
21828
|
+
groupId: "",
|
|
21829
|
+
groupName: "",
|
|
21830
|
+
name: "Agent default",
|
|
21831
|
+
value: AGENT_DEFAULT_REASONING_EFFORT
|
|
21832
|
+
}
|
|
21833
|
+
]
|
|
21834
|
+
};
|
|
21835
|
+
const modelIndex = current.findIndex((option) => option.category === "model");
|
|
21836
|
+
if (current.length < MAXIMUM_CONFIG_OPTIONS) {
|
|
21837
|
+
if (modelIndex < 0) {
|
|
21838
|
+
return [...current, unavailable];
|
|
21839
|
+
}
|
|
21840
|
+
return [
|
|
21841
|
+
...current.slice(0, modelIndex + 1),
|
|
21842
|
+
unavailable,
|
|
21843
|
+
...current.slice(modelIndex + 1)
|
|
21844
|
+
];
|
|
21845
|
+
}
|
|
21846
|
+
if (modelIndex < 0) {
|
|
21847
|
+
return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 1), unavailable];
|
|
21848
|
+
}
|
|
21849
|
+
if (modelIndex < MAXIMUM_CONFIG_OPTIONS - 1) {
|
|
21850
|
+
return [
|
|
21851
|
+
...current.slice(0, modelIndex + 1),
|
|
21852
|
+
unavailable,
|
|
21853
|
+
...current.slice(modelIndex + 1, MAXIMUM_CONFIG_OPTIONS - 1)
|
|
21854
|
+
];
|
|
21855
|
+
}
|
|
21856
|
+
const model = current[modelIndex];
|
|
21857
|
+
if (model === void 0) {
|
|
21858
|
+
return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 1), unavailable];
|
|
21859
|
+
}
|
|
21860
|
+
return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 2), model, unavailable];
|
|
21861
|
+
}
|
|
21862
|
+
function normalizeStandardLifecycle(response) {
|
|
21863
|
+
const lifecycle = isRecord3(response) ? response : {};
|
|
21864
|
+
return ensureReasoningEffortOption(
|
|
21865
|
+
normalizeConfigOptions(lifecycle["configOptions"], lifecycle["modes"])
|
|
21866
|
+
);
|
|
21867
|
+
}
|
|
21868
|
+
function replaceStandardConfigOptions(current, value) {
|
|
21869
|
+
const next = normalizeConfigOptions(value, void 0);
|
|
21870
|
+
const withMode = next.some((option) => option.category === "mode") ? next : [
|
|
21871
|
+
...current.filter((option) => option.category === "mode"),
|
|
21872
|
+
...next
|
|
21873
|
+
].slice(0, 100);
|
|
21874
|
+
return ensureReasoningEffortOption(withMode);
|
|
21875
|
+
}
|
|
21876
|
+
function updateCurrentValue(current, configId, value) {
|
|
21877
|
+
return current.map(
|
|
21878
|
+
(option) => option.id === configId ? { ...option, currentValue: value } : option
|
|
21879
|
+
);
|
|
21880
|
+
}
|
|
21881
|
+
var StandardSessionConfigProtocol = class {
|
|
21882
|
+
configure = async (current, change, nativeSessionId, transport) => {
|
|
21883
|
+
const existing = current.find((option) => option.id === change.configId);
|
|
21884
|
+
if (existing === void 0) {
|
|
21885
|
+
return current;
|
|
21886
|
+
}
|
|
21887
|
+
if (existing.type === "select" && existing.category === "mode") {
|
|
21888
|
+
await transport.request(
|
|
21889
|
+
methods2.agent.session.setMode,
|
|
21890
|
+
{ modeId: change.value, sessionId: nativeSessionId },
|
|
21891
|
+
"ACP agent exited while setting the session mode",
|
|
21892
|
+
change.signal
|
|
21893
|
+
);
|
|
21894
|
+
return updateCurrentValue(current, existing.id, change.value);
|
|
21895
|
+
}
|
|
21896
|
+
const params = existing.type === "boolean" ? {
|
|
21897
|
+
configId: existing.id,
|
|
21898
|
+
sessionId: nativeSessionId,
|
|
21899
|
+
type: "boolean",
|
|
21900
|
+
value: change.booleanValue
|
|
21901
|
+
} : {
|
|
21902
|
+
configId: existing.id,
|
|
21903
|
+
sessionId: nativeSessionId,
|
|
21904
|
+
value: change.value
|
|
21905
|
+
};
|
|
21906
|
+
const response = await transport.request(
|
|
21907
|
+
methods2.agent.session.setConfigOption,
|
|
21908
|
+
params,
|
|
21909
|
+
"ACP agent exited while changing session configuration",
|
|
21910
|
+
change.signal
|
|
21911
|
+
);
|
|
21912
|
+
if (!isRecord3(response) || !Array.isArray(response["configOptions"])) {
|
|
21913
|
+
throw new SessionConfigProtocolError(
|
|
21914
|
+
"The Agent returned an invalid session configuration response"
|
|
21915
|
+
);
|
|
21916
|
+
}
|
|
21917
|
+
return replaceStandardConfigOptions(current, response["configOptions"]);
|
|
21918
|
+
};
|
|
21919
|
+
normalizeLifecycle = (response) => normalizeStandardLifecycle(response);
|
|
21920
|
+
normalizeUpdate = (current, value) => replaceStandardConfigOptions(current, value);
|
|
21921
|
+
};
|
|
21922
|
+
var standardSessionConfigProtocol = new StandardSessionConfigProtocol();
|
|
21923
|
+
|
|
21924
|
+
// src/acp/session-config/grok-build-session-config.ts
|
|
21925
|
+
var LEGACY_MODEL_CONFIG_ID = "grok_build_legacy_model";
|
|
21926
|
+
var LEGACY_REASONING_EFFORT_CONFIG_ID = "grok_build_legacy_reasoning_effort";
|
|
21927
|
+
function legacyOptions(response) {
|
|
21928
|
+
if (!isRecord3(response)) {
|
|
21929
|
+
return [];
|
|
21930
|
+
}
|
|
21931
|
+
const metadata = response["_meta"];
|
|
21932
|
+
if (!isRecord3(metadata)) {
|
|
21933
|
+
return [];
|
|
21934
|
+
}
|
|
21935
|
+
const sessionConfig = metadata["x.ai/sessionConfig"];
|
|
21936
|
+
if (!isRecord3(sessionConfig) || !Array.isArray(sessionConfig["options"])) {
|
|
21937
|
+
return [];
|
|
21938
|
+
}
|
|
21939
|
+
return sessionConfig["options"].slice(0, 500).filter(isRecord3);
|
|
21940
|
+
}
|
|
21941
|
+
function legacyValue(option) {
|
|
21942
|
+
const value = readString2(option["id"]);
|
|
21943
|
+
return {
|
|
21944
|
+
description: readString2(option["description"]).slice(0, 500),
|
|
21945
|
+
groupId: "",
|
|
21946
|
+
groupName: "",
|
|
21947
|
+
name: readString2(option["label"], value).slice(0, 255),
|
|
21948
|
+
value: value.slice(0, 500)
|
|
21949
|
+
};
|
|
21950
|
+
}
|
|
21951
|
+
function modelsRecord(response) {
|
|
21952
|
+
if (!isRecord3(response) || !isRecord3(response["models"])) {
|
|
21953
|
+
return {};
|
|
21954
|
+
}
|
|
21955
|
+
return response["models"];
|
|
21956
|
+
}
|
|
21957
|
+
function legacyModelOptions(response) {
|
|
21958
|
+
const options = legacyOptions(response);
|
|
21959
|
+
const models = modelsRecord(response);
|
|
21960
|
+
const values = [];
|
|
21961
|
+
for (const option of options) {
|
|
21962
|
+
if (option["category"] === "model") {
|
|
21963
|
+
const value = legacyValue(option);
|
|
21964
|
+
if (value.value.length > 0 && !values.some((existing) => existing.value === value.value)) {
|
|
21965
|
+
values.push(value);
|
|
21966
|
+
}
|
|
21967
|
+
}
|
|
21968
|
+
}
|
|
21969
|
+
if (values.length === 0 && Array.isArray(models["availableModels"])) {
|
|
21970
|
+
for (const model of models["availableModels"]) {
|
|
21971
|
+
if (!isRecord3(model)) {
|
|
21972
|
+
continue;
|
|
21973
|
+
}
|
|
21974
|
+
const value = readString2(model["modelId"]).slice(0, 500);
|
|
21975
|
+
if (value.length === 0) {
|
|
21976
|
+
continue;
|
|
21977
|
+
}
|
|
21978
|
+
if (!values.some((existing) => existing.value === value)) {
|
|
21979
|
+
values.push({
|
|
21980
|
+
description: "",
|
|
21981
|
+
groupId: "",
|
|
21982
|
+
groupName: "",
|
|
21983
|
+
name: readString2(model["name"], value).slice(0, 255),
|
|
21984
|
+
value
|
|
21985
|
+
});
|
|
21986
|
+
}
|
|
21987
|
+
}
|
|
21988
|
+
}
|
|
21989
|
+
const selected = options.find(
|
|
21990
|
+
(option) => option["category"] === "model" && option["selected"] === true
|
|
21991
|
+
);
|
|
21992
|
+
const currentValue = readString2(
|
|
21993
|
+
models["currentModelId"],
|
|
21994
|
+
selected === void 0 ? "" : readString2(selected["id"])
|
|
21995
|
+
).slice(0, 500);
|
|
21996
|
+
if (values.length === 0 || !values.some((value) => value.value === currentValue)) {
|
|
21997
|
+
return [];
|
|
21998
|
+
}
|
|
21999
|
+
const result = {
|
|
22000
|
+
booleanValue: false,
|
|
22001
|
+
category: "model",
|
|
22002
|
+
currentValue,
|
|
22003
|
+
description: "Model used by Grok Build",
|
|
22004
|
+
id: LEGACY_MODEL_CONFIG_ID,
|
|
22005
|
+
name: "Model",
|
|
22006
|
+
type: "select",
|
|
22007
|
+
values: values.slice(0, 500)
|
|
22008
|
+
};
|
|
22009
|
+
return [result];
|
|
22010
|
+
}
|
|
22011
|
+
function legacyReasoningEffortOptions(response) {
|
|
22012
|
+
const options = legacyOptions(response);
|
|
22013
|
+
const values = [];
|
|
22014
|
+
for (const option of options) {
|
|
22015
|
+
if (option["category"] !== "mode") {
|
|
22016
|
+
continue;
|
|
22017
|
+
}
|
|
22018
|
+
const value = legacyValue(option);
|
|
22019
|
+
if (value.value.length > 0 && !values.some((existing) => existing.value === value.value)) {
|
|
22020
|
+
values.push(value);
|
|
22021
|
+
}
|
|
22022
|
+
}
|
|
22023
|
+
if (values.length === 0) {
|
|
22024
|
+
return [];
|
|
22025
|
+
}
|
|
22026
|
+
const selected = options.find(
|
|
22027
|
+
(option) => option["category"] === "mode" && option["selected"] === true
|
|
22028
|
+
);
|
|
22029
|
+
if (selected === void 0) {
|
|
22030
|
+
values.unshift({
|
|
22031
|
+
description: "Use the selected model's default reasoning effort",
|
|
22032
|
+
groupId: "",
|
|
22033
|
+
groupName: "",
|
|
22034
|
+
name: "Agent default",
|
|
22035
|
+
value: AGENT_DEFAULT_REASONING_EFFORT
|
|
22036
|
+
});
|
|
22037
|
+
}
|
|
22038
|
+
const currentValue = selected === void 0 ? AGENT_DEFAULT_REASONING_EFFORT : readString2(selected["id"], AGENT_DEFAULT_REASONING_EFFORT);
|
|
22039
|
+
if (!values.some((value) => value.value === currentValue)) {
|
|
22040
|
+
return [];
|
|
22041
|
+
}
|
|
22042
|
+
const result = {
|
|
22043
|
+
booleanValue: false,
|
|
22044
|
+
category: "thought_level",
|
|
22045
|
+
currentValue,
|
|
22046
|
+
description: "Reasoning effort used by Grok Build",
|
|
22047
|
+
id: LEGACY_REASONING_EFFORT_CONFIG_ID,
|
|
22048
|
+
name: "Reasoning effort",
|
|
22049
|
+
type: "select",
|
|
22050
|
+
values: values.slice(0, 500)
|
|
22051
|
+
};
|
|
22052
|
+
return [result];
|
|
22053
|
+
}
|
|
22054
|
+
function normalizeGrokLifecycle(response) {
|
|
22055
|
+
const lifecycle = isRecord3(response) ? response : {};
|
|
22056
|
+
const standard = normalizeConfigOptions(
|
|
22057
|
+
lifecycle["configOptions"],
|
|
22058
|
+
lifecycle["modes"]
|
|
22059
|
+
);
|
|
22060
|
+
const normalized = [...standard];
|
|
22061
|
+
if (!normalized.some((option) => option.category === "model")) {
|
|
22062
|
+
normalized.push(...legacyModelOptions(response));
|
|
22063
|
+
}
|
|
22064
|
+
if (!normalized.some((option) => option.category === "thought_level")) {
|
|
22065
|
+
const efforts = legacyReasoningEffortOptions(response);
|
|
22066
|
+
if (efforts.length > 0) {
|
|
22067
|
+
const modelIndex = normalized.findIndex(
|
|
22068
|
+
(option) => option.category === "model"
|
|
22069
|
+
);
|
|
22070
|
+
normalized.splice(
|
|
22071
|
+
modelIndex < 0 ? normalized.length : modelIndex + 1,
|
|
22072
|
+
0,
|
|
22073
|
+
...efforts
|
|
22074
|
+
);
|
|
22075
|
+
}
|
|
22076
|
+
}
|
|
22077
|
+
return ensureReasoningEffortOption(normalized.slice(0, 100));
|
|
22078
|
+
}
|
|
22079
|
+
function updateCurrentValue2(current, category, value) {
|
|
22080
|
+
return current.map(
|
|
22081
|
+
(option) => option.category === category ? { ...option, currentValue: value } : option
|
|
22082
|
+
);
|
|
22083
|
+
}
|
|
22084
|
+
function validateGrokResponse(response, modelId) {
|
|
22085
|
+
if (!isRecord3(response) || !isRecord3(response["_meta"])) {
|
|
22086
|
+
throw new SessionConfigProtocolError(
|
|
22087
|
+
"Grok Build returned an invalid session configuration response"
|
|
22088
|
+
);
|
|
22089
|
+
}
|
|
22090
|
+
const model = response["_meta"]["model"];
|
|
22091
|
+
const appliedModel = isRecord3(model) ? model["Ok"] : model;
|
|
22092
|
+
if (appliedModel !== modelId) {
|
|
22093
|
+
throw new SessionConfigProtocolError(
|
|
22094
|
+
"Grok Build returned an invalid session configuration response"
|
|
22095
|
+
);
|
|
22096
|
+
}
|
|
22097
|
+
}
|
|
22098
|
+
var GrokBuildSessionConfigProtocol = class {
|
|
22099
|
+
configure = async (current, change, nativeSessionId, transport) => {
|
|
22100
|
+
const existing = current.find((option) => option.id === change.configId);
|
|
22101
|
+
if (existing === void 0 || existing.id !== LEGACY_MODEL_CONFIG_ID && existing.id !== LEGACY_REASONING_EFFORT_CONFIG_ID) {
|
|
22102
|
+
return await standardSessionConfigProtocol.configure(
|
|
22103
|
+
current,
|
|
22104
|
+
change,
|
|
22105
|
+
nativeSessionId,
|
|
22106
|
+
transport
|
|
22107
|
+
);
|
|
22108
|
+
}
|
|
22109
|
+
const model = current.find((option) => option.category === "model");
|
|
22110
|
+
if (model === void 0) {
|
|
22111
|
+
return current;
|
|
22112
|
+
}
|
|
22113
|
+
if (existing.category === "thought_level" && change.value === AGENT_DEFAULT_REASONING_EFFORT) {
|
|
22114
|
+
return current;
|
|
22115
|
+
}
|
|
22116
|
+
const modelId = existing.category === "model" ? change.value : model.currentValue;
|
|
22117
|
+
const params = {
|
|
22118
|
+
modelId,
|
|
22119
|
+
sessionId: nativeSessionId
|
|
22120
|
+
};
|
|
22121
|
+
if (existing.category === "thought_level") {
|
|
22122
|
+
params["_meta"] = {
|
|
22123
|
+
reasoningEffort: change.value
|
|
22124
|
+
};
|
|
22125
|
+
}
|
|
22126
|
+
const response = await transport.request(
|
|
22127
|
+
"session/set_model",
|
|
22128
|
+
params,
|
|
22129
|
+
existing.category === "model" ? "Grok Build exited while setting the session model" : "Grok Build exited while setting reasoning effort",
|
|
22130
|
+
change.signal
|
|
22131
|
+
);
|
|
22132
|
+
validateGrokResponse(response, modelId);
|
|
22133
|
+
const updated = updateCurrentValue2(
|
|
22134
|
+
current,
|
|
22135
|
+
existing.category,
|
|
22136
|
+
change.value
|
|
22137
|
+
);
|
|
22138
|
+
return existing.category === "thought_level" ? updated.map(
|
|
22139
|
+
(option) => option.category === "thought_level" ? {
|
|
22140
|
+
...option,
|
|
22141
|
+
values: option.values.filter(
|
|
22142
|
+
(value) => value.value !== AGENT_DEFAULT_REASONING_EFFORT
|
|
22143
|
+
)
|
|
22144
|
+
} : option
|
|
22145
|
+
) : updated;
|
|
22146
|
+
};
|
|
22147
|
+
normalizeLifecycle = (response) => normalizeGrokLifecycle(response);
|
|
22148
|
+
normalizeUpdate = (current, value) => standardSessionConfigProtocol.normalizeUpdate(current, value);
|
|
22149
|
+
};
|
|
22150
|
+
var grokBuildSessionConfigProtocol = new GrokBuildSessionConfigProtocol();
|
|
22151
|
+
|
|
22152
|
+
// src/acp/session-config/session-config-registry.ts
|
|
22153
|
+
function sessionConfigProtocolForAgent(agentId) {
|
|
22154
|
+
return agentId === "grok-build" ? grokBuildSessionConfigProtocol : standardSessionConfigProtocol;
|
|
22155
|
+
}
|
|
22156
|
+
|
|
21656
22157
|
// src/acp/session-history.ts
|
|
21657
22158
|
var AcpHistoryReplay = class {
|
|
21658
22159
|
#messages = [];
|
|
@@ -21757,7 +22258,7 @@ var FoundAcpStoredSession = class extends AcpStoredSessionLookup {
|
|
|
21757
22258
|
var DeletedAcpStoredSession = class extends AcpStoredSessionLookup {
|
|
21758
22259
|
found = false;
|
|
21759
22260
|
};
|
|
21760
|
-
function
|
|
22261
|
+
function readString3(value, field) {
|
|
21761
22262
|
if (typeof value !== "string" || value.length === 0) {
|
|
21762
22263
|
throw new Error(`Stored ACP session has an invalid ${field}`);
|
|
21763
22264
|
}
|
|
@@ -21787,10 +22288,10 @@ function decodeSessionRow(row) {
|
|
|
21787
22288
|
throw new Error("Stored ACP session is not an object");
|
|
21788
22289
|
}
|
|
21789
22290
|
return new AcpStoredSession(
|
|
21790
|
-
|
|
21791
|
-
|
|
21792
|
-
|
|
21793
|
-
|
|
22291
|
+
readString3(Reflect.get(row, "session_id"), "session ID"),
|
|
22292
|
+
readString3(Reflect.get(row, "agent_id"), "agent ID"),
|
|
22293
|
+
readString3(Reflect.get(row, "native_session_id"), "native session ID"),
|
|
22294
|
+
readString3(Reflect.get(row, "cwd"), "working directory"),
|
|
21794
22295
|
readAdditionalDirectories(Reflect.get(row, "additional_directories_json")),
|
|
21795
22296
|
readPrompted(Reflect.get(row, "prompted"))
|
|
21796
22297
|
);
|
|
@@ -22052,168 +22553,37 @@ function createWritableAcpStream(output2) {
|
|
|
22052
22553
|
}
|
|
22053
22554
|
});
|
|
22054
22555
|
}
|
|
22055
|
-
function
|
|
22556
|
+
function truncate3(value, maximumLength) {
|
|
22056
22557
|
return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
|
|
22057
22558
|
}
|
|
22058
|
-
function
|
|
22559
|
+
function isRecord4(value) {
|
|
22059
22560
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22060
22561
|
}
|
|
22061
|
-
function
|
|
22562
|
+
function readString4(value, fallback = "") {
|
|
22062
22563
|
return typeof value === "string" ? value : fallback;
|
|
22063
22564
|
}
|
|
22064
|
-
function readBoolean(value, fallback = false) {
|
|
22065
|
-
return typeof value === "boolean" ? value : fallback;
|
|
22066
|
-
}
|
|
22067
22565
|
function arraysEqual(left, right) {
|
|
22068
22566
|
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
22069
22567
|
}
|
|
22070
|
-
function
|
|
22568
|
+
function normalizeCapabilities(capabilities) {
|
|
22569
|
+
const session = capabilities.sessionCapabilities;
|
|
22570
|
+
const prompt = capabilities.promptCapabilities;
|
|
22071
22571
|
return {
|
|
22072
|
-
|
|
22073
|
-
|
|
22074
|
-
|
|
22075
|
-
|
|
22076
|
-
|
|
22077
|
-
|
|
22078
|
-
|
|
22079
|
-
|
|
22572
|
+
additionalDirectories: session?.additionalDirectories != null,
|
|
22573
|
+
audioPrompt: prompt?.audio === true,
|
|
22574
|
+
closeSession: session?.close != null,
|
|
22575
|
+
deleteSession: session?.delete != null,
|
|
22576
|
+
embeddedContextPrompt: prompt?.embeddedContext === true,
|
|
22577
|
+
imagePrompt: prompt?.image === true,
|
|
22578
|
+
listSessions: session?.list != null,
|
|
22579
|
+
loadSession: capabilities.loadSession === true,
|
|
22580
|
+
resumeSession: session?.resume != null,
|
|
22581
|
+
unstableForkSession: session?.fork != null
|
|
22080
22582
|
};
|
|
22081
22583
|
}
|
|
22082
|
-
function
|
|
22083
|
-
if (
|
|
22084
|
-
return
|
|
22085
|
-
}
|
|
22086
|
-
const normalized = [];
|
|
22087
|
-
for (const entry of value) {
|
|
22088
|
-
if (!isRecord3(entry)) {
|
|
22089
|
-
continue;
|
|
22090
|
-
}
|
|
22091
|
-
const groupedOptions = entry["options"];
|
|
22092
|
-
if (Array.isArray(groupedOptions)) {
|
|
22093
|
-
const groupId = readString3(entry["group"]);
|
|
22094
|
-
const groupName = readString3(entry["name"]);
|
|
22095
|
-
for (const groupedOption of groupedOptions) {
|
|
22096
|
-
if (isRecord3(groupedOption)) {
|
|
22097
|
-
normalized.push(
|
|
22098
|
-
normalizeConfigValue(groupedOption, groupId, groupName)
|
|
22099
|
-
);
|
|
22100
|
-
}
|
|
22101
|
-
}
|
|
22102
|
-
continue;
|
|
22103
|
-
}
|
|
22104
|
-
normalized.push(normalizeConfigValue(entry));
|
|
22105
|
-
}
|
|
22106
|
-
return normalized.filter((entry) => entry.value.length > 0).slice(0, 500);
|
|
22107
|
-
}
|
|
22108
|
-
function normalizeConfigOptions(value, modes) {
|
|
22109
|
-
const normalized = [];
|
|
22110
|
-
if (Array.isArray(value)) {
|
|
22111
|
-
for (const option of value) {
|
|
22112
|
-
if (!isRecord3(option)) {
|
|
22113
|
-
continue;
|
|
22114
|
-
}
|
|
22115
|
-
const id = truncate2(readString3(option["id"]), 128);
|
|
22116
|
-
const name = truncate2(readString3(option["name"], id), 255);
|
|
22117
|
-
if (id.length === 0 || name.length === 0) {
|
|
22118
|
-
continue;
|
|
22119
|
-
}
|
|
22120
|
-
if (option["type"] === "boolean") {
|
|
22121
|
-
normalized.push({
|
|
22122
|
-
booleanValue: readBoolean(option["currentValue"]),
|
|
22123
|
-
category: truncate2(readString3(option["category"]), 128),
|
|
22124
|
-
currentValue: "",
|
|
22125
|
-
description: truncate2(readString3(option["description"]), 500),
|
|
22126
|
-
id,
|
|
22127
|
-
name,
|
|
22128
|
-
type: "boolean",
|
|
22129
|
-
values: []
|
|
22130
|
-
});
|
|
22131
|
-
continue;
|
|
22132
|
-
}
|
|
22133
|
-
if (option["type"] === "select") {
|
|
22134
|
-
const values = normalizeConfigValues(option["options"]);
|
|
22135
|
-
const currentValue = truncate2(readString3(option["currentValue"]), 500);
|
|
22136
|
-
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue)) {
|
|
22137
|
-
normalized.push({
|
|
22138
|
-
booleanValue: false,
|
|
22139
|
-
category: truncate2(readString3(option["category"]), 128),
|
|
22140
|
-
currentValue,
|
|
22141
|
-
description: truncate2(readString3(option["description"]), 500),
|
|
22142
|
-
id,
|
|
22143
|
-
name,
|
|
22144
|
-
type: "select",
|
|
22145
|
-
values
|
|
22146
|
-
});
|
|
22147
|
-
}
|
|
22148
|
-
}
|
|
22149
|
-
}
|
|
22150
|
-
}
|
|
22151
|
-
if (isRecord3(modes)) {
|
|
22152
|
-
const values = [];
|
|
22153
|
-
const availableModes = modes["availableModes"];
|
|
22154
|
-
if (Array.isArray(availableModes)) {
|
|
22155
|
-
for (const mode of availableModes) {
|
|
22156
|
-
if (!isRecord3(mode)) {
|
|
22157
|
-
continue;
|
|
22158
|
-
}
|
|
22159
|
-
const id = truncate2(readString3(mode["id"]), 500);
|
|
22160
|
-
if (id.length === 0) {
|
|
22161
|
-
continue;
|
|
22162
|
-
}
|
|
22163
|
-
values.push({
|
|
22164
|
-
description: truncate2(readString3(mode["description"]), 500),
|
|
22165
|
-
groupId: "",
|
|
22166
|
-
groupName: "",
|
|
22167
|
-
name: truncate2(readString3(mode["name"], id), 255),
|
|
22168
|
-
value: id
|
|
22169
|
-
});
|
|
22170
|
-
}
|
|
22171
|
-
}
|
|
22172
|
-
const currentValue = truncate2(readString3(modes["currentModeId"]), 500);
|
|
22173
|
-
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue) && !normalized.some((entry) => entry.category === "mode")) {
|
|
22174
|
-
normalized.unshift({
|
|
22175
|
-
booleanValue: false,
|
|
22176
|
-
category: "mode",
|
|
22177
|
-
currentValue,
|
|
22178
|
-
description: "Agent session mode",
|
|
22179
|
-
id: "mode",
|
|
22180
|
-
name: "Mode",
|
|
22181
|
-
type: "select",
|
|
22182
|
-
values
|
|
22183
|
-
});
|
|
22184
|
-
}
|
|
22185
|
-
}
|
|
22186
|
-
return normalized.slice(0, 100);
|
|
22187
|
-
}
|
|
22188
|
-
function replaceConfigOptionsKeepingMode(current, value) {
|
|
22189
|
-
const next = normalizeConfigOptions(value, void 0);
|
|
22190
|
-
if (next.some((option) => option.category === "mode")) {
|
|
22191
|
-
return next;
|
|
22192
|
-
}
|
|
22193
|
-
return [
|
|
22194
|
-
...current.filter((option) => option.category === "mode"),
|
|
22195
|
-
...next
|
|
22196
|
-
].slice(0, 100);
|
|
22197
|
-
}
|
|
22198
|
-
function normalizeCapabilities(capabilities) {
|
|
22199
|
-
const session = capabilities.sessionCapabilities;
|
|
22200
|
-
const prompt = capabilities.promptCapabilities;
|
|
22201
|
-
return {
|
|
22202
|
-
additionalDirectories: session?.additionalDirectories != null,
|
|
22203
|
-
audioPrompt: prompt?.audio === true,
|
|
22204
|
-
closeSession: session?.close != null,
|
|
22205
|
-
deleteSession: session?.delete != null,
|
|
22206
|
-
embeddedContextPrompt: prompt?.embeddedContext === true,
|
|
22207
|
-
imagePrompt: prompt?.image === true,
|
|
22208
|
-
listSessions: session?.list != null,
|
|
22209
|
-
loadSession: capabilities.loadSession === true,
|
|
22210
|
-
resumeSession: session?.resume != null,
|
|
22211
|
-
unstableForkSession: session?.fork != null
|
|
22212
|
-
};
|
|
22213
|
-
}
|
|
22214
|
-
function elicitationFieldType(value) {
|
|
22215
|
-
if (value === "boolean") {
|
|
22216
|
-
return "boolean";
|
|
22584
|
+
function elicitationFieldType(value) {
|
|
22585
|
+
if (value === "boolean") {
|
|
22586
|
+
return "boolean";
|
|
22217
22587
|
}
|
|
22218
22588
|
if (value === "integer") {
|
|
22219
22589
|
return "integer";
|
|
@@ -22231,11 +22601,11 @@ function normalizeElicitationOptions(schema) {
|
|
|
22231
22601
|
const oneOf = schema["oneOf"];
|
|
22232
22602
|
if (Array.isArray(oneOf)) {
|
|
22233
22603
|
for (const option of oneOf) {
|
|
22234
|
-
if (
|
|
22604
|
+
if (isRecord4(option) && typeof option["const"] === "string") {
|
|
22235
22605
|
normalized.push({
|
|
22236
|
-
description:
|
|
22237
|
-
label:
|
|
22238
|
-
value:
|
|
22606
|
+
description: truncate3(readString4(option["description"]), 500),
|
|
22607
|
+
label: truncate3(readString4(option["title"], option["const"]), 255),
|
|
22608
|
+
value: truncate3(option["const"], 500)
|
|
22239
22609
|
});
|
|
22240
22610
|
}
|
|
22241
22611
|
}
|
|
@@ -22251,7 +22621,7 @@ function normalizeElicitationOptions(schema) {
|
|
|
22251
22621
|
return normalized.slice(0, 200);
|
|
22252
22622
|
}
|
|
22253
22623
|
const items = schema["items"];
|
|
22254
|
-
if (!
|
|
22624
|
+
if (!isRecord4(items)) {
|
|
22255
22625
|
return normalized;
|
|
22256
22626
|
}
|
|
22257
22627
|
const anyOf = items["anyOf"];
|
|
@@ -22264,7 +22634,7 @@ function numericString(value) {
|
|
|
22264
22634
|
return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
|
|
22265
22635
|
}
|
|
22266
22636
|
function normalizeElicitationFields(requestedSchema) {
|
|
22267
|
-
if (!
|
|
22637
|
+
if (!isRecord4(requestedSchema) || !isRecord4(requestedSchema["properties"])) {
|
|
22268
22638
|
return [];
|
|
22269
22639
|
}
|
|
22270
22640
|
const properties = requestedSchema["properties"];
|
|
@@ -22274,7 +22644,7 @@ function normalizeElicitationFields(requestedSchema) {
|
|
|
22274
22644
|
);
|
|
22275
22645
|
const normalized = [];
|
|
22276
22646
|
for (const [name, property] of Object.entries(properties)) {
|
|
22277
|
-
if (!
|
|
22647
|
+
if (!isRecord4(property)) {
|
|
22278
22648
|
continue;
|
|
22279
22649
|
}
|
|
22280
22650
|
const type = elicitationFieldType(property["type"]);
|
|
@@ -22284,9 +22654,9 @@ function normalizeElicitationFields(requestedSchema) {
|
|
|
22284
22654
|
normalized.push({
|
|
22285
22655
|
defaultBooleanValue: typeof defaultValue === "boolean" ? defaultValue : false,
|
|
22286
22656
|
defaultNumberValue: typeof defaultValue === "number" && Number.isFinite(defaultValue) ? defaultValue : 0,
|
|
22287
|
-
defaultStringValue: typeof defaultValue === "string" ?
|
|
22288
|
-
description:
|
|
22289
|
-
format:
|
|
22657
|
+
defaultStringValue: typeof defaultValue === "string" ? truncate3(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate3(JSON.stringify(defaultValue), 1e4) : "",
|
|
22658
|
+
description: truncate3(readString4(property["description"]), 500),
|
|
22659
|
+
format: truncate3(readString4(property["format"]), 64),
|
|
22290
22660
|
hasDefaultValue: defaultValue !== void 0 && defaultValue !== null,
|
|
22291
22661
|
maximum: numericString(property["maximum"]),
|
|
22292
22662
|
maximumLength: numericString(
|
|
@@ -22296,11 +22666,11 @@ function normalizeElicitationFields(requestedSchema) {
|
|
|
22296
22666
|
minimumLength: numericString(
|
|
22297
22667
|
property["minLength"] ?? property["minItems"]
|
|
22298
22668
|
),
|
|
22299
|
-
name:
|
|
22669
|
+
name: truncate3(name, 128),
|
|
22300
22670
|
options,
|
|
22301
|
-
pattern:
|
|
22671
|
+
pattern: truncate3(readString4(property["pattern"]), 500),
|
|
22302
22672
|
required: required2.has(name),
|
|
22303
|
-
title:
|
|
22673
|
+
title: truncate3(readString4(property["title"], name), 255),
|
|
22304
22674
|
type: normalizedType
|
|
22305
22675
|
});
|
|
22306
22676
|
}
|
|
@@ -22369,7 +22739,7 @@ function validateElicitationContent(encoded, requestedSchema) {
|
|
|
22369
22739
|
"invalid_elicitation_response"
|
|
22370
22740
|
);
|
|
22371
22741
|
}
|
|
22372
|
-
if (!
|
|
22742
|
+
if (!isRecord4(decoded) || !isRecord4(requestedSchema) || !isRecord4(requestedSchema["properties"])) {
|
|
22373
22743
|
throw new AcpExecutionError(
|
|
22374
22744
|
"Elicitation response does not match the requested form",
|
|
22375
22745
|
{},
|
|
@@ -22393,7 +22763,7 @@ function validateElicitationContent(encoded, requestedSchema) {
|
|
|
22393
22763
|
const validated = {};
|
|
22394
22764
|
for (const [name, value] of Object.entries(decoded)) {
|
|
22395
22765
|
const property = properties[name];
|
|
22396
|
-
if (!
|
|
22766
|
+
if (!isRecord4(property)) {
|
|
22397
22767
|
throw new AcpExecutionError(
|
|
22398
22768
|
`Elicitation field ${name} was not requested`,
|
|
22399
22769
|
{},
|
|
@@ -22545,6 +22915,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22545
22915
|
#pendingPermissions = /* @__PURE__ */ new Map();
|
|
22546
22916
|
#preSessionUpdates = [];
|
|
22547
22917
|
#processExit;
|
|
22918
|
+
#sessionConfigProtocol;
|
|
22548
22919
|
#store;
|
|
22549
22920
|
#verifiedAgentVersion;
|
|
22550
22921
|
#preSessionUpdateBytes = 0;
|
|
@@ -22563,6 +22934,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22563
22934
|
unstableForkSession: false
|
|
22564
22935
|
};
|
|
22565
22936
|
#commands = [];
|
|
22937
|
+
#configRevision = 0;
|
|
22566
22938
|
#configOptions = [];
|
|
22567
22939
|
#nativeSessionId = "";
|
|
22568
22940
|
#prompted = false;
|
|
@@ -22580,6 +22952,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22580
22952
|
this.#cwd = cwd;
|
|
22581
22953
|
this.#getObserver = getObserver;
|
|
22582
22954
|
this.#mobiusSessionId = mobiusSessionId;
|
|
22955
|
+
this.#sessionConfigProtocol = sessionConfigProtocolForAgent(agent.id);
|
|
22583
22956
|
this.#store = store;
|
|
22584
22957
|
this.#verifiedAgentVersion = agent.agentVersion;
|
|
22585
22958
|
this.#child = spawn2(agent.adapterPath, [...agent.arguments], {
|
|
@@ -22684,7 +23057,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22684
23057
|
try {
|
|
22685
23058
|
await this.race(
|
|
22686
23059
|
this.#connection.agent.request(
|
|
22687
|
-
|
|
23060
|
+
methods3.agent.session.load,
|
|
22688
23061
|
{
|
|
22689
23062
|
additionalDirectories: [...this.#additionalDirectories],
|
|
22690
23063
|
cwd: this.#cwd,
|
|
@@ -22706,7 +23079,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22706
23079
|
async #initializeAgent(signal) {
|
|
22707
23080
|
const initialized = await this.race(
|
|
22708
23081
|
this.#connection.agent.request(
|
|
22709
|
-
|
|
23082
|
+
methods3.agent.initialize,
|
|
22710
23083
|
{
|
|
22711
23084
|
clientCapabilities: {
|
|
22712
23085
|
elicitation: { form: {}, url: {} },
|
|
@@ -22733,11 +23106,11 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22733
23106
|
}
|
|
22734
23107
|
const capabilities = initialized.agentCapabilities ?? {};
|
|
22735
23108
|
this.#capabilities = normalizeCapabilities(capabilities);
|
|
22736
|
-
this.#agentName =
|
|
23109
|
+
this.#agentName = truncate3(
|
|
22737
23110
|
initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId,
|
|
22738
23111
|
255
|
|
22739
23112
|
);
|
|
22740
|
-
this.#agentVersion =
|
|
23113
|
+
this.#agentVersion = truncate3(
|
|
22741
23114
|
this.#verifiedAgentVersion.length > 0 ? this.#verifiedAgentVersion : initialized.agentInfo?.version ?? "",
|
|
22742
23115
|
128
|
|
22743
23116
|
);
|
|
@@ -22774,7 +23147,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22774
23147
|
);
|
|
22775
23148
|
const forked = await this.race(
|
|
22776
23149
|
this.#connection.agent.request(
|
|
22777
|
-
|
|
23150
|
+
methods3.agent.session.fork,
|
|
22778
23151
|
{
|
|
22779
23152
|
sessionId: nativeSessionIdSchema.parse(origin.nativeSessionId),
|
|
22780
23153
|
cwd: this.#cwd,
|
|
@@ -22807,7 +23180,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22807
23180
|
if (this.#capabilities.resumeSession) {
|
|
22808
23181
|
lifecycleResponse = await this.race(
|
|
22809
23182
|
this.#connection.agent.request(
|
|
22810
|
-
|
|
23183
|
+
methods3.agent.session.resume,
|
|
22811
23184
|
{
|
|
22812
23185
|
additionalDirectories: [...this.#additionalDirectories],
|
|
22813
23186
|
cwd: this.#cwd,
|
|
@@ -22824,7 +23197,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22824
23197
|
try {
|
|
22825
23198
|
lifecycleResponse = await this.race(
|
|
22826
23199
|
this.#connection.agent.request(
|
|
22827
|
-
|
|
23200
|
+
methods3.agent.session.load,
|
|
22828
23201
|
{
|
|
22829
23202
|
additionalDirectories: [...this.#additionalDirectories],
|
|
22830
23203
|
cwd: this.#cwd,
|
|
@@ -22860,7 +23233,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22860
23233
|
}
|
|
22861
23234
|
const created = await this.race(
|
|
22862
23235
|
this.#connection.agent.request(
|
|
22863
|
-
|
|
23236
|
+
methods3.agent.session.new,
|
|
22864
23237
|
{
|
|
22865
23238
|
additionalDirectories: [...this.#additionalDirectories],
|
|
22866
23239
|
cwd: this.#cwd,
|
|
@@ -22874,11 +23247,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22874
23247
|
this.selectNativeSession(created.sessionId);
|
|
22875
23248
|
lifecycleResponse = created;
|
|
22876
23249
|
}
|
|
22877
|
-
|
|
22878
|
-
this.#configOptions = normalizeConfigOptions(
|
|
22879
|
-
lifecycleRecord["configOptions"],
|
|
22880
|
-
lifecycleRecord["modes"]
|
|
22881
|
-
);
|
|
23250
|
+
this.#configOptions = this.#sessionConfigProtocol.normalizeLifecycle(lifecycleResponse);
|
|
22882
23251
|
await this.#updateTail;
|
|
22883
23252
|
signal.throwIfAborted();
|
|
22884
23253
|
if (this.#prompted) {
|
|
@@ -22903,7 +23272,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22903
23272
|
);
|
|
22904
23273
|
const response = await this.race(
|
|
22905
23274
|
this.#connection.agent.request(
|
|
22906
|
-
|
|
23275
|
+
methods3.agent.session.list,
|
|
22907
23276
|
cursor === null ? {} : { cursor },
|
|
22908
23277
|
{ cancellationSignal: signal }
|
|
22909
23278
|
),
|
|
@@ -22928,7 +23297,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22928
23297
|
);
|
|
22929
23298
|
await this.race(
|
|
22930
23299
|
this.#connection.agent.request(
|
|
22931
|
-
|
|
23300
|
+
methods3.agent.session.delete,
|
|
22932
23301
|
{ sessionId: nativeSessionIdSchema.parse(nativeSessionId) },
|
|
22933
23302
|
{ cancellationSignal: signal }
|
|
22934
23303
|
),
|
|
@@ -22949,64 +23318,50 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22949
23318
|
);
|
|
22950
23319
|
}
|
|
22951
23320
|
if (existing.type === "select") {
|
|
22952
|
-
if (
|
|
23321
|
+
if (existing.values.length < 2) {
|
|
22953
23322
|
throw new AcpExecutionError(
|
|
22954
|
-
"The requested ACP configuration
|
|
23323
|
+
"The requested ACP configuration option is unavailable",
|
|
22955
23324
|
{},
|
|
22956
23325
|
"invalid_session_configuration"
|
|
22957
23326
|
);
|
|
22958
23327
|
}
|
|
22959
|
-
if (existing.
|
|
22960
|
-
|
|
22961
|
-
|
|
22962
|
-
|
|
22963
|
-
|
|
22964
|
-
{ cancellationSignal: options.signal }
|
|
22965
|
-
),
|
|
22966
|
-
"ACP agent exited while setting the session mode",
|
|
22967
|
-
options.signal
|
|
22968
|
-
);
|
|
22969
|
-
this.#configOptions = this.#configOptions.map(
|
|
22970
|
-
(option) => option.id === existing.id ? { ...option, currentValue: options.value } : option
|
|
22971
|
-
);
|
|
22972
|
-
} else {
|
|
22973
|
-
const response = await this.race(
|
|
22974
|
-
this.#connection.agent.request(
|
|
22975
|
-
methods2.agent.session.setConfigOption,
|
|
22976
|
-
{
|
|
22977
|
-
configId: existing.id,
|
|
22978
|
-
sessionId: this.#nativeSessionId,
|
|
22979
|
-
value: options.value
|
|
22980
|
-
},
|
|
22981
|
-
{ cancellationSignal: options.signal }
|
|
22982
|
-
),
|
|
22983
|
-
"ACP agent exited while changing session configuration",
|
|
22984
|
-
options.signal
|
|
22985
|
-
);
|
|
22986
|
-
this.#configOptions = replaceConfigOptionsKeepingMode(
|
|
22987
|
-
this.#configOptions,
|
|
22988
|
-
response.configOptions
|
|
23328
|
+
if (!existing.values.some((entry) => entry.value === options.value)) {
|
|
23329
|
+
throw new AcpExecutionError(
|
|
23330
|
+
"The requested ACP configuration value is unavailable",
|
|
23331
|
+
{},
|
|
23332
|
+
"invalid_session_configuration"
|
|
22989
23333
|
);
|
|
22990
23334
|
}
|
|
22991
|
-
}
|
|
22992
|
-
|
|
22993
|
-
|
|
22994
|
-
|
|
22995
|
-
{
|
|
22996
|
-
configId: existing.id,
|
|
22997
|
-
sessionId: this.#nativeSessionId,
|
|
22998
|
-
type: "boolean",
|
|
22999
|
-
value: options.booleanValue
|
|
23000
|
-
},
|
|
23001
|
-
{ cancellationSignal: options.signal }
|
|
23002
|
-
),
|
|
23003
|
-
"ACP agent exited while changing session configuration",
|
|
23004
|
-
options.signal
|
|
23005
|
-
);
|
|
23006
|
-
this.#configOptions = replaceConfigOptionsKeepingMode(
|
|
23335
|
+
}
|
|
23336
|
+
const configRevision = this.#configRevision;
|
|
23337
|
+
try {
|
|
23338
|
+
const configured = await this.#sessionConfigProtocol.configure(
|
|
23007
23339
|
this.#configOptions,
|
|
23008
|
-
|
|
23340
|
+
options,
|
|
23341
|
+
this.#nativeSessionId,
|
|
23342
|
+
{
|
|
23343
|
+
request: async (method, params, failureMessage, signal) => await this.race(
|
|
23344
|
+
this.#connection.agent.request(method, params, {
|
|
23345
|
+
cancellationSignal: signal
|
|
23346
|
+
}),
|
|
23347
|
+
failureMessage,
|
|
23348
|
+
signal
|
|
23349
|
+
)
|
|
23350
|
+
}
|
|
23009
23351
|
);
|
|
23352
|
+
await this.#updateTail;
|
|
23353
|
+
if (this.#configRevision === configRevision) {
|
|
23354
|
+
this.#configOptions = configured;
|
|
23355
|
+
}
|
|
23356
|
+
} catch (error61) {
|
|
23357
|
+
if (error61 instanceof SessionConfigProtocolError) {
|
|
23358
|
+
throw new AcpExecutionError(
|
|
23359
|
+
error61.message,
|
|
23360
|
+
{ cause: error61 },
|
|
23361
|
+
error61.code
|
|
23362
|
+
);
|
|
23363
|
+
}
|
|
23364
|
+
throw error61;
|
|
23010
23365
|
}
|
|
23011
23366
|
return this.#configOptions;
|
|
23012
23367
|
};
|
|
@@ -23090,7 +23445,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23090
23445
|
try {
|
|
23091
23446
|
const response = await this.race(
|
|
23092
23447
|
this.#connection.agent.request(
|
|
23093
|
-
|
|
23448
|
+
methods3.agent.session.prompt,
|
|
23094
23449
|
{ prompt, sessionId: this.#nativeSessionId },
|
|
23095
23450
|
{ cancellationSignal: options.signal }
|
|
23096
23451
|
),
|
|
@@ -23137,7 +23492,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23137
23492
|
try {
|
|
23138
23493
|
await this.cancelPendingInteractions();
|
|
23139
23494
|
if (this.#turn.running) {
|
|
23140
|
-
await this.#connection.agent.notify(
|
|
23495
|
+
await this.#connection.agent.notify(methods3.agent.session.cancel, {
|
|
23141
23496
|
sessionId: this.#nativeSessionId
|
|
23142
23497
|
});
|
|
23143
23498
|
}
|
|
@@ -23227,8 +23582,8 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23227
23582
|
const interactionId = `permission-${crypto.randomUUID()}`;
|
|
23228
23583
|
const options = request.options.slice(0, 20).map((option) => ({
|
|
23229
23584
|
kind: option.kind,
|
|
23230
|
-
name:
|
|
23231
|
-
optionId:
|
|
23585
|
+
name: truncate3(option.name, 255),
|
|
23586
|
+
optionId: truncate3(option.optionId, 255)
|
|
23232
23587
|
}));
|
|
23233
23588
|
if (options.length === 0) {
|
|
23234
23589
|
throw new AcpExecutionError(
|
|
@@ -23253,9 +23608,9 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23253
23608
|
kind: SESSION_PERMISSION_REQUESTED_KIND,
|
|
23254
23609
|
options,
|
|
23255
23610
|
sessionId: this.#mobiusSessionId,
|
|
23256
|
-
title:
|
|
23257
|
-
toolCallId:
|
|
23258
|
-
toolKind:
|
|
23611
|
+
title: truncate3(request.toolCall.title ?? "Permission required", 500),
|
|
23612
|
+
toolCallId: truncate3(request.toolCall.toolCallId, 255),
|
|
23613
|
+
toolKind: truncate3(request.toolCall.kind ?? "other", 64)
|
|
23259
23614
|
});
|
|
23260
23615
|
return await pending.completion.promise;
|
|
23261
23616
|
} finally {
|
|
@@ -23284,7 +23639,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23284
23639
|
const schemaValue = Reflect.get(request, "requestedSchema");
|
|
23285
23640
|
const requestedSchema = request.mode === "form" ? schemaValue : {};
|
|
23286
23641
|
const elicitationIdValue = Reflect.get(request, "elicitationId");
|
|
23287
|
-
const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ?
|
|
23642
|
+
const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate3(elicitationIdValue, 255) : "";
|
|
23288
23643
|
const pending = new PendingElicitation(
|
|
23289
23644
|
interactionId,
|
|
23290
23645
|
elicitationId,
|
|
@@ -23303,10 +23658,10 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23303
23658
|
fields: normalizeElicitationFields(requestedSchema),
|
|
23304
23659
|
interactionId,
|
|
23305
23660
|
kind: SESSION_ELICITATION_REQUESTED_KIND,
|
|
23306
|
-
message:
|
|
23661
|
+
message: truncate3(request.message, 2e3),
|
|
23307
23662
|
mode: request.mode,
|
|
23308
23663
|
sessionId: this.#mobiusSessionId,
|
|
23309
|
-
url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ?
|
|
23664
|
+
url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate3(readString4(Reflect.get(request, "url")), 4096) : ""
|
|
23310
23665
|
});
|
|
23311
23666
|
return await pending.completion.promise;
|
|
23312
23667
|
} finally {
|
|
@@ -23395,7 +23750,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23395
23750
|
content: normalizeContentBlock(update.content),
|
|
23396
23751
|
contentId: `content-${crypto.randomUUID()}`,
|
|
23397
23752
|
kind: AGENT_CONTENT_KIND,
|
|
23398
|
-
messageId:
|
|
23753
|
+
messageId: truncate3(update.messageId ?? "", 255),
|
|
23399
23754
|
sessionId: this.#mobiusSessionId
|
|
23400
23755
|
});
|
|
23401
23756
|
}
|
|
@@ -23433,9 +23788,9 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23433
23788
|
}
|
|
23434
23789
|
if (update.sessionUpdate === "available_commands_update") {
|
|
23435
23790
|
const commands = update.availableCommands.slice(0, 500).map((command) => ({
|
|
23436
|
-
description:
|
|
23437
|
-
inputHint:
|
|
23438
|
-
name:
|
|
23791
|
+
description: truncate3(command.description, 500),
|
|
23792
|
+
inputHint: truncate3(command.input?.hint ?? "", 255),
|
|
23793
|
+
name: truncate3(command.name, 128)
|
|
23439
23794
|
})).filter((command) => command.name.length > 0);
|
|
23440
23795
|
this.#commands = commands;
|
|
23441
23796
|
await this.#getObserver().onCommands({
|
|
@@ -23446,10 +23801,11 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23446
23801
|
return;
|
|
23447
23802
|
}
|
|
23448
23803
|
if (update.sessionUpdate === "config_option_update") {
|
|
23449
|
-
this.#configOptions =
|
|
23804
|
+
this.#configOptions = this.#sessionConfigProtocol.normalizeUpdate(
|
|
23450
23805
|
this.#configOptions,
|
|
23451
23806
|
update.configOptions
|
|
23452
23807
|
);
|
|
23808
|
+
this.#configRevision += 1;
|
|
23453
23809
|
await this.emitConfigUpdate();
|
|
23454
23810
|
return;
|
|
23455
23811
|
}
|
|
@@ -23457,15 +23813,16 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23457
23813
|
this.#configOptions = this.#configOptions.map(
|
|
23458
23814
|
(option) => option.category === "mode" ? { ...option, currentValue: update.currentModeId } : option
|
|
23459
23815
|
);
|
|
23816
|
+
this.#configRevision += 1;
|
|
23460
23817
|
await this.emitConfigUpdate();
|
|
23461
23818
|
return;
|
|
23462
23819
|
}
|
|
23463
23820
|
if (update.sessionUpdate === "session_info_update") {
|
|
23464
23821
|
if (Object.hasOwn(update, "title")) {
|
|
23465
|
-
this.#sessionTitle =
|
|
23822
|
+
this.#sessionTitle = truncate3(update.title ?? "", 500);
|
|
23466
23823
|
}
|
|
23467
23824
|
if (Object.hasOwn(update, "updatedAt")) {
|
|
23468
|
-
this.#sessionUpdatedAt =
|
|
23825
|
+
this.#sessionUpdatedAt = truncate3(update.updatedAt ?? "", 128);
|
|
23469
23826
|
}
|
|
23470
23827
|
await this.#getObserver().onInfo({
|
|
23471
23828
|
kind: SESSION_INFO_UPDATED_KIND,
|
|
@@ -23478,7 +23835,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23478
23835
|
if (update.sessionUpdate === "usage_update") {
|
|
23479
23836
|
await this.#getObserver().onUsage({
|
|
23480
23837
|
costAmount: update.cost?.amount ?? 0,
|
|
23481
|
-
costCurrency:
|
|
23838
|
+
costCurrency: truncate3(update.cost?.currency ?? "", 16),
|
|
23482
23839
|
hasCost: update.cost !== void 0 && update.cost !== null,
|
|
23483
23840
|
kind: SESSION_USAGE_UPDATED_KIND,
|
|
23484
23841
|
sessionId: this.#mobiusSessionId,
|
|
@@ -23493,7 +23850,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23493
23850
|
if (this.#capabilities.closeSession && this.#nativeSessionId.length > 0) {
|
|
23494
23851
|
try {
|
|
23495
23852
|
await this.#connection.agent.request(
|
|
23496
|
-
|
|
23853
|
+
methods3.agent.session.close,
|
|
23497
23854
|
{ sessionId: this.#nativeSessionId },
|
|
23498
23855
|
{
|
|
23499
23856
|
cancellationSignal: AbortSignal.timeout(
|
|
@@ -24184,7 +24541,7 @@ var LocalAuthorizationError = class extends Error {
|
|
|
24184
24541
|
import { randomUUID } from "node:crypto";
|
|
24185
24542
|
import {
|
|
24186
24543
|
mkdir as mkdir3,
|
|
24187
|
-
open as
|
|
24544
|
+
open as open4,
|
|
24188
24545
|
realpath as realpath6,
|
|
24189
24546
|
rename as rename3,
|
|
24190
24547
|
stat as stat5,
|
|
@@ -24211,12 +24568,19 @@ var AvailableAgent = class extends AgentDiscovery {
|
|
|
24211
24568
|
};
|
|
24212
24569
|
var UnavailableAgent = class extends AgentDiscovery {
|
|
24213
24570
|
};
|
|
24214
|
-
var
|
|
24571
|
+
var UnavailableInstalledAgent = class extends UnavailableAgent {
|
|
24572
|
+
agent;
|
|
24573
|
+
constructor(specification, agent) {
|
|
24574
|
+
super(specification);
|
|
24575
|
+
this.agent = agent;
|
|
24576
|
+
}
|
|
24577
|
+
};
|
|
24578
|
+
var MissingAdapter = class extends UnavailableInstalledAgent {
|
|
24215
24579
|
code = "adapter_not_found";
|
|
24216
24580
|
message = "ACP adapter not found";
|
|
24217
24581
|
status = "missing_adapter";
|
|
24218
|
-
constructor(specification) {
|
|
24219
|
-
super(specification);
|
|
24582
|
+
constructor(specification, agent) {
|
|
24583
|
+
super(specification, agent);
|
|
24220
24584
|
}
|
|
24221
24585
|
};
|
|
24222
24586
|
var MissingAgent = class extends UnavailableAgent {
|
|
@@ -24227,7 +24591,7 @@ var MissingAgent = class extends UnavailableAgent {
|
|
|
24227
24591
|
super(specification);
|
|
24228
24592
|
}
|
|
24229
24593
|
};
|
|
24230
|
-
var
|
|
24594
|
+
var AgentProbeFailed = class extends UnavailableAgent {
|
|
24231
24595
|
code;
|
|
24232
24596
|
message;
|
|
24233
24597
|
status = "probe_failed";
|
|
@@ -24237,20 +24601,30 @@ var ProbeFailed = class extends UnavailableAgent {
|
|
|
24237
24601
|
this.message = message;
|
|
24238
24602
|
}
|
|
24239
24603
|
};
|
|
24240
|
-
var
|
|
24604
|
+
var IntegrationProbeFailed = class extends UnavailableInstalledAgent {
|
|
24605
|
+
code;
|
|
24606
|
+
message;
|
|
24607
|
+
status = "probe_failed";
|
|
24608
|
+
constructor(specification, agent, code, message) {
|
|
24609
|
+
super(specification, agent);
|
|
24610
|
+
this.code = code;
|
|
24611
|
+
this.message = message;
|
|
24612
|
+
}
|
|
24613
|
+
};
|
|
24614
|
+
var IncompatibleAdapter = class extends UnavailableInstalledAgent {
|
|
24241
24615
|
code = "acp_incompatible";
|
|
24242
24616
|
message = "ACP adapter is incompatible";
|
|
24243
24617
|
status = "incompatible_adapter";
|
|
24244
|
-
constructor(specification) {
|
|
24245
|
-
super(specification);
|
|
24618
|
+
constructor(specification, agent) {
|
|
24619
|
+
super(specification, agent);
|
|
24246
24620
|
}
|
|
24247
24621
|
};
|
|
24248
|
-
var AuthenticationRequiredAgent = class extends
|
|
24622
|
+
var AuthenticationRequiredAgent = class extends UnavailableInstalledAgent {
|
|
24249
24623
|
code = "authentication_required";
|
|
24250
24624
|
message = "Agent authentication is required";
|
|
24251
24625
|
status = "authentication_required";
|
|
24252
|
-
constructor(specification) {
|
|
24253
|
-
super(specification);
|
|
24626
|
+
constructor(specification, agent) {
|
|
24627
|
+
super(specification, agent);
|
|
24254
24628
|
}
|
|
24255
24629
|
};
|
|
24256
24630
|
var LocalAgentInventory = class {
|
|
@@ -24258,7 +24632,7 @@ var LocalAgentInventory = class {
|
|
|
24258
24632
|
discoveries;
|
|
24259
24633
|
installable;
|
|
24260
24634
|
unavailable;
|
|
24261
|
-
constructor(discoveries
|
|
24635
|
+
constructor(discoveries) {
|
|
24262
24636
|
const available = [];
|
|
24263
24637
|
const unavailable = [];
|
|
24264
24638
|
for (const discovery of discoveries) {
|
|
@@ -24273,13 +24647,8 @@ var LocalAgentInventory = class {
|
|
|
24273
24647
|
this.available = Object.freeze(available);
|
|
24274
24648
|
this.discoveries = Object.freeze([...discoveries]);
|
|
24275
24649
|
this.installable = Object.freeze(
|
|
24276
|
-
unavailable.
|
|
24277
|
-
(discovery) =>
|
|
24278
|
-
platform,
|
|
24279
|
-
architecture
|
|
24280
|
-
)
|
|
24281
|
-
).map(
|
|
24282
|
-
(discovery) => new InstallableAgentDefinition(
|
|
24650
|
+
unavailable.map(
|
|
24651
|
+
(discovery) => discovery instanceof UnavailableInstalledAgent ? discovery.agent : new MissingAgentDefinition(
|
|
24283
24652
|
discovery.specification.id,
|
|
24284
24653
|
discovery.specification.label
|
|
24285
24654
|
)
|
|
@@ -24347,7 +24716,7 @@ var ManagedNpmPackageError = class extends Error {
|
|
|
24347
24716
|
this.name = "ManagedNpmPackageError";
|
|
24348
24717
|
}
|
|
24349
24718
|
};
|
|
24350
|
-
function
|
|
24719
|
+
function isRecord5(value) {
|
|
24351
24720
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24352
24721
|
}
|
|
24353
24722
|
function packagePath(root, packageName) {
|
|
@@ -24371,7 +24740,7 @@ async function readJsonRecord(path2, maximumBytes) {
|
|
|
24371
24740
|
const value = JSON.parse(
|
|
24372
24741
|
await handle.readFile({ encoding: "utf8" })
|
|
24373
24742
|
);
|
|
24374
|
-
if (!
|
|
24743
|
+
if (!isRecord5(value)) {
|
|
24375
24744
|
throw new ManagedNpmPackageError(
|
|
24376
24745
|
"managed_package_verification_failed",
|
|
24377
24746
|
"The managed npm package metadata is invalid"
|
|
@@ -24397,7 +24766,7 @@ function readBinPath(packageMetadata, executableName) {
|
|
|
24397
24766
|
if (typeof bin === "string") {
|
|
24398
24767
|
return bin;
|
|
24399
24768
|
}
|
|
24400
|
-
if (
|
|
24769
|
+
if (isRecord5(bin) && typeof bin[executableName] === "string") {
|
|
24401
24770
|
return bin[executableName];
|
|
24402
24771
|
}
|
|
24403
24772
|
throw new ManagedNpmPackageError(
|
|
@@ -24413,7 +24782,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
24413
24782
|
);
|
|
24414
24783
|
}
|
|
24415
24784
|
const packages = lock["packages"];
|
|
24416
|
-
if (!
|
|
24785
|
+
if (!isRecord5(packages)) {
|
|
24417
24786
|
throw new ManagedNpmPackageError(
|
|
24418
24787
|
"managed_package_verification_failed",
|
|
24419
24788
|
"The managed npm package lockfile is invalid"
|
|
@@ -24427,7 +24796,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
24427
24796
|
if (verifyDependencyClosure && normalizedKey.length > 0) {
|
|
24428
24797
|
let resolved;
|
|
24429
24798
|
try {
|
|
24430
|
-
if (!normalizedKey.split("/").includes("node_modules") || !
|
|
24799
|
+
if (!normalizedKey.split("/").includes("node_modules") || !isRecord5(candidate) || typeof candidate["version"] !== "string" || candidate["version"].length === 0 || typeof candidate["integrity"] !== "string" || !/^sha512-[A-Za-z0-9+/]{86}==$/.test(candidate["integrity"]) || typeof candidate["resolved"] !== "string") {
|
|
24431
24800
|
throw new Error("Invalid locked dependency");
|
|
24432
24801
|
}
|
|
24433
24802
|
resolved = new URL(candidate["resolved"]);
|
|
@@ -24450,7 +24819,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
24450
24819
|
matches += 1;
|
|
24451
24820
|
}
|
|
24452
24821
|
}
|
|
24453
|
-
if (matches !== 1 || !
|
|
24822
|
+
if (matches !== 1 || !isRecord5(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
|
|
24454
24823
|
throw new ManagedNpmPackageError(
|
|
24455
24824
|
"managed_package_verification_failed",
|
|
24456
24825
|
"The managed npm package lockfile does not match the pinned artifact"
|
|
@@ -24673,7 +25042,6 @@ var LocalAgentSpecification = class {
|
|
|
24673
25042
|
createLaunchEnvironment = async (_agent, _context) => Object.freeze({});
|
|
24674
25043
|
recoveryCommand = () => "";
|
|
24675
25044
|
resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
|
|
24676
|
-
supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
|
|
24677
25045
|
verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
|
|
24678
25046
|
};
|
|
24679
25047
|
var DirectAcpAgentDefinition = class extends LocalAgentSpecification {
|
|
@@ -24779,11 +25147,11 @@ var AgentProbeError = class extends Error {
|
|
|
24779
25147
|
|
|
24780
25148
|
// src/agent-catalog/agents/verify-session-creation.ts
|
|
24781
25149
|
import {
|
|
24782
|
-
methods as
|
|
25150
|
+
methods as methods4
|
|
24783
25151
|
} from "@agentclientprotocol/sdk";
|
|
24784
25152
|
async function verifySessionCreation(connection, capabilities, defaultWorkspace, signal, label) {
|
|
24785
25153
|
const session = await connection.agent.request(
|
|
24786
|
-
|
|
25154
|
+
methods4.agent.session.new,
|
|
24787
25155
|
{
|
|
24788
25156
|
additionalDirectories: [],
|
|
24789
25157
|
cwd: defaultWorkspace,
|
|
@@ -24799,7 +25167,7 @@ async function verifySessionCreation(connection, capabilities, defaultWorkspace,
|
|
|
24799
25167
|
}
|
|
24800
25168
|
if (capabilities.sessionCapabilities?.close != null) {
|
|
24801
25169
|
await connection.agent.request(
|
|
24802
|
-
|
|
25170
|
+
methods4.agent.session.close,
|
|
24803
25171
|
{ sessionId: session.sessionId },
|
|
24804
25172
|
{ cancellationSignal: signal }
|
|
24805
25173
|
);
|
|
@@ -24821,7 +25189,6 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
24821
25189
|
["agents", "cursor", CURSOR_CLI_TESTED_VERSION, "bin", "cursor-agent"]
|
|
24822
25190
|
);
|
|
24823
25191
|
}
|
|
24824
|
-
supportsInstallation = (_platform, _architecture) => false;
|
|
24825
25192
|
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
24826
25193
|
const capabilities = initialized.agentCapabilities ?? {};
|
|
24827
25194
|
if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || !(initialized.authMethods ?? []).some(
|
|
@@ -25124,14 +25491,14 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
25124
25491
|
import { join as join9 } from "node:path";
|
|
25125
25492
|
|
|
25126
25493
|
// src/agent-installation/managed-agent-archive.ts
|
|
25127
|
-
import { createHash
|
|
25494
|
+
import { createHash } from "node:crypto";
|
|
25128
25495
|
import { createReadStream } from "node:fs";
|
|
25129
25496
|
import {
|
|
25130
25497
|
chmod,
|
|
25131
25498
|
copyFile,
|
|
25132
25499
|
mkdir as mkdir2,
|
|
25133
25500
|
mkdtemp as mkdtemp2,
|
|
25134
|
-
open as
|
|
25501
|
+
open as open3,
|
|
25135
25502
|
realpath as realpath5,
|
|
25136
25503
|
rename as rename2,
|
|
25137
25504
|
rm as rm2,
|
|
@@ -25141,259 +25508,64 @@ import {
|
|
|
25141
25508
|
import { dirname as dirname4, isAbsolute as isAbsolute4, join as join8, relative as relative3, sep as sep3 } from "node:path";
|
|
25142
25509
|
|
|
25143
25510
|
// src/agent-installation/verified-download.ts
|
|
25144
|
-
import { createHash } from "node:crypto";
|
|
25145
|
-
import { open as open3, unlink } from "node:fs/promises";
|
|
25146
25511
|
import { fetch } from "undici";
|
|
25147
25512
|
|
|
25148
25513
|
// src/network/environment-proxy.ts
|
|
25149
25514
|
import { EnvHttpProxyAgent } from "undici";
|
|
25150
25515
|
var environmentProxyDispatcher = new EnvHttpProxyAgent();
|
|
25151
25516
|
|
|
25152
|
-
// src/agent-installation/
|
|
25153
|
-
var
|
|
25154
|
-
var
|
|
25155
|
-
var
|
|
25517
|
+
// src/agent-installation/managed-agent-archive.ts
|
|
25518
|
+
var ARCHIVE_DOWNLOAD_LIMIT_BYTES = 128 * 1024 * 1024;
|
|
25519
|
+
var ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3;
|
|
25520
|
+
var MANIFEST_LIMIT_BYTES = 16 * 1024;
|
|
25521
|
+
var ManagedAgentArchiveDefinition = class {
|
|
25522
|
+
archiveName;
|
|
25523
|
+
archiveSha256;
|
|
25524
|
+
archiveUrl;
|
|
25525
|
+
executableName;
|
|
25526
|
+
version;
|
|
25527
|
+
constructor(version2, archiveName, archiveUrl, archiveSha256, executableName) {
|
|
25528
|
+
this.archiveName = archiveName;
|
|
25529
|
+
this.archiveSha256 = archiveSha256;
|
|
25530
|
+
this.archiveUrl = new URL(archiveUrl);
|
|
25531
|
+
this.executableName = executableName;
|
|
25532
|
+
this.version = version2;
|
|
25533
|
+
}
|
|
25534
|
+
};
|
|
25535
|
+
var ZipManagedAgentArchiveDefinition = class extends ManagedAgentArchiveDefinition {
|
|
25536
|
+
extractor = "/usr/bin/unzip";
|
|
25537
|
+
extractArguments = (archivePath, destination) => ["-q", archivePath, "-d", destination];
|
|
25538
|
+
listArguments = (archivePath) => [
|
|
25539
|
+
"-Z1",
|
|
25540
|
+
archivePath
|
|
25541
|
+
];
|
|
25542
|
+
};
|
|
25543
|
+
var TarGzipManagedAgentArchiveDefinition = class extends ManagedAgentArchiveDefinition {
|
|
25544
|
+
extractor = "/usr/bin/tar";
|
|
25545
|
+
extractArguments = (archivePath, destination) => ["-xzf", archivePath, "-C", destination];
|
|
25546
|
+
listArguments = (archivePath) => [
|
|
25547
|
+
"-tzf",
|
|
25548
|
+
archivePath
|
|
25549
|
+
];
|
|
25550
|
+
};
|
|
25551
|
+
var ManagedAgentArchiveError = class extends Error {
|
|
25156
25552
|
code;
|
|
25157
25553
|
constructor(code, message, options = {}) {
|
|
25158
25554
|
super(message, options);
|
|
25159
25555
|
this.code = code;
|
|
25160
|
-
this.name = "
|
|
25161
|
-
}
|
|
25162
|
-
};
|
|
25163
|
-
var VerifiedDownload = class {
|
|
25164
|
-
bytes;
|
|
25165
|
-
sha256;
|
|
25166
|
-
url;
|
|
25167
|
-
constructor(url2, bytes, sha256) {
|
|
25168
|
-
this.bytes = bytes;
|
|
25169
|
-
this.sha256 = sha256;
|
|
25170
|
-
this.url = url2;
|
|
25556
|
+
this.name = "ManagedAgentArchiveError";
|
|
25171
25557
|
}
|
|
25172
25558
|
};
|
|
25173
|
-
|
|
25174
|
-
|
|
25175
|
-
dispatcher: environmentProxyDispatcher,
|
|
25176
|
-
headers: {
|
|
25177
|
-
accept: "text/plain, application/octet-stream;q=0.9",
|
|
25178
|
-
"user-agent": "Mobius-Agent-Installer/0.0.3"
|
|
25179
|
-
},
|
|
25180
|
-
method: "GET",
|
|
25181
|
-
redirect: "manual",
|
|
25182
|
-
signal
|
|
25183
|
-
});
|
|
25184
|
-
};
|
|
25185
|
-
function validateUrl(url2, allowedHosts) {
|
|
25186
|
-
if (url2.protocol !== "https:" || url2.username.length > 0 || url2.password.length > 0 || url2.port.length > 0 || !allowedHosts.has(url2.hostname)) {
|
|
25187
|
-
throw new InstallerDownloadError(
|
|
25188
|
-
"installer_host_not_allowed",
|
|
25189
|
-
"The installer download target is not allowed"
|
|
25190
|
-
);
|
|
25191
|
-
}
|
|
25559
|
+
function isRecord6(value) {
|
|
25560
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25192
25561
|
}
|
|
25193
|
-
|
|
25194
|
-
|
|
25195
|
-
|
|
25196
|
-
validateUrl(url2, options.allowedHosts);
|
|
25197
|
-
const response = await transport.get(url2, signal);
|
|
25198
|
-
if (!REDIRECT_STATUSES.has(response.status)) {
|
|
25199
|
-
return { response, url: url2 };
|
|
25200
|
-
}
|
|
25201
|
-
await response.body?.cancel();
|
|
25202
|
-
const location = response.headers.get("location");
|
|
25203
|
-
if (location === null || redirectCount === MAX_REDIRECTS) {
|
|
25204
|
-
throw new InstallerDownloadError(
|
|
25205
|
-
"installer_redirect_invalid",
|
|
25206
|
-
"The installer returned an invalid redirect"
|
|
25207
|
-
);
|
|
25208
|
-
}
|
|
25209
|
-
let redirected;
|
|
25210
|
-
try {
|
|
25211
|
-
redirected = new URL(location, url2);
|
|
25212
|
-
} catch (error61) {
|
|
25213
|
-
throw new InstallerDownloadError(
|
|
25214
|
-
"installer_redirect_invalid",
|
|
25215
|
-
"The installer returned an invalid redirect",
|
|
25216
|
-
{ cause: error61 }
|
|
25217
|
-
);
|
|
25218
|
-
}
|
|
25219
|
-
try {
|
|
25220
|
-
validateUrl(redirected, options.allowedHosts);
|
|
25221
|
-
} catch (error61) {
|
|
25222
|
-
throw new InstallerDownloadError(
|
|
25223
|
-
"installer_redirect_not_allowed",
|
|
25224
|
-
"The installer redirect left the approved host allowlist",
|
|
25225
|
-
{ cause: error61 }
|
|
25226
|
-
);
|
|
25227
|
-
}
|
|
25228
|
-
url2 = redirected;
|
|
25229
|
-
}
|
|
25230
|
-
throw new InstallerDownloadError(
|
|
25231
|
-
"installer_redirect_invalid",
|
|
25232
|
-
"The installer returned too many redirects"
|
|
25233
|
-
);
|
|
25234
|
-
}
|
|
25235
|
-
async function writeCompleteChunk(handle, chunk) {
|
|
25236
|
-
let offset = 0;
|
|
25237
|
-
while (offset < chunk.byteLength) {
|
|
25238
|
-
const written = await handle.write(
|
|
25239
|
-
chunk,
|
|
25240
|
-
offset,
|
|
25241
|
-
chunk.byteLength - offset
|
|
25242
|
-
);
|
|
25243
|
-
if (written.bytesWritten < 1) {
|
|
25244
|
-
throw new InstallerDownloadError(
|
|
25245
|
-
"installer_write_failed",
|
|
25246
|
-
"The verified installer could not be stored"
|
|
25247
|
-
);
|
|
25248
|
-
}
|
|
25249
|
-
offset += written.bytesWritten;
|
|
25250
|
-
}
|
|
25251
|
-
}
|
|
25252
|
-
async function downloadVerifiedFile(options, transport = new UndiciInstallerDownloadTransport()) {
|
|
25253
|
-
options.signal.throwIfAborted();
|
|
25254
|
-
const timeoutSignal = AbortSignal.timeout(options.timeoutMilliseconds);
|
|
25255
|
-
const signal = AbortSignal.any([options.signal, timeoutSignal]);
|
|
25256
|
-
let handle = null;
|
|
25257
|
-
let responseBody = null;
|
|
25258
|
-
try {
|
|
25259
|
-
const fetched = await fetchInstaller(options, signal, transport);
|
|
25260
|
-
responseBody = fetched.response.body;
|
|
25261
|
-
if (!fetched.response.ok || fetched.response.body === null) {
|
|
25262
|
-
throw new InstallerDownloadError(
|
|
25263
|
-
"installer_download_failed",
|
|
25264
|
-
"The approved installer could not be downloaded"
|
|
25265
|
-
);
|
|
25266
|
-
}
|
|
25267
|
-
const contentLength = fetched.response.headers.get("content-length");
|
|
25268
|
-
if (contentLength !== null) {
|
|
25269
|
-
const declaredLength = Number(contentLength);
|
|
25270
|
-
if (!Number.isSafeInteger(declaredLength) || declaredLength < 1 || declaredLength > options.maximumBytes) {
|
|
25271
|
-
throw new InstallerDownloadError(
|
|
25272
|
-
"installer_size_invalid",
|
|
25273
|
-
"The installer size is outside the approved limit"
|
|
25274
|
-
);
|
|
25275
|
-
}
|
|
25276
|
-
}
|
|
25277
|
-
handle = await open3(options.destination, "wx", 384);
|
|
25278
|
-
const digest = createHash("sha256");
|
|
25279
|
-
const reader = fetched.response.body.getReader();
|
|
25280
|
-
let bytes = 0;
|
|
25281
|
-
try {
|
|
25282
|
-
while (true) {
|
|
25283
|
-
signal.throwIfAborted();
|
|
25284
|
-
const chunk = await reader.read();
|
|
25285
|
-
if (chunk.done) {
|
|
25286
|
-
break;
|
|
25287
|
-
}
|
|
25288
|
-
bytes += chunk.value.byteLength;
|
|
25289
|
-
if (bytes > options.maximumBytes) {
|
|
25290
|
-
throw new InstallerDownloadError(
|
|
25291
|
-
"installer_size_invalid",
|
|
25292
|
-
"The installer exceeded the approved size limit"
|
|
25293
|
-
);
|
|
25294
|
-
}
|
|
25295
|
-
digest.update(chunk.value);
|
|
25296
|
-
await writeCompleteChunk(handle, chunk.value);
|
|
25297
|
-
}
|
|
25298
|
-
} finally {
|
|
25299
|
-
await reader.cancel().catch(() => void 0);
|
|
25300
|
-
reader.releaseLock();
|
|
25301
|
-
}
|
|
25302
|
-
if (bytes === 0) {
|
|
25303
|
-
throw new InstallerDownloadError(
|
|
25304
|
-
"installer_verification_failed",
|
|
25305
|
-
"The downloaded installer is empty"
|
|
25306
|
-
);
|
|
25307
|
-
}
|
|
25308
|
-
await handle.sync();
|
|
25309
|
-
await handle.close();
|
|
25310
|
-
handle = null;
|
|
25311
|
-
return new VerifiedDownload(fetched.url, bytes, digest.digest("hex"));
|
|
25312
|
-
} catch (error61) {
|
|
25313
|
-
if (handle !== null) {
|
|
25314
|
-
await handle.close().catch(() => void 0);
|
|
25315
|
-
}
|
|
25316
|
-
await unlink(options.destination).catch(() => void 0);
|
|
25317
|
-
if (options.signal.aborted) {
|
|
25318
|
-
options.signal.throwIfAborted();
|
|
25319
|
-
}
|
|
25320
|
-
if (timeoutSignal.aborted) {
|
|
25321
|
-
throw new InstallerDownloadError(
|
|
25322
|
-
"installer_download_timeout",
|
|
25323
|
-
"The installer download timed out",
|
|
25324
|
-
{ cause: error61 }
|
|
25325
|
-
);
|
|
25326
|
-
}
|
|
25327
|
-
if (error61 instanceof InstallerDownloadError) {
|
|
25328
|
-
throw error61;
|
|
25329
|
-
}
|
|
25330
|
-
throw new InstallerDownloadError(
|
|
25331
|
-
"installer_download_failed",
|
|
25332
|
-
"The approved installer could not be downloaded",
|
|
25333
|
-
{ cause: error61 }
|
|
25334
|
-
);
|
|
25335
|
-
} finally {
|
|
25336
|
-
await responseBody?.cancel().catch(() => void 0);
|
|
25337
|
-
}
|
|
25338
|
-
}
|
|
25339
|
-
|
|
25340
|
-
// src/agent-installation/managed-agent-archive.ts
|
|
25341
|
-
var ARCHIVE_DOWNLOAD_LIMIT_BYTES = 128 * 1024 * 1024;
|
|
25342
|
-
var ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3;
|
|
25343
|
-
var ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS = 6e4;
|
|
25344
|
-
var MANIFEST_LIMIT_BYTES = 16 * 1024;
|
|
25345
|
-
var MINIMAL_PATH = "/usr/bin:/bin";
|
|
25346
|
-
var ManagedAgentArchiveDefinition = class {
|
|
25347
|
-
archiveName;
|
|
25348
|
-
archiveSha256;
|
|
25349
|
-
archiveUrl;
|
|
25350
|
-
executableName;
|
|
25351
|
-
version;
|
|
25352
|
-
constructor(version2, archiveName, archiveUrl, archiveSha256, executableName) {
|
|
25353
|
-
this.archiveName = archiveName;
|
|
25354
|
-
this.archiveSha256 = archiveSha256;
|
|
25355
|
-
this.archiveUrl = new URL(archiveUrl);
|
|
25356
|
-
this.executableName = executableName;
|
|
25357
|
-
this.version = version2;
|
|
25358
|
-
}
|
|
25359
|
-
};
|
|
25360
|
-
var ZipManagedAgentArchiveDefinition = class extends ManagedAgentArchiveDefinition {
|
|
25361
|
-
extractor = "/usr/bin/unzip";
|
|
25362
|
-
extractArguments = (archivePath, destination) => ["-q", archivePath, "-d", destination];
|
|
25363
|
-
listArguments = (archivePath) => [
|
|
25364
|
-
"-Z1",
|
|
25365
|
-
archivePath
|
|
25366
|
-
];
|
|
25367
|
-
};
|
|
25368
|
-
var TarGzipManagedAgentArchiveDefinition = class extends ManagedAgentArchiveDefinition {
|
|
25369
|
-
extractor = "/usr/bin/tar";
|
|
25370
|
-
extractArguments = (archivePath, destination) => ["-xzf", archivePath, "-C", destination];
|
|
25371
|
-
listArguments = (archivePath) => [
|
|
25372
|
-
"-tzf",
|
|
25373
|
-
archivePath
|
|
25374
|
-
];
|
|
25375
|
-
};
|
|
25376
|
-
var ManagedAgentArchiveError = class extends Error {
|
|
25377
|
-
code;
|
|
25378
|
-
constructor(code, message, options = {}) {
|
|
25379
|
-
super(message, options);
|
|
25380
|
-
this.code = code;
|
|
25381
|
-
this.name = "ManagedAgentArchiveError";
|
|
25382
|
-
}
|
|
25383
|
-
};
|
|
25384
|
-
var ManagedAgentArchiveDownloader = class {
|
|
25385
|
-
download = async (options) => await downloadVerifiedFile(options);
|
|
25386
|
-
};
|
|
25387
|
-
function isRecord5(value) {
|
|
25388
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25389
|
-
}
|
|
25390
|
-
function isContainedPath3(root, candidate) {
|
|
25391
|
-
const difference = relative3(root, candidate);
|
|
25392
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute4(difference);
|
|
25562
|
+
function isContainedPath3(root, candidate) {
|
|
25563
|
+
const difference = relative3(root, candidate);
|
|
25564
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute4(difference);
|
|
25393
25565
|
}
|
|
25394
25566
|
async function hashFile(path2, signal) {
|
|
25395
25567
|
signal.throwIfAborted();
|
|
25396
|
-
const digest =
|
|
25568
|
+
const digest = createHash("sha256");
|
|
25397
25569
|
const stream = createReadStream(path2, { signal });
|
|
25398
25570
|
try {
|
|
25399
25571
|
for await (const chunk of stream) {
|
|
@@ -25424,7 +25596,7 @@ async function hashFile(path2, signal) {
|
|
|
25424
25596
|
async function readManifest(path2) {
|
|
25425
25597
|
let handle;
|
|
25426
25598
|
try {
|
|
25427
|
-
handle = await
|
|
25599
|
+
handle = await open3(path2, "r");
|
|
25428
25600
|
} catch (error61) {
|
|
25429
25601
|
throw new ManagedAgentArchiveError(
|
|
25430
25602
|
"managed_archive_verification_failed",
|
|
@@ -25443,7 +25615,7 @@ async function readManifest(path2) {
|
|
|
25443
25615
|
const parsed = JSON.parse(
|
|
25444
25616
|
await handle.readFile({ encoding: "utf8" })
|
|
25445
25617
|
);
|
|
25446
|
-
if (!
|
|
25618
|
+
if (!isRecord6(parsed)) {
|
|
25447
25619
|
throw new ManagedAgentArchiveError(
|
|
25448
25620
|
"managed_archive_verification_failed",
|
|
25449
25621
|
"The managed Agent archive manifest is invalid"
|
|
@@ -25495,144 +25667,6 @@ async function validateManagedAgentArchive(root, definition, signal) {
|
|
|
25495
25667
|
);
|
|
25496
25668
|
}
|
|
25497
25669
|
}
|
|
25498
|
-
function validateArchiveEntries(output2, definition) {
|
|
25499
|
-
const entries = output2.split(/\r?\n/).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
25500
|
-
if (entries.length !== 1 || entries[0] !== definition.executableName && entries[0] !== `./${definition.executableName}`) {
|
|
25501
|
-
throw new ManagedAgentArchiveError(
|
|
25502
|
-
"managed_archive_verification_failed",
|
|
25503
|
-
"The managed Agent archive contains unexpected entries"
|
|
25504
|
-
);
|
|
25505
|
-
}
|
|
25506
|
-
}
|
|
25507
|
-
var ManagedAgentArchiveInstaller = class {
|
|
25508
|
-
#downloader;
|
|
25509
|
-
constructor(downloader = new ManagedAgentArchiveDownloader()) {
|
|
25510
|
-
this.#downloader = downloader;
|
|
25511
|
-
}
|
|
25512
|
-
install = async (root, definition, signal) => {
|
|
25513
|
-
signal.throwIfAborted();
|
|
25514
|
-
try {
|
|
25515
|
-
const metadata = await stat4(root);
|
|
25516
|
-
if (metadata.isDirectory()) {
|
|
25517
|
-
return await validateManagedAgentArchive(root, definition, signal);
|
|
25518
|
-
}
|
|
25519
|
-
} catch (error61) {
|
|
25520
|
-
if (error61 instanceof ManagedAgentArchiveError || !(error61 instanceof Error) || !("code" in error61) || error61.code !== "ENOENT") {
|
|
25521
|
-
throw error61;
|
|
25522
|
-
}
|
|
25523
|
-
}
|
|
25524
|
-
const parent = dirname4(root);
|
|
25525
|
-
await mkdir2(parent, { mode: 448, recursive: true });
|
|
25526
|
-
const working = await mkdtemp2(
|
|
25527
|
-
join8(parent, `.${definition.version}.archive-`)
|
|
25528
|
-
);
|
|
25529
|
-
const staging = await mkdtemp2(
|
|
25530
|
-
join8(parent, `.${definition.version}.staging-`)
|
|
25531
|
-
);
|
|
25532
|
-
try {
|
|
25533
|
-
const archivePath = join8(working, definition.archiveName);
|
|
25534
|
-
const extractionRoot = join8(working, "extracted");
|
|
25535
|
-
await mkdir2(extractionRoot, { mode: 448 });
|
|
25536
|
-
const canonicalExtractionRoot = await realpath5(extractionRoot);
|
|
25537
|
-
const download = await this.#downloader.download({
|
|
25538
|
-
allowedHosts: /* @__PURE__ */ new Set([
|
|
25539
|
-
"github.com",
|
|
25540
|
-
"objects.githubusercontent.com",
|
|
25541
|
-
"release-assets.githubusercontent.com"
|
|
25542
|
-
]),
|
|
25543
|
-
destination: archivePath,
|
|
25544
|
-
maximumBytes: ARCHIVE_DOWNLOAD_LIMIT_BYTES,
|
|
25545
|
-
signal,
|
|
25546
|
-
timeoutMilliseconds: ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS,
|
|
25547
|
-
url: definition.archiveUrl
|
|
25548
|
-
});
|
|
25549
|
-
if (download.sha256 !== definition.archiveSha256) {
|
|
25550
|
-
throw new ManagedAgentArchiveError(
|
|
25551
|
-
"managed_archive_verification_failed",
|
|
25552
|
-
"The managed Agent archive checksum is invalid"
|
|
25553
|
-
);
|
|
25554
|
-
}
|
|
25555
|
-
const list = await runBoundedProcess({
|
|
25556
|
-
arguments: definition.listArguments(archivePath),
|
|
25557
|
-
command: definition.extractor,
|
|
25558
|
-
cwd: working,
|
|
25559
|
-
environment: { PATH: MINIMAL_PATH },
|
|
25560
|
-
outputLimitBytes: 64 * 1024,
|
|
25561
|
-
signal,
|
|
25562
|
-
timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
|
|
25563
|
-
});
|
|
25564
|
-
validateArchiveEntries(list.stdout, definition);
|
|
25565
|
-
await runBoundedProcess({
|
|
25566
|
-
arguments: definition.extractArguments(archivePath, extractionRoot),
|
|
25567
|
-
command: definition.extractor,
|
|
25568
|
-
cwd: working,
|
|
25569
|
-
environment: { PATH: MINIMAL_PATH },
|
|
25570
|
-
outputLimitBytes: 64 * 1024,
|
|
25571
|
-
signal,
|
|
25572
|
-
timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
|
|
25573
|
-
});
|
|
25574
|
-
const extracted = await realpath5(
|
|
25575
|
-
join8(canonicalExtractionRoot, definition.executableName)
|
|
25576
|
-
);
|
|
25577
|
-
const extractedMetadata = await stat4(extracted);
|
|
25578
|
-
if (!isContainedPath3(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
|
|
25579
|
-
throw new ManagedAgentArchiveError(
|
|
25580
|
-
"managed_archive_verification_failed",
|
|
25581
|
-
"The managed Agent archive executable is invalid"
|
|
25582
|
-
);
|
|
25583
|
-
}
|
|
25584
|
-
const binDirectory = join8(staging, "bin");
|
|
25585
|
-
const executablePath = join8(binDirectory, definition.executableName);
|
|
25586
|
-
await mkdir2(binDirectory, { mode: 448 });
|
|
25587
|
-
await copyFile(extracted, executablePath);
|
|
25588
|
-
await chmod(executablePath, 448);
|
|
25589
|
-
const executableSha256 = await hashFile(executablePath, signal);
|
|
25590
|
-
await writeFile(
|
|
25591
|
-
join8(staging, "archive.json"),
|
|
25592
|
-
`${JSON.stringify({
|
|
25593
|
-
archiveSha256: definition.archiveSha256,
|
|
25594
|
-
archiveUrl: definition.archiveUrl.toString(),
|
|
25595
|
-
executableSha256,
|
|
25596
|
-
version: definition.version
|
|
25597
|
-
})}
|
|
25598
|
-
`,
|
|
25599
|
-
{ mode: 384 }
|
|
25600
|
-
);
|
|
25601
|
-
await validateManagedAgentArchive(staging, definition, signal);
|
|
25602
|
-
try {
|
|
25603
|
-
await rename2(staging, root);
|
|
25604
|
-
} catch (error61) {
|
|
25605
|
-
try {
|
|
25606
|
-
return await validateManagedAgentArchive(root, definition, signal);
|
|
25607
|
-
} catch {
|
|
25608
|
-
throw new ManagedAgentArchiveError(
|
|
25609
|
-
"managed_archive_publish_failed",
|
|
25610
|
-
"The managed Agent archive could not be published",
|
|
25611
|
-
{ cause: error61 }
|
|
25612
|
-
);
|
|
25613
|
-
}
|
|
25614
|
-
}
|
|
25615
|
-
return await validateManagedAgentArchive(root, definition, signal);
|
|
25616
|
-
} catch (error61) {
|
|
25617
|
-
if (signal.aborted) {
|
|
25618
|
-
signal.throwIfAborted();
|
|
25619
|
-
}
|
|
25620
|
-
if (error61 instanceof ManagedAgentArchiveError) {
|
|
25621
|
-
throw error61;
|
|
25622
|
-
}
|
|
25623
|
-
throw new ManagedAgentArchiveError(
|
|
25624
|
-
"managed_archive_install_failed",
|
|
25625
|
-
"The pinned Agent archive could not be installed",
|
|
25626
|
-
{ cause: error61 }
|
|
25627
|
-
);
|
|
25628
|
-
} finally {
|
|
25629
|
-
await Promise.all([
|
|
25630
|
-
rm2(working, { force: true, recursive: true }),
|
|
25631
|
-
rm2(staging, { force: true, recursive: true })
|
|
25632
|
-
]);
|
|
25633
|
-
}
|
|
25634
|
-
};
|
|
25635
|
-
};
|
|
25636
25670
|
|
|
25637
25671
|
// src/agent-installation/opencode-managed-release.ts
|
|
25638
25672
|
var OPENCODE_MANAGED_VERSION = "1.18.29";
|
|
@@ -25730,7 +25764,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
25730
25764
|
// src/agent-catalog/agents/pi-agent.ts
|
|
25731
25765
|
import { join as join10 } from "node:path";
|
|
25732
25766
|
import {
|
|
25733
|
-
methods as
|
|
25767
|
+
methods as methods5
|
|
25734
25768
|
} from "@agentclientprotocol/sdk";
|
|
25735
25769
|
|
|
25736
25770
|
// src/agent-installation/pi-managed-packages.ts
|
|
@@ -25802,7 +25836,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
25802
25836
|
);
|
|
25803
25837
|
}
|
|
25804
25838
|
const session = await connection.agent.request(
|
|
25805
|
-
|
|
25839
|
+
methods5.agent.session.new,
|
|
25806
25840
|
{
|
|
25807
25841
|
additionalDirectories: [],
|
|
25808
25842
|
cwd: defaultWorkspace,
|
|
@@ -25817,7 +25851,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
25817
25851
|
);
|
|
25818
25852
|
}
|
|
25819
25853
|
const prompt = await connection.agent.request(
|
|
25820
|
-
|
|
25854
|
+
methods5.agent.session.prompt,
|
|
25821
25855
|
{
|
|
25822
25856
|
prompt: [{ text: "/session", type: "text" }],
|
|
25823
25857
|
sessionId: session.sessionId
|
|
@@ -25954,7 +25988,7 @@ function supportedLocalAgentSpecifications() {
|
|
|
25954
25988
|
// src/agent-catalog/acp-readiness-probe.ts
|
|
25955
25989
|
import { spawn as spawn3 } from "node:child_process";
|
|
25956
25990
|
import {
|
|
25957
|
-
methods as
|
|
25991
|
+
methods as methods6,
|
|
25958
25992
|
ndJsonStream as ndJsonStream2,
|
|
25959
25993
|
PROTOCOL_VERSION as PROTOCOL_VERSION2,
|
|
25960
25994
|
RequestError as RequestError2
|
|
@@ -26135,10 +26169,6 @@ async function resolveAdapterExecutables(specification, context) {
|
|
|
26135
26169
|
context
|
|
26136
26170
|
);
|
|
26137
26171
|
}
|
|
26138
|
-
async function resolveAgentExecutable(specification, context) {
|
|
26139
|
-
const executables = await resolveAgentExecutables(specification, context);
|
|
26140
|
-
return executables[0] ?? null;
|
|
26141
|
-
}
|
|
26142
26172
|
async function resolveAdapterExecutable(specification, context) {
|
|
26143
26173
|
const executables = await resolveAdapterExecutables(specification, context);
|
|
26144
26174
|
return executables[0] ?? null;
|
|
@@ -26204,41 +26234,41 @@ var DiscoveryAcpHandler = class {
|
|
|
26204
26234
|
};
|
|
26205
26235
|
function readableAcpStream(input2) {
|
|
26206
26236
|
let byteLength = 0;
|
|
26207
|
-
let
|
|
26237
|
+
let open5 = true;
|
|
26208
26238
|
return new ReadableStream({
|
|
26209
26239
|
start(controller) {
|
|
26210
26240
|
input2.on("data", (chunk) => {
|
|
26211
|
-
if (!
|
|
26241
|
+
if (!open5) {
|
|
26212
26242
|
return;
|
|
26213
26243
|
}
|
|
26214
26244
|
if (!(chunk instanceof Uint8Array)) {
|
|
26215
|
-
|
|
26245
|
+
open5 = false;
|
|
26216
26246
|
controller.error(new Error("ACP adapter produced invalid output"));
|
|
26217
26247
|
return;
|
|
26218
26248
|
}
|
|
26219
26249
|
byteLength += chunk.byteLength;
|
|
26220
26250
|
if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
|
|
26221
|
-
|
|
26251
|
+
open5 = false;
|
|
26222
26252
|
controller.error(new Error("ACP adapter output limit exceeded"));
|
|
26223
26253
|
return;
|
|
26224
26254
|
}
|
|
26225
26255
|
controller.enqueue(new Uint8Array(chunk));
|
|
26226
26256
|
});
|
|
26227
26257
|
input2.once("end", () => {
|
|
26228
|
-
if (
|
|
26229
|
-
|
|
26258
|
+
if (open5) {
|
|
26259
|
+
open5 = false;
|
|
26230
26260
|
controller.close();
|
|
26231
26261
|
}
|
|
26232
26262
|
});
|
|
26233
26263
|
input2.once("error", (error61) => {
|
|
26234
|
-
if (
|
|
26235
|
-
|
|
26264
|
+
if (open5) {
|
|
26265
|
+
open5 = false;
|
|
26236
26266
|
controller.error(error61);
|
|
26237
26267
|
}
|
|
26238
26268
|
});
|
|
26239
26269
|
},
|
|
26240
26270
|
cancel() {
|
|
26241
|
-
|
|
26271
|
+
open5 = false;
|
|
26242
26272
|
}
|
|
26243
26273
|
});
|
|
26244
26274
|
}
|
|
@@ -26307,7 +26337,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
26307
26337
|
try {
|
|
26308
26338
|
const initialized = await Promise.race([
|
|
26309
26339
|
connection.agent.request(
|
|
26310
|
-
|
|
26340
|
+
methods6.agent.initialize,
|
|
26311
26341
|
{
|
|
26312
26342
|
clientCapabilities: {},
|
|
26313
26343
|
clientInfo: { name: "mobius", version: "0.0.3" },
|
|
@@ -26367,25 +26397,50 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
26367
26397
|
}
|
|
26368
26398
|
|
|
26369
26399
|
// src/agent-catalog/discover-agent.ts
|
|
26370
|
-
function
|
|
26400
|
+
function agentProbeFailure(specification, error61) {
|
|
26401
|
+
if (error61 instanceof AgentProbeError) {
|
|
26402
|
+
return new AgentProbeFailed(specification, error61.code, error61.message);
|
|
26403
|
+
}
|
|
26404
|
+
if (error61 instanceof ProcessExecutionError) {
|
|
26405
|
+
const code = error61.code === "process_timeout" ? "agent_probe_timeout" : "agent_probe_failed";
|
|
26406
|
+
return new AgentProbeFailed(
|
|
26407
|
+
specification,
|
|
26408
|
+
code,
|
|
26409
|
+
"Agent version probe failed"
|
|
26410
|
+
);
|
|
26411
|
+
}
|
|
26412
|
+
return new AgentProbeFailed(
|
|
26413
|
+
specification,
|
|
26414
|
+
"agent_probe_failed",
|
|
26415
|
+
"Agent probe failed"
|
|
26416
|
+
);
|
|
26417
|
+
}
|
|
26418
|
+
function integrationProbeFailure(specification, agent, error61) {
|
|
26371
26419
|
if (error61 instanceof AgentProbeError) {
|
|
26372
26420
|
if (error61.code === "authentication_required") {
|
|
26373
|
-
return new AuthenticationRequiredAgent(specification);
|
|
26421
|
+
return new AuthenticationRequiredAgent(specification, agent);
|
|
26374
26422
|
}
|
|
26375
|
-
return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification) : new
|
|
26423
|
+
return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification, agent) : new IntegrationProbeFailed(
|
|
26424
|
+
specification,
|
|
26425
|
+
agent,
|
|
26426
|
+
error61.code,
|
|
26427
|
+
error61.message
|
|
26428
|
+
);
|
|
26376
26429
|
}
|
|
26377
26430
|
if (error61 instanceof ProcessExecutionError) {
|
|
26378
|
-
const code = error61.code === "process_timeout" ?
|
|
26379
|
-
return new
|
|
26431
|
+
const code = error61.code === "process_timeout" ? "adapter_probe_timeout" : "adapter_probe_failed";
|
|
26432
|
+
return new IntegrationProbeFailed(
|
|
26380
26433
|
specification,
|
|
26434
|
+
agent,
|
|
26381
26435
|
code,
|
|
26382
|
-
|
|
26436
|
+
"Adapter version probe failed"
|
|
26383
26437
|
);
|
|
26384
26438
|
}
|
|
26385
|
-
return new
|
|
26439
|
+
return new IntegrationProbeFailed(
|
|
26386
26440
|
specification,
|
|
26387
|
-
|
|
26388
|
-
|
|
26441
|
+
agent,
|
|
26442
|
+
"adapter_probe_failed",
|
|
26443
|
+
"Adapter probe failed"
|
|
26389
26444
|
);
|
|
26390
26445
|
}
|
|
26391
26446
|
async function discoverAgent(specification, context) {
|
|
@@ -26394,12 +26449,6 @@ async function discoverAgent(specification, context) {
|
|
|
26394
26449
|
resolveAdapterExecutables(specification, context),
|
|
26395
26450
|
resolveAgentExecutables(specification, context)
|
|
26396
26451
|
]);
|
|
26397
|
-
if (specification instanceof DirectAcpAgentDefinition && agents.length === 0) {
|
|
26398
|
-
return new MissingAgent(specification);
|
|
26399
|
-
}
|
|
26400
|
-
if (adapters.length === 0) {
|
|
26401
|
-
return new MissingAdapter(specification);
|
|
26402
|
-
}
|
|
26403
26452
|
if (agents.length === 0) {
|
|
26404
26453
|
return new MissingAgent(specification);
|
|
26405
26454
|
}
|
|
@@ -26419,9 +26468,18 @@ async function discoverAgent(specification, context) {
|
|
|
26419
26468
|
if (context.signal.aborted) {
|
|
26420
26469
|
context.signal.throwIfAborted();
|
|
26421
26470
|
}
|
|
26422
|
-
lastFailure =
|
|
26471
|
+
lastFailure = agentProbeFailure(specification, error61);
|
|
26423
26472
|
continue;
|
|
26424
26473
|
}
|
|
26474
|
+
const installedAgent = new AgentIntegrationDefinition(
|
|
26475
|
+
specification.id,
|
|
26476
|
+
specification.label,
|
|
26477
|
+
agent.identity.requestedPath,
|
|
26478
|
+
agentVersion
|
|
26479
|
+
);
|
|
26480
|
+
if (adapters.length === 0) {
|
|
26481
|
+
return new MissingAdapter(specification, installedAgent);
|
|
26482
|
+
}
|
|
26425
26483
|
for (const adapter of adapters) {
|
|
26426
26484
|
if (specification instanceof DirectAcpAgentDefinition && adapter.path !== agent.path) {
|
|
26427
26485
|
continue;
|
|
@@ -26450,7 +26508,11 @@ async function discoverAgent(specification, context) {
|
|
|
26450
26508
|
if (context.signal.aborted) {
|
|
26451
26509
|
context.signal.throwIfAborted();
|
|
26452
26510
|
}
|
|
26453
|
-
lastFailure =
|
|
26511
|
+
lastFailure = integrationProbeFailure(
|
|
26512
|
+
specification,
|
|
26513
|
+
installedAgent,
|
|
26514
|
+
error61
|
|
26515
|
+
);
|
|
26454
26516
|
continue;
|
|
26455
26517
|
}
|
|
26456
26518
|
const definition = new LocalAgentDefinition(
|
|
@@ -26499,7 +26561,11 @@ async function discoverAgent(specification, context) {
|
|
|
26499
26561
|
if (context.signal.aborted) {
|
|
26500
26562
|
context.signal.throwIfAborted();
|
|
26501
26563
|
}
|
|
26502
|
-
const failure =
|
|
26564
|
+
const failure = integrationProbeFailure(
|
|
26565
|
+
specification,
|
|
26566
|
+
installedAgent,
|
|
26567
|
+
error61
|
|
26568
|
+
);
|
|
26503
26569
|
if (failure instanceof AuthenticationRequiredAgent) {
|
|
26504
26570
|
return failure;
|
|
26505
26571
|
}
|
|
@@ -26507,7 +26573,7 @@ async function discoverAgent(specification, context) {
|
|
|
26507
26573
|
}
|
|
26508
26574
|
}
|
|
26509
26575
|
}
|
|
26510
|
-
return lastFailure ?? new
|
|
26576
|
+
return lastFailure ?? new MissingAgent(specification);
|
|
26511
26577
|
}
|
|
26512
26578
|
|
|
26513
26579
|
// src/agent-catalog/discover-local-agents.ts
|
|
@@ -26518,11 +26584,7 @@ async function discoverLocalAgentInventory(options) {
|
|
|
26518
26584
|
async (specification) => await discoverAgent(specification, options)
|
|
26519
26585
|
)
|
|
26520
26586
|
);
|
|
26521
|
-
return new LocalAgentInventory(
|
|
26522
|
-
discoveries,
|
|
26523
|
-
options.platform,
|
|
26524
|
-
options.architecture
|
|
26525
|
-
);
|
|
26587
|
+
return new LocalAgentInventory(discoveries);
|
|
26526
26588
|
}
|
|
26527
26589
|
|
|
26528
26590
|
// src/pairing/pair-local-machine.ts
|
|
@@ -26550,7 +26612,7 @@ var PairingClientError = class extends Error {
|
|
|
26550
26612
|
this.name = "PairingClientError";
|
|
26551
26613
|
}
|
|
26552
26614
|
};
|
|
26553
|
-
function
|
|
26615
|
+
function isRecord7(value) {
|
|
26554
26616
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26555
26617
|
}
|
|
26556
26618
|
function hasExactKeys(value, expectedKeys) {
|
|
@@ -26703,9 +26765,9 @@ async function readJsonResponse(response) {
|
|
|
26703
26765
|
}
|
|
26704
26766
|
}
|
|
26705
26767
|
function readRelayError(value) {
|
|
26706
|
-
if (
|
|
26768
|
+
if (isRecord7(value)) {
|
|
26707
26769
|
const error61 = value["error"];
|
|
26708
|
-
if (
|
|
26770
|
+
if (isRecord7(error61)) {
|
|
26709
26771
|
const code = error61["code"];
|
|
26710
26772
|
const message = error61["message"];
|
|
26711
26773
|
if (typeof code === "string" && typeof message === "string") {
|
|
@@ -26719,7 +26781,7 @@ function readRelayError(value) {
|
|
|
26719
26781
|
);
|
|
26720
26782
|
}
|
|
26721
26783
|
function decodeClaimResponse(value) {
|
|
26722
|
-
if (!
|
|
26784
|
+
if (!isRecord7(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
|
|
26723
26785
|
throw new PairingClientError(
|
|
26724
26786
|
"invalid_relay_response",
|
|
26725
26787
|
"The relay returned an invalid pairing response"
|
|
@@ -26738,6 +26800,8 @@ function decodeClaimResponse(value) {
|
|
|
26738
26800
|
}
|
|
26739
26801
|
async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
|
|
26740
26802
|
const agents = localAgents.map((agent) => ({
|
|
26803
|
+
agentPath: agent.agentIdentity.requestedPath,
|
|
26804
|
+
agentVersion: agent.agentVersion,
|
|
26741
26805
|
id: agent.id,
|
|
26742
26806
|
label: agent.label
|
|
26743
26807
|
}));
|
|
@@ -26747,10 +26811,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
26747
26811
|
response = await fetch2(endpoint, {
|
|
26748
26812
|
body: JSON.stringify({
|
|
26749
26813
|
agents,
|
|
26750
|
-
installableAgents
|
|
26751
|
-
id: agent.id,
|
|
26752
|
-
label: agent.label
|
|
26753
|
-
})),
|
|
26814
|
+
installableAgents,
|
|
26754
26815
|
machineName: hostname3(),
|
|
26755
26816
|
pairingCode: options.code,
|
|
26756
26817
|
workspaceName: basename(defaultWorkspace) || "Local workspace"
|
|
@@ -26803,7 +26864,7 @@ async function persistConnection(channelId, relayOrigin, daemonToken, defaultWor
|
|
|
26803
26864
|
return connectionPath;
|
|
26804
26865
|
}
|
|
26805
26866
|
function decodeSavedConnection(value, expectedChannelId) {
|
|
26806
|
-
if (!
|
|
26867
|
+
if (!isRecord7(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
|
|
26807
26868
|
throw new PairingClientError(
|
|
26808
26869
|
"invalid_connection",
|
|
26809
26870
|
"The saved connection is invalid"
|
|
@@ -26833,7 +26894,7 @@ async function readSavedConnection(channelId) {
|
|
|
26833
26894
|
`${channelId}.json`
|
|
26834
26895
|
);
|
|
26835
26896
|
let encoded = "";
|
|
26836
|
-
const handle = await
|
|
26897
|
+
const handle = await open4(connectionPath, "r");
|
|
26837
26898
|
try {
|
|
26838
26899
|
const metadata = await handle.stat();
|
|
26839
26900
|
if (!metadata.isFile() || metadata.size > MAX_CONNECTION_FILE_LENGTH) {
|
|
@@ -26870,7 +26931,7 @@ function assertInventoryUsable(inventory) {
|
|
|
26870
26931
|
if (inventory.available.length + inventory.installable.length === 0) {
|
|
26871
26932
|
throw new PairingClientError(
|
|
26872
26933
|
"no_supported_agent",
|
|
26873
|
-
"No supported Agent is
|
|
26934
|
+
"No supported Agent is available for local discovery"
|
|
26874
26935
|
);
|
|
26875
26936
|
}
|
|
26876
26937
|
}
|
|
@@ -26958,7 +27019,7 @@ async function resumeLocalMachine(arguments_, signal = new AbortController().sig
|
|
|
26958
27019
|
// src/run-daemon.ts
|
|
26959
27020
|
import { basename as basename3 } from "node:path";
|
|
26960
27021
|
import { styleText } from "node:util";
|
|
26961
|
-
import { WebSocket as WebSocket2 } from "undici";
|
|
27022
|
+
import { fetch as fetch4, WebSocket as WebSocket2 } from "undici";
|
|
26962
27023
|
|
|
26963
27024
|
// src/agent-catalog/publish-agent-catalog.ts
|
|
26964
27025
|
import { fetch as fetch3 } from "undici";
|
|
@@ -26991,13 +27052,12 @@ async function publishAgentCatalog(config2, signal) {
|
|
|
26991
27052
|
response = await fetch3(catalogEndpoint(config2.relayUrl), {
|
|
26992
27053
|
body: JSON.stringify({
|
|
26993
27054
|
agents: catalog.agents.map((agent) => ({
|
|
27055
|
+
agentPath: agent.agentIdentity.requestedPath,
|
|
27056
|
+
agentVersion: agent.agentVersion,
|
|
26994
27057
|
id: agent.id,
|
|
26995
27058
|
label: agent.label
|
|
26996
27059
|
})),
|
|
26997
|
-
installableAgents: catalog.installableAgents
|
|
26998
|
-
id: agent.id,
|
|
26999
|
-
label: agent.label
|
|
27000
|
-
}))
|
|
27060
|
+
installableAgents: catalog.installableAgents
|
|
27001
27061
|
}),
|
|
27002
27062
|
dispatcher: environmentProxyDispatcher,
|
|
27003
27063
|
headers: { "content-type": "application/json" },
|
|
@@ -27093,7 +27153,7 @@ var InstallationJob = class {
|
|
|
27093
27153
|
};
|
|
27094
27154
|
function authorizedSpecificationFor(specifications, agentId) {
|
|
27095
27155
|
for (const specification of specifications) {
|
|
27096
|
-
if (specification.id === agentId
|
|
27156
|
+
if (specification.id === agentId) {
|
|
27097
27157
|
return specification;
|
|
27098
27158
|
}
|
|
27099
27159
|
}
|
|
@@ -27105,7 +27165,7 @@ function executionFailure(error61) {
|
|
|
27105
27165
|
}
|
|
27106
27166
|
return new InstallationManagerError(
|
|
27107
27167
|
"installation_failed",
|
|
27108
|
-
"The local Agent installation failed",
|
|
27168
|
+
"The local Agent integration installation failed",
|
|
27109
27169
|
{ cause: error61 }
|
|
27110
27170
|
);
|
|
27111
27171
|
}
|
|
@@ -27176,7 +27236,7 @@ var AgentInstallationManager = class {
|
|
|
27176
27236
|
command.requestId,
|
|
27177
27237
|
command.agentId,
|
|
27178
27238
|
"installation_in_progress",
|
|
27179
|
-
"An installation for this Agent is already running"
|
|
27239
|
+
"An integration installation for this Agent is already running"
|
|
27180
27240
|
);
|
|
27181
27241
|
const job2 = new InstallationJob(command.requestId, command.agentId);
|
|
27182
27242
|
job2.state = busy;
|
|
@@ -27213,7 +27273,7 @@ var AgentInstallationManager = class {
|
|
|
27213
27273
|
job.requestId,
|
|
27214
27274
|
job.agentId
|
|
27215
27275
|
);
|
|
27216
|
-
job.controller.abort(new Error("Agent installation cancelled"));
|
|
27276
|
+
job.controller.abort(new Error("Agent integration installation cancelled"));
|
|
27217
27277
|
return await job.completion.promise;
|
|
27218
27278
|
};
|
|
27219
27279
|
close = async () => {
|
|
@@ -27223,7 +27283,7 @@ var AgentInstallationManager = class {
|
|
|
27223
27283
|
if (job === void 0) {
|
|
27224
27284
|
throw new InstallationManagerError(
|
|
27225
27285
|
"installation_state_invalid",
|
|
27226
|
-
"An active Agent installation is unavailable"
|
|
27286
|
+
"An active Agent integration installation is unavailable"
|
|
27227
27287
|
);
|
|
27228
27288
|
}
|
|
27229
27289
|
job.controller.abort(new Error("Mobius daemon stopped"));
|
|
@@ -27245,7 +27305,7 @@ var AgentInstallationManager = class {
|
|
|
27245
27305
|
job.controller.abort(
|
|
27246
27306
|
new InstallationManagerError(
|
|
27247
27307
|
"installation_timeout",
|
|
27248
|
-
"The local Agent installation exceeded its deadline"
|
|
27308
|
+
"The local Agent integration installation exceeded its deadline"
|
|
27249
27309
|
)
|
|
27250
27310
|
);
|
|
27251
27311
|
}, INSTALLATION_DEADLINE_MILLISECONDS);
|
|
@@ -27257,898 +27317,87 @@ var AgentInstallationManager = class {
|
|
|
27257
27317
|
job.requestId,
|
|
27258
27318
|
specification.id
|
|
27259
27319
|
);
|
|
27260
|
-
await this.#executor.execute(
|
|
27261
|
-
specification.id,
|
|
27262
|
-
job.requestId,
|
|
27263
|
-
async (stage) => {
|
|
27264
|
-
signal.throwIfAborted();
|
|
27265
|
-
await this.#transition(
|
|
27266
|
-
job,
|
|
27267
|
-
new RunningInstallation(job.requestId, job.agentId, stage)
|
|
27268
|
-
);
|
|
27269
|
-
this.#audit.record(
|
|
27270
|
-
`agent_installation_${stage}`,
|
|
27271
|
-
job.requestId,
|
|
27272
|
-
job.agentId
|
|
27273
|
-
);
|
|
27274
|
-
},
|
|
27275
|
-
signal
|
|
27276
|
-
);
|
|
27277
|
-
signal.throwIfAborted();
|
|
27278
|
-
const succeeded = new SucceededInstallation(job.requestId, job.agentId);
|
|
27279
|
-
await this.#transition(job, succeeded);
|
|
27280
|
-
this.#audit.record(
|
|
27281
|
-
"agent_installation_completed",
|
|
27282
|
-
job.requestId,
|
|
27283
|
-
job.agentId
|
|
27284
|
-
);
|
|
27285
|
-
job.completion.resolve(succeeded);
|
|
27286
|
-
} catch (error61) {
|
|
27287
|
-
if (signal.aborted) {
|
|
27288
|
-
if (signal.reason instanceof InstallationManagerError && signal.reason.code === "installation_timeout") {
|
|
27289
|
-
const timedOut = new FailedInstallation(
|
|
27290
|
-
job.requestId,
|
|
27291
|
-
job.agentId,
|
|
27292
|
-
signal.reason.code,
|
|
27293
|
-
signal.reason.message
|
|
27294
|
-
);
|
|
27295
|
-
await this.#transition(job, timedOut);
|
|
27296
|
-
this.#audit.record(
|
|
27297
|
-
"agent_installation_failed_installation_timeout",
|
|
27298
|
-
job.requestId,
|
|
27299
|
-
job.agentId
|
|
27300
|
-
);
|
|
27301
|
-
job.completion.resolve(timedOut);
|
|
27302
|
-
return;
|
|
27303
|
-
}
|
|
27304
|
-
const cancelled = new CancelledInstallation(job.requestId, job.agentId);
|
|
27305
|
-
await this.#transition(job, cancelled);
|
|
27306
|
-
this.#audit.record(
|
|
27307
|
-
"agent_installation_cancelled",
|
|
27308
|
-
job.requestId,
|
|
27309
|
-
job.agentId
|
|
27310
|
-
);
|
|
27311
|
-
job.completion.resolve(cancelled);
|
|
27312
|
-
} else {
|
|
27313
|
-
const failure = executionFailure(error61);
|
|
27314
|
-
const failed = new FailedInstallation(
|
|
27315
|
-
job.requestId,
|
|
27316
|
-
job.agentId,
|
|
27317
|
-
failure.code,
|
|
27318
|
-
failure.message
|
|
27319
|
-
);
|
|
27320
|
-
await this.#transition(job, failed);
|
|
27321
|
-
this.#audit.record(
|
|
27322
|
-
`agent_installation_failed_${failure.code}`,
|
|
27323
|
-
job.requestId,
|
|
27324
|
-
job.agentId
|
|
27325
|
-
);
|
|
27326
|
-
job.completion.resolve(failed);
|
|
27327
|
-
}
|
|
27328
|
-
} finally {
|
|
27329
|
-
clearTimeout(deadline);
|
|
27330
|
-
externalSignal.removeEventListener("abort", abort);
|
|
27331
|
-
if (this.#activeAgents.get(job.agentId) === job.requestId) {
|
|
27332
|
-
this.#activeAgents.delete(job.agentId);
|
|
27333
|
-
}
|
|
27334
|
-
}
|
|
27335
|
-
};
|
|
27336
|
-
};
|
|
27337
|
-
|
|
27338
|
-
// src/agent-installation/automatic-adapter-provisioner.ts
|
|
27339
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
27340
|
-
var AUTOMATIC_ADAPTER_FAILURE_CODES = /* @__PURE__ */ new Set([
|
|
27341
|
-
"adapter_not_found",
|
|
27342
|
-
"adapter_probe_failed",
|
|
27343
|
-
"adapter_probe_timeout",
|
|
27344
|
-
"acp_incompatible"
|
|
27345
|
-
]);
|
|
27346
|
-
var InstalledAutomaticAdapter = class {
|
|
27347
|
-
executable;
|
|
27348
|
-
requestId;
|
|
27349
|
-
specification;
|
|
27350
|
-
constructor(specification, requestId, executable) {
|
|
27351
|
-
this.executable = executable;
|
|
27352
|
-
this.requestId = requestId;
|
|
27353
|
-
this.specification = specification;
|
|
27354
|
-
}
|
|
27355
|
-
};
|
|
27356
|
-
function shouldProvisionAdapter(unavailable, options) {
|
|
27357
|
-
return unavailable.specification instanceof BridgedAcpAgentDefinition && AUTOMATIC_ADAPTER_FAILURE_CODES.has(unavailable.code) && options.environment[unavailable.specification.adapterOverrideVariable] === void 0 && unavailable.specification.supportsInstallation(
|
|
27358
|
-
options.platform ?? process.platform,
|
|
27359
|
-
options.architecture ?? process.arch
|
|
27360
|
-
);
|
|
27361
|
-
}
|
|
27362
|
-
function stableFailureCode(error61) {
|
|
27363
|
-
return error61 instanceof ManagedAdapterInstallError ? error61.code : "adapter_install_failed";
|
|
27364
|
-
}
|
|
27365
|
-
function discoveryOptions(options, environment, signal, specifications) {
|
|
27366
|
-
return {
|
|
27367
|
-
...options.architecture === void 0 ? {} : { architecture: options.architecture },
|
|
27368
|
-
defaultWorkspace: options.defaultWorkspace,
|
|
27369
|
-
environment,
|
|
27370
|
-
...options.platform === void 0 ? {} : { platform: options.platform },
|
|
27371
|
-
signal,
|
|
27372
|
-
specifications
|
|
27373
|
-
};
|
|
27374
|
-
}
|
|
27375
|
-
var AutomaticAdapterProvisioner = class {
|
|
27376
|
-
#adapterInstaller;
|
|
27377
|
-
#options;
|
|
27378
|
-
#specifications;
|
|
27379
|
-
constructor(options, adapterInstaller, specifications = supportedLocalAgentSpecifications()) {
|
|
27380
|
-
this.#adapterInstaller = adapterInstaller;
|
|
27381
|
-
this.#options = options;
|
|
27382
|
-
this.#specifications = Object.freeze([...specifications]);
|
|
27383
|
-
}
|
|
27384
|
-
prepare = async (signal) => {
|
|
27385
|
-
signal.throwIfAborted();
|
|
27386
|
-
let inventory = await discoverLocalAgentInventory(
|
|
27387
|
-
discoveryOptions(
|
|
27388
|
-
this.#options,
|
|
27389
|
-
this.#options.environment,
|
|
27390
|
-
signal,
|
|
27391
|
-
this.#specifications
|
|
27392
|
-
)
|
|
27393
|
-
);
|
|
27394
|
-
const candidates = inventory.unavailable.filter(
|
|
27395
|
-
(unavailable) => shouldProvisionAdapter(unavailable, this.#options)
|
|
27396
|
-
);
|
|
27397
|
-
const attempts = [];
|
|
27398
|
-
for (const unavailable of candidates) {
|
|
27399
|
-
signal.throwIfAborted();
|
|
27400
|
-
const specification = unavailable.specification;
|
|
27401
|
-
if (!(specification instanceof BridgedAcpAgentDefinition)) {
|
|
27402
|
-
attempts.push(null);
|
|
27403
|
-
continue;
|
|
27404
|
-
}
|
|
27405
|
-
const verifiedAgent = await findVerifiedAgentExecutable(
|
|
27406
|
-
specification,
|
|
27407
|
-
discoveryOptions(
|
|
27408
|
-
this.#options,
|
|
27409
|
-
this.#options.environment,
|
|
27410
|
-
signal,
|
|
27411
|
-
this.#specifications
|
|
27412
|
-
)
|
|
27413
|
-
);
|
|
27414
|
-
if (verifiedAgent === null) {
|
|
27415
|
-
attempts.push(null);
|
|
27416
|
-
continue;
|
|
27417
|
-
}
|
|
27418
|
-
const requestId = `automatic-adapter-${randomUUID2()}`;
|
|
27419
|
-
this.#options.audit.record(
|
|
27420
|
-
"agent_adapter_auto_install_started",
|
|
27421
|
-
requestId,
|
|
27422
|
-
specification.id,
|
|
27423
|
-
{
|
|
27424
|
-
agentVersion: verifiedAgent.version,
|
|
27425
|
-
adapterVersion: specification.adapterVersion
|
|
27426
|
-
}
|
|
27427
|
-
);
|
|
27428
|
-
process.stdout.write(
|
|
27429
|
-
`Installing the pinned ACP adapter for ${specification.label}.
|
|
27430
|
-
`
|
|
27431
|
-
);
|
|
27432
|
-
try {
|
|
27433
|
-
const executable = await this.#adapterInstaller.install(
|
|
27434
|
-
specification,
|
|
27435
|
-
signal
|
|
27436
|
-
);
|
|
27437
|
-
this.#options.audit.record(
|
|
27438
|
-
"agent_adapter_auto_install_completed",
|
|
27439
|
-
requestId,
|
|
27440
|
-
specification.id,
|
|
27441
|
-
{ adapterVersion: specification.adapterVersion }
|
|
27442
|
-
);
|
|
27443
|
-
attempts.push(
|
|
27444
|
-
new InstalledAutomaticAdapter(specification, requestId, executable)
|
|
27445
|
-
);
|
|
27446
|
-
} catch (error61) {
|
|
27447
|
-
if (signal.aborted) {
|
|
27448
|
-
this.#options.audit.record(
|
|
27449
|
-
"agent_adapter_auto_install_cancelled",
|
|
27450
|
-
requestId,
|
|
27451
|
-
specification.id
|
|
27452
|
-
);
|
|
27453
|
-
signal.throwIfAborted();
|
|
27454
|
-
}
|
|
27455
|
-
this.#options.audit.record(
|
|
27456
|
-
"agent_adapter_auto_install_failed",
|
|
27457
|
-
requestId,
|
|
27458
|
-
specification.id,
|
|
27459
|
-
{ code: stableFailureCode(error61) }
|
|
27460
|
-
);
|
|
27461
|
-
process.stderr.write(
|
|
27462
|
-
`The pinned ACP adapter for ${specification.label} could not be installed automatically; the daemon will continue.
|
|
27463
|
-
`
|
|
27464
|
-
);
|
|
27465
|
-
attempts.push(null);
|
|
27466
|
-
}
|
|
27467
|
-
}
|
|
27468
|
-
signal.throwIfAborted();
|
|
27469
|
-
const installed = attempts.filter(
|
|
27470
|
-
(attempt) => attempt !== null
|
|
27471
|
-
);
|
|
27472
|
-
if (installed.length > 0) {
|
|
27473
|
-
const verificationEnvironment = {
|
|
27474
|
-
...this.#options.environment
|
|
27475
|
-
};
|
|
27476
|
-
for (const attempt of installed) {
|
|
27477
|
-
verificationEnvironment[attempt.specification.adapterOverrideVariable] = attempt.executable.path;
|
|
27478
|
-
}
|
|
27479
|
-
inventory = await discoverLocalAgentInventory(
|
|
27480
|
-
discoveryOptions(
|
|
27481
|
-
this.#options,
|
|
27482
|
-
verificationEnvironment,
|
|
27483
|
-
signal,
|
|
27484
|
-
this.#specifications
|
|
27485
|
-
)
|
|
27486
|
-
);
|
|
27487
|
-
}
|
|
27488
|
-
this.#options.catalog.transition(
|
|
27489
|
-
inventory.readyAgents(),
|
|
27490
|
-
inventory.installable
|
|
27491
|
-
);
|
|
27492
|
-
for (const attempt of installed) {
|
|
27493
|
-
const available = inventory.available.find(
|
|
27494
|
-
(candidate) => candidate instanceof AvailableAgent && candidate.specification.id === attempt.specification.id
|
|
27495
|
-
);
|
|
27496
|
-
if (available === void 0) {
|
|
27497
|
-
const unavailable = inventory.unavailable.find(
|
|
27498
|
-
(candidate) => candidate.specification.id === attempt.specification.id
|
|
27499
|
-
);
|
|
27500
|
-
this.#options.audit.record(
|
|
27501
|
-
"agent_adapter_auto_install_verification_failed",
|
|
27502
|
-
attempt.requestId,
|
|
27503
|
-
attempt.specification.id,
|
|
27504
|
-
{ code: unavailable?.code ?? "agent_verification_failed" }
|
|
27505
|
-
);
|
|
27506
|
-
continue;
|
|
27507
|
-
}
|
|
27508
|
-
this.#options.audit.record(
|
|
27509
|
-
"agent_adapter_auto_install_verified",
|
|
27510
|
-
attempt.requestId,
|
|
27511
|
-
attempt.specification.id,
|
|
27512
|
-
{
|
|
27513
|
-
adapterVersion: available.agent.adapterVersion,
|
|
27514
|
-
agentVersion: available.agent.agentVersion
|
|
27515
|
-
}
|
|
27516
|
-
);
|
|
27517
|
-
process.stdout.write(
|
|
27518
|
-
`${attempt.specification.label} ACP integration is ready.
|
|
27519
|
-
`
|
|
27520
|
-
);
|
|
27521
|
-
}
|
|
27522
|
-
return inventory;
|
|
27523
|
-
};
|
|
27524
|
-
};
|
|
27525
|
-
|
|
27526
|
-
// src/agent-installation/fixed-installation-executor.ts
|
|
27527
|
-
import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
27528
|
-
import { resolve as resolve4 } from "node:path";
|
|
27529
|
-
|
|
27530
|
-
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
27531
|
-
import { mkdir as mkdir5, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
|
|
27532
|
-
import { join as join17 } from "node:path";
|
|
27533
|
-
|
|
27534
|
-
// src/agent-installation/fixed-agent-install-recipe.ts
|
|
27535
|
-
var FixedAgentInstallRecipe = class {
|
|
27536
|
-
assertSupportedPlatform = () => {
|
|
27537
|
-
if (process.platform !== "darwin" && process.platform !== "linux" || process.arch !== "arm64" && process.arch !== "x64") {
|
|
27538
|
-
throw new InstallationManagerError(
|
|
27539
|
-
"unsupported_install_platform",
|
|
27540
|
-
"This Agent installation recipe does not support the local platform"
|
|
27541
|
-
);
|
|
27542
|
-
}
|
|
27543
|
-
};
|
|
27544
|
-
requireInstalledExecutable = async (path2) => {
|
|
27545
|
-
const executable = await resolveExecutablePath(path2);
|
|
27546
|
-
if (executable === null) {
|
|
27547
|
-
throw new InstallationManagerError(
|
|
27548
|
-
"agent_verification_failed",
|
|
27549
|
-
"The Agent installer did not produce a valid executable"
|
|
27550
|
-
);
|
|
27551
|
-
}
|
|
27552
|
-
return executable;
|
|
27553
|
-
};
|
|
27554
|
-
};
|
|
27555
|
-
|
|
27556
|
-
// src/agent-installation/grok-build-install-recipe.ts
|
|
27557
|
-
import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
|
|
27558
|
-
import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute7, join as join15, relative as relative4, sep as sep4 } from "node:path";
|
|
27559
|
-
var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
|
|
27560
|
-
function isContainedPath4(root, candidate) {
|
|
27561
|
-
const difference = relative4(root, candidate);
|
|
27562
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute7(difference);
|
|
27563
|
-
}
|
|
27564
|
-
async function resolveLifecycleScript(packageRoot) {
|
|
27565
|
-
try {
|
|
27566
|
-
const canonicalPackageRoot = await realpath7(packageRoot);
|
|
27567
|
-
const script = await realpath7(
|
|
27568
|
-
join15(canonicalPackageRoot, "bin", "postinstall.js")
|
|
27569
|
-
);
|
|
27570
|
-
const metadata = await stat6(script);
|
|
27571
|
-
if (!metadata.isFile() || !isContainedPath4(canonicalPackageRoot, script)) {
|
|
27572
|
-
throw new Error("Invalid Grok Build lifecycle script");
|
|
27573
|
-
}
|
|
27574
|
-
return script;
|
|
27575
|
-
} catch (error61) {
|
|
27576
|
-
throw new InstallationManagerError(
|
|
27577
|
-
"agent_verification_failed",
|
|
27578
|
-
"The managed Grok Build lifecycle script is invalid",
|
|
27579
|
-
{ cause: error61 }
|
|
27580
|
-
);
|
|
27581
|
-
}
|
|
27582
|
-
}
|
|
27583
|
-
var GrokBuildInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27584
|
-
#npmInstaller;
|
|
27585
|
-
id = "grok-build";
|
|
27586
|
-
label = "Grok Build";
|
|
27587
|
-
releaseChannel = GROK_BUILD_MANAGED_VERSION;
|
|
27588
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27589
|
-
super();
|
|
27590
|
-
this.#npmInstaller = npmInstaller;
|
|
27591
|
-
}
|
|
27592
|
-
install = async (options) => {
|
|
27593
|
-
this.assertSupportedPlatform();
|
|
27594
|
-
const definition = grokBuildManagedPackage(process.platform, process.arch);
|
|
27595
|
-
const versionRoot = join15(
|
|
27596
|
-
options.stateDirectory,
|
|
27597
|
-
"agents",
|
|
27598
|
-
this.id,
|
|
27599
|
-
GROK_BUILD_MANAGED_VERSION
|
|
27600
|
-
);
|
|
27601
|
-
const packageRoot = join15(versionRoot, "package");
|
|
27602
|
-
const managedHome = join15(versionRoot, "home");
|
|
27603
|
-
try {
|
|
27604
|
-
await mkdir4(managedHome, { mode: 448, recursive: true });
|
|
27605
|
-
const canonicalHome = await realpath7(managedHome);
|
|
27606
|
-
await options.report("downloading");
|
|
27607
|
-
await options.report("verifying");
|
|
27608
|
-
await options.report("installing_agent");
|
|
27609
|
-
await this.#npmInstaller.install(
|
|
27610
|
-
packageRoot,
|
|
27611
|
-
definition,
|
|
27612
|
-
options.environment,
|
|
27613
|
-
options.signal
|
|
27614
|
-
);
|
|
27615
|
-
options.audit.record(
|
|
27616
|
-
"agent_npm_package_verified",
|
|
27617
|
-
options.requestId,
|
|
27618
|
-
this.id,
|
|
27619
|
-
{
|
|
27620
|
-
integrity: definition.integrity,
|
|
27621
|
-
package: definition.packageName,
|
|
27622
|
-
version: definition.version
|
|
27623
|
-
}
|
|
27624
|
-
);
|
|
27625
|
-
const script = await resolveLifecycleScript(
|
|
27626
|
-
join15(packageRoot, "node_modules", "@xai-official", "grok")
|
|
27627
|
-
);
|
|
27628
|
-
await runBoundedProcess({
|
|
27629
|
-
arguments: [script],
|
|
27630
|
-
command: process.execPath,
|
|
27631
|
-
cwd: dirname5(script),
|
|
27632
|
-
environment: {
|
|
27633
|
-
GROK_HOME: canonicalHome,
|
|
27634
|
-
GROK_INSTALL_COMPLETIONS: "0",
|
|
27635
|
-
GROK_NPM_REGISTRY: "https://registry.npmjs.org/",
|
|
27636
|
-
HOME: canonicalHome,
|
|
27637
|
-
PATH: `${dirname5(process.execPath)}${delimiter2}/usr/bin${delimiter2}/bin`
|
|
27638
|
-
},
|
|
27639
|
-
outputLimitBytes: 64 * 1024,
|
|
27640
|
-
signal: options.signal,
|
|
27641
|
-
timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS2
|
|
27642
|
-
});
|
|
27643
|
-
options.audit.record(
|
|
27644
|
-
"agent_lifecycle_step_completed",
|
|
27645
|
-
options.requestId,
|
|
27646
|
-
this.id,
|
|
27647
|
-
{
|
|
27648
|
-
lifecycle: "postinstall",
|
|
27649
|
-
package: definition.packageName,
|
|
27650
|
-
version: definition.version
|
|
27651
|
-
}
|
|
27652
|
-
);
|
|
27653
|
-
return await this.requireInstalledExecutable(
|
|
27654
|
-
join15(canonicalHome, "bin", "grok")
|
|
27655
|
-
);
|
|
27656
|
-
} catch (error61) {
|
|
27657
|
-
if (options.signal.aborted) {
|
|
27658
|
-
options.signal.throwIfAborted();
|
|
27659
|
-
}
|
|
27660
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
27661
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
27662
|
-
throw new InstallationManagerError(
|
|
27663
|
-
"agent_verification_failed",
|
|
27664
|
-
"The managed Grok Build packages did not match their pinned artifacts",
|
|
27665
|
-
{ cause: error61 }
|
|
27666
|
-
);
|
|
27667
|
-
}
|
|
27668
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
27669
|
-
throw new InstallationManagerError(
|
|
27670
|
-
"agent_publish_failed",
|
|
27671
|
-
"The managed Grok Build package could not be published",
|
|
27672
|
-
{ cause: error61 }
|
|
27673
|
-
);
|
|
27674
|
-
}
|
|
27675
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
27676
|
-
cause: error61
|
|
27677
|
-
});
|
|
27678
|
-
}
|
|
27679
|
-
if (error61 instanceof InstallationManagerError) {
|
|
27680
|
-
throw error61;
|
|
27681
|
-
}
|
|
27682
|
-
throw new InstallationManagerError(
|
|
27683
|
-
"agent_install_failed",
|
|
27684
|
-
"The fixed Grok Build installation recipe failed",
|
|
27685
|
-
{ cause: error61 }
|
|
27686
|
-
);
|
|
27687
|
-
}
|
|
27688
|
-
};
|
|
27689
|
-
};
|
|
27690
|
-
|
|
27691
|
-
// src/agent-installation/workbuddy-install-recipe.ts
|
|
27692
|
-
import { join as join16 } from "node:path";
|
|
27693
|
-
var WorkBuddyInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27694
|
-
#npmInstaller;
|
|
27695
|
-
id = "workbuddy";
|
|
27696
|
-
label = "WorkBuddy";
|
|
27697
|
-
releaseChannel = WORKBUDDY_MANAGED_VERSION;
|
|
27698
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27699
|
-
super();
|
|
27700
|
-
this.#npmInstaller = npmInstaller;
|
|
27701
|
-
}
|
|
27702
|
-
install = async (options) => {
|
|
27703
|
-
this.assertSupportedPlatform();
|
|
27704
|
-
try {
|
|
27705
|
-
await options.report("downloading");
|
|
27706
|
-
await options.report("verifying");
|
|
27707
|
-
await options.report("installing_agent");
|
|
27708
|
-
const executable = await this.#npmInstaller.install(
|
|
27709
|
-
join16(
|
|
27710
|
-
options.stateDirectory,
|
|
27711
|
-
"agents",
|
|
27712
|
-
this.id,
|
|
27713
|
-
WORKBUDDY_MANAGED_VERSION
|
|
27714
|
-
),
|
|
27715
|
-
WORKBUDDY_MANAGED_PACKAGE,
|
|
27716
|
-
options.environment,
|
|
27717
|
-
options.signal
|
|
27718
|
-
);
|
|
27719
|
-
options.audit.record(
|
|
27720
|
-
"agent_npm_package_verified",
|
|
27721
|
-
options.requestId,
|
|
27722
|
-
this.id,
|
|
27723
|
-
{
|
|
27724
|
-
integrity: WORKBUDDY_MANAGED_PACKAGE.integrity,
|
|
27725
|
-
package: WORKBUDDY_MANAGED_PACKAGE.packageName,
|
|
27726
|
-
version: WORKBUDDY_MANAGED_PACKAGE.version
|
|
27727
|
-
}
|
|
27728
|
-
);
|
|
27729
|
-
return executable;
|
|
27730
|
-
} catch (error61) {
|
|
27731
|
-
if (options.signal.aborted) {
|
|
27732
|
-
options.signal.throwIfAborted();
|
|
27733
|
-
}
|
|
27734
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
27735
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
27736
|
-
throw new InstallationManagerError(
|
|
27737
|
-
"agent_verification_failed",
|
|
27738
|
-
"The managed WorkBuddy package did not match its pinned artifact",
|
|
27739
|
-
{ cause: error61 }
|
|
27740
|
-
);
|
|
27741
|
-
}
|
|
27742
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
27743
|
-
throw new InstallationManagerError(
|
|
27744
|
-
"agent_publish_failed",
|
|
27745
|
-
"The managed WorkBuddy package could not be published",
|
|
27746
|
-
{ cause: error61 }
|
|
27747
|
-
);
|
|
27748
|
-
}
|
|
27749
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
27750
|
-
cause: error61
|
|
27751
|
-
});
|
|
27752
|
-
}
|
|
27753
|
-
if (error61 instanceof InstallationManagerError) {
|
|
27754
|
-
throw error61;
|
|
27755
|
-
}
|
|
27756
|
-
throw new InstallationManagerError(
|
|
27757
|
-
"agent_install_failed",
|
|
27758
|
-
"The fixed WorkBuddy installation recipe failed",
|
|
27759
|
-
{ cause: error61 }
|
|
27760
|
-
);
|
|
27761
|
-
}
|
|
27762
|
-
};
|
|
27763
|
-
};
|
|
27764
|
-
|
|
27765
|
-
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
27766
|
-
var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
|
|
27767
|
-
var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
|
|
27768
|
-
var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
27769
|
-
var MINIMAL_PATH2 = "/usr/bin:/bin";
|
|
27770
|
-
var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27771
|
-
id = "codex";
|
|
27772
|
-
label = "Codex";
|
|
27773
|
-
releaseChannel = "latest";
|
|
27774
|
-
install = async (options) => {
|
|
27775
|
-
this.assertSupportedPlatform();
|
|
27776
|
-
const root = join17(options.stateDirectory, "agents", this.id);
|
|
27777
|
-
const temporaryRoot = join17(options.stateDirectory, "temporary");
|
|
27778
|
-
await Promise.all([
|
|
27779
|
-
mkdir5(root, { mode: 448, recursive: true }),
|
|
27780
|
-
mkdir5(temporaryRoot, { mode: 448, recursive: true })
|
|
27781
|
-
]);
|
|
27782
|
-
const temporaryDirectory = await mkdtemp3(
|
|
27783
|
-
join17(temporaryRoot, ".codex-install-")
|
|
27784
|
-
);
|
|
27785
|
-
const installerPath = join17(temporaryDirectory, "install.sh");
|
|
27786
|
-
const installDirectory = join17(root, "bin");
|
|
27787
|
-
const codexHome = join17(root, "home");
|
|
27788
|
-
try {
|
|
27789
|
-
await Promise.all([
|
|
27790
|
-
mkdir5(installDirectory, { mode: 448, recursive: true }),
|
|
27791
|
-
mkdir5(codexHome, { mode: 448, recursive: true })
|
|
27792
|
-
]);
|
|
27793
|
-
await options.report("downloading");
|
|
27794
|
-
const download = await downloadVerifiedFile({
|
|
27795
|
-
allowedHosts: /* @__PURE__ */ new Set(["chatgpt.com", "releases.openai.com"]),
|
|
27796
|
-
destination: installerPath,
|
|
27797
|
-
maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
|
|
27798
|
-
signal: options.signal,
|
|
27799
|
-
timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
|
|
27800
|
-
url: new URL("https://chatgpt.com/codex/install.sh")
|
|
27801
|
-
});
|
|
27802
|
-
options.audit.record(
|
|
27803
|
-
"agent_installer_download_verified",
|
|
27804
|
-
options.requestId,
|
|
27805
|
-
this.id,
|
|
27806
|
-
{
|
|
27807
|
-
bytes: download.bytes.toString(),
|
|
27808
|
-
releaseChannel: this.releaseChannel,
|
|
27809
|
-
sha256: download.sha256
|
|
27810
|
-
}
|
|
27811
|
-
);
|
|
27812
|
-
await options.report("verifying");
|
|
27813
|
-
await options.report("installing_agent");
|
|
27814
|
-
await runBoundedProcess({
|
|
27815
|
-
arguments: [installerPath],
|
|
27816
|
-
command: "/bin/sh",
|
|
27817
|
-
cwd: temporaryDirectory,
|
|
27818
|
-
environment: {
|
|
27819
|
-
CODEX_HOME: codexHome,
|
|
27820
|
-
CODEX_INSTALL_DIR: installDirectory,
|
|
27821
|
-
CODEX_NON_INTERACTIVE: "1",
|
|
27822
|
-
CODEX_RELEASE: this.releaseChannel,
|
|
27823
|
-
HOME: codexHome,
|
|
27824
|
-
PATH: MINIMAL_PATH2
|
|
27825
|
-
},
|
|
27826
|
-
outputLimitBytes: 64 * 1024,
|
|
27827
|
-
signal: options.signal,
|
|
27828
|
-
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
27829
|
-
});
|
|
27830
|
-
return await this.requireInstalledExecutable(
|
|
27831
|
-
join17(installDirectory, "codex")
|
|
27832
|
-
);
|
|
27833
|
-
} catch (error61) {
|
|
27834
|
-
if (options.signal.aborted) {
|
|
27835
|
-
options.signal.throwIfAborted();
|
|
27836
|
-
}
|
|
27837
|
-
if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
|
|
27838
|
-
throw error61;
|
|
27839
|
-
}
|
|
27840
|
-
throw new InstallationManagerError(
|
|
27841
|
-
"agent_install_failed",
|
|
27842
|
-
"The fixed Codex installation recipe failed"
|
|
27843
|
-
);
|
|
27844
|
-
} finally {
|
|
27845
|
-
await rm3(temporaryDirectory, { force: true, recursive: true });
|
|
27846
|
-
}
|
|
27847
|
-
};
|
|
27848
|
-
};
|
|
27849
|
-
var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27850
|
-
id = "claude";
|
|
27851
|
-
label = "Claude Code";
|
|
27852
|
-
releaseChannel = "stable";
|
|
27853
|
-
install = async (options) => {
|
|
27854
|
-
this.assertSupportedPlatform();
|
|
27855
|
-
const root = join17(options.stateDirectory, "agents", this.id);
|
|
27856
|
-
const managedHome = join17(root, "home");
|
|
27857
|
-
const temporaryRoot = join17(options.stateDirectory, "temporary");
|
|
27858
|
-
await Promise.all([
|
|
27859
|
-
mkdir5(managedHome, { mode: 448, recursive: true }),
|
|
27860
|
-
mkdir5(temporaryRoot, { mode: 448, recursive: true })
|
|
27861
|
-
]);
|
|
27862
|
-
const temporaryDirectory = await mkdtemp3(
|
|
27863
|
-
join17(temporaryRoot, ".claude-install-")
|
|
27864
|
-
);
|
|
27865
|
-
const installerPath = join17(temporaryDirectory, "install.sh");
|
|
27866
|
-
try {
|
|
27867
|
-
await options.report("downloading");
|
|
27868
|
-
const download = await downloadVerifiedFile({
|
|
27869
|
-
allowedHosts: /* @__PURE__ */ new Set(["claude.ai"]),
|
|
27870
|
-
destination: installerPath,
|
|
27871
|
-
maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
|
|
27872
|
-
signal: options.signal,
|
|
27873
|
-
timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
|
|
27874
|
-
url: new URL("https://claude.ai/install.sh")
|
|
27875
|
-
});
|
|
27876
|
-
options.audit.record(
|
|
27877
|
-
"agent_installer_download_verified",
|
|
27878
|
-
options.requestId,
|
|
27879
|
-
this.id,
|
|
27880
|
-
{
|
|
27881
|
-
bytes: download.bytes.toString(),
|
|
27882
|
-
releaseChannel: this.releaseChannel,
|
|
27883
|
-
sha256: download.sha256
|
|
27884
|
-
}
|
|
27885
|
-
);
|
|
27886
|
-
await options.report("verifying");
|
|
27887
|
-
await options.report("installing_agent");
|
|
27888
|
-
await runBoundedProcess({
|
|
27889
|
-
arguments: [installerPath, "stable"],
|
|
27890
|
-
command: "/bin/bash",
|
|
27891
|
-
cwd: temporaryDirectory,
|
|
27892
|
-
environment: {
|
|
27893
|
-
HOME: managedHome,
|
|
27894
|
-
PATH: MINIMAL_PATH2,
|
|
27895
|
-
SHELL: "/bin/bash"
|
|
27896
|
-
},
|
|
27897
|
-
outputLimitBytes: 64 * 1024,
|
|
27898
|
-
signal: options.signal,
|
|
27899
|
-
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
27900
|
-
});
|
|
27901
|
-
return await this.requireInstalledExecutable(
|
|
27902
|
-
join17(managedHome, ".local", "bin", "claude")
|
|
27903
|
-
);
|
|
27904
|
-
} catch (error61) {
|
|
27905
|
-
if (options.signal.aborted) {
|
|
27906
|
-
options.signal.throwIfAborted();
|
|
27907
|
-
}
|
|
27908
|
-
if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
|
|
27909
|
-
throw error61;
|
|
27910
|
-
}
|
|
27911
|
-
throw new InstallationManagerError(
|
|
27912
|
-
"agent_install_failed",
|
|
27913
|
-
"The fixed Claude Code installation recipe failed"
|
|
27914
|
-
);
|
|
27915
|
-
} finally {
|
|
27916
|
-
await rm3(temporaryDirectory, { force: true, recursive: true });
|
|
27917
|
-
}
|
|
27918
|
-
};
|
|
27919
|
-
};
|
|
27920
|
-
var PiInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27921
|
-
#npmInstaller;
|
|
27922
|
-
id = "pi";
|
|
27923
|
-
label = "Pi";
|
|
27924
|
-
releaseChannel = PI_AGENT_PACKAGE.version;
|
|
27925
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27926
|
-
super();
|
|
27927
|
-
this.#npmInstaller = npmInstaller;
|
|
27928
|
-
}
|
|
27929
|
-
install = async (options) => {
|
|
27930
|
-
this.assertSupportedPlatform();
|
|
27931
|
-
try {
|
|
27932
|
-
await options.report("downloading");
|
|
27933
|
-
await options.report("verifying");
|
|
27934
|
-
await options.report("installing_agent");
|
|
27935
|
-
const executable = await this.#npmInstaller.install(
|
|
27936
|
-
join17(
|
|
27937
|
-
options.stateDirectory,
|
|
27938
|
-
"agents",
|
|
27939
|
-
this.id,
|
|
27940
|
-
PI_AGENT_PACKAGE.version
|
|
27941
|
-
),
|
|
27942
|
-
PI_AGENT_PACKAGE,
|
|
27943
|
-
options.environment,
|
|
27944
|
-
options.signal
|
|
27945
|
-
);
|
|
27946
|
-
options.audit.record(
|
|
27947
|
-
"agent_npm_package_verified",
|
|
27948
|
-
options.requestId,
|
|
27949
|
-
this.id,
|
|
27950
|
-
{
|
|
27951
|
-
integrity: PI_AGENT_PACKAGE.integrity,
|
|
27952
|
-
package: PI_AGENT_PACKAGE.packageName,
|
|
27953
|
-
version: PI_AGENT_PACKAGE.version
|
|
27954
|
-
}
|
|
27955
|
-
);
|
|
27956
|
-
return executable;
|
|
27957
|
-
} catch (error61) {
|
|
27958
|
-
if (options.signal.aborted) {
|
|
27959
|
-
options.signal.throwIfAborted();
|
|
27960
|
-
}
|
|
27961
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
27962
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
27963
|
-
throw new InstallationManagerError(
|
|
27964
|
-
"agent_verification_failed",
|
|
27965
|
-
"The managed Pi package did not match its pinned artifact",
|
|
27966
|
-
{ cause: error61 }
|
|
27967
|
-
);
|
|
27968
|
-
}
|
|
27969
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
27970
|
-
throw new InstallationManagerError(
|
|
27971
|
-
"agent_publish_failed",
|
|
27972
|
-
"The managed Pi package could not be published",
|
|
27973
|
-
{ cause: error61 }
|
|
27974
|
-
);
|
|
27975
|
-
}
|
|
27976
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
27977
|
-
cause: error61
|
|
27978
|
-
});
|
|
27979
|
-
}
|
|
27980
|
-
if (error61 instanceof InstallationManagerError) {
|
|
27981
|
-
throw error61;
|
|
27982
|
-
}
|
|
27983
|
-
throw new InstallationManagerError(
|
|
27984
|
-
"agent_install_failed",
|
|
27985
|
-
"The fixed Pi installation recipe failed",
|
|
27986
|
-
{ cause: error61 }
|
|
27987
|
-
);
|
|
27988
|
-
}
|
|
27989
|
-
};
|
|
27990
|
-
};
|
|
27991
|
-
var DeepSeekHarnessInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27992
|
-
#npmInstaller;
|
|
27993
|
-
id = "deepseek-harness";
|
|
27994
|
-
label = "DeepSeek Harness";
|
|
27995
|
-
releaseChannel = DEEPSEEK_HARNESS_PACKAGE.version;
|
|
27996
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27997
|
-
super();
|
|
27998
|
-
this.#npmInstaller = npmInstaller;
|
|
27999
|
-
}
|
|
28000
|
-
install = async (options) => {
|
|
28001
|
-
this.assertSupportedPlatform();
|
|
28002
|
-
try {
|
|
28003
|
-
const managedHome = join17(
|
|
28004
|
-
options.stateDirectory,
|
|
28005
|
-
"agents",
|
|
28006
|
-
this.id,
|
|
28007
|
-
"home"
|
|
28008
|
-
);
|
|
28009
|
-
await mkdir5(managedHome, { mode: 448, recursive: true });
|
|
28010
|
-
await options.report("downloading");
|
|
28011
|
-
await options.report("verifying");
|
|
28012
|
-
await options.report("installing_agent");
|
|
28013
|
-
const executable = await this.#npmInstaller.install(
|
|
28014
|
-
join17(
|
|
28015
|
-
options.stateDirectory,
|
|
28016
|
-
"agents",
|
|
28017
|
-
this.id,
|
|
28018
|
-
DEEPSEEK_HARNESS_PACKAGE.version
|
|
28019
|
-
),
|
|
28020
|
-
DEEPSEEK_HARNESS_PACKAGE,
|
|
28021
|
-
options.environment,
|
|
28022
|
-
options.signal
|
|
28023
|
-
);
|
|
28024
|
-
options.audit.record(
|
|
28025
|
-
"agent_npm_package_verified",
|
|
28026
|
-
options.requestId,
|
|
28027
|
-
this.id,
|
|
28028
|
-
{
|
|
28029
|
-
integrity: DEEPSEEK_HARNESS_PACKAGE.integrity,
|
|
28030
|
-
package: DEEPSEEK_HARNESS_PACKAGE.packageName,
|
|
28031
|
-
version: DEEPSEEK_HARNESS_PACKAGE.version
|
|
28032
|
-
}
|
|
28033
|
-
);
|
|
28034
|
-
return executable;
|
|
28035
|
-
} catch (error61) {
|
|
28036
|
-
if (options.signal.aborted) {
|
|
28037
|
-
options.signal.throwIfAborted();
|
|
28038
|
-
}
|
|
28039
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
28040
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
28041
|
-
throw new InstallationManagerError(
|
|
28042
|
-
"agent_verification_failed",
|
|
28043
|
-
"The managed DeepSeek Harness package did not match its pinned artifact",
|
|
28044
|
-
{ cause: error61 }
|
|
27320
|
+
await this.#executor.execute(
|
|
27321
|
+
specification.id,
|
|
27322
|
+
job.requestId,
|
|
27323
|
+
async (stage) => {
|
|
27324
|
+
signal.throwIfAborted();
|
|
27325
|
+
await this.#transition(
|
|
27326
|
+
job,
|
|
27327
|
+
new RunningInstallation(job.requestId, job.agentId, stage)
|
|
28045
27328
|
);
|
|
28046
|
-
|
|
28047
|
-
|
|
28048
|
-
|
|
28049
|
-
|
|
28050
|
-
"The managed DeepSeek Harness package could not be published",
|
|
28051
|
-
{ cause: error61 }
|
|
27329
|
+
this.#audit.record(
|
|
27330
|
+
`agent_installation_${stage}`,
|
|
27331
|
+
job.requestId,
|
|
27332
|
+
job.agentId
|
|
28052
27333
|
);
|
|
28053
|
-
}
|
|
28054
|
-
|
|
28055
|
-
cause: error61
|
|
28056
|
-
});
|
|
28057
|
-
}
|
|
28058
|
-
if (error61 instanceof InstallationManagerError) {
|
|
28059
|
-
throw error61;
|
|
28060
|
-
}
|
|
28061
|
-
throw new InstallationManagerError(
|
|
28062
|
-
"agent_install_failed",
|
|
28063
|
-
"The fixed DeepSeek Harness installation recipe failed",
|
|
28064
|
-
{ cause: error61 }
|
|
28065
|
-
);
|
|
28066
|
-
}
|
|
28067
|
-
};
|
|
28068
|
-
};
|
|
28069
|
-
var OpenCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
28070
|
-
#archiveInstaller;
|
|
28071
|
-
id = "opencode";
|
|
28072
|
-
label = "OpenCode";
|
|
28073
|
-
releaseChannel = OPENCODE_MANAGED_VERSION;
|
|
28074
|
-
constructor(archiveInstaller = new ManagedAgentArchiveInstaller()) {
|
|
28075
|
-
super();
|
|
28076
|
-
this.#archiveInstaller = archiveInstaller;
|
|
28077
|
-
}
|
|
28078
|
-
install = async (options) => {
|
|
28079
|
-
this.assertSupportedPlatform();
|
|
28080
|
-
const definition = openCodeManagedArchive(process.platform, process.arch);
|
|
28081
|
-
try {
|
|
28082
|
-
await options.report("downloading");
|
|
28083
|
-
await options.report("verifying");
|
|
28084
|
-
await options.report("installing_agent");
|
|
28085
|
-
const executable = await this.#archiveInstaller.install(
|
|
28086
|
-
join17(
|
|
28087
|
-
options.stateDirectory,
|
|
28088
|
-
"agents",
|
|
28089
|
-
this.id,
|
|
28090
|
-
OPENCODE_MANAGED_VERSION
|
|
28091
|
-
),
|
|
28092
|
-
definition,
|
|
28093
|
-
options.signal
|
|
27334
|
+
},
|
|
27335
|
+
signal
|
|
28094
27336
|
);
|
|
28095
|
-
|
|
28096
|
-
|
|
28097
|
-
|
|
28098
|
-
|
|
28099
|
-
|
|
28100
|
-
|
|
28101
|
-
|
|
28102
|
-
}
|
|
27337
|
+
signal.throwIfAborted();
|
|
27338
|
+
const succeeded = new SucceededInstallation(job.requestId, job.agentId);
|
|
27339
|
+
await this.#transition(job, succeeded);
|
|
27340
|
+
this.#audit.record(
|
|
27341
|
+
"agent_installation_completed",
|
|
27342
|
+
job.requestId,
|
|
27343
|
+
job.agentId
|
|
28103
27344
|
);
|
|
28104
|
-
|
|
27345
|
+
job.completion.resolve(succeeded);
|
|
28105
27346
|
} catch (error61) {
|
|
28106
|
-
if (
|
|
28107
|
-
|
|
28108
|
-
|
|
28109
|
-
|
|
28110
|
-
|
|
28111
|
-
|
|
28112
|
-
|
|
28113
|
-
"The managed OpenCode archive did not match its pinned artifact",
|
|
28114
|
-
{ cause: error61 }
|
|
27347
|
+
if (signal.aborted) {
|
|
27348
|
+
if (signal.reason instanceof InstallationManagerError && signal.reason.code === "installation_timeout") {
|
|
27349
|
+
const timedOut = new FailedInstallation(
|
|
27350
|
+
job.requestId,
|
|
27351
|
+
job.agentId,
|
|
27352
|
+
signal.reason.code,
|
|
27353
|
+
signal.reason.message
|
|
28115
27354
|
);
|
|
28116
|
-
|
|
28117
|
-
|
|
28118
|
-
|
|
28119
|
-
|
|
28120
|
-
|
|
28121
|
-
{ cause: error61 }
|
|
27355
|
+
await this.#transition(job, timedOut);
|
|
27356
|
+
this.#audit.record(
|
|
27357
|
+
"agent_installation_failed_installation_timeout",
|
|
27358
|
+
job.requestId,
|
|
27359
|
+
job.agentId
|
|
28122
27360
|
);
|
|
27361
|
+
job.completion.resolve(timedOut);
|
|
27362
|
+
return;
|
|
28123
27363
|
}
|
|
28124
|
-
|
|
28125
|
-
|
|
28126
|
-
|
|
27364
|
+
const cancelled = new CancelledInstallation(job.requestId, job.agentId);
|
|
27365
|
+
await this.#transition(job, cancelled);
|
|
27366
|
+
this.#audit.record(
|
|
27367
|
+
"agent_installation_cancelled",
|
|
27368
|
+
job.requestId,
|
|
27369
|
+
job.agentId
|
|
27370
|
+
);
|
|
27371
|
+
job.completion.resolve(cancelled);
|
|
27372
|
+
} else {
|
|
27373
|
+
const failure = executionFailure(error61);
|
|
27374
|
+
const failed = new FailedInstallation(
|
|
27375
|
+
job.requestId,
|
|
27376
|
+
job.agentId,
|
|
27377
|
+
failure.code,
|
|
27378
|
+
failure.message
|
|
27379
|
+
);
|
|
27380
|
+
await this.#transition(job, failed);
|
|
27381
|
+
this.#audit.record(
|
|
27382
|
+
`agent_installation_failed_${failure.code}`,
|
|
27383
|
+
job.requestId,
|
|
27384
|
+
job.agentId
|
|
27385
|
+
);
|
|
27386
|
+
job.completion.resolve(failed);
|
|
28127
27387
|
}
|
|
28128
|
-
|
|
28129
|
-
|
|
27388
|
+
} finally {
|
|
27389
|
+
clearTimeout(deadline);
|
|
27390
|
+
externalSignal.removeEventListener("abort", abort);
|
|
27391
|
+
if (this.#activeAgents.get(job.agentId) === job.requestId) {
|
|
27392
|
+
this.#activeAgents.delete(job.agentId);
|
|
28130
27393
|
}
|
|
28131
|
-
throw new InstallationManagerError(
|
|
28132
|
-
"agent_install_failed",
|
|
28133
|
-
"The fixed OpenCode installation recipe failed",
|
|
28134
|
-
{ cause: error61 }
|
|
28135
|
-
);
|
|
28136
27394
|
}
|
|
28137
27395
|
};
|
|
28138
27396
|
};
|
|
28139
|
-
function fixedAgentInstallRecipes() {
|
|
28140
|
-
return Object.freeze([
|
|
28141
|
-
new CodexInstallRecipe(),
|
|
28142
|
-
new ClaudeCodeInstallRecipe(),
|
|
28143
|
-
new PiInstallRecipe(),
|
|
28144
|
-
new DeepSeekHarnessInstallRecipe(),
|
|
28145
|
-
new OpenCodeInstallRecipe(),
|
|
28146
|
-
new GrokBuildInstallRecipe(),
|
|
28147
|
-
new WorkBuddyInstallRecipe()
|
|
28148
|
-
]);
|
|
28149
|
-
}
|
|
28150
27397
|
|
|
28151
27398
|
// src/agent-installation/fixed-installation-executor.ts
|
|
27399
|
+
import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
27400
|
+
import { resolve as resolve4 } from "node:path";
|
|
28152
27401
|
function findSpecification(specifications, agentId) {
|
|
28153
27402
|
for (const specification of specifications) {
|
|
28154
27403
|
if (specification.id === agentId) {
|
|
@@ -28160,17 +27409,6 @@ function findSpecification(specifications, agentId) {
|
|
|
28160
27409
|
"The requested Agent is not supported"
|
|
28161
27410
|
);
|
|
28162
27411
|
}
|
|
28163
|
-
function findRecipe(recipes, agentId) {
|
|
28164
|
-
for (const recipe of recipes) {
|
|
28165
|
-
if (recipe.id === agentId) {
|
|
28166
|
-
return recipe;
|
|
28167
|
-
}
|
|
28168
|
-
}
|
|
28169
|
-
throw new InstallationManagerError(
|
|
28170
|
-
"agent_not_installable",
|
|
28171
|
-
"The requested Agent does not have an approved installation recipe"
|
|
28172
|
-
);
|
|
28173
|
-
}
|
|
28174
27412
|
function resolveDefaultWorkspace2(path2) {
|
|
28175
27413
|
try {
|
|
28176
27414
|
const directory = realpathSync2(resolve4(path2));
|
|
@@ -28186,7 +27424,7 @@ function resolveDefaultWorkspace2(path2) {
|
|
|
28186
27424
|
);
|
|
28187
27425
|
}
|
|
28188
27426
|
}
|
|
28189
|
-
function
|
|
27427
|
+
function resolveIntegrationStateDirectory(path2) {
|
|
28190
27428
|
try {
|
|
28191
27429
|
const directory = realpathSync2(resolve4(path2));
|
|
28192
27430
|
const metadata = statSync2(directory);
|
|
@@ -28197,7 +27435,7 @@ function resolveUserInstallationDirectory(path2) {
|
|
|
28197
27435
|
} catch (error61) {
|
|
28198
27436
|
throw new InstallationManagerError(
|
|
28199
27437
|
"unsafe_installation_root",
|
|
28200
|
-
"The local
|
|
27438
|
+
"The local integration state directory is unavailable or unsafe",
|
|
28201
27439
|
{ cause: error61 }
|
|
28202
27440
|
);
|
|
28203
27441
|
}
|
|
@@ -28206,20 +27444,17 @@ function translateExecutionError(error61) {
|
|
|
28206
27444
|
if (error61 instanceof InstallationManagerError) {
|
|
28207
27445
|
return error61;
|
|
28208
27446
|
}
|
|
28209
|
-
if (error61 instanceof ManagedAdapterInstallError
|
|
27447
|
+
if (error61 instanceof ManagedAdapterInstallError) {
|
|
28210
27448
|
return new InstallationManagerError(error61.code, error61.message, {
|
|
28211
27449
|
cause: error61
|
|
28212
27450
|
});
|
|
28213
27451
|
}
|
|
28214
27452
|
return new InstallationManagerError(
|
|
28215
27453
|
"installation_failed",
|
|
28216
|
-
"The
|
|
27454
|
+
"The local Agent integration installation failed",
|
|
28217
27455
|
{ cause: error61 }
|
|
28218
27456
|
);
|
|
28219
27457
|
}
|
|
28220
|
-
function requiresAgentReplacement(code) {
|
|
28221
|
-
return code === "agent_not_found" || code === "agent_probe_failed" || code === "agent_probe_timeout";
|
|
28222
|
-
}
|
|
28223
27458
|
function requiresAdapterReplacement(code) {
|
|
28224
27459
|
return code === "adapter_not_found" || code === "adapter_probe_failed" || code === "adapter_probe_timeout" || code === "acp_incompatible";
|
|
28225
27460
|
}
|
|
@@ -28230,12 +27465,10 @@ var FixedInstallationExecutor = class {
|
|
|
28230
27465
|
#catalog;
|
|
28231
27466
|
#environment;
|
|
28232
27467
|
#publishCatalog;
|
|
28233
|
-
#recipes;
|
|
28234
27468
|
#specifications;
|
|
28235
|
-
|
|
28236
|
-
constructor(options, specifications = supportedLocalAgentSpecifications(), recipes = fixedAgentInstallRecipes(), adapterInstaller) {
|
|
27469
|
+
constructor(options, specifications = supportedLocalAgentSpecifications(), adapterInstaller) {
|
|
28237
27470
|
const defaultWorkspace = resolveDefaultWorkspace2(options.defaultWorkspace);
|
|
28238
|
-
const stateDirectory =
|
|
27471
|
+
const stateDirectory = resolveIntegrationStateDirectory(
|
|
28239
27472
|
options.stateDirectory
|
|
28240
27473
|
);
|
|
28241
27474
|
this.#defaultWorkspace = defaultWorkspace;
|
|
@@ -28243,9 +27476,7 @@ var FixedInstallationExecutor = class {
|
|
|
28243
27476
|
this.#catalog = options.catalog;
|
|
28244
27477
|
this.#environment = Object.freeze({ ...options.environment });
|
|
28245
27478
|
this.#publishCatalog = options.publishCatalog;
|
|
28246
|
-
this.#recipes = Object.freeze([...recipes]);
|
|
28247
27479
|
this.#specifications = Object.freeze([...specifications]);
|
|
28248
|
-
this.#stateDirectory = stateDirectory;
|
|
28249
27480
|
this.#adapterInstaller = adapterInstaller ?? new ManagedAdapterInstaller({
|
|
28250
27481
|
environment: this.#environment,
|
|
28251
27482
|
stateDirectory
|
|
@@ -28254,35 +27485,59 @@ var FixedInstallationExecutor = class {
|
|
|
28254
27485
|
execute = async (agentId, requestId, report, signal) => {
|
|
28255
27486
|
try {
|
|
28256
27487
|
const specification = findSpecification(this.#specifications, agentId);
|
|
28257
|
-
const
|
|
28258
|
-
this.#audit.record(
|
|
28259
|
-
"agent_installation_recipe_resolved",
|
|
28260
|
-
requestId,
|
|
28261
|
-
agentId,
|
|
28262
|
-
{
|
|
28263
|
-
adapterVersion: specification.adapterVersion,
|
|
28264
|
-
releaseChannel: recipe.releaseChannel
|
|
28265
|
-
}
|
|
28266
|
-
);
|
|
28267
|
-
const discoveryOptions2 = {
|
|
27488
|
+
const discoveryOptions = {
|
|
28268
27489
|
defaultWorkspace: this.#defaultWorkspace,
|
|
28269
27490
|
environment: this.#environment,
|
|
28270
27491
|
signal
|
|
28271
27492
|
};
|
|
28272
|
-
|
|
28273
|
-
|
|
28274
|
-
|
|
28275
|
-
|
|
28276
|
-
|
|
28277
|
-
|
|
28278
|
-
|
|
28279
|
-
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
|
|
28283
|
-
|
|
27493
|
+
const initialInventory = await discoverLocalAgentInventory({
|
|
27494
|
+
...discoveryOptions,
|
|
27495
|
+
specifications: this.#specifications
|
|
27496
|
+
});
|
|
27497
|
+
const previous = this.#catalog.read();
|
|
27498
|
+
this.#catalog.transition(
|
|
27499
|
+
initialInventory.readyAgents(),
|
|
27500
|
+
initialInventory.installable
|
|
27501
|
+
);
|
|
27502
|
+
try {
|
|
27503
|
+
await this.#publishCatalog(signal);
|
|
27504
|
+
} catch (error61) {
|
|
27505
|
+
this.#catalog.transition(previous.agents, previous.installableAgents);
|
|
27506
|
+
throw error61;
|
|
27507
|
+
}
|
|
27508
|
+
const alreadyReady = initialInventory.available.find(
|
|
27509
|
+
(candidate2) => candidate2.specification.id === agentId
|
|
27510
|
+
);
|
|
27511
|
+
if (alreadyReady instanceof AvailableAgent) {
|
|
27512
|
+
return;
|
|
27513
|
+
}
|
|
27514
|
+
const candidate = initialInventory.installable.find(
|
|
27515
|
+
(agent2) => agent2.id === agentId
|
|
27516
|
+
);
|
|
27517
|
+
if (candidate instanceof MissingAgentDefinition) {
|
|
27518
|
+
throw new InstallationManagerError(
|
|
27519
|
+
"agent_not_installed",
|
|
27520
|
+
`Install ${specification.label} on this machine, then try installing the integration again.`
|
|
27521
|
+
);
|
|
27522
|
+
}
|
|
27523
|
+
if (!(candidate instanceof AgentIntegrationDefinition)) {
|
|
27524
|
+
throw new InstallationManagerError(
|
|
27525
|
+
"agent_verification_failed",
|
|
27526
|
+
"The local Agent discovery result is unavailable"
|
|
27527
|
+
);
|
|
27528
|
+
}
|
|
27529
|
+
const verifiedAgent = await findVerifiedAgentExecutable(
|
|
27530
|
+
specification,
|
|
27531
|
+
discoveryOptions
|
|
27532
|
+
);
|
|
27533
|
+
if (verifiedAgent === null) {
|
|
27534
|
+
throw new InstallationManagerError(
|
|
27535
|
+
"agent_not_installed",
|
|
27536
|
+
`Install ${specification.label} on this machine, then try installing the integration again.`
|
|
27537
|
+
);
|
|
28284
27538
|
}
|
|
28285
|
-
|
|
27539
|
+
const agent = verifiedAgent.executable;
|
|
27540
|
+
let adapter = specification instanceof DirectAcpAgentDefinition ? agent : await resolveAdapterExecutable(specification, discoveryOptions);
|
|
28286
27541
|
let installedAdapter = false;
|
|
28287
27542
|
if (adapter === null) {
|
|
28288
27543
|
if (!(specification instanceof BridgedAcpAgentDefinition)) {
|
|
@@ -28291,6 +27546,12 @@ var FixedInstallationExecutor = class {
|
|
|
28291
27546
|
"The direct Agent executable is unavailable"
|
|
28292
27547
|
);
|
|
28293
27548
|
}
|
|
27549
|
+
if (this.#environment[specification.adapterOverrideVariable] !== void 0) {
|
|
27550
|
+
throw new InstallationManagerError(
|
|
27551
|
+
"adapter_not_found",
|
|
27552
|
+
"The configured ACP adapter is unavailable"
|
|
27553
|
+
);
|
|
27554
|
+
}
|
|
28294
27555
|
await report("installing_adapter");
|
|
28295
27556
|
adapter = await this.#adapterInstaller.install(specification, signal);
|
|
28296
27557
|
installedAdapter = true;
|
|
@@ -28301,8 +27562,8 @@ var FixedInstallationExecutor = class {
|
|
|
28301
27562
|
while (true) {
|
|
28302
27563
|
await report("checking_acp");
|
|
28303
27564
|
const environment = { ...this.#environment };
|
|
28304
|
-
environment[specification.agentOverrideVariable] = agent.
|
|
28305
|
-
environment[specification.adapterOverrideVariable] = adapter.
|
|
27565
|
+
environment[specification.agentOverrideVariable] = agent.identity.requestedPath;
|
|
27566
|
+
environment[specification.adapterOverrideVariable] = adapter.identity.requestedPath;
|
|
28306
27567
|
const inventory = await discoverLocalAgentInventory({
|
|
28307
27568
|
defaultWorkspace: this.#defaultWorkspace,
|
|
28308
27569
|
environment,
|
|
@@ -28310,7 +27571,7 @@ var FixedInstallationExecutor = class {
|
|
|
28310
27571
|
specifications: this.#specifications
|
|
28311
27572
|
});
|
|
28312
27573
|
const verified = inventory.available.find(
|
|
28313
|
-
(
|
|
27574
|
+
(candidate2) => candidate2.specification.id === agentId
|
|
28314
27575
|
);
|
|
28315
27576
|
if (verified instanceof AvailableAgent) {
|
|
28316
27577
|
this.#audit.record(
|
|
@@ -28322,7 +27583,7 @@ var FixedInstallationExecutor = class {
|
|
|
28322
27583
|
agentVersion: verified.agent.agentVersion
|
|
28323
27584
|
}
|
|
28324
27585
|
);
|
|
28325
|
-
const
|
|
27586
|
+
const previousCatalog = this.#catalog.read();
|
|
28326
27587
|
this.#catalog.transition(
|
|
28327
27588
|
inventory.readyAgents(),
|
|
28328
27589
|
inventory.installable
|
|
@@ -28331,15 +27592,15 @@ var FixedInstallationExecutor = class {
|
|
|
28331
27592
|
await this.#publishCatalog(signal);
|
|
28332
27593
|
} catch (error61) {
|
|
28333
27594
|
this.#catalog.transition(
|
|
28334
|
-
|
|
28335
|
-
|
|
27595
|
+
previousCatalog.agents,
|
|
27596
|
+
previousCatalog.installableAgents
|
|
28336
27597
|
);
|
|
28337
27598
|
throw error61;
|
|
28338
27599
|
}
|
|
28339
27600
|
return;
|
|
28340
27601
|
}
|
|
28341
27602
|
const unavailable = inventory.unavailable.find(
|
|
28342
|
-
(
|
|
27603
|
+
(candidate2) => candidate2.specification.id === agentId
|
|
28343
27604
|
);
|
|
28344
27605
|
if (unavailable === void 0) {
|
|
28345
27606
|
throw new InstallationManagerError(
|
|
@@ -28347,7 +27608,7 @@ var FixedInstallationExecutor = class {
|
|
|
28347
27608
|
"The complete Agent ACP path did not pass verification"
|
|
28348
27609
|
);
|
|
28349
27610
|
}
|
|
28350
|
-
if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && requiresAdapterReplacement(unavailable.code)) {
|
|
27611
|
+
if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && this.#environment[specification.adapterOverrideVariable] === void 0 && requiresAdapterReplacement(unavailable.code)) {
|
|
28351
27612
|
await report("installing_adapter");
|
|
28352
27613
|
adapter = await this.#adapterInstaller.install(specification, signal);
|
|
28353
27614
|
installedAdapter = true;
|
|
@@ -28356,21 +27617,6 @@ var FixedInstallationExecutor = class {
|
|
|
28356
27617
|
});
|
|
28357
27618
|
continue;
|
|
28358
27619
|
}
|
|
28359
|
-
if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
|
|
28360
|
-
agent = await recipe.install({
|
|
28361
|
-
audit: this.#audit,
|
|
28362
|
-
environment: this.#environment,
|
|
28363
|
-
report,
|
|
28364
|
-
requestId,
|
|
28365
|
-
signal,
|
|
28366
|
-
stateDirectory: this.#stateDirectory
|
|
28367
|
-
});
|
|
28368
|
-
installedAgent = true;
|
|
28369
|
-
if (specification instanceof DirectAcpAgentDefinition) {
|
|
28370
|
-
adapter = agent;
|
|
28371
|
-
}
|
|
28372
|
-
continue;
|
|
28373
|
-
}
|
|
28374
27620
|
throw new InstallationManagerError(
|
|
28375
27621
|
unavailable.code,
|
|
28376
27622
|
unavailable.message
|
|
@@ -28386,15 +27632,15 @@ var FixedInstallationExecutor = class {
|
|
|
28386
27632
|
};
|
|
28387
27633
|
|
|
28388
27634
|
// src/authorization/workspace-directory.ts
|
|
28389
|
-
import { readdir, realpath as
|
|
27635
|
+
import { readdir, realpath as realpath7, stat as stat6 } from "node:fs/promises";
|
|
28390
27636
|
import { homedir as homedir2 } from "node:os";
|
|
28391
27637
|
import {
|
|
28392
27638
|
basename as basename2,
|
|
28393
|
-
dirname as
|
|
28394
|
-
isAbsolute as
|
|
28395
|
-
join as
|
|
27639
|
+
dirname as dirname5,
|
|
27640
|
+
isAbsolute as isAbsolute7,
|
|
27641
|
+
join as join15,
|
|
28396
27642
|
normalize as normalize2,
|
|
28397
|
-
relative as
|
|
27643
|
+
relative as relative4
|
|
28398
27644
|
} from "node:path";
|
|
28399
27645
|
var WorkspaceDirectoryListing = class {
|
|
28400
27646
|
directoryId;
|
|
@@ -28444,20 +27690,20 @@ var WorkspaceDirectoryService = class {
|
|
|
28444
27690
|
if (id === "home") return homedir2();
|
|
28445
27691
|
if (id.startsWith("path-")) {
|
|
28446
27692
|
const path2 = decodePath(id, "path-");
|
|
28447
|
-
if (
|
|
27693
|
+
if (isAbsolute7(path2)) return path2;
|
|
28448
27694
|
}
|
|
28449
27695
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28450
27696
|
};
|
|
28451
27697
|
resolvePath = async (requested, signal) => {
|
|
28452
27698
|
signal.throwIfAborted();
|
|
28453
|
-
if (!
|
|
27699
|
+
if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested)
|
|
28454
27700
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
28455
27701
|
try {
|
|
28456
|
-
const target = await
|
|
27702
|
+
const target = await realpath7(requested);
|
|
28457
27703
|
signal.throwIfAborted();
|
|
28458
|
-
const metadata = await
|
|
27704
|
+
const metadata = await stat6(target);
|
|
28459
27705
|
signal.throwIfAborted();
|
|
28460
|
-
if (!
|
|
27706
|
+
if (!isAbsolute7(target) || normalize2(target) !== target || !metadata.isDirectory())
|
|
28461
27707
|
throw new LocalAuthorizationError(
|
|
28462
27708
|
"The selected location is not a directory"
|
|
28463
27709
|
);
|
|
@@ -28472,8 +27718,8 @@ var WorkspaceDirectoryService = class {
|
|
|
28472
27718
|
}
|
|
28473
27719
|
};
|
|
28474
27720
|
label = (path2) => {
|
|
28475
|
-
const suffix =
|
|
28476
|
-
return suffix === "" ? "~" : !
|
|
27721
|
+
const suffix = relative4(homedir2(), path2);
|
|
27722
|
+
return suffix === "" ? "~" : !isAbsolute7(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
28477
27723
|
};
|
|
28478
27724
|
identify = async (bindingId, requestedPath, signal) => {
|
|
28479
27725
|
this.authorizeMachine(bindingId);
|
|
@@ -28501,7 +27747,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28501
27747
|
continue;
|
|
28502
27748
|
}
|
|
28503
27749
|
try {
|
|
28504
|
-
const path2 = await this.resolvePath(
|
|
27750
|
+
const path2 = await this.resolvePath(join15(target, child.name), signal);
|
|
28505
27751
|
entries.push({ directoryId: encodePath(path2), name: child.name });
|
|
28506
27752
|
} catch (cause) {
|
|
28507
27753
|
signal.throwIfAborted();
|
|
@@ -28509,7 +27755,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28509
27755
|
}
|
|
28510
27756
|
}
|
|
28511
27757
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
28512
|
-
const parent =
|
|
27758
|
+
const parent = dirname5(target);
|
|
28513
27759
|
return new WorkspaceDirectoryListing(
|
|
28514
27760
|
id,
|
|
28515
27761
|
this.label(target),
|
|
@@ -28533,7 +27779,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28533
27779
|
};
|
|
28534
27780
|
|
|
28535
27781
|
// src/native-sessions/service.ts
|
|
28536
|
-
import { randomUUID as
|
|
27782
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
28537
27783
|
|
|
28538
27784
|
// src/native-sessions/codex-history.ts
|
|
28539
27785
|
import { spawn as spawn4 } from "node:child_process";
|
|
@@ -28847,7 +28093,7 @@ var NativeSessionService = class {
|
|
|
28847
28093
|
for (const info of page.sessions) {
|
|
28848
28094
|
const authorized = await this.authorizeEntry(command, options, info);
|
|
28849
28095
|
if (authorized === null) continue;
|
|
28850
|
-
const entryId =
|
|
28096
|
+
const entryId = randomUUID2();
|
|
28851
28097
|
if (this.#entries.size >= 5e3) this.#entries.clear();
|
|
28852
28098
|
this.#entries.set(entryId, {
|
|
28853
28099
|
scope: entryScope,
|
|
@@ -28872,7 +28118,7 @@ var NativeSessionService = class {
|
|
|
28872
28118
|
{},
|
|
28873
28119
|
"invalid_native_session_response"
|
|
28874
28120
|
);
|
|
28875
|
-
nextCursor =
|
|
28121
|
+
nextCursor = randomUUID2();
|
|
28876
28122
|
if (this.#cursors.size >= 500) this.#cursors.clear();
|
|
28877
28123
|
this.#cursors.set(nextCursor, {
|
|
28878
28124
|
scope: cursorScope,
|
|
@@ -29192,7 +28438,7 @@ function connectRelay(url2, signal) {
|
|
|
29192
28438
|
}
|
|
29193
28439
|
|
|
29194
28440
|
// src/relay-connection/liveness.ts
|
|
29195
|
-
import { randomUUID as
|
|
28441
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
29196
28442
|
var HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 1e4;
|
|
29197
28443
|
var HEARTBEAT_INTERVAL_MILLISECONDS = 2e4;
|
|
29198
28444
|
var RelayLivenessState = class {
|
|
@@ -29283,7 +28529,7 @@ var RelayConnectionLiveness = class {
|
|
|
29283
28529
|
}
|
|
29284
28530
|
throw new Error("Heartbeat was scheduled in an invalid state");
|
|
29285
28531
|
}
|
|
29286
|
-
const heartbeatId =
|
|
28532
|
+
const heartbeatId = randomUUID3();
|
|
29287
28533
|
this.#state = new AwaitingHeartbeatAckState(
|
|
29288
28534
|
heartbeatId,
|
|
29289
28535
|
this.#timer.schedule(
|
|
@@ -29302,7 +28548,7 @@ var RelayConnectionLiveness = class {
|
|
|
29302
28548
|
|
|
29303
28549
|
// src/relay-connection/session-event-outbox.ts
|
|
29304
28550
|
import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
29305
|
-
import { dirname as
|
|
28551
|
+
import { dirname as dirname6 } from "node:path";
|
|
29306
28552
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
29307
28553
|
function readPendingEnvelope(row) {
|
|
29308
28554
|
if (typeof row !== "object" || row === null || Array.isArray(row)) {
|
|
@@ -29317,7 +28563,7 @@ function readPendingEnvelope(row) {
|
|
|
29317
28563
|
var SessionEventOutbox = class {
|
|
29318
28564
|
#database;
|
|
29319
28565
|
constructor(path2) {
|
|
29320
|
-
mkdirSync3(
|
|
28566
|
+
mkdirSync3(dirname6(path2), { recursive: true });
|
|
29321
28567
|
this.#database = new DatabaseSync3(path2);
|
|
29322
28568
|
this.#database.exec(`
|
|
29323
28569
|
CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
|
|
@@ -29471,6 +28717,7 @@ var systemDaemonTimer = new SystemDaemonTimer();
|
|
|
29471
28717
|
// src/run-daemon.ts
|
|
29472
28718
|
var RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
|
|
29473
28719
|
var RELAY_CONNECTION_REFRESH_MILLISECONDS = 20 * 60 * 1e3;
|
|
28720
|
+
var ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS = 2e4;
|
|
29474
28721
|
var RelayConnectionRefreshState = class {
|
|
29475
28722
|
};
|
|
29476
28723
|
var ScheduledRelayConnectionRefreshState = class extends RelayConnectionRefreshState {
|
|
@@ -29668,7 +28915,7 @@ var DaemonInstallationObserver = class {
|
|
|
29668
28915
|
);
|
|
29669
28916
|
return Promise.resolve();
|
|
29670
28917
|
}
|
|
29671
|
-
throw new Error("Unsupported Agent installation state");
|
|
28918
|
+
throw new Error("Unsupported Agent integration installation state");
|
|
29672
28919
|
};
|
|
29673
28920
|
};
|
|
29674
28921
|
var ResolvedSessionDirectories = class {
|
|
@@ -29682,16 +28929,20 @@ var ResolvedSessionDirectories = class {
|
|
|
29682
28929
|
}
|
|
29683
28930
|
};
|
|
29684
28931
|
var ActiveDaemonTurn = class {
|
|
28932
|
+
attemptId;
|
|
29685
28933
|
command;
|
|
29686
|
-
#
|
|
28934
|
+
#controller;
|
|
28935
|
+
#finished = Promise.withResolvers();
|
|
29687
28936
|
#cancellationRequested = false;
|
|
29688
|
-
constructor(command,
|
|
28937
|
+
constructor(command, attemptId) {
|
|
28938
|
+
this.attemptId = attemptId;
|
|
29689
28939
|
this.command = command;
|
|
29690
|
-
this.#
|
|
28940
|
+
this.#controller = new AbortController();
|
|
29691
28941
|
}
|
|
29692
|
-
|
|
29693
|
-
this.#
|
|
28942
|
+
abortDaemon = () => {
|
|
28943
|
+
this.#controller.abort();
|
|
29694
28944
|
};
|
|
28945
|
+
finish = () => this.#finished.resolve();
|
|
29695
28946
|
matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
|
|
29696
28947
|
requestCancellation = () => {
|
|
29697
28948
|
if (this.#cancellationRequested) {
|
|
@@ -29701,25 +28952,118 @@ var ActiveDaemonTurn = class {
|
|
|
29701
28952
|
return true;
|
|
29702
28953
|
};
|
|
29703
28954
|
get signal() {
|
|
29704
|
-
return this.#
|
|
28955
|
+
return this.#controller.signal;
|
|
28956
|
+
}
|
|
28957
|
+
get completion() {
|
|
28958
|
+
return this.#finished.promise;
|
|
28959
|
+
}
|
|
28960
|
+
};
|
|
28961
|
+
var ActiveTurnReconciliationError = class extends Error {
|
|
28962
|
+
code = "active_turn_reconciliation_failed";
|
|
28963
|
+
constructor(message, options = {}) {
|
|
28964
|
+
super(message, options);
|
|
28965
|
+
this.name = "ActiveTurnReconciliationError";
|
|
29705
28966
|
}
|
|
29706
28967
|
};
|
|
28968
|
+
function activeTurnReconciliationEndpoint(config2, turn) {
|
|
28969
|
+
const endpoint = new URL(config2.relayUrl);
|
|
28970
|
+
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
28971
|
+
if (!endpoint.pathname.endsWith("/daemon")) {
|
|
28972
|
+
throw new ActiveTurnReconciliationError("The Relay URL is invalid");
|
|
28973
|
+
}
|
|
28974
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
|
|
28975
|
+
endpoint.searchParams.delete("liveness");
|
|
28976
|
+
return endpoint;
|
|
28977
|
+
}
|
|
28978
|
+
async function reconcileActiveTurn(config2, turn, signal) {
|
|
28979
|
+
signal.throwIfAborted();
|
|
28980
|
+
const timeoutSignal = AbortSignal.timeout(
|
|
28981
|
+
ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS
|
|
28982
|
+
);
|
|
28983
|
+
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
28984
|
+
let response;
|
|
28985
|
+
try {
|
|
28986
|
+
response = await fetch4(activeTurnReconciliationEndpoint(config2, turn), {
|
|
28987
|
+
body: JSON.stringify({ outcome: { kind: "running" } }),
|
|
28988
|
+
dispatcher: environmentProxyDispatcher,
|
|
28989
|
+
headers: { "content-type": "application/json" },
|
|
28990
|
+
method: "POST",
|
|
28991
|
+
signal: requestSignal
|
|
28992
|
+
});
|
|
28993
|
+
} catch (error61) {
|
|
28994
|
+
if (signal.aborted) {
|
|
28995
|
+
signal.throwIfAborted();
|
|
28996
|
+
}
|
|
28997
|
+
throw new ActiveTurnReconciliationError(
|
|
28998
|
+
timeoutSignal.aborted ? "The active Agent turn reconciliation timed out" : "The active Agent turn could not be reconciled",
|
|
28999
|
+
{ cause: error61 }
|
|
29000
|
+
);
|
|
29001
|
+
}
|
|
29002
|
+
await response.body?.cancel();
|
|
29003
|
+
if (!response.ok) {
|
|
29004
|
+
throw new ActiveTurnReconciliationError(
|
|
29005
|
+
"The Relay rejected the active Agent turn reconciliation"
|
|
29006
|
+
);
|
|
29007
|
+
}
|
|
29008
|
+
}
|
|
29009
|
+
async function reconcileActiveTurns(config2, turns, signal) {
|
|
29010
|
+
await Promise.all(
|
|
29011
|
+
turns.map(async (turn) => await reconcileActiveTurn(config2, turn, signal))
|
|
29012
|
+
);
|
|
29013
|
+
}
|
|
29707
29014
|
function send(socket, message) {
|
|
29708
29015
|
if (socket.readyState !== WebSocket2.OPEN) {
|
|
29709
29016
|
throw new Error("Relay connection is not open");
|
|
29710
29017
|
}
|
|
29711
29018
|
socket.send(message);
|
|
29712
29019
|
}
|
|
29713
|
-
|
|
29714
|
-
|
|
29715
|
-
|
|
29716
|
-
|
|
29020
|
+
var DaemonSessionEventConnectionState = class {
|
|
29021
|
+
};
|
|
29022
|
+
var DisconnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
|
|
29023
|
+
disconnect = () => this;
|
|
29024
|
+
send = () => void 0;
|
|
29025
|
+
};
|
|
29026
|
+
var ConnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
|
|
29027
|
+
#socket;
|
|
29028
|
+
constructor(socket) {
|
|
29029
|
+
super();
|
|
29030
|
+
this.#socket = socket;
|
|
29717
29031
|
}
|
|
29718
|
-
|
|
29719
|
-
|
|
29720
|
-
|
|
29721
|
-
|
|
29722
|
-
|
|
29032
|
+
disconnect = (socket) => socket === this.#socket ? new DisconnectedDaemonSessionEventState() : this;
|
|
29033
|
+
send = (message) => {
|
|
29034
|
+
if (this.#socket.readyState === WebSocket2.OPEN) {
|
|
29035
|
+
try {
|
|
29036
|
+
this.#socket.send(message);
|
|
29037
|
+
} catch {
|
|
29038
|
+
}
|
|
29039
|
+
}
|
|
29040
|
+
};
|
|
29041
|
+
};
|
|
29042
|
+
var DaemonSessionEventPublisher = class {
|
|
29043
|
+
#outbox;
|
|
29044
|
+
#connection = new DisconnectedDaemonSessionEventState();
|
|
29045
|
+
constructor(outbox) {
|
|
29046
|
+
this.#outbox = outbox;
|
|
29047
|
+
}
|
|
29048
|
+
connect = (socket) => {
|
|
29049
|
+
const connection = new ConnectedDaemonSessionEventState(socket);
|
|
29050
|
+
this.#connection = connection;
|
|
29051
|
+
for (const pending of this.#outbox.pending()) {
|
|
29052
|
+
connection.send(pending);
|
|
29053
|
+
}
|
|
29054
|
+
};
|
|
29055
|
+
disconnect = (socket) => {
|
|
29056
|
+
this.#connection = this.#connection.disconnect(socket);
|
|
29057
|
+
};
|
|
29058
|
+
recordAttempt = (sessionId, payload, attemptId) => {
|
|
29059
|
+
this.#connection.send(this.#outbox.enqueue(sessionId, payload, attemptId));
|
|
29060
|
+
};
|
|
29061
|
+
recordRuntime = (sessionId, payload) => {
|
|
29062
|
+
this.#connection.send(this.#outbox.enqueue(sessionId, payload));
|
|
29063
|
+
};
|
|
29064
|
+
};
|
|
29065
|
+
function reportFailure(publisher, command, code, message, attemptId) {
|
|
29066
|
+
publisher.recordAttempt(
|
|
29723
29067
|
command.sessionId,
|
|
29724
29068
|
encodeSessionFailedEvent({
|
|
29725
29069
|
code,
|
|
@@ -29815,7 +29159,7 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
|
|
|
29815
29159
|
reportOperationFailure(socket, command.requestId, "", error61);
|
|
29816
29160
|
}
|
|
29817
29161
|
}
|
|
29818
|
-
async function executeSessionPrepare(
|
|
29162
|
+
async function executeSessionPrepare(publisher, socket, command, config2, directories, audit, sessions, signal) {
|
|
29819
29163
|
try {
|
|
29820
29164
|
const resolved = await resolveSessionDirectories(
|
|
29821
29165
|
directories,
|
|
@@ -29842,9 +29186,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
|
|
|
29842
29186
|
event: "session_prepared",
|
|
29843
29187
|
sessionId: command.sessionId
|
|
29844
29188
|
});
|
|
29845
|
-
|
|
29846
|
-
outbox,
|
|
29847
|
-
socket,
|
|
29189
|
+
publisher.recordRuntime(
|
|
29848
29190
|
command.sessionId,
|
|
29849
29191
|
encodeSessionReadyEvent({
|
|
29850
29192
|
additionalDirectories: resolved.additionalDirectoryEntries,
|
|
@@ -29875,7 +29217,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
|
|
|
29875
29217
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
29876
29218
|
}
|
|
29877
29219
|
}
|
|
29878
|
-
async function executeSessionConfigure(
|
|
29220
|
+
async function executeSessionConfigure(publisher, socket, command, config2, directories, audit, sessions, signal) {
|
|
29879
29221
|
try {
|
|
29880
29222
|
const resolved = await resolveSessionDirectories(
|
|
29881
29223
|
directories,
|
|
@@ -29901,9 +29243,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
|
|
|
29901
29243
|
event: "session_configured",
|
|
29902
29244
|
sessionId: command.sessionId
|
|
29903
29245
|
});
|
|
29904
|
-
|
|
29905
|
-
outbox,
|
|
29906
|
-
socket,
|
|
29246
|
+
publisher.recordRuntime(
|
|
29907
29247
|
command.sessionId,
|
|
29908
29248
|
encodeSessionConfigUpdatedEvent({
|
|
29909
29249
|
configOptions,
|
|
@@ -29916,7 +29256,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
|
|
|
29916
29256
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
29917
29257
|
}
|
|
29918
29258
|
}
|
|
29919
|
-
async function executePrompt(outbox,
|
|
29259
|
+
async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, signal) {
|
|
29920
29260
|
try {
|
|
29921
29261
|
const resolved = await resolveSessionDirectories(
|
|
29922
29262
|
directories,
|
|
@@ -29932,9 +29272,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29932
29272
|
sessionId: command.sessionId
|
|
29933
29273
|
});
|
|
29934
29274
|
outbox.transitionExecution(command.commandId, "running");
|
|
29935
|
-
|
|
29936
|
-
outbox,
|
|
29937
|
-
socket,
|
|
29275
|
+
publisher.recordAttempt(
|
|
29938
29276
|
command.sessionId,
|
|
29939
29277
|
encodeSessionStartedEvent({
|
|
29940
29278
|
commandId: command.commandId,
|
|
@@ -29951,9 +29289,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29951
29289
|
cwd: resolved.cwd,
|
|
29952
29290
|
images: command.images,
|
|
29953
29291
|
onActivity: (activity) => {
|
|
29954
|
-
|
|
29955
|
-
outbox,
|
|
29956
|
-
socket,
|
|
29292
|
+
publisher.recordAttempt(
|
|
29957
29293
|
command.sessionId,
|
|
29958
29294
|
encodeAgentActivityEvent({
|
|
29959
29295
|
activityId: activity.activityId,
|
|
@@ -29977,9 +29313,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29977
29313
|
return Promise.resolve();
|
|
29978
29314
|
},
|
|
29979
29315
|
onText: (text) => {
|
|
29980
|
-
|
|
29981
|
-
outbox,
|
|
29982
|
-
socket,
|
|
29316
|
+
publisher.recordAttempt(
|
|
29983
29317
|
command.sessionId,
|
|
29984
29318
|
encodeAgentMessageDeltaEvent({
|
|
29985
29319
|
commandId: command.commandId,
|
|
@@ -29996,9 +29330,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29996
29330
|
sessionId: command.sessionId,
|
|
29997
29331
|
signal
|
|
29998
29332
|
});
|
|
29999
|
-
|
|
30000
|
-
outbox,
|
|
30001
|
-
socket,
|
|
29333
|
+
publisher.recordAttempt(
|
|
30002
29334
|
command.sessionId,
|
|
30003
29335
|
encodeSessionCompletedEvent({
|
|
30004
29336
|
commandId: command.commandId,
|
|
@@ -30025,8 +29357,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
30025
29357
|
});
|
|
30026
29358
|
const code = operationErrorCode(error61);
|
|
30027
29359
|
reportFailure(
|
|
30028
|
-
|
|
30029
|
-
socket,
|
|
29360
|
+
publisher,
|
|
30030
29361
|
command,
|
|
30031
29362
|
code === "session_operation_failed" ? "agent_execution_failed" : code,
|
|
30032
29363
|
code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error61),
|
|
@@ -30072,29 +29403,15 @@ async function publishAgentCatalogUntilAvailable(config2, signal, timer) {
|
|
|
30072
29403
|
}
|
|
30073
29404
|
}
|
|
30074
29405
|
}
|
|
30075
|
-
async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, onConnected, signal, timer) {
|
|
29406
|
+
async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, publisher, activeTurns, activeAttemptIds, onConnected, signal, timer) {
|
|
30076
29407
|
const relayUrl = new URL(config2.relayUrl);
|
|
30077
29408
|
relayUrl.searchParams.set("liveness", "1");
|
|
30078
29409
|
const socket = await connectRelay(relayUrl, signal);
|
|
29410
|
+
const reconnectingTurns = [...activeTurns.values()];
|
|
30079
29411
|
onConnected();
|
|
30080
|
-
const activeTurns = /* @__PURE__ */ new Map();
|
|
30081
|
-
const activeAttemptIds = /* @__PURE__ */ new Map();
|
|
30082
29412
|
const connectionController = new AbortController();
|
|
30083
29413
|
const nativeRequests = /* @__PURE__ */ new Map();
|
|
30084
|
-
const record2 = (sessionId, payload) => {
|
|
30085
|
-
recordSessionEvent(
|
|
30086
|
-
outbox,
|
|
30087
|
-
socket,
|
|
30088
|
-
sessionId,
|
|
30089
|
-
payload,
|
|
30090
|
-
activeAttemptIds.get(sessionId) ?? null
|
|
30091
|
-
);
|
|
30092
|
-
};
|
|
30093
|
-
sessions.setObserver(new DaemonAcpObserver(record2));
|
|
30094
29414
|
installationObserver.connect(socket);
|
|
30095
|
-
for (const pending of outbox.pending()) {
|
|
30096
|
-
send(socket, pending);
|
|
30097
|
-
}
|
|
30098
29415
|
try {
|
|
30099
29416
|
await new Promise((resolve5, reject) => {
|
|
30100
29417
|
let finished = false;
|
|
@@ -30106,11 +29423,8 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30106
29423
|
socket.removeEventListener("error", handleError);
|
|
30107
29424
|
socket.removeEventListener("message", handleMessage);
|
|
30108
29425
|
installationObserver.disconnect(socket);
|
|
29426
|
+
publisher.disconnect(socket);
|
|
30109
29427
|
connectionController.abort();
|
|
30110
|
-
for (const turn of activeTurns.values()) {
|
|
30111
|
-
turn.abortConnection();
|
|
30112
|
-
}
|
|
30113
|
-
activeTurns.clear();
|
|
30114
29428
|
};
|
|
30115
29429
|
const resolveConnection = () => {
|
|
30116
29430
|
if (finished) {
|
|
@@ -30329,7 +29643,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30329
29643
|
if (kind === SESSION_PREPARE_KIND) {
|
|
30330
29644
|
const command2 = decodeSessionPrepareCommand(encoded);
|
|
30331
29645
|
void executeSessionPrepare(
|
|
30332
|
-
|
|
29646
|
+
publisher,
|
|
30333
29647
|
socket,
|
|
30334
29648
|
command2,
|
|
30335
29649
|
config2,
|
|
@@ -30343,7 +29657,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30343
29657
|
if (kind === SESSION_CONFIGURE_KIND) {
|
|
30344
29658
|
const command2 = decodeSessionConfigureCommand(encoded);
|
|
30345
29659
|
void executeSessionConfigure(
|
|
30346
|
-
|
|
29660
|
+
publisher,
|
|
30347
29661
|
socket,
|
|
30348
29662
|
command2,
|
|
30349
29663
|
config2,
|
|
@@ -30393,7 +29707,10 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30393
29707
|
if (kind === AGENT_INSTALL_REQUEST_KIND) {
|
|
30394
29708
|
const command2 = decodeAgentInstallRequestCommand(encoded);
|
|
30395
29709
|
void installations.request(command2, signal).catch((error61) => {
|
|
30396
|
-
console.error(
|
|
29710
|
+
console.error(
|
|
29711
|
+
"Mobius Agent integration installation failed",
|
|
29712
|
+
error61
|
|
29713
|
+
);
|
|
30397
29714
|
});
|
|
30398
29715
|
return;
|
|
30399
29716
|
}
|
|
@@ -30419,12 +29736,12 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30419
29736
|
if (receipt.kind === "duplicate") {
|
|
30420
29737
|
return;
|
|
30421
29738
|
}
|
|
30422
|
-
const turn = new ActiveDaemonTurn(command,
|
|
29739
|
+
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
30423
29740
|
activeTurns.set(command.commandId, turn);
|
|
30424
29741
|
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
30425
29742
|
void executePrompt(
|
|
30426
29743
|
outbox,
|
|
30427
|
-
|
|
29744
|
+
publisher,
|
|
30428
29745
|
command,
|
|
30429
29746
|
config2,
|
|
30430
29747
|
directories,
|
|
@@ -30439,6 +29756,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30439
29756
|
if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
|
|
30440
29757
|
activeAttemptIds.delete(command.sessionId);
|
|
30441
29758
|
}
|
|
29759
|
+
turn.finish();
|
|
30442
29760
|
connectionRefresh.afterTurnFinished();
|
|
30443
29761
|
});
|
|
30444
29762
|
} catch (error61) {
|
|
@@ -30450,6 +29768,28 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30450
29768
|
socket.addEventListener("close", handleClose);
|
|
30451
29769
|
socket.addEventListener("error", handleError);
|
|
30452
29770
|
socket.addEventListener("message", handleMessage);
|
|
29771
|
+
void reconcileActiveTurns(
|
|
29772
|
+
config2,
|
|
29773
|
+
reconnectingTurns,
|
|
29774
|
+
connectionController.signal
|
|
29775
|
+
).then(
|
|
29776
|
+
() => {
|
|
29777
|
+
if (finished) {
|
|
29778
|
+
return;
|
|
29779
|
+
}
|
|
29780
|
+
publisher.connect(socket);
|
|
29781
|
+
void Promise.all(
|
|
29782
|
+
reconnectingTurns.map((turn) => turn.completion)
|
|
29783
|
+
).then(connectionRefresh.afterTurnFinished);
|
|
29784
|
+
},
|
|
29785
|
+
() => {
|
|
29786
|
+
if (finished) {
|
|
29787
|
+
return;
|
|
29788
|
+
}
|
|
29789
|
+
socket.close(1011, "Active Agent turn reconciliation failed");
|
|
29790
|
+
rejectConnection();
|
|
29791
|
+
}
|
|
29792
|
+
);
|
|
30453
29793
|
if (signal.aborted) {
|
|
30454
29794
|
stop();
|
|
30455
29795
|
}
|
|
@@ -30473,23 +29813,21 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
30473
29813
|
publishCatalog: async (installationSignal) => await publishAgentCatalog(config2, installationSignal),
|
|
30474
29814
|
stateDirectory
|
|
30475
29815
|
});
|
|
30476
|
-
await new AutomaticAdapterProvisioner(
|
|
30477
|
-
{
|
|
30478
|
-
defaultWorkspace: config2.defaultWorkspace,
|
|
30479
|
-
audit: installationAudit,
|
|
30480
|
-
catalog: config2.catalog,
|
|
30481
|
-
environment: process.env
|
|
30482
|
-
},
|
|
30483
|
-
new ManagedAdapterInstaller({
|
|
30484
|
-
environment: process.env,
|
|
30485
|
-
stateDirectory
|
|
30486
|
-
}),
|
|
30487
|
-
specifications
|
|
30488
|
-
).prepare(signal);
|
|
30489
29816
|
const sessionStore = new SqliteAcpSessionStore(config2.auditDatabasePath);
|
|
30490
29817
|
const outbox = new SessionEventOutbox(config2.auditDatabasePath);
|
|
29818
|
+
const publisher = new DaemonSessionEventPublisher(outbox);
|
|
29819
|
+
const activeTurns = /* @__PURE__ */ new Map();
|
|
29820
|
+
const activeAttemptIds = /* @__PURE__ */ new Map();
|
|
29821
|
+
const recordSessionEvent = (sessionId, payload) => {
|
|
29822
|
+
const attemptId = activeAttemptIds.get(sessionId);
|
|
29823
|
+
if (attemptId === void 0) {
|
|
29824
|
+
publisher.recordRuntime(sessionId, payload);
|
|
29825
|
+
return;
|
|
29826
|
+
}
|
|
29827
|
+
publisher.recordAttempt(sessionId, payload, attemptId);
|
|
29828
|
+
};
|
|
30491
29829
|
const sessions = new AcpSessionManager(
|
|
30492
|
-
new
|
|
29830
|
+
new DaemonAcpObserver(recordSessionEvent),
|
|
30493
29831
|
sessionStore
|
|
30494
29832
|
);
|
|
30495
29833
|
const directories = new WorkspaceDirectoryService(
|
|
@@ -30545,6 +29883,9 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
30545
29883
|
installationObserver,
|
|
30546
29884
|
nativeSessions,
|
|
30547
29885
|
outbox,
|
|
29886
|
+
publisher,
|
|
29887
|
+
activeTurns,
|
|
29888
|
+
activeAttemptIds,
|
|
30548
29889
|
announceConnection,
|
|
30549
29890
|
signal,
|
|
30550
29891
|
timer
|
|
@@ -30562,6 +29903,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
30562
29903
|
await waitForRelayRetry(signal, timer);
|
|
30563
29904
|
}
|
|
30564
29905
|
} finally {
|
|
29906
|
+
const turns = [...activeTurns.values()];
|
|
29907
|
+
for (const turn of turns) {
|
|
29908
|
+
turn.abortDaemon();
|
|
29909
|
+
}
|
|
29910
|
+
await Promise.all(turns.map((turn) => turn.completion));
|
|
30565
29911
|
try {
|
|
30566
29912
|
await catalogPublication;
|
|
30567
29913
|
} finally {
|