@borgee/agents-host 0.2.2 → 0.2.26

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 (76) hide show
  1. package/README.md +184 -21
  2. package/dist/agents-host-supervisor.d.ts +7 -5
  3. package/dist/agents-host-supervisor.js +24 -4
  4. package/dist/agents-host.d.ts +89 -15
  5. package/dist/agents-host.js +2099 -141
  6. package/dist/chat/chat-control-plane.d.ts +13 -2
  7. package/dist/chat/sdk-chat-control-plane.d.ts +14 -3
  8. package/dist/chat/sdk-chat-control-plane.js +54 -2
  9. package/dist/cli-args.d.ts +46 -5
  10. package/dist/cli-args.js +313 -32
  11. package/dist/cli.d.ts +9 -0
  12. package/dist/cli.js +112 -5
  13. package/dist/compatibility-gates.d.ts +35 -0
  14. package/dist/compatibility-gates.js +127 -0
  15. package/dist/config.d.ts +1 -0
  16. package/dist/config.js +23 -5
  17. package/dist/connections-state-store.d.ts +81 -0
  18. package/dist/connections-state-store.js +228 -0
  19. package/dist/context/injection.d.ts +109 -0
  20. package/dist/context/injection.js +350 -0
  21. package/dist/context/prompt.d.ts +4 -1
  22. package/dist/context/prompt.js +170 -1
  23. package/dist/context/turn-preparation.d.ts +9 -0
  24. package/dist/context/turn-preparation.js +106 -0
  25. package/dist/debug.d.ts +44 -0
  26. package/dist/debug.js +135 -0
  27. package/dist/gateway/localhost-gateway.d.ts +52 -0
  28. package/dist/gateway/localhost-gateway.js +857 -0
  29. package/dist/index.js +7 -5
  30. package/dist/local-config.d.ts +4 -1
  31. package/dist/local-config.js +24 -7
  32. package/dist/managed-daemon-log.d.ts +34 -0
  33. package/dist/managed-daemon-log.js +261 -0
  34. package/dist/managed-daemon.d.ts +220 -0
  35. package/dist/managed-daemon.js +1601 -0
  36. package/dist/policy/authorization-audit.d.ts +63 -0
  37. package/dist/policy/authorization-audit.js +94 -0
  38. package/dist/policy/copilot-permission.d.ts +15 -0
  39. package/dist/policy/copilot-permission.js +193 -0
  40. package/dist/policy/gateway-authorization.d.ts +42 -0
  41. package/dist/policy/gateway-authorization.js +162 -0
  42. package/dist/providers/awaiting-user.d.ts +12 -0
  43. package/dist/providers/awaiting-user.js +151 -0
  44. package/dist/providers/claude/adapter.d.ts +3 -1
  45. package/dist/providers/claude/adapter.js +8 -12
  46. package/dist/providers/claude/cli-client.d.ts +12 -5
  47. package/dist/providers/claude/cli-client.js +184 -37
  48. package/dist/providers/claude/session-store.d.ts +1 -0
  49. package/dist/providers/codex/adapter.d.ts +11 -0
  50. package/dist/providers/codex/adapter.js +19 -0
  51. package/dist/providers/codex/cli-client.d.ts +103 -0
  52. package/dist/providers/codex/cli-client.js +1133 -0
  53. package/dist/providers/codex/project-doc.d.ts +3 -0
  54. package/dist/providers/codex/project-doc.js +66 -0
  55. package/dist/providers/codex/session-store.d.ts +38 -0
  56. package/dist/providers/codex/session-store.js +150 -0
  57. package/dist/providers/copilot/adapter.d.ts +3 -1
  58. package/dist/providers/copilot/adapter.js +8 -12
  59. package/dist/providers/copilot/cli-client.d.ts +20 -2
  60. package/dist/providers/copilot/cli-client.js +251 -71
  61. package/dist/providers/copilot/session-store.d.ts +1 -0
  62. package/dist/providers/create-provider.d.ts +11 -2
  63. package/dist/providers/create-provider.js +131 -12
  64. package/dist/run.d.ts +1 -0
  65. package/dist/run.js +5 -2
  66. package/dist/state-paths.d.ts +13 -1
  67. package/dist/state-paths.js +84 -3
  68. package/dist/task-thread-resolution.d.ts +10 -0
  69. package/dist/task-thread-resolution.js +48 -0
  70. package/dist/types.d.ts +174 -1
  71. package/dist/visible-mentions.d.ts +3 -0
  72. package/dist/visible-mentions.js +15 -0
  73. package/package.json +19 -17
  74. package/skills/borgee-agent/SKILL.md +33 -0
  75. package/skills/borgee-agent/borgee-agent.mjs +473 -0
  76. package/skills/borgee-agent/borgee-agent.py +409 -0
