@borgee/agents-host 0.2.97 → 0.2.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -5
- package/dist/agents-host.d.ts +16 -0
- package/dist/agents-host.js +608 -82
- package/dist/catalog-worker.js +21 -0
- package/dist/catalog-worker.js.map +7 -0
- package/dist/chat/chat-control-plane.d.ts +19 -4
- package/dist/chat/normalized-input.d.ts +9 -0
- package/dist/chat/normalized-input.js +24 -0
- package/dist/chat/sdk-chat-control-plane.d.ts +46 -6
- package/dist/chat/sdk-chat-control-plane.js +169 -6
- package/dist/cli-args.d.ts +1 -1
- package/dist/cli-args.js +13 -4
- package/dist/config.d.ts +3 -1
- package/dist/config.js +25 -0
- package/dist/context/injection.d.ts +16 -0
- package/dist/context/injection.js +37 -21
- package/dist/context/prompt.d.ts +12 -0
- package/dist/context/prompt.js +25 -0
- package/dist/context/skill-manual.js +1 -1
- package/dist/context/turn-preparation.d.ts +2 -1
- package/dist/context/turn-preparation.js +15 -0
- package/dist/execution-telemetry.d.ts +96 -0
- package/dist/execution-telemetry.js +583 -0
- package/dist/gateway/channel-file-workspace.d.ts +15 -0
- package/dist/gateway/channel-file-workspace.js +130 -0
- package/dist/gateway/localhost-gateway.js +167 -2
- package/dist/hosted-turn-content.js +3 -2
- package/dist/local-config.js +34 -1
- package/dist/managed-daemon.js +15 -0
- package/dist/native-environment.d.ts +2 -0
- package/dist/native-environment.js +9 -0
- package/dist/native-protocol-types/codec.d.ts +49 -0
- package/dist/native-protocol-types/commands.d.ts +71 -0
- package/dist/native-protocol-types/compatibility.d.ts +5 -0
- package/dist/native-protocol-types/cursor.d.ts +7 -0
- package/dist/native-protocol-types/envelope.d.ts +1105 -0
- package/dist/native-protocol-types/file-changes.d.ts +20 -0
- package/dist/native-protocol-types/history.d.ts +487 -0
- package/dist/native-protocol-types/index.d.ts +18 -0
- package/dist/native-protocol-types/interactions.d.ts +619 -0
- package/dist/native-protocol-types/messages.d.ts +2482 -0
- package/dist/native-protocol-types/public-validation.d.ts +10 -0
- package/dist/native-protocol-types/remote-host-uplink.d.ts +67 -0
- package/dist/native-protocol-types/resources.d.ts +126 -0
- package/dist/native-protocol-types/session-settings.d.ts +22 -0
- package/dist/native-protocol-types/snapshot.d.ts +575 -0
- package/dist/native-protocol-types/timeline.d.ts +1503 -0
- package/dist/native-protocol-types/tool-result.d.ts +26 -0
- package/dist/native-protocol-types/uplink.d.ts +56 -0
- package/dist/native-protocol-types/version.d.ts +5 -0
- package/dist/native-provider-types/commands.d.ts +51 -0
- package/dist/native-provider-types/control.d.ts +192 -0
- package/dist/native-provider-types/file-changes.d.ts +9 -0
- package/dist/native-provider-types/index.d.ts +8 -0
- package/dist/native-provider-types/interactions.d.ts +7 -0
- package/dist/native-provider-types/observation.d.ts +209 -0
- package/dist/native-provider-types/provider.d.ts +124 -0
- package/dist/native-provider-types/session-settings.d.ts +17 -0
- package/dist/native-provider-types/testing.d.ts +27 -0
- package/dist/native-provider-types/tool-result.d.ts +21 -0
- package/dist/native-providers.d.ts +21 -0
- package/dist/native-providers.js +18402 -0
- package/dist/native-providers.js.map +7 -0
- package/dist/plugin-sdk.js +10713 -229
- package/dist/plugin-sdk.js.map +4 -4
- package/dist/policy/copilot-permission.js +1 -8
- package/dist/policy/gateway-authorization.d.ts +1 -1
- package/dist/policy/gateway-authorization.js +22 -2
- package/dist/providers/claude/adapter.js +1 -0
- package/dist/providers/claude/cli-client.js +4 -0
- package/dist/providers/codex/adapter.js +1 -0
- package/dist/providers/codex/cli-client.js +5 -0
- package/dist/providers/copilot/adapter.js +4 -0
- package/dist/providers/copilot/cli-client.js +11 -1
- package/dist/providers/copilot/sdk-session.d.ts +12 -3
- package/dist/providers/copilot/sdk-session.js +230 -6
- package/dist/providers/create-provider.js +24 -0
- package/dist/providers/normalized/adapter.d.ts +107 -0
- package/dist/providers/normalized/adapter.js +1650 -0
- package/dist/providers/normalized/control-policy.d.ts +5 -0
- package/dist/providers/normalized/control-policy.js +12 -0
- package/dist/providers/normalized/interactions.d.ts +3 -0
- package/dist/providers/normalized/interactions.js +39 -0
- package/dist/providers/normalized/legacy-input-ownership.d.ts +34 -0
- package/dist/providers/normalized/legacy-input-ownership.js +123 -0
- package/dist/providers/normalized/session-management.d.ts +67 -0
- package/dist/providers/normalized/session-management.js +334 -0
- package/dist/providers/normalized/session-ownership.d.ts +3 -0
- package/dist/providers/normalized/session-ownership.js +90 -0
- package/dist/providers/prompt-usage.d.ts +8 -0
- package/dist/providers/prompt-usage.js +52 -0
- package/dist/providers/provider-adapter.d.ts +43 -1
- package/dist/providers/provider-adapter.js +8 -0
- package/dist/state-paths.d.ts +2 -0
- package/dist/state-paths.js +6 -0
- package/dist/types.d.ts +66 -0
- package/dist/typing-lease.d.ts +14 -0
- package/dist/typing-lease.js +31 -0
- package/dist/vendor/agent-provider-codex/LICENSE +211 -0
- package/dist/vendor/agent-provider-codex/NOTICE +13 -0
- package/package.json +22 -13
- package/skills/borgee-agent/SKILL.md +12 -4
- package/skills/borgee-agent/scripts/borgee-agent.mjs +110 -0
- package/skills/borgee-agent/scripts/borgee-agent.py +116 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createRequire as __nodeCreateRequire } from 'node:module';
|
|
2
|
+
const require = __nodeCreateRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// ../agent-provider-claude/src/catalog-worker.ts
|
|
5
|
+
import { getSessionInfo, getSessionMessages, listSessions, listSubagents, getSubagentMessages } from "@borgee/claude-native-sdk";
|
|
6
|
+
var [operation, sessionId, childId] = process.argv.slice(2);
|
|
7
|
+
try {
|
|
8
|
+
const result = operation === "list" ? await listSessions() : operation === "info" && sessionId ? await getSessionInfo(sessionId) : operation === "messages" && sessionId ? await getSessionMessages(sessionId) : operation === "child-messages" && sessionId && childId ? await getSubagentMessages(sessionId, childId) : operation === "children" && sessionId ? await readChildren(sessionId) : (() => {
|
|
9
|
+
throw new Error("Unknown catalog operation.");
|
|
10
|
+
})();
|
|
11
|
+
process.stdout.write(JSON.stringify(result ?? null));
|
|
12
|
+
} catch {
|
|
13
|
+
process.stderr.write("Claude native catalog could not be read.\n");
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
}
|
|
16
|
+
async function readChildren(parentId) {
|
|
17
|
+
const children = [];
|
|
18
|
+
for (const id of await listSubagents(parentId)) children.push({ id, messages: await getSubagentMessages(parentId, id) });
|
|
19
|
+
return children;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=catalog-worker.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../agent-provider-claude/src/catalog-worker.ts"],
|
|
4
|
+
"sourcesContent": ["import { getSessionInfo, getSessionMessages, listSessions, listSubagents, getSubagentMessages } from '@anthropic-ai/claude-agent-sdk';\n\nconst [operation, sessionId, childId] = process.argv.slice(2);\ntry {\n const result = operation === 'list' ? await listSessions() : operation === 'info' && sessionId ? await getSessionInfo(sessionId)\n : operation === 'messages' && sessionId ? await getSessionMessages(sessionId)\n : operation === 'child-messages' && sessionId && childId ? await getSubagentMessages(sessionId, childId)\n : operation === 'children' && sessionId ? await readChildren(sessionId)\n : (() => { throw new Error('Unknown catalog operation.'); })();\n process.stdout.write(JSON.stringify(result ?? null));\n} catch {\n process.stderr.write('Claude native catalog could not be read.\\n');\n process.exitCode = 1;\n}\n\nasync function readChildren(parentId: string) {\n const children = [];\n for (const id of await listSubagents(parentId)) children.push({ id, messages: await getSubagentMessages(parentId, id) });\n return children;\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAAA,SAAS,gBAAgB,oBAAoB,cAAc,eAAe,2BAA2B;AAErG,IAAM,CAAC,WAAW,WAAW,OAAO,IAAI,QAAQ,KAAK,MAAM,CAAC;AAC5D,IAAI;AACF,QAAM,SAAS,cAAc,SAAS,MAAM,aAAa,IAAI,cAAc,UAAU,YAAY,MAAM,eAAe,SAAS,IAC3H,cAAc,cAAc,YAAY,MAAM,mBAAmB,SAAS,IAC1E,cAAc,oBAAoB,aAAa,UAAU,MAAM,oBAAoB,WAAW,OAAO,IACrG,cAAc,cAAc,YAAY,MAAM,aAAa,SAAS,KACnE,MAAM;AAAE,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAAG,GAAG;AAC/D,UAAQ,OAAO,MAAM,KAAK,UAAU,UAAU,IAAI,CAAC;AACrD,QAAQ;AACN,UAAQ,OAAO,MAAM,4CAA4C;AACjE,UAAQ,WAAW;AACrB;AAEA,eAAe,aAAa,UAAkB;AAC5C,QAAM,WAAW,CAAC;AAClB,aAAW,MAAM,MAAM,cAAc,QAAQ,EAAG,UAAS,KAAK,EAAE,IAAI,UAAU,MAAM,oBAAoB,UAAU,EAAE,EAAE,CAAC;AACvH,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,24 +1,39 @@
|
|
|
1
|
-
import type { AgentActivity, ReportTaskFinishedInput, ReportTurnActivityInput, StopBackgroundRunHandler, StopTurnHandler, TurnActivityReporter } from '../plugin-sdk.js';
|
|
2
|
-
import type { ChannelSummary, ChannelHistoryEntry, ChannelMessageEvent, CreateTaskInput, DirectoryUser, MeResponseUser, PostMessageInput, PostedMessage, ReadChannelHistoryInput, Task, UpdateTaskInput } from '../types.js';
|
|
1
|
+
import type { AgentActivity, ExecutionTelemetryFrame, ServerRequestHandler, ReportTaskFinishedInput, ReportTurnActivityInput, StopBackgroundRunHandler, StopTurnHandler, TurnActivityReporter } from '../plugin-sdk.js';
|
|
2
|
+
import type { ChannelSummary, ChannelFileEntry, ChannelFileContent, PublishChannelFileInput, ChannelHistoryEntry, ChannelMessageEvent, CreateTaskInput, DirectoryUser, MeResponseUser, PostMessageInput, PostedMessage, ReadChannelHistoryInput, Task, UpdateTaskInput } from '../types.js';
|
|
3
3
|
export interface ChatControlPlane {
|
|
4
|
+
reportExecutionTelemetryFrame?(frame: ExecutionTelemetryFrame): void;
|
|
5
|
+
onExecutionTelemetryAck?(handler: (ack: import('../plugin-sdk.js').ExecutionTelemetryAck) => void): () => void;
|
|
6
|
+
onExecutionTransportReady?(handler: () => void): () => void;
|
|
7
|
+
onServerRequest?(handler: ServerRequestHandler | undefined): void;
|
|
4
8
|
onStopTurn?(handler: StopTurnHandler | undefined): void;
|
|
5
9
|
onStopBackgroundRun?(handler: StopBackgroundRunHandler | undefined): void;
|
|
6
10
|
onActivityTransportReady?(handler: (() => void) | undefined): void;
|
|
7
11
|
connect(onMessage: (message: ChannelMessageEvent) => void): Promise<void>;
|
|
8
12
|
close(): Promise<void>;
|
|
9
|
-
postMessage(input: PostMessageInput): Promise<PostedMessage>;
|
|
13
|
+
postMessage(input: PostMessageInput, source?: Pick<import('../plugin-sdk.js').ServerRequestContext, 'isConnectionCurrent'>): Promise<PostedMessage>;
|
|
10
14
|
editMessage(messageId: string, content: string): Promise<void>;
|
|
11
15
|
deleteMessage(messageId: string): Promise<void>;
|
|
12
|
-
|
|
16
|
+
reportTyping(channelId: string): void;
|
|
13
17
|
/** Opens one turn's report on the activity rail. Fire-and-forget: nothing recovers what it sends. */
|
|
14
18
|
reportTurnActivity(input: ReportTurnActivityInput): TurnActivityReporter;
|
|
19
|
+
reportExecutionTelemetry?(frame: ExecutionTelemetryFrame): Promise<void>;
|
|
15
20
|
reportTaskFinished?(input: ReportTaskFinishedInput): void;
|
|
21
|
+
readonly sessionBindingsSupported?: boolean;
|
|
16
22
|
reportActivity?(input: {
|
|
17
23
|
channelId: string;
|
|
18
24
|
activity: AgentActivity;
|
|
19
25
|
}): void;
|
|
20
26
|
getMe(): Promise<MeResponseUser>;
|
|
21
27
|
listUsers(): Promise<DirectoryUser[]>;
|
|
28
|
+
listChannelFiles(input: {
|
|
29
|
+
channelId: string;
|
|
30
|
+
}): Promise<ChannelFileEntry[]>;
|
|
31
|
+
readChannelFile(input: {
|
|
32
|
+
channelId: string;
|
|
33
|
+
path: string;
|
|
34
|
+
textOnly: boolean;
|
|
35
|
+
}): Promise<ChannelFileContent>;
|
|
36
|
+
publishChannelFile(input: PublishChannelFileInput): Promise<ChannelFileEntry>;
|
|
22
37
|
listChannels(): Promise<ChannelSummary[]>;
|
|
23
38
|
readChannelHistory(input: ReadChannelHistoryInput): Promise<ChannelHistoryEntry[]>;
|
|
24
39
|
createTask(input: CreateTaskInput): Promise<Task>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChannelMessageEvent } from '../types.js';
|
|
2
|
+
import type { ChatControlPlane } from './chat-control-plane.js';
|
|
3
|
+
/** Plugin bodies may include server-only instructions; only the durable row is public input. */
|
|
4
|
+
export declare function readNormalizedInputText(controlPlane: Pick<ChatControlPlane, 'readChannelHistory'>, message: ChannelMessageEvent, timeoutMs?: number): Promise<string | null>;
|
|
5
|
+
export declare function readDurableInputText(controlPlane: Pick<ChatControlPlane, 'readChannelHistory'>, inputRef: {
|
|
6
|
+
channelId: string;
|
|
7
|
+
inputMessageId?: string;
|
|
8
|
+
createdAt?: number;
|
|
9
|
+
}, timeoutMs?: number): Promise<string | null>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Plugin bodies may include server-only instructions; only the durable row is public input. */
|
|
2
|
+
export async function readNormalizedInputText(controlPlane, message, timeoutMs = 2000) {
|
|
3
|
+
return readDurableInputText(controlPlane, { channelId: message.channel_id, inputMessageId: message.message_id, createdAt: message.created_at }, timeoutMs);
|
|
4
|
+
}
|
|
5
|
+
export async function readDurableInputText(controlPlane, inputRef, timeoutMs = 2000) {
|
|
6
|
+
if (!inputRef.inputMessageId)
|
|
7
|
+
return null;
|
|
8
|
+
let timer;
|
|
9
|
+
try {
|
|
10
|
+
const history = await Promise.race([
|
|
11
|
+
controlPlane.readChannelHistory({ channelId: inputRef.channelId, before: inputRef.createdAt == null ? undefined : inputRef.createdAt + 1, limit: 200 }),
|
|
12
|
+
new Promise(resolve => { timer = setTimeout(() => resolve(null), timeoutMs); }),
|
|
13
|
+
]);
|
|
14
|
+
const input = history?.find(entry => entry.id === inputRef.inputMessageId && entry.channelId === inputRef.channelId);
|
|
15
|
+
return typeof input?.body === 'string' ? input.body : null;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
if (timer)
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import { type BorgeePluginClient, type BorgeePluginOptions, type InboundMessageEvent, type ReportTaskFinishedInput, type ReportTurnActivityInput, type StopTurnHandler, type StopBackgroundRunHandler, type TurnActivityReporter } from '../plugin-sdk.js';
|
|
2
|
-
import
|
|
1
|
+
import { type BorgeePluginClient, type BorgeePluginOptions, type ExecutionTelemetryFrame, type InboundMessageEvent, type ReportTaskFinishedInput, type ReportTurnActivityInput, type StopTurnHandler, type ServerRequestHandler, type StopBackgroundRunHandler, type TurnActivityReporter } from '../plugin-sdk.js';
|
|
2
|
+
import { type ExecutionTelemetryOutboxPolicy } from '../execution-telemetry.js';
|
|
3
|
+
import type { ChannelSummary, ChannelFileEntry, ChannelFileContent, PublishChannelFileInput, ChannelHistoryEntry, ChannelMessageEvent, CreateTaskInput, DirectoryUser, MeResponseUser, PostMessageInput, PostedMessage, ReadChannelHistoryInput, Task, UpdateTaskInput } from '../types.js';
|
|
3
4
|
import type { ChatControlPlane } from './chat-control-plane.js';
|
|
4
|
-
type PluginClientLike = Pick<BorgeePluginClient, 'agentId' | 'close' | 'connect' | 'createTask' | 'deleteMessage' | 'editMessage' | 'getMe' | 'getTask' | 'listChannels' | 'listTasks' | 'listUsers' | 'on' | 'onStopTurn' | 'onStopBackgroundRun' | 'reportActivity' | 'readHistory' | 'reportTurnActivity' | '
|
|
5
|
+
type PluginClientLike = Pick<BorgeePluginClient, 'agentId' | 'close' | 'connect' | 'createTask' | 'deleteMessage' | 'editMessage' | 'getMe' | 'getTask' | 'listChannelFiles' | 'readChannelFile' | 'publishChannelFile' | 'listChannels' | 'listTasks' | 'listUsers' | 'on' | 'onStopTurn' | 'onStopBackgroundRun' | 'reportActivity' | 'readHistory' | 'reportTurnActivity' | 'reportTyping' | 'sendMessage' | 'updateTask' | 'setTaskProperty' | 'deleteTaskProperty'> & Partial<Pick<BorgeePluginClient, 'connectionState' | 'reportExecutionTelemetry' | 'reportTaskFinished' | 'onServerRequest' | 'sessionBindingsSupported'>>;
|
|
5
6
|
type PluginClientFactory = (options: BorgeePluginOptions) => PluginClientLike;
|
|
6
|
-
type SdkChatControlPlaneOptions = Pick<BorgeePluginOptions, 'pluginId'
|
|
7
|
+
type SdkChatControlPlaneOptions = Pick<BorgeePluginOptions, 'pluginId'> & {
|
|
8
|
+
providerOutputMode?: () => 'normalized' | 'legacy';
|
|
9
|
+
normalizedActivitySync?: () => boolean;
|
|
10
|
+
sessionControl?: () => boolean;
|
|
11
|
+
sessionBindings?: () => boolean;
|
|
12
|
+
sessionDirectory?: () => boolean;
|
|
13
|
+
sessionManagement?: () => boolean;
|
|
14
|
+
sessionRelations?: () => boolean;
|
|
15
|
+
sessionObservation?: () => boolean;
|
|
16
|
+
connectionLiveness?: () => BorgeePluginOptions['connectionLiveness'];
|
|
17
|
+
sessionInputOperations?: () => readonly ('start_turn' | 'steer' | 'next_turn')[];
|
|
18
|
+
executionTelemetryCapacityWaitMs?: number;
|
|
19
|
+
executionTelemetryOutboxPath?: string;
|
|
20
|
+
executionTelemetryOutboxPolicy?: Partial<ExecutionTelemetryOutboxPolicy>;
|
|
21
|
+
onExecutionTelemetryError?: (error: unknown) => void;
|
|
22
|
+
};
|
|
7
23
|
/**
|
|
8
24
|
* Thin adapter over `@borgee/plugin-sdk` (the same BPP/`/ws/plugin` SDK used by
|
|
9
25
|
* the OpenClaw plugin) that implements the minimal `ChatControlPlane` surface
|
|
@@ -14,24 +30,48 @@ export declare class SdkChatControlPlane implements ChatControlPlane {
|
|
|
14
30
|
private pendingMessages;
|
|
15
31
|
private unsubscribe;
|
|
16
32
|
private stateUnsubscribe;
|
|
33
|
+
private telemetryAckUnsubscribe;
|
|
34
|
+
private executionTelemetryRetry?;
|
|
17
35
|
private activityTransportReady;
|
|
36
|
+
private readonly executionTelemetryOutbox;
|
|
37
|
+
private readonly onExecutionTelemetryError;
|
|
18
38
|
private connected;
|
|
39
|
+
private transportOnline;
|
|
40
|
+
private readonly executionTelemetryCapacityWaitMs;
|
|
19
41
|
private me;
|
|
20
42
|
constructor(baseUrl: string, apiKey: string, createClient?: PluginClientFactory, options?: SdkChatControlPlaneOptions);
|
|
43
|
+
reportExecutionTelemetryFrame(frame: ExecutionTelemetryFrame): void;
|
|
44
|
+
onExecutionTelemetryAck(handler: (ack: import('../plugin-sdk.js').ExecutionTelemetryAck) => void): () => void;
|
|
45
|
+
onExecutionTransportReady(handler: () => void): () => void;
|
|
46
|
+
onServerRequest(handler: ServerRequestHandler | undefined): void;
|
|
21
47
|
onStopTurn(handler: StopTurnHandler | undefined): void;
|
|
22
48
|
onStopBackgroundRun(handler: StopBackgroundRunHandler | undefined): void;
|
|
23
49
|
onActivityTransportReady(handler: (() => void) | undefined): void;
|
|
24
50
|
connect(onMessage: (message: ChannelMessageEvent) => void): Promise<void>;
|
|
25
51
|
close(): Promise<void>;
|
|
26
|
-
postMessage(input: PostMessageInput): Promise<PostedMessage>;
|
|
52
|
+
postMessage(input: PostMessageInput, source?: Pick<import('../plugin-sdk.js').ServerRequestContext, 'isConnectionCurrent'>): Promise<PostedMessage>;
|
|
53
|
+
get sessionBindingsSupported(): boolean;
|
|
27
54
|
reportActivity(input: Parameters<BorgeePluginClient['reportActivity']>[0]): void;
|
|
28
55
|
reportTaskFinished(input: ReportTaskFinishedInput): void;
|
|
29
56
|
editMessage(messageId: string, content: string): Promise<void>;
|
|
30
57
|
deleteMessage(messageId: string): Promise<void>;
|
|
31
|
-
|
|
58
|
+
reportTyping(channelId: string): void;
|
|
32
59
|
reportTurnActivity(input: ReportTurnActivityInput): TurnActivityReporter;
|
|
60
|
+
reportExecutionTelemetry(frame: ExecutionTelemetryFrame): Promise<void>;
|
|
61
|
+
private flushExecutionTelemetry;
|
|
62
|
+
private scheduleExecutionTelemetryRetry;
|
|
63
|
+
private cancelExecutionTelemetryRetry;
|
|
33
64
|
getMe(): Promise<MeResponseUser>;
|
|
34
65
|
listUsers(): Promise<DirectoryUser[]>;
|
|
66
|
+
listChannelFiles(input: {
|
|
67
|
+
channelId: string;
|
|
68
|
+
}): Promise<ChannelFileEntry[]>;
|
|
69
|
+
readChannelFile(input: {
|
|
70
|
+
channelId: string;
|
|
71
|
+
path: string;
|
|
72
|
+
textOnly: boolean;
|
|
73
|
+
}): Promise<ChannelFileContent>;
|
|
74
|
+
publishChannelFile(input: PublishChannelFileInput): Promise<ChannelFileEntry>;
|
|
35
75
|
readChannelHistory(input: ReadChannelHistoryInput): Promise<ChannelHistoryEntry[]>;
|
|
36
76
|
listChannels(): Promise<ChannelSummary[]>;
|
|
37
77
|
createTask(input: CreateTaskInput): Promise<Task>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createBorgeePlugin, } from '../plugin-sdk.js';
|
|
2
|
+
import { ExecutionTelemetryOutbox, ExecutionTelemetryOutboxCapacityError, } from '../execution-telemetry.js';
|
|
2
3
|
import { normalizeHostedMessageAttachment } from '../hosted-turn-content.js';
|
|
3
4
|
/**
|
|
4
5
|
* Thin adapter over `@borgee/plugin-sdk` (the same BPP/`/ws/plugin` SDK used by
|
|
@@ -10,11 +11,63 @@ export class SdkChatControlPlane {
|
|
|
10
11
|
pendingMessages = [];
|
|
11
12
|
unsubscribe = null;
|
|
12
13
|
stateUnsubscribe = null;
|
|
14
|
+
telemetryAckUnsubscribe = null;
|
|
15
|
+
executionTelemetryRetry;
|
|
13
16
|
activityTransportReady;
|
|
17
|
+
executionTelemetryOutbox;
|
|
18
|
+
onExecutionTelemetryError;
|
|
14
19
|
connected = false;
|
|
20
|
+
transportOnline = false;
|
|
21
|
+
executionTelemetryCapacityWaitMs;
|
|
15
22
|
me = null;
|
|
16
23
|
constructor(baseUrl, apiKey, createClient = createBorgeePlugin, options = {}) {
|
|
17
|
-
|
|
24
|
+
const clientOptions = { baseUrl, apiKey, pluginId: options.pluginId };
|
|
25
|
+
// The adapter is selected after its control plane; read its policy at connect.
|
|
26
|
+
if (options.providerOutputMode)
|
|
27
|
+
Object.defineProperty(clientOptions, 'providerOutputMode', { enumerable: true, get: options.providerOutputMode });
|
|
28
|
+
if (options.normalizedActivitySync)
|
|
29
|
+
Object.defineProperty(clientOptions, 'normalizedActivitySync', { enumerable: true, get: options.normalizedActivitySync });
|
|
30
|
+
if (options.sessionControl)
|
|
31
|
+
Object.defineProperty(clientOptions, 'sessionControl', { enumerable: true, get: options.sessionControl });
|
|
32
|
+
if (options.sessionBindings)
|
|
33
|
+
Object.defineProperty(clientOptions, 'sessionBindings', { enumerable: true, get: options.sessionBindings });
|
|
34
|
+
if (options.sessionManagement)
|
|
35
|
+
Object.defineProperty(clientOptions, 'sessionManagement', { enumerable: true, get: options.sessionManagement });
|
|
36
|
+
if (options.sessionDirectory)
|
|
37
|
+
Object.defineProperty(clientOptions, 'sessionDirectory', { enumerable: true, get: options.sessionDirectory });
|
|
38
|
+
if (options.sessionRelations)
|
|
39
|
+
Object.defineProperty(clientOptions, 'sessionRelations', { enumerable: true, get: options.sessionRelations });
|
|
40
|
+
if (options.sessionObservation)
|
|
41
|
+
Object.defineProperty(clientOptions, 'sessionObservation', { enumerable: true, get: options.sessionObservation });
|
|
42
|
+
if (options.connectionLiveness)
|
|
43
|
+
Object.defineProperty(clientOptions, 'connectionLiveness', { enumerable: true, get: options.connectionLiveness });
|
|
44
|
+
if (options.sessionInputOperations)
|
|
45
|
+
clientOptions.sessionInputOperations = options.sessionInputOperations;
|
|
46
|
+
this.client = createClient(clientOptions);
|
|
47
|
+
this.onExecutionTelemetryError =
|
|
48
|
+
options.onExecutionTelemetryError ??
|
|
49
|
+
(() => console.error('[agents-host] execution telemetry persistence failed'));
|
|
50
|
+
this.executionTelemetryCapacityWaitMs =
|
|
51
|
+
options.executionTelemetryCapacityWaitMs ?? 1_000;
|
|
52
|
+
this.executionTelemetryOutbox = new ExecutionTelemetryOutbox(options.executionTelemetryOutboxPath, {
|
|
53
|
+
onRetired: (count) => {
|
|
54
|
+
this.onExecutionTelemetryError(new Error(`Retired ${count} unacknowledged execution telemetry event(s)`));
|
|
55
|
+
},
|
|
56
|
+
policy: options.executionTelemetryOutboxPolicy,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
reportExecutionTelemetryFrame(frame) {
|
|
60
|
+
this.client.reportExecutionTelemetry?.(frame);
|
|
61
|
+
}
|
|
62
|
+
onExecutionTelemetryAck(handler) {
|
|
63
|
+
return this.client.on('executionTelemetryAck', handler);
|
|
64
|
+
}
|
|
65
|
+
onExecutionTransportReady(handler) {
|
|
66
|
+
return this.client.on('connectionState', state => { if (state.status === 'online')
|
|
67
|
+
handler(); });
|
|
68
|
+
}
|
|
69
|
+
onServerRequest(handler) {
|
|
70
|
+
this.client.onServerRequest?.(handler);
|
|
18
71
|
}
|
|
19
72
|
onStopTurn(handler) {
|
|
20
73
|
this.client.onStopTurn(handler);
|
|
@@ -26,6 +79,7 @@ export class SdkChatControlPlane {
|
|
|
26
79
|
this.activityTransportReady = handler;
|
|
27
80
|
}
|
|
28
81
|
async connect(onMessage) {
|
|
82
|
+
await this.executionTelemetryOutbox.load();
|
|
29
83
|
this.unsubscribe = this.client.on('message', (event) => {
|
|
30
84
|
const message = mapInboundToChannelMessage(event);
|
|
31
85
|
if (!this.connected) {
|
|
@@ -35,13 +89,26 @@ export class SdkChatControlPlane {
|
|
|
35
89
|
onMessage(message);
|
|
36
90
|
});
|
|
37
91
|
this.stateUnsubscribe = this.client.on('connectionState', (state) => {
|
|
92
|
+
this.transportOnline = state.status === 'online';
|
|
38
93
|
if (state.status === 'online') {
|
|
39
94
|
this.activityTransportReady?.();
|
|
95
|
+
void this.flushExecutionTelemetry(true);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.cancelExecutionTelemetryRetry();
|
|
40
99
|
}
|
|
41
100
|
});
|
|
101
|
+
this.telemetryAckUnsubscribe = this.client.on('executionTelemetryAck', (ack) => {
|
|
102
|
+
void this.executionTelemetryOutbox
|
|
103
|
+
.acknowledge(ack.eventId)
|
|
104
|
+
.then(() => this.scheduleExecutionTelemetryRetry())
|
|
105
|
+
.catch(this.onExecutionTelemetryError);
|
|
106
|
+
});
|
|
42
107
|
try {
|
|
43
108
|
await this.client.connect();
|
|
44
109
|
this.connected = true;
|
|
110
|
+
this.transportOnline =
|
|
111
|
+
this.transportOnline || this.client.connectionState?.status === 'online';
|
|
45
112
|
if (this.client.agentId) {
|
|
46
113
|
this.me = { id: this.client.agentId };
|
|
47
114
|
}
|
|
@@ -49,36 +116,48 @@ export class SdkChatControlPlane {
|
|
|
49
116
|
onMessage(message);
|
|
50
117
|
}
|
|
51
118
|
this.pendingMessages = [];
|
|
119
|
+
await this.flushExecutionTelemetry(true);
|
|
52
120
|
}
|
|
53
121
|
catch (error) {
|
|
122
|
+
this.transportOnline = false;
|
|
123
|
+
this.cancelExecutionTelemetryRetry();
|
|
54
124
|
this.unsubscribe?.();
|
|
55
125
|
this.unsubscribe = null;
|
|
56
126
|
this.stateUnsubscribe?.();
|
|
57
127
|
this.stateUnsubscribe = null;
|
|
128
|
+
this.telemetryAckUnsubscribe?.();
|
|
129
|
+
this.telemetryAckUnsubscribe = null;
|
|
58
130
|
this.pendingMessages = [];
|
|
59
131
|
throw error;
|
|
60
132
|
}
|
|
61
133
|
}
|
|
62
134
|
async close() {
|
|
63
135
|
this.connected = false;
|
|
136
|
+
this.transportOnline = false;
|
|
137
|
+
this.cancelExecutionTelemetryRetry();
|
|
64
138
|
this.pendingMessages = [];
|
|
65
139
|
this.unsubscribe?.();
|
|
66
140
|
this.unsubscribe = null;
|
|
67
141
|
this.stateUnsubscribe?.();
|
|
68
142
|
this.stateUnsubscribe = null;
|
|
143
|
+
this.telemetryAckUnsubscribe?.();
|
|
144
|
+
this.telemetryAckUnsubscribe = null;
|
|
69
145
|
this.activityTransportReady = undefined;
|
|
70
146
|
this.client.onStopTurn(undefined);
|
|
71
147
|
this.client.onStopBackgroundRun?.(undefined);
|
|
148
|
+
await this.executionTelemetryOutbox.settle();
|
|
72
149
|
await this.client.close();
|
|
73
150
|
}
|
|
74
|
-
async postMessage(input) {
|
|
75
|
-
const
|
|
151
|
+
async postMessage(input, source) {
|
|
152
|
+
const message = {
|
|
76
153
|
channelId: input.channelId,
|
|
77
154
|
body: input.body,
|
|
78
155
|
replyToId: input.replyToId,
|
|
79
|
-
}
|
|
156
|
+
};
|
|
157
|
+
const sent = source ? await this.client.sendMessage(message, source) : await this.client.sendMessage(message);
|
|
80
158
|
return { messageId: sent.messageId };
|
|
81
159
|
}
|
|
160
|
+
get sessionBindingsSupported() { return this.client.sessionBindingsSupported ?? false; }
|
|
82
161
|
reportActivity(input) {
|
|
83
162
|
this.client.reportActivity(input);
|
|
84
163
|
}
|
|
@@ -91,12 +170,65 @@ export class SdkChatControlPlane {
|
|
|
91
170
|
async deleteMessage(messageId) {
|
|
92
171
|
await this.client.deleteMessage({ messageId });
|
|
93
172
|
}
|
|
94
|
-
|
|
95
|
-
|
|
173
|
+
reportTyping(channelId) {
|
|
174
|
+
this.client.reportTyping(channelId);
|
|
96
175
|
}
|
|
97
176
|
reportTurnActivity(input) {
|
|
98
177
|
return this.client.reportTurnActivity(input);
|
|
99
178
|
}
|
|
179
|
+
async reportExecutionTelemetry(frame) {
|
|
180
|
+
if (!this.client.reportExecutionTelemetry) {
|
|
181
|
+
throw new Error('Plugin SDK execution telemetry is unavailable');
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
await this.executionTelemetryOutbox.enqueue(frame);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
if (!(error instanceof ExecutionTelemetryOutboxCapacityError) ||
|
|
188
|
+
!this.transportOnline) {
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
await this.flushExecutionTelemetry(true);
|
|
192
|
+
const capacityAvailable = await this.executionTelemetryOutbox.waitForCapacity(this.executionTelemetryCapacityWaitMs);
|
|
193
|
+
if (!capacityAvailable)
|
|
194
|
+
throw error;
|
|
195
|
+
await this.executionTelemetryOutbox.enqueue(frame);
|
|
196
|
+
}
|
|
197
|
+
await this.flushExecutionTelemetry();
|
|
198
|
+
}
|
|
199
|
+
async flushExecutionTelemetry(force = false) {
|
|
200
|
+
if (!this.connected || !this.transportOnline || !this.client.reportExecutionTelemetry)
|
|
201
|
+
return;
|
|
202
|
+
try {
|
|
203
|
+
await this.executionTelemetryOutbox.flush((frame) => {
|
|
204
|
+
this.client.reportExecutionTelemetry?.(frame);
|
|
205
|
+
}, force);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
this.onExecutionTelemetryError(error);
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
this.scheduleExecutionTelemetryRetry();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
scheduleExecutionTelemetryRetry() {
|
|
215
|
+
this.cancelExecutionTelemetryRetry();
|
|
216
|
+
if (!this.connected || !this.transportOnline)
|
|
217
|
+
return;
|
|
218
|
+
const delay = this.executionTelemetryOutbox.nextRetryDelayMs();
|
|
219
|
+
if (delay === undefined)
|
|
220
|
+
return;
|
|
221
|
+
this.executionTelemetryRetry = setTimeout(() => {
|
|
222
|
+
this.executionTelemetryRetry = undefined;
|
|
223
|
+
void this.flushExecutionTelemetry();
|
|
224
|
+
}, Math.max(1, delay));
|
|
225
|
+
}
|
|
226
|
+
cancelExecutionTelemetryRetry() {
|
|
227
|
+
if (!this.executionTelemetryRetry)
|
|
228
|
+
return;
|
|
229
|
+
clearTimeout(this.executionTelemetryRetry);
|
|
230
|
+
this.executionTelemetryRetry = undefined;
|
|
231
|
+
}
|
|
100
232
|
async getMe() {
|
|
101
233
|
if (this.me) {
|
|
102
234
|
return this.me;
|
|
@@ -117,6 +249,34 @@ export class SdkChatControlPlane {
|
|
|
117
249
|
kind: user.kind,
|
|
118
250
|
}));
|
|
119
251
|
}
|
|
252
|
+
async listChannelFiles(input) {
|
|
253
|
+
const files = await this.client.listChannelFiles({ channelId: input.channelId });
|
|
254
|
+
return files.map((file) => ({
|
|
255
|
+
id: file.id,
|
|
256
|
+
ownerUserId: file.ownerUserId,
|
|
257
|
+
channelId: file.channelId,
|
|
258
|
+
path: file.path,
|
|
259
|
+
parentPath: file.parentPath,
|
|
260
|
+
name: file.name,
|
|
261
|
+
isDirectory: file.isDirectory,
|
|
262
|
+
mimeType: file.mimeType,
|
|
263
|
+
sizeBytes: file.sizeBytes,
|
|
264
|
+
source: file.source,
|
|
265
|
+
sourceMessageId: file.sourceMessageId,
|
|
266
|
+
createdAt: file.createdAt,
|
|
267
|
+
updatedAt: file.updatedAt,
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
async readChannelFile(input) {
|
|
271
|
+
return await this.client.readChannelFile(input);
|
|
272
|
+
}
|
|
273
|
+
async publishChannelFile(input) {
|
|
274
|
+
const file = await this.client.publishChannelFile(input);
|
|
275
|
+
return {
|
|
276
|
+
...file,
|
|
277
|
+
sourceMessageId: file.sourceMessageId,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
120
280
|
async readChannelHistory(input) {
|
|
121
281
|
const messages = await this.client.readHistory({
|
|
122
282
|
channelId: input.channelId,
|
|
@@ -167,6 +327,9 @@ export class SdkChatControlPlane {
|
|
|
167
327
|
export function mapInboundToChannelMessage(event) {
|
|
168
328
|
return {
|
|
169
329
|
type: event.kind,
|
|
330
|
+
...(event.executionGrant ? { execution_grant: { ...event.executionGrant } } : {}),
|
|
331
|
+
...(event.sessionTarget ? { sessionTarget: { ...event.sessionTarget } } : {}),
|
|
332
|
+
...(event.sourceCurrent ? { sourceCurrent: event.sourceCurrent } : {}),
|
|
170
333
|
...(event.message?.type != null ? { message_type: event.message.type } : {}),
|
|
171
334
|
channel_id: event.channelId,
|
|
172
335
|
channel_type: event.channelType,
|
package/dist/cli-args.d.ts
CHANGED
|
@@ -85,4 +85,4 @@ export declare function parseCleanupManagedArgs(argv: string[]): ParsedCleanupMa
|
|
|
85
85
|
export declare function parseApplyManagedArgs(argv: string[]): ParsedApplyManagedArgs;
|
|
86
86
|
/** `update` always installs the latest published release; it takes no options. */
|
|
87
87
|
export declare function assertNoUpdateArgs(argv: string[]): void;
|
|
88
|
-
export declare const USAGE = "Usage:\n agents-host start <serverUrl> <apiKey> [options]\n agents-host start-managed <serverUrl>\n agents-host start-managed <serverUrl> <apiKey> [agent-options]\n agents-host describe-managed <serverUrl>\n agents-host cleanup-managed <serverUrl> [--purge]\n agents-host apply-managed <serverUrl> --stdin\n agents-host apply-managed <serverUrl> --spec-json <json>\n agents-host log <serverUrl> [--lines <n>] [--follow]\n agents-host log <serverUrl> --path\n agents-host start --config <path-to-host-config> [--debug]\n agents-host validate --config <path-to-host-config>\n agents-host describe --config <path-to-host-config>\n agents-host print-layout --root <dir>\n agents-host generate-config --root <dir> --stdin\n agents-host generate-config --root <dir> --spec-json <json>\n agents-host update\n\nForeground start options:\n --debug Enable host/provider debug logs (or set AGENTS_HOST_DEBUG=1)\n\nSingle-agent agent options:\n --name <name> Display name (default: Assistant)\n --provider <claude|codex|copilot>\n Runtime provider (default: claude)\n --claude-command <cmd> Local Claude ACP adapter command (default: claude-agent-acp)\n --claude-args <args> Local Claude ACP adapter args (empty on the shipped bundled path)\n --codex-command <cmd> Local Codex ACP adapter command (default: codex-acp)\n --codex-args <args> Local Codex ACP adapter args\n --copilot-command <cmd>
|
|
88
|
+
export declare const USAGE = "Usage:\n agents-host start <serverUrl> <apiKey> [options]\n agents-host start-managed <serverUrl>\n agents-host start-managed <serverUrl> <apiKey> [agent-options]\n agents-host describe-managed <serverUrl>\n agents-host cleanup-managed <serverUrl> [--purge]\n agents-host apply-managed <serverUrl> --stdin\n agents-host apply-managed <serverUrl> --spec-json <json>\n agents-host log <serverUrl> [--lines <n>] [--follow]\n agents-host log <serverUrl> --path\n agents-host start --config <path-to-host-config> [--debug]\n agents-host validate --config <path-to-host-config>\n agents-host describe --config <path-to-host-config>\n agents-host print-layout --root <dir>\n agents-host generate-config --root <dir> --stdin\n agents-host generate-config --root <dir> --spec-json <json>\n agents-host update\n\nForeground start options:\n --debug Enable host/provider debug logs (or set AGENTS_HOST_DEBUG=1)\n\nSingle-agent agent options:\n --name <name> Display name (default: Assistant)\n --provider <claude|codex|copilot>\n Runtime provider (default: claude)\n --provider-output-mode <legacy|normalized>\n Output adapter (default: legacy; overrides PROVIDER_OUTPUT_MODE)\n --native-provider-command <path>\n Native executable for normalized output (overrides NATIVE_PROVIDER_COMMAND)\n --codex-connection-mode <shared|stdio>\n Normalized Codex transport (default: stdio; overrides CODEX_CONNECTION_MODE)\n --claude-command <cmd> Local Claude ACP adapter command (default: claude-agent-acp)\n --claude-args <args> Local Claude ACP adapter args (empty on the shipped bundled path)\n --codex-command <cmd> Local Codex ACP adapter command (default: codex-acp)\n --codex-args <args> Local Codex ACP adapter args\n --copilot-command <cmd> Legacy Copilot CLI command (default: copilot)\n --copilot-args <args> Parsed but ignored by the legacy Copilot SDK adapter\n --copilot-session-ttl-minutes <minutes>\n Idle session TTL for legacy Copilot SDK sessions (default: 2880)\n --provider-idle-shutdown-minutes <minutes>\n Shut the legacy provider process down after this much idle\n time and re-spawn it on the next turn; 0 keeps it resident\n (default: 10)\n\nCommand summary:\n start <serverUrl> <apiKey> Start one foreground hosted agent (legacy-compatible behavior)\n start --config <path> Start agents + supervisor + watchers from a host config file\n start-managed <serverUrl> Restart or resume an existing per-serverUrl managed daemon\n start-managed <serverUrl> <apiKey>\n Upsert one agent into the per-serverUrl local daemon and exit after reconcile\n describe-managed <serverUrl> Print managed-runtime spec JSON for machine callers\n cleanup-managed <serverUrl> Stop one managed-runtime daemon locally; --purge also removes its runtime root\n apply-managed <serverUrl> Apply one managed-runtime full-set spec for machine callers\n log <serverUrl> Print the managed daemon log tail for one server runtime\n validate --config <path> Validate local-config files without starting agents or watchers\n describe --config <path> Print the current managed full-set spec as JSON\n print-layout --root <dir> Print the canonical default local-config layout as JSON\n generate-config --root <dir> --stdin Materialize canonical local-config files from stdin\n generate-config --root <dir> --spec-json <json>\n Compatibility input; JSON is exposed in process arguments\n update Update the globally installed @borgee/agents-host to the latest release\n\nStartup update check:\n Startup commands print an advisory notice on stderr when a newer release is published.\n Set AGENTS_HOST_DISABLE_UPDATE_CHECK=1 to turn that check off.\n\nExamples:\n agents-host start https://borgee.example.com bgr_xxxxxxxx --provider copilot --debug\n agents-host start-managed https://borgee.example.com\n agents-host start-managed https://borgee.example.com bgr_xxxxxxxx --provider copilot\n agents-host describe-managed https://borgee.example.com\n agents-host cleanup-managed https://borgee.example.com --purge\n printf '%s' '{\"host\":{\"borgeeBaseUrl\":\"https://borgee.example.com\"},\"agents\":[{\"key\":\"cp1\",\"name\":\"Copilot\",\"apiKey\":\"bgr_xxx\",\"provider\":\"copilot\"}]}' | agents-host apply-managed https://borgee.example.com --stdin\n agents-host log https://borgee.example.com --lines 200 --follow\n agents-host log https://borgee.example.com --path\n agents-host start --config ./agents-host.yaml --debug\n agents-host validate --config ./agents-host.yaml\n agents-host describe --config ./agents-host.yaml\n agents-host print-layout --root ./runtime-root\n printf '%s' '{\"host\":{\"borgeeBaseUrl\":\"https://borgee.example.com\"},\"agents\":[{\"key\":\"cp1\",\"name\":\"Copilot\",\"apiKey\":\"bgr_xxx\",\"provider\":\"copilot\"}]}' | agents-host generate-config --root ./runtime-root --stdin\n agents-host update\n";
|
package/dist/cli-args.js
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
export const CLI_FLAG_TO_ENV = {
|
|
9
9
|
name: 'BORGEE_AGENT_NAME',
|
|
10
10
|
provider: 'RUNTIME_PROVIDER',
|
|
11
|
+
'provider-output-mode': 'PROVIDER_OUTPUT_MODE',
|
|
12
|
+
'native-provider-command': 'NATIVE_PROVIDER_COMMAND',
|
|
13
|
+
'codex-connection-mode': 'CODEX_CONNECTION_MODE',
|
|
11
14
|
'claude-command': 'CLAUDE_COMMAND',
|
|
12
15
|
'claude-args': 'CLAUDE_ARGS',
|
|
13
16
|
'codex-command': 'CODEX_COMMAND',
|
|
@@ -505,16 +508,22 @@ Single-agent agent options:
|
|
|
505
508
|
--name <name> Display name (default: Assistant)
|
|
506
509
|
--provider <claude|codex|copilot>
|
|
507
510
|
Runtime provider (default: claude)
|
|
511
|
+
--provider-output-mode <legacy|normalized>
|
|
512
|
+
Output adapter (default: legacy; overrides PROVIDER_OUTPUT_MODE)
|
|
513
|
+
--native-provider-command <path>
|
|
514
|
+
Native executable for normalized output (overrides NATIVE_PROVIDER_COMMAND)
|
|
515
|
+
--codex-connection-mode <shared|stdio>
|
|
516
|
+
Normalized Codex transport (default: stdio; overrides CODEX_CONNECTION_MODE)
|
|
508
517
|
--claude-command <cmd> Local Claude ACP adapter command (default: claude-agent-acp)
|
|
509
518
|
--claude-args <args> Local Claude ACP adapter args (empty on the shipped bundled path)
|
|
510
519
|
--codex-command <cmd> Local Codex ACP adapter command (default: codex-acp)
|
|
511
520
|
--codex-args <args> Local Codex ACP adapter args
|
|
512
|
-
--copilot-command <cmd>
|
|
513
|
-
--copilot-args <args>
|
|
521
|
+
--copilot-command <cmd> Legacy Copilot CLI command (default: copilot)
|
|
522
|
+
--copilot-args <args> Parsed but ignored by the legacy Copilot SDK adapter
|
|
514
523
|
--copilot-session-ttl-minutes <minutes>
|
|
515
|
-
Idle session TTL for Copilot
|
|
524
|
+
Idle session TTL for legacy Copilot SDK sessions (default: 2880)
|
|
516
525
|
--provider-idle-shutdown-minutes <minutes>
|
|
517
|
-
Shut the
|
|
526
|
+
Shut the legacy provider process down after this much idle
|
|
518
527
|
time and re-spawn it on the next turn; 0 keeps it resident
|
|
519
528
|
(default: 10)
|
|
520
529
|
|
package/dist/config.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare function isLegacyClaudeCompatibilityAlias(command: string, args:
|
|
|
21
21
|
export declare function isLegacyClaudeBinaryCommand(command: string): boolean;
|
|
22
22
|
export declare function hasLegacyClaudeOneShotArgs(args: string[]): boolean;
|
|
23
23
|
export declare function assertClaudeCommandCompatibility(command: string, args: string[], sourceLabel: string): void;
|
|
24
|
-
export declare function assertProviderCommandCompatibility(provider: ProviderKind, config: Pick<ProviderCommandConfig, 'claudeCommand' | 'claudeArgs'
|
|
24
|
+
export declare function assertProviderCommandCompatibility(provider: ProviderKind, config: Pick<ProviderCommandConfig, 'claudeCommand' | 'claudeArgs'> & Partial<Pick<ProviderCommandConfig, 'providerOutputMode' | 'codexConnectionMode' | 'codexSharedSocketPath'>>, sourceLabel: string): void;
|
|
25
|
+
export declare function parseCodexConnectionMode(value: unknown): 'shared' | 'stdio';
|
|
26
|
+
export declare function parseProviderOutputMode(value: unknown): 'legacy' | 'normalized';
|
|
25
27
|
export declare function resolveProviderCommandConfig(overrides?: Partial<ProviderCommandConfig>): ProviderCommandConfig;
|
|
26
28
|
export declare function loadConfigFromEnv(env?: NodeJS.ProcessEnv): AgentsHostConfig;
|
package/dist/config.js
CHANGED
|
@@ -137,9 +137,28 @@ export function assertProviderCommandCompatibility(provider, config, sourceLabel
|
|
|
137
137
|
if (provider === 'claude') {
|
|
138
138
|
assertClaudeCommandCompatibility(config.claudeCommand, config.claudeArgs, sourceLabel);
|
|
139
139
|
}
|
|
140
|
+
if (provider === 'codex' && config.providerOutputMode === 'normalized' && (config.codexConnectionMode ?? 'stdio') === 'stdio' && config.codexSharedSocketPath !== undefined) {
|
|
141
|
+
throw new Error(`${sourceLabel}: a Codex shared socket cannot be configured in stdio mode. Set codexConnectionMode: shared (CODEX_CONNECTION_MODE=shared) explicitly to use a shared daemon.`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function parseCodexConnectionMode(value) {
|
|
145
|
+
if (value !== 'shared' && value !== 'stdio')
|
|
146
|
+
throw new Error('codexConnectionMode must be shared or stdio.');
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
export function parseProviderOutputMode(value) {
|
|
150
|
+
if (value !== 'legacy' && value !== 'normalized')
|
|
151
|
+
throw new Error('providerOutputMode must be legacy or normalized.');
|
|
152
|
+
return value;
|
|
140
153
|
}
|
|
141
154
|
export function resolveProviderCommandConfig(overrides = {}) {
|
|
142
155
|
return {
|
|
156
|
+
...(overrides.providerOutputMode !== undefined ? { providerOutputMode: parseProviderOutputMode(overrides.providerOutputMode) } : {}),
|
|
157
|
+
...(overrides.sessionWorkspaceRoot !== undefined ? { sessionWorkspaceRoot: overrides.sessionWorkspaceRoot } : {}),
|
|
158
|
+
...(overrides.nativeProviderCommand !== undefined ? { nativeProviderCommand: overrides.nativeProviderCommand } : {}),
|
|
159
|
+
...(overrides.codexConnectionMode !== undefined ? { codexConnectionMode: parseCodexConnectionMode(overrides.codexConnectionMode) } : {}),
|
|
160
|
+
...(overrides.codexSharedSocketPath !== undefined ? { codexSharedSocketPath: overrides.codexSharedSocketPath } : {}),
|
|
161
|
+
...(overrides.codexTrustShared !== undefined ? { codexTrustShared: parseBooleanValue(overrides.codexTrustShared, 'codexTrustShared', 'provider configuration') } : {}),
|
|
143
162
|
claudeCommand: overrides.claudeCommand ?? DEFAULT_PROVIDER_COMMAND_CONFIG.claudeCommand,
|
|
144
163
|
claudeArgs: [...(overrides.claudeArgs ?? DEFAULT_PROVIDER_COMMAND_CONFIG.claudeArgs)],
|
|
145
164
|
codexCommand: overrides.codexCommand ?? DEFAULT_PROVIDER_COMMAND_CONFIG.codexCommand,
|
|
@@ -158,8 +177,14 @@ export function loadConfigFromEnv(env = process.env) {
|
|
|
158
177
|
assertProviderCompatibility(provider, 'Unsupported RUNTIME_PROVIDER', env);
|
|
159
178
|
const agentApiKey = requireEnv('BORGEE_AGENT_API_KEY', env);
|
|
160
179
|
const providerConfig = resolveProviderCommandConfig({
|
|
180
|
+
...(env.PROVIDER_OUTPUT_MODE ? { providerOutputMode: parseProviderOutputMode(env.PROVIDER_OUTPUT_MODE) } : {}),
|
|
181
|
+
...(env.SESSION_WORKSPACE_ROOT ? { sessionWorkspaceRoot: requireNonEmptyString(env.SESSION_WORKSPACE_ROOT, 'SESSION_WORKSPACE_ROOT') } : {}),
|
|
182
|
+
...(env.NATIVE_PROVIDER_COMMAND ? { nativeProviderCommand: env.NATIVE_PROVIDER_COMMAND } : {}),
|
|
161
183
|
claudeCommand: envOr('CLAUDE_COMMAND', DEFAULT_PROVIDER_COMMAND_CONFIG.claudeCommand, env),
|
|
162
184
|
claudeArgs: parseArgs(envOr('CLAUDE_ARGS', DEFAULT_PROVIDER_COMMAND_CONFIG.claudeArgs.join(' '), env)),
|
|
185
|
+
...(env.CODEX_CONNECTION_MODE !== undefined ? { codexConnectionMode: parseCodexConnectionMode(env.CODEX_CONNECTION_MODE) } : {}),
|
|
186
|
+
...(env.CODEX_SHARED_SOCKET_PATH ? { codexSharedSocketPath: requireNonEmptyString(env.CODEX_SHARED_SOCKET_PATH, 'CODEX_SHARED_SOCKET_PATH') } : {}),
|
|
187
|
+
...(env.CODEX_TRUST_SHARED !== undefined ? { codexTrustShared: parseBooleanValue(env.CODEX_TRUST_SHARED, 'CODEX_TRUST_SHARED', 'environment') } : {}),
|
|
163
188
|
codexCommand: envOr('CODEX_COMMAND', DEFAULT_PROVIDER_COMMAND_CONFIG.codexCommand, env),
|
|
164
189
|
codexArgs: parseArgs(envOr('CODEX_ARGS', DEFAULT_PROVIDER_COMMAND_CONFIG.codexArgs.join(' '), env)),
|
|
165
190
|
copilotCommand: envOr('COPILOT_COMMAND', DEFAULT_PROVIDER_COMMAND_CONFIG.copilotCommand, env),
|
|
@@ -57,6 +57,10 @@ export interface ChannelContextStore {
|
|
|
57
57
|
incomingContent?: string;
|
|
58
58
|
taskAssignmentContextOverride?: TaskAssignmentThreadContext;
|
|
59
59
|
taskAssignmentContextOverridePersistence?: 'persist' | 'ephemeral';
|
|
60
|
+
independentSessionWorkspace?: {
|
|
61
|
+
bindingId: string;
|
|
62
|
+
cwd: string;
|
|
63
|
+
};
|
|
60
64
|
}): Promise<PreparedChannelContext>;
|
|
61
65
|
prepare(channelId: string, options?: {
|
|
62
66
|
provider?: ProviderKind;
|
|
@@ -72,6 +76,10 @@ export interface ChannelContextStore {
|
|
|
72
76
|
incomingContent?: string;
|
|
73
77
|
taskAssignmentContextOverride?: TaskAssignmentThreadContext;
|
|
74
78
|
taskAssignmentContextOverridePersistence?: 'persist' | 'ephemeral';
|
|
79
|
+
independentSessionWorkspace?: {
|
|
80
|
+
bindingId: string;
|
|
81
|
+
cwd: string;
|
|
82
|
+
};
|
|
75
83
|
}): Promise<PreparedChannelContext>;
|
|
76
84
|
}
|
|
77
85
|
export interface SkillAssetResolver {
|
|
@@ -173,6 +181,10 @@ export declare class FileChannelContextStore implements ChannelContextStore {
|
|
|
173
181
|
incomingContent?: string;
|
|
174
182
|
taskAssignmentContextOverride?: TaskAssignmentThreadContext;
|
|
175
183
|
taskAssignmentContextOverridePersistence?: 'persist' | 'ephemeral';
|
|
184
|
+
independentSessionWorkspace?: {
|
|
185
|
+
bindingId: string;
|
|
186
|
+
cwd: string;
|
|
187
|
+
};
|
|
176
188
|
} | string, options?: {
|
|
177
189
|
provider?: ProviderKind;
|
|
178
190
|
projectionStrategy?: ProjectionStrategy;
|
|
@@ -187,6 +199,10 @@ export declare class FileChannelContextStore implements ChannelContextStore {
|
|
|
187
199
|
incomingContent?: string;
|
|
188
200
|
taskAssignmentContextOverride?: TaskAssignmentThreadContext;
|
|
189
201
|
taskAssignmentContextOverridePersistence?: 'persist' | 'ephemeral';
|
|
202
|
+
independentSessionWorkspace?: {
|
|
203
|
+
bindingId: string;
|
|
204
|
+
cwd: string;
|
|
205
|
+
};
|
|
190
206
|
}): Promise<PreparedChannelContext>;
|
|
191
207
|
private resolveSkillRuntimeBestEffort;
|
|
192
208
|
}
|