@addai/node 0.30.13 → 0.30.14

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.
Files changed (143) hide show
  1. package/dist/auto-update.d.ts +3 -0
  2. package/dist/auto-update.js +15 -0
  3. package/dist/capabilities.d.ts +17 -3
  4. package/dist/capabilities.js +18 -8
  5. package/dist/claude-models.d.ts +4 -12
  6. package/dist/claude-models.js +12 -88
  7. package/dist/claude-print.d.ts +15 -0
  8. package/dist/claude-print.js +16 -0
  9. package/dist/codex-models.d.ts +81 -0
  10. package/dist/codex-models.js +385 -0
  11. package/dist/codex-spawn.d.ts +14 -8
  12. package/dist/codex-spawn.js +30 -10
  13. package/dist/command-runner.js +31 -9
  14. package/dist/desktop/docker.js +2 -0
  15. package/dist/desktop/manager.d.ts +2 -1
  16. package/dist/desktop/manager.js +51 -1
  17. package/dist/desktop/provider.d.ts +1 -1
  18. package/dist/desktop/provider.js +2 -0
  19. package/dist/desktop/relay-client.js +7 -0
  20. package/dist/desktop/spec.d.ts +2 -0
  21. package/dist/direct/aios-bridge.d.ts +13 -0
  22. package/dist/direct/aios-bridge.js +177 -0
  23. package/dist/direct/aios-mcp.d.ts +2 -0
  24. package/dist/direct/aios-mcp.js +132 -0
  25. package/dist/direct/aios-tools.d.ts +351 -0
  26. package/dist/direct/aios-tools.js +120 -0
  27. package/dist/direct/board-chat-provider.d.ts +64 -0
  28. package/dist/direct/board-chat-provider.js +151 -0
  29. package/dist/direct/board-chat.d.ts +40 -0
  30. package/dist/direct/board-chat.js +414 -0
  31. package/dist/direct/config.d.ts +2 -0
  32. package/dist/direct/config.js +60 -0
  33. package/dist/direct/launch.d.ts +14 -0
  34. package/dist/direct/launch.js +121 -0
  35. package/dist/direct/protocol.d.ts +46 -0
  36. package/dist/direct/protocol.js +84 -0
  37. package/dist/direct/relay-main.d.ts +1 -0
  38. package/dist/direct/relay-main.js +21 -0
  39. package/dist/direct/relay.d.ts +26 -0
  40. package/dist/direct/relay.js +334 -0
  41. package/dist/direct/sessions.d.ts +61 -0
  42. package/dist/direct/sessions.js +368 -0
  43. package/dist/direct/supervisor.d.ts +9 -0
  44. package/dist/direct/supervisor.js +137 -0
  45. package/dist/direct/terminal.d.ts +1 -0
  46. package/dist/direct/terminal.js +106 -0
  47. package/dist/direct/worker.d.ts +1 -0
  48. package/dist/direct/worker.js +278 -0
  49. package/dist/entitybox/container-action.cjs +85 -0
  50. package/dist/entitybox/container-watchdog.cjs +70 -0
  51. package/dist/entitybox/model-entry.d.ts +3 -0
  52. package/dist/entitybox/model-entry.js +233 -0
  53. package/dist/entitybox/model-mcp-proxy.d.ts +3 -0
  54. package/dist/entitybox/model-mcp-proxy.js +85 -0
  55. package/dist/entitybox-application-boundary.d.ts +59 -0
  56. package/dist/entitybox-application-boundary.js +161 -0
  57. package/dist/entitybox-application-guard-core.d.ts +44 -0
  58. package/dist/entitybox-application-guard-core.js +164 -0
  59. package/dist/entitybox-application-guard-process.d.ts +1 -0
  60. package/dist/entitybox-application-guard-process.js +83 -0
  61. package/dist/entitybox-application-guard.d.ts +46 -0
  62. package/dist/entitybox-application-guard.js +239 -0
  63. package/dist/entitybox-capacity-health-host.d.ts +12 -0
  64. package/dist/entitybox-capacity-health-host.js +80 -0
  65. package/dist/entitybox-capacity-health-worker.d.ts +22 -0
  66. package/dist/entitybox-capacity-health-worker.js +168 -0
  67. package/dist/entitybox-capacity-host.d.ts +17 -0
  68. package/dist/entitybox-capacity-host.js +155 -0
  69. package/dist/entitybox-capacity-owner-process.d.ts +1 -0
  70. package/dist/entitybox-capacity-owner-process.js +32 -0
  71. package/dist/entitybox-capacity-owner.d.ts +16 -0
  72. package/dist/entitybox-capacity-owner.js +90 -0
  73. package/dist/entitybox-capacity-programs.d.ts +7 -0
  74. package/dist/entitybox-capacity-programs.js +49 -0
  75. package/dist/entitybox-capacity-provisioner.d.ts +82 -0
  76. package/dist/entitybox-capacity-provisioner.js +404 -0
  77. package/dist/entitybox-capacity-publication.d.ts +29 -0
  78. package/dist/entitybox-capacity-publication.js +199 -0
  79. package/dist/entitybox-capacity-registration.d.ts +36 -0
  80. package/dist/entitybox-capacity-registration.js +75 -0
  81. package/dist/entitybox-capacity-worker.d.ts +29 -0
  82. package/dist/entitybox-capacity-worker.js +113 -0
  83. package/dist/entitybox-computer-task.d.ts +69 -0
  84. package/dist/entitybox-computer-task.js +176 -0
  85. package/dist/entitybox-controller-recovery.d.ts +40 -0
  86. package/dist/entitybox-controller-recovery.js +156 -0
  87. package/dist/entitybox-desktop-action-server.d.ts +34 -0
  88. package/dist/entitybox-desktop-action-server.js +176 -0
  89. package/dist/entitybox-desktop-admission.d.ts +32 -0
  90. package/dist/entitybox-desktop-admission.js +79 -0
  91. package/dist/entitybox-display-binding.d.ts +13 -0
  92. package/dist/entitybox-display-binding.js +31 -0
  93. package/dist/entitybox-execution-container.d.ts +82 -0
  94. package/dist/entitybox-execution-container.js +450 -0
  95. package/dist/entitybox-execution-host.d.ts +40 -0
  96. package/dist/entitybox-execution-host.js +168 -0
  97. package/dist/entitybox-execution-lease.d.ts +81 -0
  98. package/dist/entitybox-execution-lease.js +332 -0
  99. package/dist/entitybox-file-inputs.d.ts +51 -0
  100. package/dist/entitybox-file-inputs.js +182 -0
  101. package/dist/entitybox-file-session.d.ts +38 -0
  102. package/dist/entitybox-file-session.js +82 -0
  103. package/dist/entitybox-host-process.d.ts +12 -0
  104. package/dist/entitybox-host-process.js +120 -0
  105. package/dist/entitybox-install.d.ts +10 -0
  106. package/dist/entitybox-install.js +40 -0
  107. package/dist/entitybox-mcp-broker.d.ts +77 -0
  108. package/dist/entitybox-mcp-broker.js +420 -0
  109. package/dist/entitybox-mcp-contract.d.ts +10 -0
  110. package/dist/entitybox-mcp-contract.js +24 -0
  111. package/dist/entitybox-mcp-guard.d.ts +3 -0
  112. package/dist/entitybox-mcp-guard.js +167 -0
  113. package/dist/entitybox-model-artifact.d.ts +9 -0
  114. package/dist/entitybox-model-artifact.js +83 -0
  115. package/dist/entitybox-native-services.d.ts +33 -0
  116. package/dist/entitybox-native-services.js +172 -0
  117. package/dist/entitybox-operation.d.ts +4 -0
  118. package/dist/entitybox-operation.js +34 -0
  119. package/dist/entitybox-provider-broker.d.ts +41 -0
  120. package/dist/entitybox-provider-broker.js +149 -0
  121. package/dist/entitybox-queue-request.d.ts +32 -0
  122. package/dist/entitybox-queue-request.js +141 -0
  123. package/dist/entitybox-recovery-host.d.ts +12 -0
  124. package/dist/entitybox-recovery-host.js +80 -0
  125. package/dist/entitybox-recovery-store.d.ts +33 -0
  126. package/dist/entitybox-recovery-store.js +150 -0
  127. package/dist/entitybox-recovery-worker.d.ts +30 -0
  128. package/dist/entitybox-recovery-worker.js +134 -0
  129. package/dist/entitybox-vault-provider.d.ts +27 -0
  130. package/dist/entitybox-vault-provider.js +127 -0
  131. package/dist/harness-registry.js +3 -1
  132. package/dist/index.js +72 -38
  133. package/dist/install.d.ts +14 -2
  134. package/dist/install.js +115 -10
  135. package/dist/model-cache.d.ts +38 -0
  136. package/dist/model-cache.js +137 -0
  137. package/dist/request-pump.d.ts +3 -0
  138. package/dist/request-pump.js +21 -7
  139. package/dist/session-runner.d.ts +8 -1
  140. package/dist/session-runner.js +48 -3
  141. package/dist/supabase-client.js +4 -1
  142. package/package.json +5 -1
  143. package/scripts/copy-assets.js +4 -2
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ENTITYBOX_MODEL_LOADER = exports.ENTITYBOX_MODEL_FILES = void 0;
37
+ exports.readEntityboxModelArtifact = readEntityboxModelArtifact;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const crypto_1 = require("crypto");
41
+ const entitybox_execution_lease_1 = require("./entitybox-execution-lease");
42
+ /** Explicit compiled adapter dependencies. Never enumerate host configuration,
43
+ * login state, provider directories or the rest of the runtime distribution. */
44
+ exports.ENTITYBOX_MODEL_FILES = Object.freeze([
45
+ 'paths.js', 'claude-binary.js', 'win.js', 'claude-system-prompt.js',
46
+ 'prompt-transport.js', 'claude-print.js', 'entitybox/model-mcp-proxy.js', 'entitybox/model-entry.js',
47
+ ]);
48
+ function readEntityboxModelArtifact(compiledRoot = __dirname) {
49
+ try {
50
+ const files = {};
51
+ for (const name of exports.ENTITYBOX_MODEL_FILES) {
52
+ const file = path.join(compiledRoot, ...name.split('/'));
53
+ const stat = fs.lstatSync(file);
54
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 128 * 1024)
55
+ throw Error();
56
+ files[name] = fs.readFileSync(file, 'utf8');
57
+ }
58
+ const bytes = JSON.stringify(files);
59
+ if (Buffer.byteLength(bytes) > 192 * 1024)
60
+ throw Error();
61
+ return Object.freeze({ files: Object.freeze(files), sha256: (0, crypto_1.createHash)('sha256').update(bytes).digest('hex') });
62
+ }
63
+ catch {
64
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('The isolated native model adapter is unavailable');
65
+ }
66
+ }
67
+ // This entrypoint executes only inside the task namespace as UID 10001. All
68
+ // filenames are fixed, and only the public adapter/task crosses stdin.
69
+ exports.ENTITYBOX_MODEL_LOADER = `
70
+ const fs=require('node:fs'),path=require('node:path');
71
+ const names=${JSON.stringify(exports.ENTITYBOX_MODEL_FILES)};
72
+ let input='';const fail=()=>{console.log(JSON.stringify({type:'error',code:'entitybox_model_adapter_failed',message:'The isolated model adapter could not start.'}));process.exit(70);};
73
+ if(process.getuid?.()!==10001||process.env.HOME!=='/home/entitybox'||!fs.existsSync('/.dockerenv'))fail();
74
+ process.stdin.setEncoding('utf8');process.stdin.on('error',fail);
75
+ process.stdin.on('data',part=>{input+=part;if(Buffer.byteLength(input)>240*1024)fail();});
76
+ process.stdin.on('end',async()=>{try{
77
+ const value=JSON.parse(input),files=value.files;
78
+ if(!files||Array.isArray(files)||Object.keys(files).sort().join(',')!==[...names].sort().join(','))throw Error();
79
+ fs.mkdirSync('/work/entitybox-runner/entitybox',{recursive:true});
80
+ for(const name of names){if(typeof files[name]!=='string'||Buffer.byteLength(files[name])>128*1024)throw Error();fs.writeFileSync(path.join('/work/entitybox-runner',name),files[name],{mode:0o600,flag:'wx'});}
81
+ const code=await require('/work/entitybox-runner/entitybox/model-entry.js').runEntityboxModel(value.task);process.exit(code===0?0:70);
82
+ }catch{fail();}});
83
+ `;
@@ -0,0 +1,33 @@
1
+ import { type EntityboxApplicationBinding, type EntityboxApplicationDocker } from './entitybox-application-boundary';
2
+ import { type EntityboxDisplayBinding } from './entitybox-display-binding';
3
+ import type { EntityboxQueueServices } from './entitybox-queue-request';
4
+ import type { resolveEntityboxDesktopConnection } from './install';
5
+ export interface EntityboxDedicatedCapacity {
6
+ application: EntityboxApplicationBinding;
7
+ display: EntityboxDisplayBinding;
8
+ }
9
+ export interface EntityboxNativeServicesConfiguration {
10
+ /** Explicit trusted host configuration. SQL feature flags still authorize
11
+ * every claim/registration. Nothing is discovered from an ordinary desktop. */
12
+ enabled?: boolean;
13
+ runtimeId: string;
14
+ imageId: string;
15
+ dockerContext?: string;
16
+ recoveryDirectory: string;
17
+ capacities: readonly EntityboxDedicatedCapacity[];
18
+ desktopTools: readonly string[];
19
+ fileGatewayUrl?: string;
20
+ }
21
+ export interface EntityboxNativeServicesTransport {
22
+ /** Test transports only; never renderer, request, tool or model input. */
23
+ docker?: EntityboxApplicationDocker;
24
+ resolveConnection?: typeof resolveEntityboxDesktopConnection;
25
+ providerFetch?: typeof fetch;
26
+ vaultFetch?: typeof fetch;
27
+ fileFetch?: typeof fetch;
28
+ }
29
+ /** Compose existing native identity/Vault/CLI/MCP and independent browser
30
+ * ownership. The normal queue is unchanged until an explicit caller registers
31
+ * these services. Preparation is read-only; every resource owner is retained
32
+ * before its asynchronous startup can fail. */
33
+ export declare function createEntityboxNativeServices(config: EntityboxNativeServicesConfiguration, transport?: EntityboxNativeServicesTransport): EntityboxQueueServices | undefined;
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createEntityboxNativeServices = createEntityboxNativeServices;
37
+ const child_process_1 = require("child_process");
38
+ const util_1 = require("util");
39
+ const entitybox_execution_lease_1 = require("./entitybox-execution-lease");
40
+ const entitybox_application_guard_1 = require("./entitybox-application-guard");
41
+ const entitybox_application_boundary_1 = require("./entitybox-application-boundary");
42
+ const entitybox_display_binding_1 = require("./entitybox-display-binding");
43
+ const entitybox_recovery_store_1 = require("./entitybox-recovery-store");
44
+ const entitybox_vault_provider_1 = require("./entitybox-vault-provider");
45
+ const entitybox_operation_1 = require("./entitybox-operation");
46
+ const entitybox_file_inputs_1 = require("./entitybox-file-inputs");
47
+ const uuid = /^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$/, fail = () => new entitybox_execution_lease_1.EntityboxExecutionError('The dedicated computer task configuration could not be verified'), exec = (0, util_1.promisify)(child_process_1.execFile);
48
+ /** Compose existing native identity/Vault/CLI/MCP and independent browser
49
+ * ownership. The normal queue is unchanged until an explicit caller registers
50
+ * these services. Preparation is read-only; every resource owner is retained
51
+ * before its asynchronous startup can fail. */
52
+ function createEntityboxNativeServices(config, transport = {}) {
53
+ if (config.enabled !== true)
54
+ return undefined;
55
+ const context = config.dockerContext ?? 'desktop-linux';
56
+ const fileGateway = config.fileGatewayUrl === undefined ? undefined : (0, entitybox_file_inputs_1.entityboxFileGatewayUrl)(config.fileGatewayUrl);
57
+ if (!uuid.test(config.runtimeId) || !/^sha256:[a-f0-9]{64}$/.test(config.imageId) || !/^[-a-zA-Z0-9_.]{1,80}$/.test(context)
58
+ || !Array.isArray(config.capacities) || !config.capacities.length || config.capacities.length > 50
59
+ || !Array.isArray(config.desktopTools) || !config.desktopTools.length || config.desktopTools.length > 64
60
+ || !config.desktopTools.every(s => /^[A-Za-z0-9_-]{1,128}$/.test(s)) || new Set(config.desktopTools).size !== config.desktopTools.length)
61
+ throw fail();
62
+ const runtimeId = config.runtimeId, imageId = config.imageId, tools = Object.freeze([...config.desktopTools]), capacities = new Map(), ids = new Set();
63
+ for (const c of config.capacities) {
64
+ const a = c?.application, d = c?.display;
65
+ if (!a || !d || !uuid.test(a.desktopId) || !uuid.test(a.capacityId) || a.desktopId !== d.desktopId || a.runtimeId !== runtimeId || d.runtimeId !== runtimeId || a.capacityId !== d.capacityId || a.containerId === d.containerId || capacities.has(a.desktopId) || ids.has(a.capacityId) || ids.has(a.containerId) || ids.has(d.containerId))
66
+ throw fail();
67
+ for (const b of [a, d])
68
+ if (!/^[a-f0-9]{64}$/.test(b.containerId) || !/^sha256:[a-f0-9]{64}$/.test(b.imageId) || !Number.isFinite(Date.parse(b.startedAt)))
69
+ throw fail();
70
+ ids.add(a.capacityId);
71
+ ids.add(a.containerId);
72
+ ids.add(d.containerId);
73
+ capacities.set(a.desktopId, { application: Object.freeze({ ...a }), display: Object.freeze({ ...d }) });
74
+ }
75
+ const store = new entitybox_recovery_store_1.EntityboxRecoveryStore(config.recoveryDirectory), docker = transport.docker ?? (async (args) => (await exec('docker', ['--context', context, ...args], { windowsHide: true, timeout: 5000, maxBuffer: 1024 * 1024 })).stdout.trim());
76
+ return { prepare: async (request, lease, signal) => {
77
+ try {
78
+ lease.assertActive();
79
+ if (signal.aborted || request.runtime_id !== runtimeId || lease.identity.scope.runtimeId !== runtimeId || request.id !== lease.identity.requestId || request.desktop_id !== lease.identity.scope.desktopId)
80
+ throw fail();
81
+ const capacity = capacities.get(request.desktop_id);
82
+ if (!capacity)
83
+ throw fail();
84
+ // Never silently discard a selected installation or reuse a host session.
85
+ // Those broader capabilities require their own contained installation path.
86
+ if (request.mcp_mode !== 'override' || !Array.isArray(request.mcps_override) || request.mcps_override.length !== 1 || !uuid.test(request.mcps_override[0])
87
+ || (request.skills_override ?? []).length || (request.packages_override ?? []).length || Object.keys(request.skill_var_values ?? {}).length
88
+ || request.resume_session_id || request.working_directory || request.project_id || request.ephemeral_git_remote || (request.ephemeral_git_remotes ?? []).length
89
+ || Object.keys(request.mcp_env_overrides ?? {}).some(k => k !== 'entity-desktop-mcp')
90
+ || typeof request.prompt !== 'string' || !request.prompt.trim() || request.prompt.length > 12000
91
+ || (request.system_prompt != null && (typeof request.system_prompt !== 'string' || request.system_prompt.length > 64000))
92
+ || (request.permission_mode != null && !['default', 'plan', 'dontAsk', 'acceptEdits', 'auto', 'bypassPermissions'].includes(request.permission_mode))
93
+ || (request.effort != null && !['low', 'medium', 'high', 'xhigh', 'max'].includes(request.effort)))
94
+ throw fail();
95
+ let selected = [...tools];
96
+ if (request.allowed_tools != null) {
97
+ if (!Array.isArray(request.allowed_tools) || !request.allowed_tools.length || request.allowed_tools.some(t => !tools.some(n => t === 'mcp__entity-desktop-mcp__' + n)))
98
+ throw fail();
99
+ selected = tools.filter(t => request.allowed_tools.includes('mcp__entity-desktop-mcp__' + t));
100
+ }
101
+ await (0, entitybox_operation_1.entityboxOperation)([lease.signal, signal], 5000, async () => {
102
+ await (0, entitybox_display_binding_1.verifyEntityboxDisplay)(capacity.display, lease.identity.scope, docker);
103
+ if (await (0, entitybox_application_boundary_1.inspectEntityboxApplication)(capacity.application, lease.identity.scope, docker) !== 'paused')
104
+ throw fail();
105
+ });
106
+ const resolve = transport.resolveConnection ?? (await Promise.resolve().then(() => __importStar(require('./install')))).resolveEntityboxDesktopConnection;
107
+ const connection = await resolve({ mcpIds: [...request.mcps_override], skillIds: [], packageIds: [] }, request.mcp_env_overrides ?? undefined, request.id, signal);
108
+ lease.assertActive();
109
+ if (signal.aborted)
110
+ throw fail();
111
+ const provider = await (0, entitybox_vault_provider_1.entityboxNativeProvider)(lease, connection.env.ENTITY_API_KEY, signal, transport.vaultFetch);
112
+ if (provider.models.length !== 1 || request.model !== provider.models[0])
113
+ throw fail();
114
+ lease.assertActive();
115
+ if (signal.aborted)
116
+ throw fail();
117
+ if (request.entitybox_file_request === true && !fileGateway)
118
+ throw fail();
119
+ const fileInputs = request.entitybox_file_request === true && fileGateway ? lease.fileInputs(fileGateway, transport.fileFetch) : undefined;
120
+ let guard, preparing, resource, registered;
121
+ return {
122
+ options: { imageId, dockerContext: context, display: capacity.display, connection, desktopTools: selected, provider: { ...provider, ...(fileInputs ? { fileInputs } : {}), ...(transport.providerFetch ? { fetch: transport.providerFetch } : {}) },
123
+ task: { prompt: fileInputs ? fileInputs.prompt(request.prompt) : request.prompt, model: provider.models[0], systemPrompt: request.system_prompt ?? undefined, permissionMode: request.permission_mode ?? undefined, effort: request.effort ?? undefined },
124
+ onContainerCreated: r => {
125
+ if (preparing)
126
+ throw fail();
127
+ resource = Object.freeze({ ...r });
128
+ preparing = Promise.resolve().then(async () => {
129
+ lease.assertActive();
130
+ await lease.registerResource('display', { ...capacity.display });
131
+ await entitybox_application_guard_1.EntityboxApplicationGuard.attach(lease, capacity.application, { dockerContext: context, requireInventory: true, recoveryStore: store, onOwner: value => { guard = value; } });
132
+ lease.assertActive();
133
+ await lease.registerResource('execution', { ...resource });
134
+ await lease.sealInventory(true);
135
+ });
136
+ return preparing;
137
+ },
138
+ },
139
+ register: async (container) => {
140
+ if (!preparing || !resource || registered || container.id !== resource.containerId)
141
+ throw fail();
142
+ registered = container;
143
+ await preparing;
144
+ lease.assertInventorySealed();
145
+ if (!guard)
146
+ throw fail();
147
+ await guard.resume();
148
+ },
149
+ verifyAllStopped: async () => {
150
+ // Late preparation must settle, even when the coordinator's observation
151
+ // deadline already failed. An unresolved/failed guard cannot grant reuse.
152
+ if (preparing)
153
+ try {
154
+ await preparing;
155
+ }
156
+ catch { }
157
+ if (registered)
158
+ await registered.stopAndVerify();
159
+ if (guard)
160
+ await guard.pauseAndVerify();
161
+ else if (preparing)
162
+ throw fail();
163
+ if (await (0, entitybox_application_boundary_1.inspectEntityboxApplication)(capacity.application, lease.identity.scope, docker) === 'running')
164
+ throw fail();
165
+ },
166
+ };
167
+ }
168
+ catch {
169
+ throw fail();
170
+ }
171
+ } };
172
+ }
@@ -0,0 +1,4 @@
1
+ /** A bounded host operation. Cancellation covers response bodies and delayed
2
+ * credential callbacks, not just receipt of HTTP headers. Late settlement is
3
+ * observed by the race but cannot return a result to the caller. */
4
+ export declare function entityboxOperation<T>(signals: readonly AbortSignal[], timeoutMs: number, operation: (signal: AbortSignal) => Promise<T>): Promise<T>;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.entityboxOperation = entityboxOperation;
4
+ const entitybox_execution_lease_1 = require("./entitybox-execution-lease");
5
+ /** A bounded host operation. Cancellation covers response bodies and delayed
6
+ * credential callbacks, not just receipt of HTTP headers. Late settlement is
7
+ * observed by the race but cannot return a result to the caller. */
8
+ async function entityboxOperation(signals, timeoutMs, operation) {
9
+ if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 120000)
10
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Invalid operation deadline');
11
+ const controller = new AbortController(), inputs = [...new Set(signals)];
12
+ let reject;
13
+ const canceled = new Promise((_, r) => { reject = r; });
14
+ const abort = () => { controller.abort(); reject(new entitybox_execution_lease_1.EntityboxExecutionError('Computer operation ended')); };
15
+ for (const signal of inputs)
16
+ signal.addEventListener('abort', abort, { once: true });
17
+ const timer = setTimeout(abort, timeoutMs);
18
+ try {
19
+ if (inputs.some(s => s.aborted))
20
+ abort();
21
+ const work = Promise.resolve().then(() => { if (controller.signal.aborted)
22
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Computer operation ended'); return operation(controller.signal); });
23
+ const result = await Promise.race([work, canceled]);
24
+ if (controller.signal.aborted)
25
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Computer operation ended');
26
+ return result;
27
+ }
28
+ finally {
29
+ clearTimeout(timer);
30
+ for (const signal of inputs)
31
+ signal.removeEventListener('abort', abort);
32
+ controller.abort();
33
+ }
34
+ }
@@ -0,0 +1,41 @@
1
+ import { type EntityboxExecutionLease } from './entitybox-execution-lease';
2
+ import { EntityboxFileInputs } from './entitybox-file-inputs';
3
+ export type EntityboxBrokerEvent = {
4
+ type: 'head';
5
+ status: number;
6
+ contentType: string;
7
+ } | {
8
+ type: 'data';
9
+ data: string;
10
+ } | {
11
+ type: 'end';
12
+ };
13
+ export type EntityboxBrokerEmit = (event: EntityboxBrokerEvent) => Promise<void>;
14
+ interface Config {
15
+ /** Supplied by the trusted native request adapter, never by model input. */
16
+ models: readonly string[];
17
+ fileInputs?: EntityboxFileInputs;
18
+ apiKey: (signal: AbortSignal) => Promise<string>;
19
+ /** Transport injection for isolated fixtures; production defaults to fetch. */
20
+ fetch?: typeof fetch;
21
+ }
22
+ /** Streaming exact-secret scrubber retains partial prefixes across chunks.
23
+ * Provider error bodies and response headers are never passed through. */
24
+ export declare class EntityboxSecretFilter {
25
+ private readonly secret;
26
+ private tail;
27
+ constructor(secret: string);
28
+ push(text: string, final?: boolean): string;
29
+ }
30
+ /** Provider access stays in the trusted native process. The container can
31
+ * submit only bounded Anthropic-format inference/token-count requests, not a
32
+ * URL, authentication header, upload, admin operation or arbitrary fetch. */
33
+ export declare class EntityboxProviderBroker {
34
+ private readonly lease;
35
+ private readonly config;
36
+ private count;
37
+ constructor(lease: EntityboxExecutionLease, config: Config);
38
+ handle(raw: unknown, signal: AbortSignal, emit: EntityboxBrokerEmit): Promise<void>;
39
+ private send;
40
+ }
41
+ export {};
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityboxProviderBroker = exports.EntityboxSecretFilter = void 0;
4
+ const entitybox_execution_lease_1 = require("./entitybox-execution-lease");
5
+ const entitybox_operation_1 = require("./entitybox-operation");
6
+ const entitybox_file_inputs_1 = require("./entitybox-file-inputs");
7
+ /** Streaming exact-secret scrubber retains partial prefixes across chunks.
8
+ * Provider error bodies and response headers are never passed through. */
9
+ class EntityboxSecretFilter {
10
+ secret;
11
+ tail = '';
12
+ constructor(secret) {
13
+ this.secret = secret;
14
+ }
15
+ push(text, final = false) {
16
+ const all = (this.tail + text).split(this.secret).join('[redacted]');
17
+ this.tail = '';
18
+ if (final)
19
+ return all;
20
+ let hold = 0;
21
+ for (let i = 1; i < Math.min(this.secret.length, all.length + 1); i++)
22
+ if (all.endsWith(this.secret.slice(0, i)))
23
+ hold = i;
24
+ if (hold) {
25
+ this.tail = all.slice(-hold);
26
+ return all.slice(0, -hold);
27
+ }
28
+ return all;
29
+ }
30
+ }
31
+ exports.EntityboxSecretFilter = EntityboxSecretFilter;
32
+ /** Provider access stays in the trusted native process. The container can
33
+ * submit only bounded Anthropic-format inference/token-count requests, not a
34
+ * URL, authentication header, upload, admin operation or arbitrary fetch. */
35
+ class EntityboxProviderBroker {
36
+ lease;
37
+ config;
38
+ count = 0;
39
+ constructor(lease, config) {
40
+ this.lease = lease;
41
+ this.config = config;
42
+ if (!config.models.length || !config.models.every(m => /^[a-zA-Z0-9_.:-]{1,120}$/.test(m)))
43
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Invalid provider model configuration');
44
+ }
45
+ async handle(raw, signal, emit) {
46
+ this.lease.assertActive();
47
+ const r = raw;
48
+ if (!r || r.kind !== 'provider' || r.method !== 'POST' || !['/v1/messages', '/v1/messages?beta=true', '/v1/messages/count_tokens', '/v1/messages/count_tokens?beta=true'].includes(r.path)
49
+ || typeof r.body !== 'string' || Buffer.byteLength(r.body) > 512 * 1024
50
+ || (r.beta !== undefined && (typeof r.beta !== 'string' || !/^[-a-zA-Z0-9,]{1,1024}$/.test(r.beta)))
51
+ || Object.keys(r).some(k => !['kind', 'method', 'path', 'body', 'beta'].includes(k)))
52
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Provider request is unavailable');
53
+ let body;
54
+ try {
55
+ body = JSON.parse(r.body);
56
+ }
57
+ catch {
58
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Invalid provider request');
59
+ }
60
+ if (!body || !this.config.models.includes(String(body.model)) || !Array.isArray(body.messages)
61
+ || (body.max_tokens !== undefined && (!Number.isInteger(body.max_tokens) || Number(body.max_tokens) < 1 || Number(body.max_tokens) > 32768)))
62
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Provider model or limits are unavailable');
63
+ if (++this.count > 128)
64
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Provider request limit reached');
65
+ const controller = new AbortController();
66
+ const abort = () => controller.abort();
67
+ signal.addEventListener('abort', abort, { once: true });
68
+ this.lease.signal.addEventListener('abort', abort, { once: true });
69
+ const timer = setTimeout(abort, 120000);
70
+ let reader;
71
+ try {
72
+ if (signal.aborted || this.lease.signal.aborted)
73
+ throw new Error();
74
+ let attached = false, requestBody = r.body;
75
+ if (this.config.fileInputs) {
76
+ attached = await this.config.fileInputs.attach(body, controller.signal);
77
+ this.lease.assertActive();
78
+ if (controller.signal.aborted)
79
+ throw new Error();
80
+ requestBody = JSON.stringify(body);
81
+ if (Buffer.byteLength(requestBody) > entitybox_file_inputs_1.ENTITYBOX_PROVIDER_BYTES)
82
+ throw new entitybox_file_inputs_1.EntityboxFileInputError();
83
+ }
84
+ const key = await (0, entitybox_operation_1.entityboxOperation)([controller.signal], 10000, signal => this.config.apiKey(signal));
85
+ this.lease.assertActive();
86
+ if (signal.aborted || controller.signal.aborted || typeof key !== 'string' || !/^sk-ant-[A-Za-z0-9_-]{20,}$/.test(key))
87
+ throw new Error();
88
+ const headers = { 'content-type': 'application/json', 'anthropic-version': '2023-06-01', 'x-api-key': key };
89
+ if (r.beta)
90
+ headers['anthropic-beta'] = r.beta;
91
+ const response = await (this.config.fetch ?? fetch)('https://api.anthropic.com' + r.path, { method: 'POST', headers, body: requestBody, signal: controller.signal, redirect: 'error' });
92
+ this.lease.assertActive();
93
+ if (controller.signal.aborted)
94
+ throw new Error();
95
+ if (!response.ok) {
96
+ await response.body?.cancel();
97
+ await emit({ type: 'head', status: response.status === 429 ? 429 : attached && response.status === 400 ? 400 : 502, contentType: 'application/json' });
98
+ await emit({ type: 'data', data: Buffer.from(JSON.stringify({ type: 'error', error: { type: 'api_error', message: attached && response.status === 400 ? new entitybox_file_inputs_1.EntityboxFileInputError().message : 'The configured provider could not complete this request.' } })).toString('base64') });
99
+ await emit({ type: 'end' });
100
+ return;
101
+ }
102
+ const contentType = (response.headers.get('content-type') || '').split(';')[0];
103
+ if (!['application/json', 'text/event-stream'].includes(contentType) || !response.body)
104
+ throw new Error();
105
+ await emit({ type: 'head', status: 200, contentType });
106
+ reader = response.body.getReader();
107
+ const decoder = new TextDecoder(), filter = new EntityboxSecretFilter(key);
108
+ let total = 0;
109
+ while (true) {
110
+ const value = await reader.read();
111
+ this.lease.assertActive();
112
+ if (controller.signal.aborted)
113
+ throw new Error();
114
+ if (value.done)
115
+ break;
116
+ total += value.value.byteLength;
117
+ if (total > 16 * 1024 * 1024)
118
+ throw new Error();
119
+ const safe = filter.push(decoder.decode(value.value, { stream: true }));
120
+ if (safe)
121
+ await this.send(safe, emit);
122
+ }
123
+ const rest = filter.push(decoder.decode(), true);
124
+ if (rest)
125
+ await this.send(rest, emit);
126
+ await emit({ type: 'end' });
127
+ }
128
+ catch (error) {
129
+ controller.abort();
130
+ if (error instanceof entitybox_file_inputs_1.EntityboxFileInputError && !signal.aborted && !this.lease.signal.aborted) {
131
+ await emit({ type: 'head', status: 400, contentType: 'application/json' });
132
+ await emit({ type: 'data', data: Buffer.from(JSON.stringify({ type: 'error', error: { type: 'invalid_request_error', message: error.message } })).toString('base64') });
133
+ await emit({ type: 'end' });
134
+ return;
135
+ }
136
+ throw new entitybox_execution_lease_1.EntityboxExecutionError('Provider connection ended');
137
+ }
138
+ finally {
139
+ clearTimeout(timer);
140
+ signal.removeEventListener('abort', abort);
141
+ this.lease.signal.removeEventListener('abort', abort);
142
+ await reader?.cancel().catch(() => { });
143
+ reader?.releaseLock();
144
+ }
145
+ }
146
+ async send(text, emit) { const bytes = Buffer.from(text); for (let offset = 0; offset < bytes.length; offset += 16384)
147
+ await emit({ type: 'data', data: bytes.subarray(offset, offset + 16384).toString('base64') }); }
148
+ }
149
+ exports.EntityboxProviderBroker = EntityboxProviderBroker;
@@ -0,0 +1,32 @@
1
+ import { EntityboxExecutionLease } from './entitybox-execution-lease';
2
+ import { EntityboxComputerTask, type EntityboxComputerTaskOptions } from './entitybox-computer-task';
3
+ import type { EntityboxExecutionContainer } from './entitybox-execution-container';
4
+ import type { RuntimeRequestRow } from './session-runner';
5
+ interface Io {
6
+ rpc: <T>(name: string, args: Record<string, unknown>) => Promise<T>;
7
+ pairing: () => {
8
+ runtimeId: string;
9
+ daemonToken: string;
10
+ } | null;
11
+ }
12
+ export interface EntityboxQueueServices {
13
+ /** Runtime shutdown fences isolated work; ordinary native requests are unchanged. */
14
+ readonly signal?: AbortSignal;
15
+ /** Trusted runtime adapter only. Resolve selected credentials and existing
16
+ * dedicated capacity without starting processes or writing host projects.
17
+ * The lease already proves the native request mapping and its principal. */
18
+ prepare: (request: Readonly<RuntimeRequestRow>, lease: EntityboxExecutionLease, signal: AbortSignal) => Promise<{
19
+ options: Omit<EntityboxComputerTaskOptions, 'onEvent' | 'onContainer' | 'onTask'>;
20
+ register: (container: EntityboxExecutionContainer) => Promise<void>;
21
+ /** Must prove ALL owned resources, including persistent application work.
22
+ * A stopped model/MCP alone is insufficient. Uncertain cleanup retains
23
+ * the native reservation for explicit recovery. */
24
+ verifyAllStopped: () => Promise<void>;
25
+ onTask?: (task: EntityboxComputerTask) => void;
26
+ }>;
27
+ }
28
+ /** Called before native host auth, cwd/project preparation or installation.
29
+ * No adapter means disabled, never ordinary-host fallback. An MCP scope is
30
+ * only a route marker: the runtime-authenticated SQL claim is authorization. */
31
+ export declare function runEntityboxQueueRequest(req: RuntimeRequestRow, io: Io, services?: EntityboxQueueServices): Promise<boolean>;
32
+ export {};