package/dist/cli.js CHANGED
@@ -1,36 +1,85 @@
1
1
  #!/usr/bin/env node
2
2
  import { realpathSync } from 'node:fs';
3
- import { resolve } from 'node:path';
3
+ import { dirname, resolve } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
- import { CliUsageError, parseDescribeArgs, parseGenerateConfigArgs, parsePrintLayoutArgs, parseStartArgs, parseValidateArgs, USAGE, } from './cli-args.js';
6
- import { describeLocalConfig, generateLocalConfig, printLocalConfigLayout, runMain, validateLocalConfig } from './run.js';
5
+ import { CliUsageError, parseApplyManagedArgs, parseDaemonArgs, parseDescribeArgs, parseDescribeManagedArgs, parseCleanupManagedArgs, parseGenerateConfigArgs, parseLogArgs, parseManagedStartArgs, parsePrintLayoutArgs, parseStartArgs, parseValidateArgs, USAGE, } from './cli-args.js';
6
+ import { resolveAgentsHostDebugMode } from './debug.js';
7
+ import { applyManagedSpec, bootstrapManagedDaemonStart, cleanupManagedRuntime, describeManagedSpec, ManagedAgentsHostDaemon, } from './managed-daemon.js';
8
+ import { runManagedDaemonLogCommand } from './managed-daemon-log.js';
9
+ import { describeLocalConfig, generateLocalConfig, printLocalConfigLayout, runMain, validateLocalConfig, } from './run.js';
7
10
  function formatErrorMessage(error) {
8
11
  if (error instanceof Error) {
9
12
  return error.message;
10
13
  }
11
14
  return String(error);
12
15
  }
