@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,130 @@
|
|
|
1
|
+
import { constants as fsConstants, promises as fs } from 'node:fs';
|
|
2
|
+
import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
|
|
3
|
+
export const CHANNEL_FILE_WORKING_COPY_DIRECTORY = '.borgee/channel-files';
|
|
4
|
+
export const CHANNEL_FILE_TRANSFER_MAX_BYTES = 10 * 1024 * 1024;
|
|
5
|
+
export class ChannelFileWorkspaceError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = 'ChannelFileWorkspaceError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function validatePortableRelativePath(path) {
|
|
14
|
+
if (path.length === 0
|
|
15
|
+
|| isAbsolute(path)
|
|
16
|
+
|| path.includes('\\')
|
|
17
|
+
|| path.includes('\0')
|
|
18
|
+
|| path.split('/').some((part) => part === '' || part === '.' || part === '..' || /[\u0000-\u001f\u007f]/u.test(part))
|
|
19
|
+
|| /^[A-Za-z]:/u.test(path)) {
|
|
20
|
+
throw new ChannelFileWorkspaceError('invalid_file_path', `Invalid relative file path: ${path}`);
|
|
21
|
+
}
|
|
22
|
+
return path;
|
|
23
|
+
}
|
|
24
|
+
export function requireExecutionRoot(payload) {
|
|
25
|
+
const workspace = payload.resolvedWorkspace;
|
|
26
|
+
if (workspace?.authority !== 'task-execution-target' || !isAbsolute(workspace.rootPath)) {
|
|
27
|
+
throw new ChannelFileWorkspaceError('execution_local_directory_required', 'Channel file transfer requires a task execution.local_directory');
|
|
28
|
+
}
|
|
29
|
+
return workspace.rootPath;
|
|
30
|
+
}
|
|
31
|
+
export async function readWorkspaceFile(rootPath, sourcePath) {
|
|
32
|
+
const safePath = validatePortableRelativePath(sourcePath);
|
|
33
|
+
const rootRealPath = await fs.realpath(rootPath);
|
|
34
|
+
const candidate = resolve(rootRealPath, ...safePath.split('/'));
|
|
35
|
+
assertContained(rootRealPath, candidate);
|
|
36
|
+
await rejectSymlinks(rootRealPath, candidate);
|
|
37
|
+
let stat;
|
|
38
|
+
try {
|
|
39
|
+
stat = await fs.stat(candidate);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error.code === 'ENOENT') {
|
|
43
|
+
throw new ChannelFileWorkspaceError('file_not_found', `Workspace file not found: ${sourcePath}`);
|
|
44
|
+
}
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
if (!stat.isFile()) {
|
|
48
|
+
throw new ChannelFileWorkspaceError('file_not_found', `Workspace path is not a file: ${sourcePath}`);
|
|
49
|
+
}
|
|
50
|
+
if (stat.size > CHANNEL_FILE_TRANSFER_MAX_BYTES) {
|
|
51
|
+
throw new ChannelFileWorkspaceError('file_too_large', 'File too large (max 10MB)');
|
|
52
|
+
}
|
|
53
|
+
return await fs.readFile(candidate);
|
|
54
|
+
}
|
|
55
|
+
export async function writeWorkingCopy(rootPath, channelPath, content, overwrite) {
|
|
56
|
+
if (content.byteLength > CHANNEL_FILE_TRANSFER_MAX_BYTES) {
|
|
57
|
+
throw new ChannelFileWorkspaceError('file_too_large', 'File too large (max 10MB)');
|
|
58
|
+
}
|
|
59
|
+
const safePath = validatePortableRelativePath(channelPath);
|
|
60
|
+
const executionRoot = await fs.realpath(rootPath);
|
|
61
|
+
const workingRoot = resolve(executionRoot, ...CHANNEL_FILE_WORKING_COPY_DIRECTORY.split('/'));
|
|
62
|
+
assertContained(executionRoot, workingRoot);
|
|
63
|
+
await ensureSafeDirectory(executionRoot, workingRoot);
|
|
64
|
+
const destination = resolve(workingRoot, ...safePath.split('/'));
|
|
65
|
+
assertContained(workingRoot, destination);
|
|
66
|
+
await ensureSafeDirectory(workingRoot, dirname(destination));
|
|
67
|
+
await rejectSymlinks(workingRoot, destination, true);
|
|
68
|
+
try {
|
|
69
|
+
await fs.writeFile(destination, content, { flag: overwrite ? 'w' : 'wx', mode: 0o600 });
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === 'EEXIST') {
|
|
73
|
+
throw new ChannelFileWorkspaceError('file_exists', `Working copy already exists: ${channelPath}`);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
return destination;
|
|
78
|
+
}
|
|
79
|
+
async function ensureSafeDirectory(rootPath, directoryPath) {
|
|
80
|
+
const rel = relative(rootPath, directoryPath);
|
|
81
|
+
if (rel === '') {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
let current = rootPath;
|
|
85
|
+
for (const segment of rel.split(sep)) {
|
|
86
|
+
current = resolve(current, segment);
|
|
87
|
+
try {
|
|
88
|
+
const stat = await fs.lstat(current);
|
|
89
|
+
if (stat.isSymbolicLink()) {
|
|
90
|
+
throw new ChannelFileWorkspaceError('symlink_not_allowed', `Symbolic link is not allowed: ${current}`);
|
|
91
|
+
}
|
|
92
|
+
if (!stat.isDirectory()) {
|
|
93
|
+
throw new ChannelFileWorkspaceError('invalid_file_path', `Path component is not a directory: ${current}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error.code !== 'ENOENT') {
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
await fs.mkdir(current, { mode: 0o700 });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function rejectSymlinks(rootPath, candidate, allowMissingLeaf = false) {
|
|
105
|
+
const rel = relative(rootPath, candidate);
|
|
106
|
+
let current = rootPath;
|
|
107
|
+
const parts = rel.split(sep);
|
|
108
|
+
for (const [index, segment] of parts.entries()) {
|
|
109
|
+
current = resolve(current, segment);
|
|
110
|
+
try {
|
|
111
|
+
const stat = await fs.lstat(current);
|
|
112
|
+
if (stat.isSymbolicLink()) {
|
|
113
|
+
throw new ChannelFileWorkspaceError('symlink_not_allowed', `Symbolic link is not allowed: ${current}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
if (error.code === 'ENOENT' && allowMissingLeaf && index === parts.length - 1) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
await fs.access(candidate, fsConstants.F_OK);
|
|
124
|
+
}
|
|
125
|
+
function assertContained(rootPath, candidate) {
|
|
126
|
+
const rel = relative(rootPath, candidate);
|
|
127
|
+
if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
|
|
128
|
+
throw new ChannelFileWorkspaceError('invalid_file_path', 'Path escapes the execution directory');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -7,6 +7,7 @@ import { evaluateGatewayAuthorization, } from '../policy/gateway-authorization.j
|
|
|
7
7
|
import { resolveConnectionsStatePath } from '../state-paths.js';
|
|
8
8
|
import { findTaskForThread } from '../task-thread-resolution.js';
|
|
9
9
|
import { extractVisibleMentionIds } from '../visible-mentions.js';
|
|
10
|
+
import { ChannelFileWorkspaceError, readWorkspaceFile, requireExecutionRoot, validatePortableRelativePath, writeWorkingCopy, } from './channel-file-workspace.js';
|
|
10
11
|
const LOOPBACK_HOST = '127.0.0.1';
|
|
11
12
|
export const LOCALHOST_GATEWAY_HISTORY_LIMIT = 20;
|
|
12
13
|
const LOCALHOST_GATEWAY_BODY_LIMIT_BYTES = 32 * 1024;
|
|
@@ -60,13 +61,15 @@ class RestartableConnectionsStateStore {
|
|
|
60
61
|
class InMemoryGatewayTokenRegistry {
|
|
61
62
|
resolveBaseUrl;
|
|
62
63
|
tokenFactory;
|
|
64
|
+
resolveStableAgentId;
|
|
63
65
|
activateRollback;
|
|
64
66
|
byChannel = new Map();
|
|
65
67
|
byToken = new Map();
|
|
66
68
|
pendingTokensByChannel = new Map();
|
|
67
|
-
constructor(resolveBaseUrl, tokenFactory, activateRollback = () => { }) {
|
|
69
|
+
constructor(resolveBaseUrl, tokenFactory, resolveStableAgentId, activateRollback = () => { }) {
|
|
68
70
|
this.resolveBaseUrl = resolveBaseUrl;
|
|
69
71
|
this.tokenFactory = tokenFactory;
|
|
72
|
+
this.resolveStableAgentId = resolveStableAgentId;
|
|
70
73
|
this.activateRollback = activateRollback;
|
|
71
74
|
}
|
|
72
75
|
activate() {
|
|
@@ -133,6 +136,7 @@ class InMemoryGatewayTokenRegistry {
|
|
|
133
136
|
const created = {
|
|
134
137
|
channelId,
|
|
135
138
|
token: this.issueUniqueToken(),
|
|
139
|
+
agentId: this.resolveStableAgentId?.()?.trim() || undefined,
|
|
136
140
|
};
|
|
137
141
|
this.byChannel.set(channelId, created);
|
|
138
142
|
this.byToken.set(created.token, created);
|
|
@@ -422,6 +426,89 @@ class LoopbackLocalhostGatewayController {
|
|
|
422
426
|
this.recordAudit('authorized', 200, decision.path, request.method ?? 'GET', decision.binding);
|
|
423
427
|
return;
|
|
424
428
|
}
|
|
429
|
+
case 'files': {
|
|
430
|
+
const files = await this.controlPlane.listChannelFiles({ channelId: this.resolveFileScopeChannelId(binding) });
|
|
431
|
+
this.sendJson(response, 200, { files });
|
|
432
|
+
this.recordAudit('authorized', 200, decision.path, request.method ?? 'GET', decision.binding);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
case 'file-content': {
|
|
436
|
+
const url = new URL(request.url ?? '/', baseUrl);
|
|
437
|
+
const path = readRequiredQueryString(url, 'path');
|
|
438
|
+
if (!path) {
|
|
439
|
+
throw new GatewayHttpError(400, { error: 'missing_file_path' }, 'bad-request');
|
|
440
|
+
}
|
|
441
|
+
validatePortableRelativePath(path);
|
|
442
|
+
const content = await this.controlPlane.readChannelFile({
|
|
443
|
+
channelId: this.resolveFileScopeChannelId(binding),
|
|
444
|
+
path,
|
|
445
|
+
textOnly: true,
|
|
446
|
+
});
|
|
447
|
+
this.sendJson(response, 200, content);
|
|
448
|
+
this.recordAudit('authorized', 200, decision.path, request.method ?? 'GET', decision.binding);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
case 'file-download': {
|
|
452
|
+
const body = parseFileTransferBody(await readGatewayJsonBody(request));
|
|
453
|
+
const rootPath = requireExecutionRoot(binding.payload ?? {});
|
|
454
|
+
const content = await this.controlPlane.readChannelFile({
|
|
455
|
+
channelId: this.resolveFileScopeChannelId(binding),
|
|
456
|
+
path: body.path,
|
|
457
|
+
textOnly: false,
|
|
458
|
+
});
|
|
459
|
+
if (content.base64 == null) {
|
|
460
|
+
throw new GatewayHttpError(502, { error: 'invalid_file_content' }, 'invalid-file-content');
|
|
461
|
+
}
|
|
462
|
+
const localPath = await writeWorkingCopy(rootPath, body.path, Buffer.from(content.base64, 'base64'), body.overwrite);
|
|
463
|
+
this.sendJson(response, 200, { path: body.path, localPath, sizeBytes: content.sizeBytes });
|
|
464
|
+
this.recordAudit('authorized', 200, decision.path, request.method ?? 'POST', decision.binding);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
case 'file-sync': {
|
|
468
|
+
const body = parseFileSyncBody(await readGatewayJsonBody(request));
|
|
469
|
+
const rootPath = requireExecutionRoot(binding.payload ?? {});
|
|
470
|
+
const entries = (await this.controlPlane.listChannelFiles({ channelId: this.resolveFileScopeChannelId(binding) }))
|
|
471
|
+
.filter((file) => !file.isDirectory)
|
|
472
|
+
.filter((file) => body.path == null || file.path === body.path || file.path.startsWith(`${body.path}/`));
|
|
473
|
+
const synced = [];
|
|
474
|
+
for (const file of entries) {
|
|
475
|
+
const content = await this.controlPlane.readChannelFile({
|
|
476
|
+
channelId: this.resolveFileScopeChannelId(binding),
|
|
477
|
+
path: file.path,
|
|
478
|
+
textOnly: false,
|
|
479
|
+
});
|
|
480
|
+
if (content.base64 == null) {
|
|
481
|
+
throw new GatewayHttpError(502, { error: 'invalid_file_content' }, 'invalid-file-content');
|
|
482
|
+
}
|
|
483
|
+
synced.push({
|
|
484
|
+
path: file.path,
|
|
485
|
+
localPath: await writeWorkingCopy(rootPath, file.path, Buffer.from(content.base64, 'base64'), body.overwrite),
|
|
486
|
+
sizeBytes: content.sizeBytes,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
this.sendJson(response, 200, { synced });
|
|
490
|
+
this.recordAudit('authorized', 200, decision.path, request.method ?? 'POST', decision.binding);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
case 'file-publish': {
|
|
494
|
+
const body = parseFilePublishBody(await readGatewayJsonBody(request));
|
|
495
|
+
const rootPath = requireExecutionRoot(binding.payload ?? {});
|
|
496
|
+
const workspace = binding.payload?.resolvedWorkspace;
|
|
497
|
+
if (workspace?.authority !== 'task-execution-target' || !binding.agentId) {
|
|
498
|
+
throw new GatewayHttpError(403, { error: 'publish_context_required' }, 'publish-context-required');
|
|
499
|
+
}
|
|
500
|
+
const content = await readWorkspaceFile(rootPath, body.sourcePath);
|
|
501
|
+
const file = await this.controlPlane.publishChannelFile({
|
|
502
|
+
channelId: this.resolveFileScopeChannelId(binding),
|
|
503
|
+
path: body.channelPath,
|
|
504
|
+
contentType: body.contentType ?? inferContentType(body.sourcePath),
|
|
505
|
+
base64: content.toString('base64'),
|
|
506
|
+
overwrite: body.overwrite,
|
|
507
|
+
});
|
|
508
|
+
this.sendJson(response, 200, { file });
|
|
509
|
+
this.recordAudit('authorized', 200, decision.path, request.method ?? 'POST', decision.binding);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
425
512
|
case 'draft': {
|
|
426
513
|
if (!binding.payload?.localhostGateway?.collaboration?.enabled) {
|
|
427
514
|
this.sendJson(response, 404, { error: 'not_found' });
|
|
@@ -599,6 +686,20 @@ class LoopbackLocalhostGatewayController {
|
|
|
599
686
|
}
|
|
600
687
|
}
|
|
601
688
|
catch (error) {
|
|
689
|
+
if (error instanceof ChannelFileWorkspaceError) {
|
|
690
|
+
const statusCode = error.code === 'file_not_found'
|
|
691
|
+
? 404
|
|
692
|
+
: error.code === 'file_exists'
|
|
693
|
+
? 409
|
|
694
|
+
: error.code === 'file_too_large'
|
|
695
|
+
? 413
|
|
696
|
+
: error.code === 'execution_local_directory_required'
|
|
697
|
+
? 403
|
|
698
|
+
: 400;
|
|
699
|
+
this.sendJson(response, statusCode, { error: error.code });
|
|
700
|
+
this.recordAudit(error.code, statusCode, decision.path, request.method ?? 'GET', decision.binding);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
602
703
|
const gatewayError = error instanceof GatewayHttpError
|
|
603
704
|
? error
|
|
604
705
|
: mapGatewayControlPlaneError(error, 'authorized');
|
|
@@ -611,6 +712,12 @@ class LoopbackLocalhostGatewayController {
|
|
|
611
712
|
throw error;
|
|
612
713
|
}
|
|
613
714
|
}
|
|
715
|
+
resolveFileScopeChannelId(binding) {
|
|
716
|
+
const taskChannelId = binding.payload?.taskAssignmentContext?.taskChannelId;
|
|
717
|
+
return typeof taskChannelId === 'string' && taskChannelId.trim().length > 0
|
|
718
|
+
? taskChannelId
|
|
719
|
+
: binding.channelId;
|
|
720
|
+
}
|
|
614
721
|
async loadAuthorizedTask(boundChannelId, route) {
|
|
615
722
|
let task;
|
|
616
723
|
try {
|
|
@@ -757,6 +864,48 @@ async function readGatewayJsonBody(request) {
|
|
|
757
864
|
throw new GatewayHttpError(400, { error: 'invalid_json' }, 'invalid-json');
|
|
758
865
|
}
|
|
759
866
|
}
|
|
867
|
+
function parseFileTransferBody(value) {
|
|
868
|
+
if (!isRecord(value) || typeof value.path !== 'string') {
|
|
869
|
+
throw new GatewayHttpError(400, { error: 'invalid_file_request' }, 'bad-request');
|
|
870
|
+
}
|
|
871
|
+
return { path: validatePortableRelativePath(value.path), overwrite: value.overwrite === true };
|
|
872
|
+
}
|
|
873
|
+
function parseFileSyncBody(value) {
|
|
874
|
+
if (!isRecord(value) || (value.path != null && typeof value.path !== 'string')) {
|
|
875
|
+
throw new GatewayHttpError(400, { error: 'invalid_file_request' }, 'bad-request');
|
|
876
|
+
}
|
|
877
|
+
return {
|
|
878
|
+
...(typeof value.path === 'string' ? { path: validatePortableRelativePath(value.path) } : {}),
|
|
879
|
+
overwrite: value.overwrite === true,
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
function parseFilePublishBody(value) {
|
|
883
|
+
if (!isRecord(value)
|
|
884
|
+
|| typeof value.sourcePath !== 'string'
|
|
885
|
+
|| typeof value.channelPath !== 'string'
|
|
886
|
+
|| (value.contentType != null && typeof value.contentType !== 'string')) {
|
|
887
|
+
throw new GatewayHttpError(400, { error: 'invalid_file_request' }, 'bad-request');
|
|
888
|
+
}
|
|
889
|
+
return {
|
|
890
|
+
sourcePath: validatePortableRelativePath(value.sourcePath),
|
|
891
|
+
channelPath: validatePortableRelativePath(value.channelPath),
|
|
892
|
+
...(typeof value.contentType === 'string' ? { contentType: value.contentType } : {}),
|
|
893
|
+
overwrite: value.overwrite === true,
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
function inferContentType(path) {
|
|
897
|
+
const extension = path.toLowerCase().split('.').at(-1);
|
|
898
|
+
const byExtension = {
|
|
899
|
+
css: 'text/css', csv: 'text/csv', gif: 'image/gif', html: 'text/html',
|
|
900
|
+
jpeg: 'image/jpeg', jpg: 'image/jpeg', js: 'text/javascript',
|
|
901
|
+
json: 'application/json', md: 'text/markdown', pdf: 'application/pdf',
|
|
902
|
+
png: 'image/png', py: 'text/x-python', toml: 'application/toml',
|
|
903
|
+
ts: 'text/typescript', txt: 'text/plain', webp: 'image/webp',
|
|
904
|
+
xml: 'application/xml', yaml: 'application/yaml', yml: 'application/yaml',
|
|
905
|
+
zip: 'application/zip',
|
|
906
|
+
};
|
|
907
|
+
return (extension && byExtension[extension]) || 'application/octet-stream';
|
|
908
|
+
}
|
|
760
909
|
async function readCollaborationRequestBody(request) {
|
|
761
910
|
const bodyText = await readRequestBody(request, LOCALHOST_GATEWAY_COLLABORATION_BODY_LIMIT_BYTES);
|
|
762
911
|
if (!bodyText.ok) {
|
|
@@ -891,7 +1040,23 @@ function mapGatewayControlPlaneError(error, fallbackReason) {
|
|
|
891
1040
|
case 'bpp.task_not_found':
|
|
892
1041
|
case 'bpp.channel_not_found':
|
|
893
1042
|
case 'bpp.guild_not_found':
|
|
1043
|
+
case 'bpp.file_not_found':
|
|
894
1044
|
return new GatewayHttpError(404, { error: 'not_found' }, 'not-found');
|
|
1045
|
+
case 'bpp.file_invalid':
|
|
1046
|
+
case 'bpp.file_content_invalid':
|
|
1047
|
+
return new GatewayHttpError(400, { error: 'invalid_file_content' }, 'bad-request');
|
|
1048
|
+
case 'bpp.file_input_required':
|
|
1049
|
+
return new GatewayHttpError(422, { error: 'file_input_required' }, 'bad-request');
|
|
1050
|
+
case 'bpp.file_conflict':
|
|
1051
|
+
return new GatewayHttpError(409, { error: 'file_conflict' }, 'conflict');
|
|
1052
|
+
case 'bpp.file_too_large':
|
|
1053
|
+
case 'bpp.file_extracted_content_too_large':
|
|
1054
|
+
return new GatewayHttpError(413, { error: 'file_too_large' }, 'bad-request');
|
|
1055
|
+
case 'bpp.file_unsupported_media_type':
|
|
1056
|
+
case 'bpp.file_extractor_required':
|
|
1057
|
+
return new GatewayHttpError(415, { error: 'file_extractor_required' }, 'bad-request');
|
|
1058
|
+
case 'bpp.file_extraction_failed':
|
|
1059
|
+
return new GatewayHttpError(502, { error: 'file_extraction_failed' }, 'invalid-file-content');
|
|
895
1060
|
case 'bpp.task_title_required':
|
|
896
1061
|
return new GatewayHttpError(400, { error: 'title_required' }, 'bad-request');
|
|
897
1062
|
case 'bpp.task_no_updates':
|
|
@@ -948,7 +1113,7 @@ export function createLocalhostGatewayController(options) {
|
|
|
948
1113
|
}
|
|
949
1114
|
const contextPublisherFactory = (resolveBaseUrl) => {
|
|
950
1115
|
if (!options.tokenBindingGateEnabled) {
|
|
951
|
-
return new InMemoryGatewayTokenRegistry(resolveBaseUrl, options.tokenFactory ?? (() => randomUUID()), () => revokeDurableTokenBindingsIfPresent(options.stateRootDir));
|
|
1116
|
+
return new InMemoryGatewayTokenRegistry(resolveBaseUrl, options.tokenFactory ?? (() => randomUUID()), options.resolveStableAgentId, () => revokeDurableTokenBindingsIfPresent(options.stateRootDir));
|
|
952
1117
|
}
|
|
953
1118
|
const stateRootDir = options.stateRootDir?.trim();
|
|
954
1119
|
if (!stateRootDir) {
|
|
@@ -27,7 +27,7 @@ export function buildHostedTurnContentParts(input) {
|
|
|
27
27
|
return parts;
|
|
28
28
|
}
|
|
29
29
|
export function extractHostedMessageAttachments(parts) {
|
|
30
|
-
return parts.flatMap((part) =>
|
|
30
|
+
return parts.flatMap((part) => 'attachment' in part ? [normalizeHostedMessageAttachment(part.attachment)] : []);
|
|
31
31
|
}
|
|
32
32
|
export function buildHostedIncomingContentText(parts) {
|
|
33
33
|
const text = parts
|
|
@@ -42,7 +42,8 @@ export function buildHostedIncomingContentText(parts) {
|
|
|
42
42
|
`[Attachment metadata was received for ${nonTextParts.length} attachment${nonTextParts.length === 1 ? '' : 's'}]`,
|
|
43
43
|
...nonTextParts.map((part, index) => {
|
|
44
44
|
const filename = part.attachment.filename?.trim();
|
|
45
|
-
|
|
45
|
+
const size = part.attachment.sizeBytes;
|
|
46
|
+
return `${index + 1}. ${part.type};${filename ? ` filename: ${filename};` : ''} content type: ${part.attachment.contentType}${size !== undefined ? `; size: ${size} bytes` : ''}`;
|
|
46
47
|
}),
|
|
47
48
|
];
|
|
48
49
|
const summary = summaryLines.join('\n');
|
package/dist/local-config.js
CHANGED
|
@@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs';
|
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { dirname, extname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
4
4
|
import { parseDocument, stringify } from 'yaml';
|
|
5
|
-
import { assertProviderCompatibility, assertProviderCommandCompatibility, optionalNonEmptyString, optionalStringArray, parseCopilotSessionTtlMinutesValue, parseBooleanValue, parseProviderIdleShutdownMinutesValue, requireNonEmptyString, resolveProvider, resolveProviderCommandConfig, } from './config.js';
|
|
5
|
+
import { assertProviderCompatibility, assertProviderCommandCompatibility, optionalNonEmptyString, optionalStringArray, parseCopilotSessionTtlMinutesValue, parseBooleanValue, parseProviderIdleShutdownMinutesValue, parseProviderOutputMode, parseCodexConnectionMode, requireNonEmptyString, resolveProvider, resolveProviderCommandConfig, } from './config.js';
|
|
6
6
|
import { resolveLocalConfigAgentStateRoot } from './state-paths.js';
|
|
7
7
|
const SUPPORTED_CONFIG_EXTENSIONS = new Set(['.json', '.yaml', '.yml']);
|
|
8
8
|
export const DEFAULT_LOCAL_HOST_CONFIG_FILENAME = 'agents-host.yaml';
|
|
@@ -107,6 +107,21 @@ function parseProviderCommandOverrides(value, sourceLabel) {
|
|
|
107
107
|
if (claudeArgs !== undefined) {
|
|
108
108
|
overrides.claudeArgs = claudeArgs;
|
|
109
109
|
}
|
|
110
|
+
if (value.providerOutputMode !== undefined)
|
|
111
|
+
overrides.providerOutputMode = parseProviderOutputMode(value.providerOutputMode);
|
|
112
|
+
if (value.codexConnectionMode !== undefined)
|
|
113
|
+
overrides.codexConnectionMode = parseCodexConnectionMode(value.codexConnectionMode);
|
|
114
|
+
const sessionWorkspaceRoot = optionalNonEmptyString(value.sessionWorkspaceRoot, 'sessionWorkspaceRoot', sourceLabel);
|
|
115
|
+
if (sessionWorkspaceRoot !== undefined)
|
|
116
|
+
overrides.sessionWorkspaceRoot = sessionWorkspaceRoot;
|
|
117
|
+
const nativeProviderCommand = optionalNonEmptyString(value.nativeProviderCommand, 'nativeProviderCommand', sourceLabel);
|
|
118
|
+
if (nativeProviderCommand !== undefined)
|
|
119
|
+
overrides.nativeProviderCommand = nativeProviderCommand;
|
|
120
|
+
const codexSharedSocketPath = optionalNonEmptyString(value.codexSharedSocketPath, 'codexSharedSocketPath', sourceLabel);
|
|
121
|
+
if (codexSharedSocketPath !== undefined)
|
|
122
|
+
overrides.codexSharedSocketPath = codexSharedSocketPath;
|
|
123
|
+
if (value.codexTrustShared !== undefined)
|
|
124
|
+
overrides.codexTrustShared = parseBooleanValue(value.codexTrustShared, 'codexTrustShared', sourceLabel);
|
|
110
125
|
const codexCommand = optionalNonEmptyString(value.codexCommand, 'codexCommand', sourceLabel);
|
|
111
126
|
if (codexCommand !== undefined) {
|
|
112
127
|
overrides.codexCommand = codexCommand;
|
|
@@ -688,6 +703,18 @@ function renderAgentConfigYaml(agent) {
|
|
|
688
703
|
if (agent.enabled !== undefined) {
|
|
689
704
|
config.enabled = agent.enabled;
|
|
690
705
|
}
|
|
706
|
+
if (agent.providerOutputMode !== undefined)
|
|
707
|
+
config.providerOutputMode = agent.providerOutputMode;
|
|
708
|
+
if (agent.sessionWorkspaceRoot !== undefined)
|
|
709
|
+
config.sessionWorkspaceRoot = agent.sessionWorkspaceRoot;
|
|
710
|
+
if (agent.nativeProviderCommand !== undefined)
|
|
711
|
+
config.nativeProviderCommand = agent.nativeProviderCommand;
|
|
712
|
+
if (agent.codexConnectionMode !== undefined)
|
|
713
|
+
config.codexConnectionMode = agent.codexConnectionMode;
|
|
714
|
+
if (agent.codexSharedSocketPath !== undefined)
|
|
715
|
+
config.codexSharedSocketPath = agent.codexSharedSocketPath;
|
|
716
|
+
if (agent.codexTrustShared !== undefined)
|
|
717
|
+
config.codexTrustShared = agent.codexTrustShared;
|
|
691
718
|
if (agent.claudeCommand !== undefined) {
|
|
692
719
|
config.claudeCommand = agent.claudeCommand;
|
|
693
720
|
}
|
|
@@ -742,6 +769,12 @@ function buildManagedAgentSnapshot(host, stateRootBaseDir, sourcePath, agent) {
|
|
|
742
769
|
function resolveAgentProviderCommandConfig(hostDefaults, agent) {
|
|
743
770
|
return resolveProviderCommandConfig({
|
|
744
771
|
...hostDefaults,
|
|
772
|
+
...(agent.providerOutputMode !== undefined ? { providerOutputMode: agent.providerOutputMode } : {}),
|
|
773
|
+
...(agent.sessionWorkspaceRoot !== undefined ? { sessionWorkspaceRoot: agent.sessionWorkspaceRoot } : {}),
|
|
774
|
+
...(agent.nativeProviderCommand !== undefined ? { nativeProviderCommand: agent.nativeProviderCommand } : {}),
|
|
775
|
+
...(agent.codexConnectionMode !== undefined ? { codexConnectionMode: agent.codexConnectionMode } : {}),
|
|
776
|
+
...(agent.codexSharedSocketPath !== undefined ? { codexSharedSocketPath: agent.codexSharedSocketPath } : {}),
|
|
777
|
+
...(agent.codexTrustShared !== undefined ? { codexTrustShared: agent.codexTrustShared } : {}),
|
|
745
778
|
...(agent.claudeCommand !== undefined ? { claudeCommand: agent.claudeCommand } : {}),
|
|
746
779
|
...(agent.claudeArgs !== undefined ? { claudeArgs: agent.claudeArgs } : {}),
|
|
747
780
|
...(agent.codexCommand !== undefined ? { codexCommand: agent.codexCommand } : {}),
|
package/dist/managed-daemon.js
CHANGED
|
@@ -351,6 +351,11 @@ export function buildManagedLocalAgentConfig(options) {
|
|
|
351
351
|
apiKey: config.agent.agentApiKey,
|
|
352
352
|
provider: config.agent.provider,
|
|
353
353
|
enabled: true,
|
|
354
|
+
...(config.providerOutputMode !== undefined ? { providerOutputMode: config.providerOutputMode } : {}),
|
|
355
|
+
...(config.nativeProviderCommand !== undefined ? { nativeProviderCommand: config.nativeProviderCommand } : {}),
|
|
356
|
+
...(config.codexConnectionMode !== undefined ? { codexConnectionMode: config.codexConnectionMode } : {}),
|
|
357
|
+
...(config.codexSharedSocketPath !== undefined ? { codexSharedSocketPath: config.codexSharedSocketPath } : {}),
|
|
358
|
+
...(config.codexTrustShared !== undefined ? { codexTrustShared: config.codexTrustShared } : {}),
|
|
354
359
|
claudeCommand: config.claudeCommand,
|
|
355
360
|
claudeArgs: [...config.claudeArgs],
|
|
356
361
|
codexCommand: config.codexCommand,
|
|
@@ -382,6 +387,11 @@ function mergeManagedLocalAgentConfig(hostDefaults, existingAgent, generatedAgen
|
|
|
382
387
|
enabled: true,
|
|
383
388
|
name: hasOverride('BORGEE_AGENT_NAME') ? generatedAgent.name : existingAgent.name,
|
|
384
389
|
provider: hasOverride('RUNTIME_PROVIDER') ? generatedAgent.provider : existingAgent.provider,
|
|
390
|
+
providerOutputMode: hasOverride('PROVIDER_OUTPUT_MODE') ? generatedAgent.providerOutputMode : existingAgent.providerOutputMode,
|
|
391
|
+
nativeProviderCommand: hasOverride('NATIVE_PROVIDER_COMMAND') ? generatedAgent.nativeProviderCommand : existingAgent.nativeProviderCommand,
|
|
392
|
+
codexConnectionMode: hasOverride('CODEX_CONNECTION_MODE') ? generatedAgent.codexConnectionMode : existingAgent.codexConnectionMode,
|
|
393
|
+
codexSharedSocketPath: hasOverride('CODEX_SHARED_SOCKET_PATH') ? generatedAgent.codexSharedSocketPath : existingAgent.codexSharedSocketPath,
|
|
394
|
+
codexTrustShared: hasOverride('CODEX_TRUST_SHARED') ? generatedAgent.codexTrustShared : existingAgent.codexTrustShared,
|
|
385
395
|
claudeCommand: hasOverride('CLAUDE_COMMAND') || shouldRefreshLegacyClaudeDefaults
|
|
386
396
|
? generatedAgent.claudeCommand
|
|
387
397
|
: existingAgent.claudeCommand,
|
|
@@ -416,6 +426,11 @@ function collectExplicitManagedAgentEnvOverrides(processEnv, optionEnv) {
|
|
|
416
426
|
for (const key of [
|
|
417
427
|
'BORGEE_AGENT_NAME',
|
|
418
428
|
'RUNTIME_PROVIDER',
|
|
429
|
+
'PROVIDER_OUTPUT_MODE',
|
|
430
|
+
'NATIVE_PROVIDER_COMMAND',
|
|
431
|
+
'CODEX_CONNECTION_MODE',
|
|
432
|
+
'CODEX_SHARED_SOCKET_PATH',
|
|
433
|
+
'CODEX_TRUST_SHARED',
|
|
419
434
|
'CLAUDE_COMMAND',
|
|
420
435
|
'CLAUDE_ARGS',
|
|
421
436
|
'CODEX_COMMAND',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Explicit undefined values survive the native adapters' process.env merge. */
|
|
2
|
+
export function filterNativeEnvironment(env) {
|
|
3
|
+
const native = { ...env };
|
|
4
|
+
for (const key of Object.keys(native)) {
|
|
5
|
+
if (/^(?:BORGEE_|AGENT_HOST_|AGENT_REMOTE_|GATEWAY_|RELAY_)/i.test(key))
|
|
6
|
+
native[key] = undefined;
|
|
7
|
+
}
|
|
8
|
+
return native;
|
|
9
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type AgentStreamMessage as AgentStreamMessageValue } from './envelope.js';
|
|
2
|
+
import { type HistoryPage as HistoryPageValue } from './history.js';
|
|
3
|
+
import { type AgentSessionResponse as AgentSessionResponseValue, type ClientMessage as ClientMessageValue, type CommandAcknowledgementMessage as CommandAcknowledgementMessageValue, type CreateAgentRequest as CreateAgentRequestValue, type IncompatibleProtocolVersionErrorMessage as IncompatibleProtocolVersionErrorMessageValue, type ProviderListResponse as ProviderListResponseValue, type ResumeAgentRequest as ResumeAgentRequestValue, type ServerMessage as ServerMessageValue } from './messages.js';
|
|
4
|
+
import { type ResourceResponse as ResourceResponseValue, type ResourceUpdate as ResourceUpdateValue } from './resources.js';
|
|
5
|
+
import { type AgentSnapshot as AgentSnapshotValue } from './snapshot.js';
|
|
6
|
+
export interface WireIssue {
|
|
7
|
+
code: 'invalid_json' | 'invalid_shape' | 'incompatible_protocol_version' | 'not_json_serializable';
|
|
8
|
+
path: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export type WireDecodeResult<T> = {
|
|
12
|
+
status: 'ok';
|
|
13
|
+
value: T;
|
|
14
|
+
} | {
|
|
15
|
+
status: 'rejected';
|
|
16
|
+
issues: WireIssue[];
|
|
17
|
+
};
|
|
18
|
+
export type WireEncodeResult = {
|
|
19
|
+
status: 'ok';
|
|
20
|
+
json: string;
|
|
21
|
+
} | {
|
|
22
|
+
status: 'rejected';
|
|
23
|
+
issues: WireIssue[];
|
|
24
|
+
};
|
|
25
|
+
export declare function decodeAgentSnapshot(json: string): WireDecodeResult<AgentSnapshotValue>;
|
|
26
|
+
export declare function encodeAgentSnapshot(value: AgentSnapshotValue): WireEncodeResult;
|
|
27
|
+
export declare function decodeHistoryPage(json: string): WireDecodeResult<HistoryPageValue>;
|
|
28
|
+
export declare function encodeHistoryPage(value: HistoryPageValue): WireEncodeResult;
|
|
29
|
+
export declare function decodeAgentStreamMessage(json: string): WireDecodeResult<AgentStreamMessageValue>;
|
|
30
|
+
export declare function encodeAgentStreamMessage(value: AgentStreamMessageValue): WireEncodeResult;
|
|
31
|
+
export declare function decodeResourceResponse(json: string): WireDecodeResult<ResourceResponseValue>;
|
|
32
|
+
export declare function encodeResourceResponse(value: ResourceResponseValue): WireEncodeResult;
|
|
33
|
+
export declare function decodeResourceUpdate(json: string): WireDecodeResult<ResourceUpdateValue>;
|
|
34
|
+
export declare function encodeResourceUpdate(value: ResourceUpdateValue): WireEncodeResult;
|
|
35
|
+
export declare function decodeCreateAgentRequest(json: string): WireDecodeResult<CreateAgentRequestValue>;
|
|
36
|
+
export declare function encodeCreateAgentRequest(value: CreateAgentRequestValue): WireEncodeResult;
|
|
37
|
+
export declare function decodeResumeAgentRequest(json: string): WireDecodeResult<ResumeAgentRequestValue>;
|
|
38
|
+
export declare function encodeResumeAgentRequest(value: ResumeAgentRequestValue): WireEncodeResult;
|
|
39
|
+
export declare function decodeAgentSessionResponse(json: string): WireDecodeResult<AgentSessionResponseValue>;
|
|
40
|
+
export declare function encodeAgentSessionResponse(value: AgentSessionResponseValue): WireEncodeResult;
|
|
41
|
+
export declare function decodeProviderListResponse(json: string): WireDecodeResult<ProviderListResponseValue>;
|
|
42
|
+
export declare function encodeProviderListResponse(value: ProviderListResponseValue): WireEncodeResult;
|
|
43
|
+
export declare function decodeCommandAcknowledgementMessage(json: string): WireDecodeResult<CommandAcknowledgementMessageValue>;
|
|
44
|
+
export declare function encodeCommandAcknowledgementMessage(value: CommandAcknowledgementMessageValue): WireEncodeResult;
|
|
45
|
+
export declare function decodeClientMessage(json: string): WireDecodeResult<ClientMessageValue>;
|
|
46
|
+
export declare function encodeClientMessage(value: ClientMessageValue): WireEncodeResult;
|
|
47
|
+
export declare function decodeServerMessage(json: string): WireDecodeResult<ServerMessageValue>;
|
|
48
|
+
export declare function decodeIncompatibleProtocolVersionError(json: string): WireDecodeResult<IncompatibleProtocolVersionErrorMessageValue>;
|
|
49
|
+
export declare function encodeServerMessage(value: ServerMessageValue): WireEncodeResult;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type Static } from '@sinclair/typebox';
|
|
2
|
+
export declare const AgentCommand: import("@sinclair/typebox").TObject<{
|
|
3
|
+
id: import("@sinclair/typebox").TString;
|
|
4
|
+
name: import("@sinclair/typebox").TString;
|
|
5
|
+
description: import("@sinclair/typebox").TString;
|
|
6
|
+
kind: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"command">, import("@sinclair/typebox").TLiteral<"skill">, import("@sinclair/typebox").TLiteral<"prompt">]>;
|
|
7
|
+
inputHint: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
8
|
+
shortDescription: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
9
|
+
documentation: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
10
|
+
locator: import("@sinclair/typebox").TString;
|
|
11
|
+
resourceId: import("@sinclair/typebox").TString;
|
|
12
|
+
status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"pending">, import("@sinclair/typebox").TLiteral<"available">, import("@sinclair/typebox").TLiteral<"failed">, import("@sinclair/typebox").TLiteral<"unavailable">]>;
|
|
13
|
+
}>>;
|
|
14
|
+
}>;
|
|
15
|
+
export type AgentCommand = Static<typeof AgentCommand>;
|
|
16
|
+
export declare const AgentCommandResult: import("@sinclair/typebox").TObject<{
|
|
17
|
+
text: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
18
|
+
}>;
|
|
19
|
+
export type AgentCommandResult = Static<typeof AgentCommandResult>;
|
|
20
|
+
export declare const ListCommandsRequest: import("@sinclair/typebox").TObject<{
|
|
21
|
+
protocolVersion: import("@sinclair/typebox").TLiteral<"1.7.0">;
|
|
22
|
+
type: import("@sinclair/typebox").TLiteral<"list_commands">;
|
|
23
|
+
payload: import("@sinclair/typebox").TObject<{
|
|
24
|
+
requestId: import("@sinclair/typebox").TString;
|
|
25
|
+
agentId: import("@sinclair/typebox").TString;
|
|
26
|
+
}>;
|
|
27
|
+
}>;
|
|
28
|
+
export declare const CommandListResponse: import("@sinclair/typebox").TObject<{
|
|
29
|
+
protocolVersion: import("@sinclair/typebox").TLiteral<"1.7.0">;
|
|
30
|
+
type: import("@sinclair/typebox").TLiteral<"command_list">;
|
|
31
|
+
payload: import("@sinclair/typebox").TObject<{
|
|
32
|
+
commands: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
33
|
+
id: import("@sinclair/typebox").TString;
|
|
34
|
+
name: import("@sinclair/typebox").TString;
|
|
35
|
+
description: import("@sinclair/typebox").TString;
|
|
36
|
+
kind: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"command">, import("@sinclair/typebox").TLiteral<"skill">, import("@sinclair/typebox").TLiteral<"prompt">]>;
|
|
37
|
+
inputHint: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
38
|
+
shortDescription: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
39
|
+
documentation: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
40
|
+
locator: import("@sinclair/typebox").TString;
|
|
41
|
+
resourceId: import("@sinclair/typebox").TString;
|
|
42
|
+
status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"pending">, import("@sinclair/typebox").TLiteral<"available">, import("@sinclair/typebox").TLiteral<"failed">, import("@sinclair/typebox").TLiteral<"unavailable">]>;
|
|
43
|
+
}>>;
|
|
44
|
+
}>>;
|
|
45
|
+
requestId: import("@sinclair/typebox").TString;
|
|
46
|
+
agentId: import("@sinclair/typebox").TString;
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
export type CommandListResponse = Static<typeof CommandListResponse>;
|
|
50
|
+
export declare const ExecuteCommandRequest: import("@sinclair/typebox").TObject<{
|
|
51
|
+
protocolVersion: import("@sinclair/typebox").TLiteral<"1.7.0">;
|
|
52
|
+
type: import("@sinclair/typebox").TLiteral<"execute_command">;
|
|
53
|
+
payload: import("@sinclair/typebox").TObject<{
|
|
54
|
+
commandId: import("@sinclair/typebox").TString;
|
|
55
|
+
args: import("@sinclair/typebox").TString;
|
|
56
|
+
requestId: import("@sinclair/typebox").TString;
|
|
57
|
+
agentId: import("@sinclair/typebox").TString;
|
|
58
|
+
}>;
|
|
59
|
+
}>;
|
|
60
|
+
export declare const CommandResultResponse: import("@sinclair/typebox").TObject<{
|
|
61
|
+
protocolVersion: import("@sinclair/typebox").TLiteral<"1.7.0">;
|
|
62
|
+
type: import("@sinclair/typebox").TLiteral<"command_result">;
|
|
63
|
+
payload: import("@sinclair/typebox").TObject<{
|
|
64
|
+
result: import("@sinclair/typebox").TObject<{
|
|
65
|
+
text: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
66
|
+
}>;
|
|
67
|
+
requestId: import("@sinclair/typebox").TString;
|
|
68
|
+
agentId: import("@sinclair/typebox").TString;
|
|
69
|
+
}>;
|
|
70
|
+
}>;
|
|
71
|
+
export type CommandResultResponse = Static<typeof CommandResultResponse>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PROTOCOL_VERSION } from './version.js';
|
|
2
|
+
export type NormalizedProtocolVersion = typeof PROTOCOL_VERSION | '1.6.0' | '1.5.0' | '1.4.0' | '1.1.0';
|
|
3
|
+
export declare function isSupportedNormalizedVersion(version: unknown): version is NormalizedProtocolVersion;
|
|
4
|
+
/** Validate committed bytes in their declared schema before adapting a projection copy. */
|
|
5
|
+
export declare function validateNormalizedEventVersion(version: string, event: unknown): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Static } from '@sinclair/typebox';
|
|
2
|
+
export declare const SafeNonNegativeInteger: import("@sinclair/typebox").TInteger;
|
|
3
|
+
export declare const TimelineCursor: import("@sinclair/typebox").TObject<{
|
|
4
|
+
epoch: import("@sinclair/typebox").TString;
|
|
5
|
+
seq: import("@sinclair/typebox").TInteger;
|
|
6
|
+
}>;
|
|
7
|
+
export type TimelineCursor = Static<typeof TimelineCursor>;
|