@sellable/install 0.1.697 → 0.1.699
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/container/Dockerfile +4 -4
- package/container/README.md +1 -1
- package/lib/sellable-agent/fly-customer-image/Dockerfile +1 -1
- package/lib/sellable-agent/fly-customer-image/customer-runtime.mjs +1 -1
- package/lib/sellable-agent/fly-customer-image/hermes-runs-client.mjs +2 -1
- package/lib/sellable-agent/hermes-bridge.mjs +0 -91
- package/lib/sellable-agent/host-bootstrap.mjs +1 -1
- package/lib/sellable-agent/host-worker.mjs +1 -1
- package/lib/sellable-agent/profile-materializer.mjs +1 -1
- package/lib/sellable-agent/provisioning-adapter.mjs +1 -1
- package/package.json +1 -1
package/container/Dockerfile
CHANGED
|
@@ -3,12 +3,12 @@ FROM ${HERMES_IMAGE}
|
|
|
3
3
|
|
|
4
4
|
USER root
|
|
5
5
|
|
|
6
|
-
ARG INSTALLER_PACKAGE=@sellable/install@0.1.
|
|
6
|
+
ARG INSTALLER_PACKAGE=@sellable/install@0.1.698
|
|
7
7
|
ARG MCP_PACKAGE=@sellable/mcp@0.1.904
|
|
8
8
|
ARG INSTALLER_INTEGRITY
|
|
9
9
|
ARG MCP_INTEGRITY=sha512-p0oHqN6WwBbs+FQKfKd8gl/oVSgs4KWO9xfg2Jf3bt1eOF/BbEsiqazr12p0q8xuXw1G+s7m7BrCa8OyKsr6WQ==
|
|
10
10
|
|
|
11
|
-
RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.
|
|
11
|
+
RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.698" \
|
|
12
12
|
&& test "${MCP_PACKAGE}" = "@sellable/mcp@0.1.904" \
|
|
13
13
|
&& test -n "${INSTALLER_INTEGRITY}" \
|
|
14
14
|
&& test "$(npm view "${INSTALLER_PACKAGE}" dist.integrity)" = "${INSTALLER_INTEGRITY}" \
|
|
@@ -23,9 +23,9 @@ RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.697" \
|
|
|
23
23
|
&& mkdir -p /opt/sellable-agent/install-root /opt/sellable-agent/mcp-root \
|
|
24
24
|
&& npm install --prefix /opt/sellable-agent/install-root --omit=dev --ignore-scripts --no-audit --no-fund "${INSTALLER_PACKAGE}" \
|
|
25
25
|
&& npm install --prefix /opt/sellable-agent/mcp-root --omit=dev --ignore-scripts --no-audit --no-fund "${MCP_PACKAGE}" \
|
|
26
|
-
&& node --input-type=module -e "import { readFileSync } from 'node:fs'; const install = JSON.parse(readFileSync('/opt/sellable-agent/install-root/node_modules/@sellable/install/package.json')); const mcp = JSON.parse(readFileSync('/opt/sellable-agent/mcp-root/node_modules/@sellable/mcp/package.json')); if (install.name !== '@sellable/install' || install.version !== '0.1.
|
|
26
|
+
&& node --input-type=module -e "import { readFileSync } from 'node:fs'; const install = JSON.parse(readFileSync('/opt/sellable-agent/install-root/node_modules/@sellable/install/package.json')); const mcp = JSON.parse(readFileSync('/opt/sellable-agent/mcp-root/node_modules/@sellable/mcp/package.json')); if (install.name !== '@sellable/install' || install.version !== '0.1.698' || mcp.name !== '@sellable/mcp' || mcp.version !== '0.1.904') throw new Error('package identity rejected');" \
|
|
27
27
|
&& node --input-type=module -e "import { buildExternalRuntimeClosure } from '/opt/sellable-agent/install-root/node_modules/@sellable/install/lib/sellable-agent/external-runtime-builder.mjs'; const built = buildExternalRuntimeClosure({ mcpPackageRoot: '/opt/sellable-agent/mcp-root/node_modules/@sellable/mcp', mcpNodeModulesRoot: '/opt/sellable-agent/mcp-root/node_modules', hermesSourceRoot: '/opt/hermes', ownerUid: 0, ownerGid: 0 }); if (!built.closureDigest) throw new Error('runtime closure rejected');" \
|
|
28
|
-
&& node --input-type=module -e "import { chmodSync, writeFileSync } from 'node:fs'; const release = { installerPackage: '@sellable/install@0.1.
|
|
28
|
+
&& node --input-type=module -e "import { chmodSync, writeFileSync } from 'node:fs'; const release = { installerPackage: '@sellable/install@0.1.698', installerIntegrity: process.argv[1], mcpPackage: '@sellable/mcp@0.1.904', mcpIntegrity: process.argv[2] }; writeFileSync('/opt/sellable-agent/release.json', JSON.stringify(release) + '\\n', { mode: 0o444 }); chmodSync('/opt/sellable-agent/release.json', 0o444);" "${INSTALLER_INTEGRITY}" "${MCP_INTEGRITY}" \
|
|
29
29
|
&& npm cache clean --force
|
|
30
30
|
|
|
31
31
|
COPY entrypoint.sh /usr/local/bin/sellable-agent-container-entrypoint
|
package/container/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This image is a dedicated Agent worker/runtime boundary beside an existing Hermes dashboard. It never replaces or reconfigures the dashboard container.
|
|
4
4
|
|
|
5
5
|
Build from this directory after
|
|
6
|
-
`@sellable/install@0.1.
|
|
6
|
+
`@sellable/install@0.1.698` is
|
|
7
7
|
published:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
@@ -8,7 +8,7 @@ ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright
|
|
|
8
8
|
|
|
9
9
|
ARG MCP_PACKAGE=@sellable/mcp@0.1.904
|
|
10
10
|
ARG MCP_INTEGRITY=sha512-p0oHqN6WwBbs+FQKfKd8gl/oVSgs4KWO9xfg2Jf3bt1eOF/BbEsiqazr12p0q8xuXw1G+s7m7BrCa8OyKsr6WQ==
|
|
11
|
-
ARG INSTALLER_PACKAGE=@sellable/install@0.1.
|
|
11
|
+
ARG INSTALLER_PACKAGE=@sellable/install@0.1.698
|
|
12
12
|
ARG ADMIN_MCP_PACKAGE=@sellable/admin-mcp@0.1.186-wip.phase158.20260802034727
|
|
13
13
|
ARG ADMIN_MCP_INTEGRITY=sha512-qYNew5wd2IfgVcp1UYOG9QvpF/8Mx19YJ5HQtMKzvSfUf3evePjtaKsoXLf2C/GUJ5QlLlHJo84VWOI3V01+9A==
|
|
14
14
|
ARG TUS_JS_CLIENT_VERSION=4.3.1
|
|
@@ -105,7 +105,7 @@ const RUNTIME_GENERATION = Number(
|
|
|
105
105
|
const BOOT_SESSION_ID = randomUUID();
|
|
106
106
|
const HERMES_VERSION = process.env.SELLABLE_AGENT_HERMES_VERSION ?? "0.20.4";
|
|
107
107
|
const INSTALLER_PACKAGE =
|
|
108
|
-
process.env.SELLABLE_AGENT_INSTALLER_PACKAGE ?? "@sellable/install@0.1.
|
|
108
|
+
process.env.SELLABLE_AGENT_INSTALLER_PACKAGE ?? "@sellable/install@0.1.698";
|
|
109
109
|
const MCP_PACKAGE =
|
|
110
110
|
process.env.SELLABLE_AGENT_MCP_PACKAGE ?? "@sellable/mcp@0.1.904";
|
|
111
111
|
const DEFAULT_PROFILE_BUNDLE_ROOT =
|
|
@@ -9,6 +9,7 @@ const MAX_RESPONSE_BYTES = 512 * 1024;
|
|
|
9
9
|
const MAX_INPUT_BYTES = 128 * 1024;
|
|
10
10
|
const MAX_INSTRUCTIONS_BYTES = 128 * 1024;
|
|
11
11
|
const MAX_HISTORY_BYTES = 128 * 1024;
|
|
12
|
+
const MAX_HISTORY_ITEM_BYTES = 48 * 1024;
|
|
12
13
|
const MAX_HISTORY_ITEMS = 64;
|
|
13
14
|
const MAX_EVENT_BYTES = 128 * 1024;
|
|
14
15
|
const MAX_CANONICAL_OUTPUT_BYTES = 48 * 1024;
|
|
@@ -182,7 +183,7 @@ function canonicalHistory(value) {
|
|
|
182
183
|
!exactObject(item) ||
|
|
183
184
|
!["user", "assistant"].includes(item.role) ||
|
|
184
185
|
typeof item.content !== "string" ||
|
|
185
|
-
bytes(item.content) >
|
|
186
|
+
bytes(item.content) > MAX_HISTORY_ITEM_BYTES ||
|
|
186
187
|
stableJson(Object.keys(item).sort()) !== stableJson(["content", "role"])
|
|
187
188
|
) {
|
|
188
189
|
throw new Error("hermes_runs_history_rejected");
|
|
@@ -808,61 +808,6 @@ def _sellable_agent_strip_cron_mcp(toolsets, cfg):
|
|
|
808
808
|
return list(toolsets or [])
|
|
809
809
|
`;
|
|
810
810
|
|
|
811
|
-
const V020_WEB_TOOLSET_DISCOVERY_HELPER = `
|
|
812
|
-
# ${HERMES_AGENT_BRIDGE_MARKER}: keep expensive plugin discovery off the dashboard event loop.
|
|
813
|
-
_SELLABLE_AGENT_TOOLSET_DISCOVERY_LOCK = threading.Lock()
|
|
814
|
-
_SELLABLE_AGENT_TOOLSET_DISCOVERY_RUNNING = False
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
def _sellable_agent_discover_plugins():
|
|
818
|
-
global _SELLABLE_AGENT_TOOLSET_DISCOVERY_RUNNING
|
|
819
|
-
try:
|
|
820
|
-
from hermes_cli.plugins import discover_plugins
|
|
821
|
-
|
|
822
|
-
discover_plugins()
|
|
823
|
-
except BaseException:
|
|
824
|
-
_log.exception("Sellable background plugin discovery failed")
|
|
825
|
-
finally:
|
|
826
|
-
with _SELLABLE_AGENT_TOOLSET_DISCOVERY_LOCK:
|
|
827
|
-
_SELLABLE_AGENT_TOOLSET_DISCOVERY_RUNNING = False
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
def _sellable_agent_effective_toolsets(blocking_loader):
|
|
831
|
-
"""Return the built-in catalog now; merge plugins after discovery completes.
|
|
832
|
-
|
|
833
|
-
Hermes' normal loader synchronously scans and imports every plugin. On the
|
|
834
|
-
Fly one-vCPU runtime that took 31 seconds inside an async request handler,
|
|
835
|
-
freezing status, chat WebSockets, and every other Desktop API. Sellable
|
|
836
|
-
runtimes start that idempotent scan in a daemon thread and keep the first
|
|
837
|
-
response useful. A later refresh includes any unique plugin toolsets.
|
|
838
|
-
"""
|
|
839
|
-
if os.getenv("SELLABLE_AGENT_RUNTIME", "") != "1":
|
|
840
|
-
return blocking_loader()
|
|
841
|
-
|
|
842
|
-
from hermes_cli.plugins import get_plugin_manager, get_plugin_toolsets
|
|
843
|
-
from hermes_cli.tools_config import CONFIGURABLE_TOOLSETS
|
|
844
|
-
|
|
845
|
-
manager = get_plugin_manager()
|
|
846
|
-
if not getattr(manager, "_discovered", False):
|
|
847
|
-
global _SELLABLE_AGENT_TOOLSET_DISCOVERY_RUNNING
|
|
848
|
-
with _SELLABLE_AGENT_TOOLSET_DISCOVERY_LOCK:
|
|
849
|
-
if not _SELLABLE_AGENT_TOOLSET_DISCOVERY_RUNNING:
|
|
850
|
-
_SELLABLE_AGENT_TOOLSET_DISCOVERY_RUNNING = True
|
|
851
|
-
threading.Thread(
|
|
852
|
-
target=_sellable_agent_discover_plugins,
|
|
853
|
-
daemon=True,
|
|
854
|
-
name="sellable-hermes-plugin-discovery",
|
|
855
|
-
).start()
|
|
856
|
-
|
|
857
|
-
result = list(CONFIGURABLE_TOOLSETS)
|
|
858
|
-
seen = {toolset[0] for toolset in result}
|
|
859
|
-
for entry in get_plugin_toolsets():
|
|
860
|
-
if entry[0] not in seen:
|
|
861
|
-
seen.add(entry[0])
|
|
862
|
-
result.append(entry)
|
|
863
|
-
return result
|
|
864
|
-
`;
|
|
865
|
-
|
|
866
811
|
const V019_ROOT_TOKEN_FILE_HELPER = `
|
|
867
812
|
# ${HERMES_AGENT_BRIDGE_MARKER}: root-owned Slack OAuth token-map gate.
|
|
868
813
|
_SELLABLE_AGENT_SLACK_TOKEN_FILE_SENTINEL = "__SELLABLE_ROOT_SLACK_TOKEN_FILE__"
|
|
@@ -1708,34 +1653,6 @@ export function patchHermesSourceFile(patchKind, source) {
|
|
|
1708
1653
|
return patched;
|
|
1709
1654
|
}
|
|
1710
1655
|
|
|
1711
|
-
if (patchKind === "web-tools-v020") {
|
|
1712
|
-
let patched = replaceExactlyOnce(
|
|
1713
|
-
source,
|
|
1714
|
-
"import logging\nimport sys",
|
|
1715
|
-
"import logging\nimport os\nimport sys\nimport threading",
|
|
1716
|
-
"v0.20 web tools concurrency imports"
|
|
1717
|
-
);
|
|
1718
|
-
patched = replaceExactlyOnce(
|
|
1719
|
-
patched,
|
|
1720
|
-
"router = APIRouter()\n",
|
|
1721
|
-
`router = APIRouter()\n${V020_WEB_TOOLSET_DISCOVERY_HELPER}`,
|
|
1722
|
-
"v0.20 web tools background discovery helper"
|
|
1723
|
-
);
|
|
1724
|
-
patched = replaceExactlyOnce(
|
|
1725
|
-
patched,
|
|
1726
|
-
"async def get_toolsets(profile: Optional[str] = None):",
|
|
1727
|
-
"def get_toolsets(profile: Optional[str] = None):",
|
|
1728
|
-
"v0.20 synchronous toolset handler"
|
|
1729
|
-
);
|
|
1730
|
-
patched = replaceExactlyOnce(
|
|
1731
|
-
patched,
|
|
1732
|
-
" toolset_rows = _get_effective_configurable_toolsets()",
|
|
1733
|
-
" toolset_rows = _sellable_agent_effective_toolsets(_get_effective_configurable_toolsets)",
|
|
1734
|
-
"v0.20 nonblocking toolset catalog"
|
|
1735
|
-
);
|
|
1736
|
-
return patched;
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
1656
|
if (patchKind === "cron-scheduler-v020") {
|
|
1740
1657
|
let patched = replaceExactlyOnce(
|
|
1741
1658
|
source,
|
|
@@ -2122,14 +2039,6 @@ export const HERMES_AGENT_BRIDGE_DEDICATED_V020_CONTRACT = normalizeContract({
|
|
|
2122
2039
|
patchedSha256:
|
|
2123
2040
|
"f4768b3992a1a64832b82ac66981a014c1ef53bfd3f336f3d1890e348a107d7f",
|
|
2124
2041
|
},
|
|
2125
|
-
{
|
|
2126
|
-
path: "hermes_cli/web_routers/tools.py",
|
|
2127
|
-
patchKind: "web-tools-v020",
|
|
2128
|
-
sourceSha256:
|
|
2129
|
-
"06230c8d406c4ed887b1cd7d0718d90d3535f44b9c835c8ca4c75cd53fd2da67",
|
|
2130
|
-
patchedSha256:
|
|
2131
|
-
"22d4061f944700fa2fa7d0defc47cc07d6afc9fb61e79eb95483a3533956495d",
|
|
2132
|
-
},
|
|
2133
2042
|
{
|
|
2134
2043
|
path: "cron/scheduler.py",
|
|
2135
2044
|
patchKind: "cron-scheduler-v020",
|
|
@@ -38,7 +38,7 @@ import { installAgentHostServices } from "./service-installer.mjs";
|
|
|
38
38
|
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
39
39
|
const VERSION = "sellable-agent-host-bootstrap/v1";
|
|
40
40
|
const RECEIPT_VERSION = "sellable-agent-host-registration/v1";
|
|
41
|
-
const INSTALLER_PACKAGE = "@sellable/install@0.1.
|
|
41
|
+
const INSTALLER_PACKAGE = "@sellable/install@0.1.698";
|
|
42
42
|
const MCP_PACKAGE = "@sellable/mcp@0.1.904";
|
|
43
43
|
const HERMES_VERSION = "0.18.0";
|
|
44
44
|
const SHA256 = /^[a-f0-9]{64}$/;
|
|
@@ -1547,7 +1547,7 @@ export function compileClaimToProfileDesired(activeClaim, config) {
|
|
|
1547
1547
|
pinned.hermesCli !== "hermes" ||
|
|
1548
1548
|
pinned.hermesVersion !== "0.18.0" ||
|
|
1549
1549
|
pinned.installerPackage !==
|
|
1550
|
-
"@sellable/install@0.1.
|
|
1550
|
+
"@sellable/install@0.1.698" ||
|
|
1551
1551
|
pinned.mcpPackage !== "@sellable/mcp@0.1.904" ||
|
|
1552
1552
|
!Array.isArray(policy.toolInclude) ||
|
|
1553
1553
|
policy.toolInclude.length === 0 ||
|
|
@@ -283,7 +283,7 @@ function validateDesired(desired) {
|
|
|
283
283
|
desired.hermesCli !== "hermes" ||
|
|
284
284
|
desired.hermesVersion !== "0.18.0" ||
|
|
285
285
|
desired.installerPackage !==
|
|
286
|
-
"@sellable/install@0.1.
|
|
286
|
+
"@sellable/install@0.1.698" ||
|
|
287
287
|
desired.mcpPackage !== "@sellable/mcp@0.1.904" ||
|
|
288
288
|
!Array.isArray(desired.toolInclude) ||
|
|
289
289
|
desired.toolInclude.length === 0 ||
|
|
@@ -26,7 +26,7 @@ import { deriveContainedProfileId } from "./profile-materializer.mjs";
|
|
|
26
26
|
|
|
27
27
|
export const PROVISIONING_ACTION = "PROVISION_HERMES_PROFILE";
|
|
28
28
|
export const PINNED_INSTALL_PACKAGE =
|
|
29
|
-
"@sellable/install@0.1.
|
|
29
|
+
"@sellable/install@0.1.698";
|
|
30
30
|
export const PINNED_MCP_PACKAGE = "@sellable/mcp@0.1.904";
|
|
31
31
|
const PINNED_INSTALL_VERSION = PINNED_INSTALL_PACKAGE.slice(
|
|
32
32
|
PINNED_INSTALL_PACKAGE.lastIndexOf("@") + 1
|