16
+ const TASK_WORKSPACE_ROOT_DIR_ENV = 'AGENTS_HOST_INTERNAL_TASK_WORKSPACE_ROOT_DIR';
13
17
  export async function dispatchCli(argv, deps = {}) {
14
18
  const [command, ...rest] = argv;
15
19
  const env = deps.env ?? process.env;
16
20
  const runMainImpl = deps.runMain ?? runMain;
21
+ const bootstrapManagedDaemonStartImpl = deps.bootstrapManagedDaemonStart ?? bootstrapManagedDaemonStart;
17
22
  const validateLocalConfigImpl = deps.validateLocalConfig ?? validateLocalConfig;
18
23
  const describeLocalConfigImpl = deps.describeLocalConfig ?? describeLocalConfig;
19
24
  const printLocalConfigLayoutImpl = deps.printLocalConfigLayout ?? printLocalConfigLayout;
20
25
  const generateLocalConfigImpl = deps.generateLocalConfig ?? generateLocalConfig;
26
+ const runManagedDaemonLogCommandImpl = deps.runManagedDaemonLogCommand ?? runManagedDaemonLogCommand;
27
+ const describeManagedSpecImpl = deps.describeManagedSpec ?? describeManagedSpec;
28
+ const cleanupManagedRuntimeImpl = deps.cleanupManagedRuntime ?? cleanupManagedRuntime;
29
+ const applyManagedSpecImpl = deps.applyManagedSpec ?? applyManagedSpec;
30
+ const startManagedDaemonImpl = deps.startManagedDaemon ??
31
+ (async (rootPath, debug) => {
32
+ env[TASK_WORKSPACE_ROOT_DIR_ENV] = rootPath;
33
+ const daemon = new ManagedAgentsHostDaemon(rootPath, debug, {
34
+ logPath: env.AGENTS_HOST_MANAGED_DAEMON_LOG_PATH,
35
+ });
36
+ const shutdown = async (signal) => {
37
+ console.log(`[agents-host] managed daemon received ${signal}, shutting down`);
38
+ await daemon.stop().catch((error) => {
39
+ console.error('[agents-host] managed daemon shutdown failed', error);
40
+ });
41
+ process.exit(0);
42
+ };
43
+ process.on('SIGINT', () => void shutdown('SIGINT'));
44
+ process.on('SIGTERM', () => void shutdown('SIGTERM'));
45
+ await daemon.start();
46
+ });
21
47
  const readStdin = deps.readStdin ?? readAllStdin;
48
+ const stdout = deps.stdout ?? console;
22
49
  if (command === 'start') {
23
50
  const parsed = parseStartArgs(rest);
51
+ const debug = resolveAgentsHostDebugMode(parsed.debug, env);
24
52
  if (parsed.mode === 'single-agent') {
25
53
  env.BORGEE_BASE_URL = parsed.serverUrl;
26
54
  env.BORGEE_AGENT_API_KEY = parsed.apiKey;
27
55
  for (const [key, value] of Object.entries(parsed.env)) {
28
56
  env[key] = value;
29
57
  }
30
- await runMainImpl();
58
+ await runMainImpl({ debug });
31
59
  return;
32
60
  }
33
- await runMainImpl({ configPath: parsed.configPath });
61
+ env[TASK_WORKSPACE_ROOT_DIR_ENV] = dirname(resolve(parsed.configPath));
62
+ await runMainImpl({ configPath: parsed.configPath, debug });
63
+ return;
64
+ }
65
+ if (command === 'start-managed') {
66
+ const parsed = parseManagedStartArgs(rest);
67
+ if (resolveAgentsHostDebugMode(false, env)) {
68
+ throw new CliUsageError('start-managed does not support debug mode; use foreground start or start --config --debug instead');
69
+ }
70
+ if (parsed.apiKey === undefined) {
71
+ await bootstrapManagedDaemonStartImpl({
72
+ serverUrl: parsed.serverUrl,
73
+ processEnv: env,
74
+ });
75
+ return;
76
+ }
77
+ await bootstrapManagedDaemonStartImpl({
78
+ serverUrl: parsed.serverUrl,
79
+ apiKey: parsed.apiKey,
80
+ env: parsed.env,
81
+ processEnv: env,
82
+ });
34
83
  return;
35
84
  }
36
85
  if (command === 'validate') {
@@ -58,6 +107,64 @@ export async function dispatchCli(argv, deps = {}) {
58
107
  }
59
108
  return;
60
109
  }
110
+ if (command === 'describe-managed') {
111
+ const parsed = parseDescribeManagedArgs(rest);
112
+ stdout.log(JSON.stringify(await describeManagedSpecImpl({
113
+ serverUrl: parsed.serverUrl,
114
+ processEnv: env,
115
+ })));
116
+ return;
117
+ }
118
+ if (command === 'cleanup-managed') {
119
+ const parsed = parseCleanupManagedArgs(rest);
120
+ await cleanupManagedRuntimeImpl({
121
+ serverUrl: parsed.serverUrl,
122
+ purge: parsed.purge,
123
+ processEnv: env,
124
+ });
125
+ return;
126
+ }
127
+ if (command === 'apply-managed') {
128
+ const parsed = parseApplyManagedArgs(rest);
129
+ const specJson = parsed.input === 'stdin' ? await readStdin() : parsed.specJson;
130
+ let parsedSpec;
131
+ try {
132
+ parsedSpec = JSON.parse(specJson);
133
+ }
134
+ catch (error) {
135
+ stdout.log(JSON.stringify({
136
+ ok: false,
137
+ error: {
138
+ code: 'MANAGED_SPEC_INVALID',
139
+ message: `Invalid managed spec JSON: ${formatErrorMessage(error)}`,
140
+ },
141
+ }));
142
+ return;
143
+ }
144
+ stdout.log(JSON.stringify(await applyManagedSpecImpl({
145
+ serverUrl: parsed.serverUrl,
146
+ spec: parsedSpec,
147
+ processEnv: env,
148
+ })));
149
+ return;
150
+ }
151
+ if (command === 'log') {
152
+ const parsed = parseLogArgs(rest);
153
+ await runManagedDaemonLogCommandImpl({
154
+ serverUrl: parsed.serverUrl,
155
+ lines: parsed.lines,
156
+ follow: parsed.follow,
157
+ pathOnly: parsed.pathOnly,
158
+ env,
159
+ });
160
+ return;
161
+ }
162
+ if (command === 'daemon') {
163
+ const parsed = parseDaemonArgs(rest);
164
+ env[TASK_WORKSPACE_ROOT_DIR_ENV] = parsed.rootPath;
165
+ await startManagedDaemonImpl(parsed.rootPath, parsed.debug);
166
+ return;
167
+ }
61
168
  throw new CliUsageError(`Unknown command: ${command}`);
62
169
  }
