@ai-sdk/harness-deepagents 1.0.70 → 1.0.72
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/CHANGELOG.md +20 -0
- package/dist/bridge/index.mjs +44 -44
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +185 -80
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/deepagents-auth.ts +101 -8
- package/src/deepagents-bootstrap.ts +87 -0
- package/src/deepagents-harness.ts +71 -94
- package/src/index.ts +4 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,12 @@ import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
|
|
|
2
2
|
import * as _ai_sdk_harness from '@ai-sdk/harness';
|
|
3
3
|
import { HarnessV1, HarnessV1BuiltinTool } from '@ai-sdk/harness';
|
|
4
4
|
|
|
5
|
-
type
|
|
5
|
+
type DeepAgentsResolvedAuthenticationMode = 'anthropic' | 'ai-gateway';
|
|
6
|
+
type DeepAgentsAuthenticationMode = DeepAgentsResolvedAuthenticationMode | 'auto';
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Passing an object to auth options is deprecated. Use a `DeepAgentsAuthenticationMode` string value ("auto" | "anthropic" | "ai-gateway") instead, and pass credentials via environment variables.
|
|
9
|
+
*/
|
|
10
|
+
type LegacyDeepAgentsAuthOptions = {
|
|
6
11
|
readonly anthropic?: {
|
|
7
12
|
readonly apiKey?: string;
|
|
8
13
|
readonly authToken?: string;
|
|
@@ -13,6 +18,7 @@ type DeepAgentsAuthOptions = {
|
|
|
13
18
|
readonly baseUrl?: string;
|
|
14
19
|
};
|
|
15
20
|
};
|
|
21
|
+
type DeepAgentsAuthOptions = DeepAgentsAuthenticationMode | LegacyDeepAgentsAuthOptions;
|
|
16
22
|
|
|
17
23
|
type DeepAgentsThinkingConfig = {
|
|
18
24
|
readonly type: 'adaptive';
|
|
@@ -130,4 +136,4 @@ declare const deepAgents: _ai_sdk_harness.HarnessV1<{
|
|
|
130
136
|
}, any, any>;
|
|
131
137
|
}>;
|
|
132
138
|
|
|
133
|
-
export { type DeepAgentsAuthOptions, type DeepAgentsHarnessSettings, type DeepAgentsThinkingConfig, VERSION, createDeepAgents, deepAgents };
|
|
139
|
+
export { type DeepAgentsAuthOptions, type DeepAgentsAuthenticationMode, type DeepAgentsHarnessSettings, type DeepAgentsThinkingConfig, VERSION, createDeepAgents, deepAgents };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// src/deepagents-harness.ts
|
|
2
2
|
import { randomBytes } from "crypto";
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
4
3
|
import { posix } from "path";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
4
|
import {
|
|
7
5
|
commonTool,
|
|
8
6
|
HarnessCapabilityUnsupportedError,
|
|
@@ -14,9 +12,11 @@ import {
|
|
|
14
12
|
createBridgeStartupError,
|
|
15
13
|
drainBridgeProcessStream,
|
|
16
14
|
forwardBridgeProcessStream,
|
|
15
|
+
maskSandboxCredentials,
|
|
17
16
|
resolveSandboxHomeDir,
|
|
18
17
|
SandboxChannel,
|
|
19
18
|
shellQuote,
|
|
19
|
+
warnCredentialBrokeringUnavailable,
|
|
20
20
|
waitForBridgeReady,
|
|
21
21
|
writeSkills as writeHarnessSkills
|
|
22
22
|
} from "@ai-sdk/harness/utils";
|
|
@@ -24,24 +24,148 @@ import { tool } from "@ai-sdk/provider-utils";
|
|
|
24
24
|
import { WebSocket } from "ws";
|
|
25
25
|
import { z as z2 } from "zod/v4";
|
|
26
26
|
|
|
27
|
+
// src/deepagents-bootstrap.ts
|
|
28
|
+
import { readFile } from "fs/promises";
|
|
29
|
+
import { fileURLToPath } from "url";
|
|
30
|
+
var DEEPAGENTS_BOOTSTRAP_DIR = ".harness-bootstrap/deepagents";
|
|
31
|
+
var RIPGREP_VERSION = "14.1.1";
|
|
32
|
+
var RIPGREP_SHA256_X64 = "4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e";
|
|
33
|
+
var RIPGREP_SHA256_ARM = "c827481c4ff4ea10c9dc7a4022c8de5db34a5737cb74484d62eb94a95841ab2f";
|
|
34
|
+
var cachedBootstrap;
|
|
35
|
+
async function getDeepAgentsBootstrap() {
|
|
36
|
+
if (cachedBootstrap != null) return cachedBootstrap;
|
|
37
|
+
const [bridge, pkg, lock] = await Promise.all([
|
|
38
|
+
readBridgeAsset("index.mjs"),
|
|
39
|
+
readBridgeAsset("package.json"),
|
|
40
|
+
readBridgeAsset("pnpm-lock.yaml")
|
|
41
|
+
]);
|
|
42
|
+
cachedBootstrap = {
|
|
43
|
+
harnessId: "deepagents",
|
|
44
|
+
bootstrapDir: DEEPAGENTS_BOOTSTRAP_DIR,
|
|
45
|
+
files: [
|
|
46
|
+
{ path: `${DEEPAGENTS_BOOTSTRAP_DIR}/bridge.mjs`, content: bridge },
|
|
47
|
+
{ path: `${DEEPAGENTS_BOOTSTRAP_DIR}/package.json`, content: pkg },
|
|
48
|
+
{ path: `${DEEPAGENTS_BOOTSTRAP_DIR}/pnpm-lock.yaml`, content: lock }
|
|
49
|
+
],
|
|
50
|
+
commands: [
|
|
51
|
+
{ command: installRipgrepCommand() },
|
|
52
|
+
{
|
|
53
|
+
command: "pnpm install --frozen-lockfile --store-dir .pnpm-store"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
return cachedBootstrap;
|
|
58
|
+
}
|
|
59
|
+
function installRipgrepCommand() {
|
|
60
|
+
const v = RIPGREP_VERSION;
|
|
61
|
+
return [
|
|
62
|
+
"command -v rg >/dev/null 2>&1 || {",
|
|
63
|
+
'case "$(uname -m)" in',
|
|
64
|
+
`aarch64) a=aarch64-unknown-linux-gnu; sha=${RIPGREP_SHA256_ARM} ;;`,
|
|
65
|
+
`*) a=x86_64-unknown-linux-musl; sha=${RIPGREP_SHA256_X64} ;;`,
|
|
66
|
+
"esac;",
|
|
67
|
+
`f=/tmp/ripgrep-${v}.tar.gz;`,
|
|
68
|
+
`curl -fsSL "https://github.com/BurntSushi/ripgrep/releases/download/${v}/ripgrep-${v}-$a.tar.gz" -o "$f"`,
|
|
69
|
+
'&& echo "$sha $f" | sha256sum -c -',
|
|
70
|
+
'&& tar xzf "$f" -C /tmp',
|
|
71
|
+
`&& mv "/tmp/ripgrep-${v}-$a/rg" /usr/local/bin/rg && chmod +x /usr/local/bin/rg;`,
|
|
72
|
+
"}"
|
|
73
|
+
].join(" ");
|
|
74
|
+
}
|
|
75
|
+
async function readBridgeAsset(name) {
|
|
76
|
+
const candidates = [
|
|
77
|
+
new URL(`./bridge/${name}`, import.meta.url),
|
|
78
|
+
new URL(`../bridge/${name}`, import.meta.url)
|
|
79
|
+
];
|
|
80
|
+
let lastErr;
|
|
81
|
+
for (const url of candidates) {
|
|
82
|
+
try {
|
|
83
|
+
return await readFile(fileURLToPath(url), "utf8");
|
|
84
|
+
} catch (err) {
|
|
85
|
+
const code = err.code;
|
|
86
|
+
if (code !== "ENOENT") throw err;
|
|
87
|
+
lastErr = err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
throw lastErr ?? new Error(`bridge asset not found: ${name}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
27
93
|
// src/deepagents-auth.ts
|
|
28
|
-
import {
|
|
94
|
+
import {
|
|
95
|
+
createCredentialRequestTransformation,
|
|
96
|
+
getAiGatewayAuthFromEnv
|
|
97
|
+
} from "@ai-sdk/harness/utils";
|
|
98
|
+
var DEEPAGENTS_CREDENTIAL_ENVIRONMENT_VARIABLES = [
|
|
99
|
+
"AI_GATEWAY_API_KEY",
|
|
100
|
+
"ANTHROPIC_API_KEY",
|
|
101
|
+
"ANTHROPIC_AUTH_TOKEN"
|
|
102
|
+
];
|
|
103
|
+
function createDeepAgentsRequestTransformations(env, auth) {
|
|
104
|
+
const headers = {};
|
|
105
|
+
if (env.ANTHROPIC_API_KEY) {
|
|
106
|
+
headers["x-api-key"] = env.ANTHROPIC_API_KEY;
|
|
107
|
+
}
|
|
108
|
+
if (env.ANTHROPIC_AUTH_TOKEN) {
|
|
109
|
+
headers.Authorization = `Bearer ${env.ANTHROPIC_AUTH_TOKEN}`;
|
|
110
|
+
}
|
|
111
|
+
return Object.keys(headers).length === 0 ? [] : [
|
|
112
|
+
createCredentialRequestTransformation({
|
|
113
|
+
baseUrl: auth === "ai-gateway" ? env.ANTHROPIC_BASE_URL : env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com",
|
|
114
|
+
headers
|
|
115
|
+
})
|
|
116
|
+
];
|
|
117
|
+
}
|
|
29
118
|
function resolveDeepAgentsEnv({
|
|
30
119
|
auth,
|
|
31
120
|
processEnv = process.env
|
|
32
121
|
}) {
|
|
33
|
-
|
|
34
|
-
|
|
122
|
+
const normalizedAuth = normalizeDeepAgentsAuthToLegacyAuth(auth);
|
|
123
|
+
if (normalizedAuth?.anthropic) {
|
|
124
|
+
return pickAnthropic({ explicit: normalizedAuth.anthropic, processEnv });
|
|
35
125
|
}
|
|
36
126
|
const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env: processEnv });
|
|
37
|
-
if (
|
|
38
|
-
return pickGateway({
|
|
127
|
+
if (normalizedAuth?.gateway) {
|
|
128
|
+
return pickGateway({
|
|
129
|
+
explicit: normalizedAuth.gateway,
|
|
130
|
+
gatewayAuthFromEnv
|
|
131
|
+
});
|
|
39
132
|
}
|
|
40
133
|
if (gatewayAuthFromEnv.apiKey) {
|
|
41
134
|
return pickGateway({ explicit: {}, gatewayAuthFromEnv });
|
|
42
135
|
}
|
|
43
136
|
return pickAnthropic({ processEnv });
|
|
44
137
|
}
|
|
138
|
+
function resolveDeepAgentsAuthenticationMode({
|
|
139
|
+
auth,
|
|
140
|
+
processEnv = process.env
|
|
141
|
+
}) {
|
|
142
|
+
if (auth === "anthropic" || typeof auth !== "string" && auth?.anthropic) {
|
|
143
|
+
return "anthropic";
|
|
144
|
+
}
|
|
145
|
+
if (auth === "ai-gateway" || typeof auth !== "string" && auth?.gateway) {
|
|
146
|
+
return "ai-gateway";
|
|
147
|
+
}
|
|
148
|
+
return getAiGatewayAuthFromEnv({ env: processEnv }).apiKey ? "ai-gateway" : "anthropic";
|
|
149
|
+
}
|
|
150
|
+
function normalizeDeepAgentsAuthToLegacyAuth(auth) {
|
|
151
|
+
if (auth == null || auth === "auto") {
|
|
152
|
+
return void 0;
|
|
153
|
+
}
|
|
154
|
+
if (typeof auth === "string") {
|
|
155
|
+
switch (auth) {
|
|
156
|
+
case "anthropic":
|
|
157
|
+
return { anthropic: {} };
|
|
158
|
+
case "ai-gateway":
|
|
159
|
+
return { gateway: {} };
|
|
160
|
+
default:
|
|
161
|
+
return void 0;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
console.warn(
|
|
165
|
+
'[deepagents] Passing an object to auth options is deprecated. Use a string mode ("auto" | "anthropic" | "ai-gateway") instead, and pass credentials via environment variables.'
|
|
166
|
+
);
|
|
167
|
+
return auth;
|
|
168
|
+
}
|
|
45
169
|
function pickAnthropic({
|
|
46
170
|
explicit,
|
|
47
171
|
processEnv
|
|
@@ -114,30 +238,10 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
|
|
|
114
238
|
]);
|
|
115
239
|
|
|
116
240
|
// src/version.ts
|
|
117
|
-
var VERSION = true ? "1.0.
|
|
241
|
+
var VERSION = true ? "1.0.72" : "0.0.0-test";
|
|
118
242
|
|
|
119
243
|
// src/deepagents-harness.ts
|
|
120
|
-
var BOOTSTRAP_DIR = ".harness-bootstrap/deepagents";
|
|
121
244
|
var DEEPAGENTS_CLIENT_APP = `ai-sdk/harness-deepagents/${VERSION}`;
|
|
122
|
-
var RIPGREP_VERSION = "14.1.1";
|
|
123
|
-
var RIPGREP_SHA256_X64 = "4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e";
|
|
124
|
-
var RIPGREP_SHA256_ARM = "c827481c4ff4ea10c9dc7a4022c8de5db34a5737cb74484d62eb94a95841ab2f";
|
|
125
|
-
function installRipgrepCommand() {
|
|
126
|
-
const v = RIPGREP_VERSION;
|
|
127
|
-
return [
|
|
128
|
-
"command -v rg >/dev/null 2>&1 || {",
|
|
129
|
-
'case "$(uname -m)" in',
|
|
130
|
-
`aarch64) a=aarch64-unknown-linux-gnu; sha=${RIPGREP_SHA256_ARM} ;;`,
|
|
131
|
-
`*) a=x86_64-unknown-linux-musl; sha=${RIPGREP_SHA256_X64} ;;`,
|
|
132
|
-
"esac;",
|
|
133
|
-
`f=/tmp/ripgrep-${v}.tar.gz;`,
|
|
134
|
-
`curl -fsSL "https://github.com/BurntSushi/ripgrep/releases/download/${v}/ripgrep-${v}-$a.tar.gz" -o "$f"`,
|
|
135
|
-
'&& echo "$sha $f" | sha256sum -c -',
|
|
136
|
-
'&& tar xzf "$f" -C /tmp',
|
|
137
|
-
`&& mv "/tmp/ripgrep-${v}-$a/rg" /usr/local/bin/rg && chmod +x /usr/local/bin/rg;`,
|
|
138
|
-
"}"
|
|
139
|
-
].join(" ");
|
|
140
|
-
}
|
|
141
245
|
var SKILLS_SOURCE_PATH = "/.agents/skills";
|
|
142
246
|
var DEEPAGENTS_BUILTIN_TOOLS = {
|
|
143
247
|
read: commonTool("read", {
|
|
@@ -207,7 +311,6 @@ var deepAgentsResumeStateSchema = z2.object({
|
|
|
207
311
|
bridge: deepAgentsBridgeCoordsSchema.optional()
|
|
208
312
|
});
|
|
209
313
|
function createDeepAgents(settings = {}) {
|
|
210
|
-
let cachedBootstrap;
|
|
211
314
|
return {
|
|
212
315
|
specificationVersion: "harness-v1",
|
|
213
316
|
harnessId: "deepagents",
|
|
@@ -215,38 +318,39 @@ function createDeepAgents(settings = {}) {
|
|
|
215
318
|
// Built-in tool approvals are gated in-bridge via DeepAgents' interruptOn (HITL) middleware.
|
|
216
319
|
supportsBuiltinToolApprovals: true,
|
|
217
320
|
lifecycleStateSchema: deepAgentsResumeStateSchema,
|
|
218
|
-
getBootstrap:
|
|
219
|
-
if (cachedBootstrap != null) return cachedBootstrap;
|
|
220
|
-
const [bridge, pkg, lock] = await Promise.all([
|
|
221
|
-
readBridgeAsset("index.mjs"),
|
|
222
|
-
readBridgeAsset("package.json"),
|
|
223
|
-
readBridgeAsset("pnpm-lock.yaml")
|
|
224
|
-
]);
|
|
225
|
-
cachedBootstrap = {
|
|
226
|
-
harnessId: "deepagents",
|
|
227
|
-
bootstrapDir: BOOTSTRAP_DIR,
|
|
228
|
-
files: [
|
|
229
|
-
{ path: `${BOOTSTRAP_DIR}/bridge.mjs`, content: bridge },
|
|
230
|
-
{ path: `${BOOTSTRAP_DIR}/package.json`, content: pkg },
|
|
231
|
-
{ path: `${BOOTSTRAP_DIR}/pnpm-lock.yaml`, content: lock }
|
|
232
|
-
],
|
|
233
|
-
commands: [
|
|
234
|
-
{ command: installRipgrepCommand() },
|
|
235
|
-
{
|
|
236
|
-
command: "pnpm install --frozen-lockfile --store-dir .pnpm-store"
|
|
237
|
-
}
|
|
238
|
-
]
|
|
239
|
-
};
|
|
240
|
-
return cachedBootstrap;
|
|
241
|
-
},
|
|
321
|
+
getBootstrap: getDeepAgentsBootstrap,
|
|
242
322
|
doStart: async (startOpts) => {
|
|
243
323
|
const permissionMode = startOpts.permissionMode;
|
|
244
324
|
const sandboxSession = startOpts.sandboxSession;
|
|
325
|
+
const authenticationMode = resolveDeepAgentsAuthenticationMode({
|
|
326
|
+
auth: settings.auth
|
|
327
|
+
});
|
|
328
|
+
const resolvedAuthEnvironment = resolveDeepAgentsEnv({
|
|
329
|
+
auth: settings.auth
|
|
330
|
+
});
|
|
331
|
+
let sandboxAuthEnvironment = resolvedAuthEnvironment;
|
|
332
|
+
if (sandboxSession.addRequestTransformations != null) {
|
|
333
|
+
const requestTransformations = createDeepAgentsRequestTransformations(
|
|
334
|
+
resolvedAuthEnvironment,
|
|
335
|
+
authenticationMode
|
|
336
|
+
);
|
|
337
|
+
if (requestTransformations.length > 0) {
|
|
338
|
+
await sandboxSession.addRequestTransformations(
|
|
339
|
+
requestTransformations
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
sandboxAuthEnvironment = maskSandboxCredentials({
|
|
343
|
+
environment: resolvedAuthEnvironment,
|
|
344
|
+
credentialEnvironmentVariables: DEEPAGENTS_CREDENTIAL_ENVIRONMENT_VARIABLES
|
|
345
|
+
});
|
|
346
|
+
} else {
|
|
347
|
+
warnCredentialBrokeringUnavailable();
|
|
348
|
+
}
|
|
245
349
|
const session = sandboxSession.restricted();
|
|
246
350
|
const sandboxId = sandboxSession.id;
|
|
247
351
|
const bootstrapDir = posix.resolve(
|
|
248
352
|
sandboxSession.defaultWorkingDirectory,
|
|
249
|
-
|
|
353
|
+
DEEPAGENTS_BOOTSTRAP_DIR
|
|
250
354
|
);
|
|
251
355
|
const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;
|
|
252
356
|
const isResume = lifecycleState != null;
|
|
@@ -269,12 +373,16 @@ function createDeepAgents(settings = {}) {
|
|
|
269
373
|
});
|
|
270
374
|
if (coords) {
|
|
271
375
|
try {
|
|
272
|
-
const
|
|
376
|
+
const endpoint2 = await sandboxSession.getPortEndpoint({
|
|
273
377
|
port: coords.port,
|
|
274
378
|
protocol: "ws"
|
|
275
|
-
})
|
|
379
|
+
});
|
|
380
|
+
const attachEndpoint = withBridgeToken({
|
|
381
|
+
endpoint: endpoint2,
|
|
382
|
+
token: coords.token
|
|
383
|
+
});
|
|
276
384
|
const attachChannel = new SandboxChannel({
|
|
277
|
-
connect: () => openWebSocket(
|
|
385
|
+
connect: () => openWebSocket(attachEndpoint),
|
|
278
386
|
outboundSchema: outboundMessageSchema,
|
|
279
387
|
initialLastSeenEventId: coords.lastSeenEventId,
|
|
280
388
|
onDiagnostic,
|
|
@@ -319,7 +427,7 @@ function createDeepAgents(settings = {}) {
|
|
|
319
427
|
skillsPaths.push(homeSkillsRoot);
|
|
320
428
|
}
|
|
321
429
|
const env = {
|
|
322
|
-
...
|
|
430
|
+
...sandboxAuthEnvironment,
|
|
323
431
|
AI_SDK_HARNESS_CLIENT_APP: DEEPAGENTS_CLIENT_APP,
|
|
324
432
|
BRIDGE_CHANNEL_TOKEN: token,
|
|
325
433
|
BRIDGE_WS_PORT: String(port)
|
|
@@ -369,12 +477,13 @@ function createDeepAgents(settings = {}) {
|
|
|
369
477
|
})
|
|
370
478
|
});
|
|
371
479
|
void drainBridgeProcessStream(proc.stdout);
|
|
372
|
-
const
|
|
480
|
+
const endpoint = await sandboxSession.getPortEndpoint({
|
|
373
481
|
port: boundPort,
|
|
374
482
|
protocol: "ws"
|
|
375
|
-
})
|
|
483
|
+
});
|
|
484
|
+
const bridgeEndpoint = withBridgeToken({ endpoint, token });
|
|
376
485
|
const channel = new SandboxChannel({
|
|
377
|
-
connect: () => openWebSocket(
|
|
486
|
+
connect: () => openWebSocket(bridgeEndpoint),
|
|
378
487
|
outboundSchema: outboundMessageSchema,
|
|
379
488
|
onDiagnostic,
|
|
380
489
|
onBridgeError
|
|
@@ -410,23 +519,6 @@ function resolveBridgePort(sandboxSession, override) {
|
|
|
410
519
|
message: "The deepagents harness needs a TCP port exposed by the sandbox. Create the sandbox with `ports: [<port>]` or pass `createDeepAgents({ port })`."
|
|
411
520
|
});
|
|
412
521
|
}
|
|
413
|
-
async function readBridgeAsset(name) {
|
|
414
|
-
const candidates = [
|
|
415
|
-
new URL(`./bridge/${name}`, import.meta.url),
|
|
416
|
-
new URL(`../bridge/${name}`, import.meta.url)
|
|
417
|
-
];
|
|
418
|
-
let lastErr;
|
|
419
|
-
for (const url of candidates) {
|
|
420
|
-
try {
|
|
421
|
-
return await readFile(fileURLToPath(url), "utf8");
|
|
422
|
-
} catch (err) {
|
|
423
|
-
const code = err.code;
|
|
424
|
-
if (code !== "ENOENT") throw err;
|
|
425
|
-
lastErr = err;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
throw lastErr ?? new Error(`bridge asset not found: ${name}`);
|
|
429
|
-
}
|
|
430
522
|
async function writeSkills({
|
|
431
523
|
sandbox,
|
|
432
524
|
root,
|
|
@@ -444,9 +536,14 @@ async function writeSkills({
|
|
|
444
536
|
invalidSkillFilePathMessage: ({ skillName, filePath }) => `Invalid skill file path for '${skillName}': ${filePath}`
|
|
445
537
|
});
|
|
446
538
|
}
|
|
447
|
-
function openWebSocket(
|
|
539
|
+
function openWebSocket({
|
|
540
|
+
url,
|
|
541
|
+
headers
|
|
542
|
+
}) {
|
|
448
543
|
return new Promise((resolve, reject) => {
|
|
449
|
-
const ws = new WebSocket(url
|
|
544
|
+
const ws = new WebSocket(url, {
|
|
545
|
+
headers: headers == null ? void 0 : { ...headers }
|
|
546
|
+
});
|
|
450
547
|
const onOpen = () => {
|
|
451
548
|
ws.off("error", onError);
|
|
452
549
|
resolve(ws);
|
|
@@ -459,6 +556,14 @@ function openWebSocket(url) {
|
|
|
459
556
|
ws.once("error", onError);
|
|
460
557
|
});
|
|
461
558
|
}
|
|
559
|
+
function withBridgeToken({
|
|
560
|
+
endpoint,
|
|
561
|
+
token
|
|
562
|
+
}) {
|
|
563
|
+
const bridgeUrl = new URL(endpoint.url);
|
|
564
|
+
bridgeUrl.searchParams.set("agent_bridge_token", token);
|
|
565
|
+
return { ...endpoint, url: bridgeUrl.toString() };
|
|
566
|
+
}
|
|
462
567
|
function createSession({
|
|
463
568
|
sessionId,
|
|
464
569
|
channel,
|