63
170
  async function readAllStdin() {
@@ -0,0 +1,35 @@
1
+ export declare const CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE = "claude-provider-v2";
2
+ export declare const COPILOT_PROVIDER_V2_COMPATIBILITY_GATE = "copilot-provider-v2";
3
+ export declare const CODEX_PROVIDER_COMPATIBILITY_GATE = "codex-provider";
4
+ export declare const CONNECTIONS_STATE_LAYER_COMPATIBILITY_GATE = "connections-state-layer";
5
+ export declare const CONTEXT_INJECTION_COMPATIBILITY_GATE = "context-injection";
6
+ export declare const SKILL_RUNTIME_COMPATIBILITY_GATE = "skill-runtime";
7
+ export declare const LOCALHOST_GATEWAY_COMPATIBILITY_GATE = "localhost-gateway";
8
+ export declare const COLLABORATION_SKILL_FIRST_COMPATIBILITY_GATE = "collaboration-skill-first";
9
+ export declare const TOKEN_BINDING_COMPATIBILITY_GATE = "token-binding";
10
+ export declare const POLICY_AUDIT_ENFORCEMENT_COMPATIBILITY_GATE = "policy-audit-enforcement";
11
+ export declare const MANAGED_RUNTIME_CONVERGENCE_COMPATIBILITY_GATE = "managed-runtime-convergence";
12
+ export declare const COMPATIBILITY_GATES_ENV = "AGENTS_HOST_INTERNAL_COMPATIBILITY_GATES";
13
+ export declare const INTERNAL_POLICY_MODE_ENV = "AGENTS_HOST_INTERNAL_POLICY_MODE";
14
+ export declare const INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV = "AGENTS_HOST_INTERNAL_PROVIDER_IMPLEMENTATIONS";
15
+ export declare const MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION = 1;
16
+ export type InternalPolicyMode = 'audit-only' | 'enforce';
17
+ export type InternalProviderImplementationPath = 'v1' | 'v2';
18
+ export type InternalProviderImplementationKey = 'claude' | 'copilot';
19
+ export type InternalProviderImplementationOverrides = Partial<Record<InternalProviderImplementationKey, InternalProviderImplementationPath>>;
20
+ export interface ManagedRuntimeSettingsSnapshot {
21
+ schemaVersion: number;
22
+ compatibilityGates: string[];
23
+ providerImplementationOverrides: string[];
24
+ internalPolicyMode: InternalPolicyMode;
25
+ }
26
+ export declare function parseCompatibilityGates(rawValue: string | undefined): ReadonlySet<string>;
27
+ export declare function resolveInternalCompatibilityGates(): ReadonlySet<string>;
28
+ export declare function normalizeInternalProviderImplementationOverrides(rawValue: string | undefined): string[];
29
+ export declare function parseInternalProviderImplementationOverrides(rawValue: string | undefined): InternalProviderImplementationOverrides;
30
+ export declare function resolveManagedRuntimeProviderImplementationOverrides(env?: NodeJS.ProcessEnv, compatibilityGates?: string[]): string[];
31
+ export declare function resolveManagedRuntimeCompatibilityGates(env?: NodeJS.ProcessEnv): string[];
32
+ export declare function resolveInternalPolicyMode(gateEnabled: boolean, env?: NodeJS.ProcessEnv): InternalPolicyMode;
33
+ export declare function resolveManagedRuntimeSettingsSnapshot(env?: NodeJS.ProcessEnv): ManagedRuntimeSettingsSnapshot;
34
+ export declare function serializeManagedRuntimeSettingsSnapshot(snapshot: ManagedRuntimeSettingsSnapshot): string;
35
+ export declare function createManagedRuntimeSettingsFingerprint(snapshot: ManagedRuntimeSettingsSnapshot): string;
@@ -0,0 +1,127 @@
1
+ import { createHash } from 'node:crypto';
2
+ export const CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE = 'claude-provider-v2';
3
+ export const COPILOT_PROVIDER_V2_COMPATIBILITY_GATE = 'copilot-provider-v2';
4
+ export const CODEX_PROVIDER_COMPATIBILITY_GATE = 'codex-provider';
5
+ export const CONNECTIONS_STATE_LAYER_COMPATIBILITY_GATE = 'connections-state-layer';
6
+ export const CONTEXT_INJECTION_COMPATIBILITY_GATE = 'context-injection';
7
+ export const SKILL_RUNTIME_COMPATIBILITY_GATE = 'skill-runtime';
8
+ export const LOCALHOST_GATEWAY_COMPATIBILITY_GATE = 'localhost-gateway';
9
+ export const COLLABORATION_SKILL_FIRST_COMPATIBILITY_GATE = 'collaboration-skill-first';
10
+ export const TOKEN_BINDING_COMPATIBILITY_GATE = 'token-binding';
11
+ export const POLICY_AUDIT_ENFORCEMENT_COMPATIBILITY_GATE = 'policy-audit-enforcement';
12
+ export const MANAGED_RUNTIME_CONVERGENCE_COMPATIBILITY_GATE = 'managed-runtime-convergence';
13
+ export const COMPATIBILITY_GATES_ENV = 'AGENTS_HOST_INTERNAL_COMPATIBILITY_GATES';
14
+ export const INTERNAL_POLICY_MODE_ENV = 'AGENTS_HOST_INTERNAL_POLICY_MODE';
15
+ export const INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV = 'AGENTS_HOST_INTERNAL_PROVIDER_IMPLEMENTATIONS';
16
+ export const MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION = 1;
17
+ const VALID_PROVIDER_IMPLEMENTATION_ENTRIES = '"claude:v1", "claude:v2", "copilot:v1", or "copilot:v2"';
18
+ const PROVIDER_IMPLEMENTATION_COMPATIBILITY_GATES = {
19
+ claude: CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE,
20
+ copilot: COPILOT_PROVIDER_V2_COMPATIBILITY_GATE,
21
+ };
22
+ function sortUniqueStrings(values) {
23
+ return [...new Set([...values].map((value) => value.trim()).filter((value) => value.length > 0))]
24
+ .sort((left, right) => left.localeCompare(right));
25
+ }
26
+ function isInternalProviderImplementationPath(value) {
27
+ return value === 'v1' || value === 'v2';
28
+ }
29
+ function isInternalProviderImplementationKey(value) {
30
+ return value === 'claude' || value === 'copilot';
31
+ }
32
+ function createInvalidProviderImplementationEntryError(assignment) {
33
+ return new Error(`Invalid ${INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV} entry "${assignment}". Expected ${VALID_PROVIDER_IMPLEMENTATION_ENTRIES}.`);
34
+ }
35
+ export function parseCompatibilityGates(rawValue) {
36
+ if (!rawValue || rawValue.trim().length === 0) {
37
+ return new Set();
38
+ }
39
+ const gates = new Set();
40
+ for (const gateRaw of rawValue.split(',')) {
41
+ const gate = gateRaw.trim();
42
+ if (gate.length === 0) {
43
+ continue;
44
+ }
45
+ gates.add(gate);
46
+ }
47
+ return gates;
48
+ }
49
+ export function resolveInternalCompatibilityGates() {
50
+ return parseCompatibilityGates(process.env[COMPATIBILITY_GATES_ENV]);
51
+ }
52
+ export function normalizeInternalProviderImplementationOverrides(rawValue) {
53
+ if (!rawValue || rawValue.trim().length === 0) {
54
+ return [];
55
+ }
56
+ const implementationsByProvider = new Map();
57
+ for (const assignmentRaw of rawValue.split(',')) {
58
+ const assignment = assignmentRaw.trim();
59
+ if (assignment.length === 0) {
60
+ continue;
61
+ }
62
+ const [providerRaw, implementationRaw, ...extraParts] = assignment.split(':');
63
+ const provider = providerRaw?.trim();
64
+ const implementation = implementationRaw?.trim();
65
+ if (extraParts.length > 0 || !provider || !implementation) {
66
+ throw createInvalidProviderImplementationEntryError(assignment);
67
+ }
68
+ if (!isInternalProviderImplementationKey(provider)) {
69
+ throw createInvalidProviderImplementationEntryError(assignment);
70
+ }
71
+ if (!isInternalProviderImplementationPath(implementation)) {
72
+ throw createInvalidProviderImplementationEntryError(assignment);
73
+ }
74
+ implementationsByProvider.set(provider, implementation);
75
+ }
76
+ return sortUniqueStrings([...implementationsByProvider.entries()].map(([provider, implementation]) => `${provider}:${implementation}`));
77
+ }
78
+ export function parseInternalProviderImplementationOverrides(rawValue) {
79
+ const implementationOverrides = {};
80
+ for (const assignment of normalizeInternalProviderImplementationOverrides(rawValue)) {
81
+ const [provider, implementation] = assignment.split(':');
82
+ implementationOverrides[provider] = implementation;
83
+ }
84
+ return implementationOverrides;
85
+ }
86
+ export function resolveManagedRuntimeProviderImplementationOverrides(env = process.env, compatibilityGates = resolveManagedRuntimeCompatibilityGates(env)) {
87
+ const enabledGates = new Set(compatibilityGates);
88
+ return normalizeInternalProviderImplementationOverrides(env[INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV]).filter((assignment) => {
89
+ const [provider] = assignment.split(':');
90
+ return enabledGates.has(PROVIDER_IMPLEMENTATION_COMPATIBILITY_GATES[provider]);
91
+ });
92
+ }
93
+ export function resolveManagedRuntimeCompatibilityGates(env = process.env) {
94
+ const compatibilityGates = new Set(parseCompatibilityGates(env[COMPATIBILITY_GATES_ENV]));
95
+ if (compatibilityGates.has(MANAGED_RUNTIME_CONVERGENCE_COMPATIBILITY_GATE)) {
96
+ compatibilityGates.add(CONNECTIONS_STATE_LAYER_COMPATIBILITY_GATE);
97
+ compatibilityGates.add(TOKEN_BINDING_COMPATIBILITY_GATE);
98
+ }
99
+ return sortUniqueStrings(compatibilityGates);
100
+ }
101
+ export function resolveInternalPolicyMode(gateEnabled, env = process.env) {
102
+ if (!gateEnabled) {
103
+ return 'audit-only';
104
+ }
105
+ const rawValue = env[INTERNAL_POLICY_MODE_ENV]?.trim();
106
+ if (rawValue === 'enforce') {
107
+ return 'enforce';
108
+ }
109
+ return 'audit-only';
110
+ }
111
+ export function resolveManagedRuntimeSettingsSnapshot(env = process.env) {
112
+ const compatibilityGates = resolveManagedRuntimeCompatibilityGates(env);
113
+ return {
114
+ schemaVersion: MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION,
115
+ compatibilityGates,
116
+ providerImplementationOverrides: resolveManagedRuntimeProviderImplementationOverrides(env, compatibilityGates),
117
+ internalPolicyMode: resolveInternalPolicyMode(compatibilityGates.includes(POLICY_AUDIT_ENFORCEMENT_COMPATIBILITY_GATE), env),
118
+ };
119
+ }
120
+ export function serializeManagedRuntimeSettingsSnapshot(snapshot) {
121
+ return JSON.stringify(snapshot);
122
+ }
123
+ export function createManagedRuntimeSettingsFingerprint(snapshot) {
124
+ return createHash('sha256')
125
+ .update(serializeManagedRuntimeSettingsSnapshot(snapshot))
126
+ .digest('hex');
127
+ }
package/dist/config.d.ts CHANGED
@@ -8,5 +8,6 @@ export declare function parseArgs(value: string): string[];
8
8
  export declare function optionalStringArray(value: unknown, fieldName: string, sourceLabel: string): string[] | undefined;
9
9
  export declare function parseCopilotSessionTtlMinutesValue(value: unknown, sourceLabel: string): number;
10
10
  export declare function resolveProvider(rawValue: string, sourceLabel: string): ProviderKind;
11
+ export declare function assertProviderCompatibility(provider: ProviderKind, sourceLabel: string, env?: NodeJS.ProcessEnv): void;
11
12
  export declare function resolveProviderCommandConfig(overrides?: Partial<ProviderCommandConfig>): ProviderCommandConfig;
12
13
  export declare function loadConfigFromEnv(env?: NodeJS.ProcessEnv): AgentsHostConfig;
package/dist/config.js CHANGED
@@ -1,10 +1,13 @@
1
1
  import { resolveSingleAgentStateRoot } from './state-paths.js';
2
+ import { CODEX_PROVIDER_COMPATIBILITY_GATE, COMPATIBILITY_GATES_ENV, parseCompatibilityGates, } from './compatibility-gates.js';
2
3
  const MAX_TIMER_DELAY_MS = 2_147_483_647;
3
4
  export const MAX_COPILOT_SESSION_TTL_MINUTES = MAX_TIMER_DELAY_MS / 60_000;
4
5
  export const DEFAULT_COPILOT_SESSION_TTL_MINUTES = 2 * 24 * 60;
5
6
  export const DEFAULT_PROVIDER_COMMAND_CONFIG = {
6
7
  claudeCommand: 'claude',
7
- claudeArgs: ['--print'],
8
+ claudeArgs: ['--print', '--permission-mode', 'bypassPermissions'],
9
+ codexCommand: 'codex-acp',
10
+ codexArgs: [],
8
11
  copilotCommand: 'copilot',
9
12
  copilotArgs: ['-s', '--no-color', '--allow-all-tools', '--output-format', 'text'],
10
13
  copilotSessionTtlMinutes: DEFAULT_COPILOT_SESSION_TTL_MINUTES,
@@ -57,15 +60,26 @@ export function parseCopilotSessionTtlMinutesValue(value, sourceLabel) {
57
60
  }
58
61
  export function resolveProvider(rawValue, sourceLabel) {
59
62
  const raw = rawValue.trim().toLowerCase();
60
- if (raw === 'claude' || raw === 'copilot') {
63
+ if (raw === 'claude' || raw === 'codex' || raw === 'copilot') {
61
64
  return raw;
62
65
  }
63
- throw new Error(`${sourceLabel}: expected "claude" or "copilot", got "${rawValue}"`);
66
+ throw new Error(`${sourceLabel}: expected "claude", "codex", or "copilot", got "${rawValue}"`);
67
+ }
68
+ export function assertProviderCompatibility(provider, sourceLabel, env = process.env) {
69
+ if (provider !== 'codex') {
70
+ return;
71
+ }
72
+ const compatibilityGates = parseCompatibilityGates(env[COMPATIBILITY_GATES_ENV]);
73
+ if (!compatibilityGates.has(CODEX_PROVIDER_COMPATIBILITY_GATE)) {
74
+ throw new Error(`${sourceLabel}: provider "codex" requires ${COMPATIBILITY_GATES_ENV} to include ${CODEX_PROVIDER_COMPATIBILITY_GATE}`);
75
+ }
64
76
  }
65
77
  export function resolveProviderCommandConfig(overrides = {}) {
66
78
  return {
67
79
  claudeCommand: overrides.claudeCommand ?? DEFAULT_PROVIDER_COMMAND_CONFIG.claudeCommand,
68
80
  claudeArgs: [...(overrides.claudeArgs ?? DEFAULT_PROVIDER_COMMAND_CONFIG.claudeArgs)],
81
+ codexCommand: overrides.codexCommand ?? DEFAULT_PROVIDER_COMMAND_CONFIG.codexCommand,
82
+ codexArgs: [...(overrides.codexArgs ?? DEFAULT_PROVIDER_COMMAND_CONFIG.codexArgs)],
69
83
  copilotCommand: overrides.copilotCommand ?? DEFAULT_PROVIDER_COMMAND_CONFIG.copilotCommand,
70
84
  copilotArgs: [...(overrides.copilotArgs ?? DEFAULT_PROVIDER_COMMAND_CONFIG.copilotArgs)],
71
85
  copilotSessionTtlMinutes: overrides.copilotSessionTtlMinutes ?? DEFAULT_PROVIDER_COMMAND_CONFIG.copilotSessionTtlMinutes,
@@ -73,12 +87,16 @@ export function resolveProviderCommandConfig(overrides = {}) {
73
87
  }
74
88
  export function loadConfigFromEnv(env = process.env) {
75
89
  const provider = resolveProvider(envOr('RUNTIME_PROVIDER', 'claude', env), 'Unsupported RUNTIME_PROVIDER');
90
+ assertProviderCompatibility(provider, 'Unsupported RUNTIME_PROVIDER', env);
91
+ const agentApiKey = requireEnv('BORGEE_AGENT_API_KEY', env);
76
92
  return {
77
93
  borgeeBaseUrl: requireEnv('BORGEE_BASE_URL', env),
78
- stateRootDir: resolveSingleAgentStateRoot(env),
94
+ stateRootDir: resolveSingleAgentStateRoot(env, undefined, agentApiKey),
79
95
  ...resolveProviderCommandConfig({
80
96
  claudeCommand: envOr('CLAUDE_COMMAND', DEFAULT_PROVIDER_COMMAND_CONFIG.claudeCommand, env),
81
97
  claudeArgs: parseArgs(envOr('CLAUDE_ARGS', DEFAULT_PROVIDER_COMMAND_CONFIG.claudeArgs.join(' '), env)),
98
+ codexCommand: envOr('CODEX_COMMAND', DEFAULT_PROVIDER_COMMAND_CONFIG.codexCommand, env),
99
+ codexArgs: parseArgs(envOr('CODEX_ARGS', DEFAULT_PROVIDER_COMMAND_CONFIG.codexArgs.join(' '), env)),
82
100
  copilotCommand: envOr('COPILOT_COMMAND', DEFAULT_PROVIDER_COMMAND_CONFIG.copilotCommand, env),
83
101
  copilotArgs: parseArgs(envOr('COPILOT_ARGS', DEFAULT_PROVIDER_COMMAND_CONFIG.copilotArgs.join(' '), env)),
84
102
  copilotSessionTtlMinutes: env.COPILOT_SESSION_TTL_MINUTES && env.COPILOT_SESSION_TTL_MINUTES.trim().length > 0
@@ -86,7 +104,7 @@ export function loadConfigFromEnv(env = process.env) {
86
104
  : DEFAULT_PROVIDER_COMMAND_CONFIG.copilotSessionTtlMinutes,
87
105
  }),
88
106
  agent: {
89
- agentApiKey: requireEnv('BORGEE_AGENT_API_KEY', env),
107
+ agentApiKey,
90
108
  agentName: envOr('BORGEE_AGENT_NAME', 'Assistant', env),
91
109
  provider,
92
110
  },
@@ -0,0 +1,81 @@
1
+ import { type DebugLogger } from './debug.js';
2
+ import type { ProviderKind } from './types.js';
3
+ export interface ChannelSessionStoreLike {
4
+ load(agentId: string): Promise<Record<string, string>>;
5
+ save(agentId: string, sessions: Record<string, string>): Promise<void>;
6
+ close?(): Promise<void> | void;
7
+ }
8
+ export interface ChannelTokenBinding {
9
+ token: string;
10
+ agentId: string;
11
+ channelId: string;
12
+ }
13
+ export interface ConnectionsStateStore {
14
+ loadProviderSessions(provider: ProviderKind, agentId: string): Record<string, string>;
15
+ saveProviderSessions(provider: ProviderKind, agentId: string, sessions: Record<string, string>): void;
16
+ hasTokenBinding(token: string): boolean;
17
+ loadTokenBinding(token: string): ChannelTokenBinding | null;
18
+ loadTokenBindingForChannel(agentId: string, channelId: string): ChannelTokenBinding | null;
19
+ replaceTokenBinding(binding: ChannelTokenBinding): void;
20
+ deleteTokenBinding(token: string): void;
21
+ revokeTokenBinding(token: string): void;
22
+ revokeAllTokenBindings(): void;
23
+ close(): void;
24
+ }
25
+ export interface SqliteConnectionsStateStoreOptions {
26
+ stateRootDir: string;
27
+ busyTimeoutMs?: number;
28
+ resolveDatabasePath?: (stateRootDir: string) => string;
29
+ openDatabase?: (path: string) => SqliteDatabaseLike;
30
+ }
31
+ export interface ConnectionsStateBackedChannelSessionStoreOptions {
32
+ provider: ProviderKind;
33
+ legacyStore: ChannelSessionStoreLike;
34
+ sqliteStateStore?: ConnectionsStateStore;
35
+ logger?: DebugLogger;
36
+ }
37
+ export interface ProviderConnectionsSessionStoreOptions {
38
+ provider: ProviderKind;
39
+ legacyStore: ChannelSessionStoreLike;
40
+ stateRootDir: string;
41
+ gateEnabled: boolean;
42
+ logger?: DebugLogger;
43
+ }
44
+ interface SqliteStatementLike {
45
+ run(...params: unknown[]): unknown;
46
+ get(...params: unknown[]): unknown;
47
+ all(...params: unknown[]): unknown[];
48
+ }
49
+ interface SqliteDatabaseLike {
50
+ exec(sql: string): void;
51
+ prepare(sql: string): SqliteStatementLike;
52
+ close(): void;
53
+ }
54
+ export declare class SqliteConnectionsStateStore implements ConnectionsStateStore {
55
+ private readonly options;
56
+ private database;
57
+ private closed;
58
+ constructor(options: SqliteConnectionsStateStoreOptions);
59
+ loadProviderSessions(provider: ProviderKind, agentId: string): Record<string, string>;
60
+ saveProviderSessions(provider: ProviderKind, agentId: string, sessions: Record<string, string>): void;
61
+ hasTokenBinding(token: string): boolean;
62
+ loadTokenBinding(token: string): ChannelTokenBinding | null;
63
+ loadTokenBindingForChannel(agentId: string, channelId: string): ChannelTokenBinding | null;
64
+ replaceTokenBinding(binding: ChannelTokenBinding): void;
65
+ deleteTokenBinding(token: string): void;
66
+ revokeTokenBinding(token: string): void;
67
+ revokeAllTokenBindings(): void;
68
+ close(): void;
69
+ private ensureDatabase;
70
+ private loadStoredTokenBinding;
71
+ }
72
+ export declare class ConnectionsStateBackedChannelSessionStore implements ChannelSessionStoreLike {
73
+ private readonly options;
74
+ private readonly logger;
75
+ constructor(options: ConnectionsStateBackedChannelSessionStoreOptions);
76
+ load(agentId: string): Promise<Record<string, string>>;
77
+ save(agentId: string, sessions: Record<string, string>): Promise<void>;
78
+ close(): void;
79
+ }
80
+ export declare function createProviderConnectionsSessionStore(options: ProviderConnectionsSessionStoreOptions): ChannelSessionStoreLike;
81
+ export {};