@ai-sdk/harness 1.0.107 → 1.0.108
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/agent/index.d.ts +14 -3
- package/dist/agent/index.js +74 -30
- package/dist/agent/index.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/utils/index.d.ts +62 -1
- package/dist/utils/index.js +241 -7
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -5
- package/src/agent/harness-agent-session.ts +17 -3
- package/src/agent/harness-agent-settings.ts +4 -2
- package/src/agent/harness-agent.ts +11 -2
- package/src/agent/internal/run-prompt.ts +73 -32
- package/src/utils/index.ts +12 -0
- package/src/utils/native-subscription/jwt.ts +31 -0
- package/src/utils/native-subscription/linux-secret-service.ts +23 -0
- package/src/utils/native-subscription/macos-keychain.ts +26 -0
- package/src/utils/native-subscription/should-resolve-native.ts +18 -0
- package/src/utils/native-subscription/windows-credential-manager.ts +61 -0
- package/src/utils/oauth-access-token.ts +129 -0
- package/src/utils/os.ts +11 -0
- package/src/v1/harness-v1-lifecycle-state.ts +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -472,6 +472,12 @@ type HarnessV1PendingToolResult = {
|
|
|
472
472
|
readonly toolName: string;
|
|
473
473
|
readonly input: string;
|
|
474
474
|
readonly providerOptions?: ProviderOptions;
|
|
475
|
+
/** Executed while suspending; submit on resume without running the tool again. */
|
|
476
|
+
readonly completedResult?: {
|
|
477
|
+
readonly output: unknown;
|
|
478
|
+
readonly isError?: boolean;
|
|
479
|
+
readonly toolResult?: ToolResultPart;
|
|
480
|
+
};
|
|
475
481
|
};
|
|
476
482
|
/**
|
|
477
483
|
* Framework-owned settings captured when a turn begins. The same settings are
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -240,9 +240,70 @@ declare function getAiGatewayAuthFromEnv({ env, }: {
|
|
|
240
240
|
* process environment for authentication discovery.
|
|
241
241
|
*/
|
|
242
242
|
type HarnessV1AuthenticationEnvironment = Readonly<Record<string, string>>;
|
|
243
|
+
/**
|
|
244
|
+
* Authentication options shared by harness adapters. Adapter choices must be
|
|
245
|
+
* a non-empty union of concrete string values.
|
|
246
|
+
*/
|
|
247
|
+
type HarnessV1Authentication<ADAPTER_CHOICES extends string = 'direct'> = [
|
|
248
|
+
ADAPTER_CHOICES
|
|
249
|
+
] extends [never] ? never : string extends ADAPTER_CHOICES ? never : 'auto' | 'ai-gateway' | ADAPTER_CHOICES | HarnessV1AuthenticationEnvironment;
|
|
243
250
|
|
|
244
251
|
declare function isHarnessAuthenticationEnvironment(value: unknown): value is HarnessV1AuthenticationEnvironment;
|
|
245
252
|
|
|
253
|
+
declare function parseJwtPayload({ token, }: {
|
|
254
|
+
token: string;
|
|
255
|
+
}): Promise<Readonly<Record<string, unknown>> | undefined>;
|
|
256
|
+
declare function getJwtExpiresAt({ token, }: {
|
|
257
|
+
token: string;
|
|
258
|
+
}): Promise<number | undefined>;
|
|
259
|
+
|
|
260
|
+
declare function readLinuxSecretServicePassword({ attributes, }: {
|
|
261
|
+
attributes: Readonly<Record<string, string>>;
|
|
262
|
+
}): Promise<string | undefined>;
|
|
263
|
+
|
|
264
|
+
declare function readMacOSKeychainPassword({ service, account, }: {
|
|
265
|
+
service: string;
|
|
266
|
+
account: string;
|
|
267
|
+
}): Promise<string | undefined>;
|
|
268
|
+
|
|
269
|
+
declare function shouldResolveNativeSubscription({ auth, env, hasDirectCredential, }: {
|
|
270
|
+
auth: Extract<HarnessV1Authentication, string> | undefined;
|
|
271
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
272
|
+
hasDirectCredential: boolean;
|
|
273
|
+
}): boolean;
|
|
274
|
+
|
|
275
|
+
declare function readWindowsCredentialManagerPassword({ targetName, }: {
|
|
276
|
+
targetName: string;
|
|
277
|
+
}): Promise<string | undefined>;
|
|
278
|
+
|
|
279
|
+
type OAuthCredential = {
|
|
280
|
+
readonly accessToken: string;
|
|
281
|
+
readonly refreshToken: string;
|
|
282
|
+
readonly expiresAt: number;
|
|
283
|
+
};
|
|
284
|
+
type RefreshOAuthAccessTokenResult = {
|
|
285
|
+
readonly accessToken: string;
|
|
286
|
+
readonly expiresAt: number;
|
|
287
|
+
readonly refreshToken?: string;
|
|
288
|
+
};
|
|
289
|
+
declare function isAccessTokenExpiringSoon({ expiresAt, now, refreshWindowMs, }: {
|
|
290
|
+
readonly expiresAt: number;
|
|
291
|
+
readonly now?: number;
|
|
292
|
+
readonly refreshWindowMs?: number;
|
|
293
|
+
}): boolean;
|
|
294
|
+
declare function refreshOAuthAccessToken({ tokenUrl, clientId, refreshToken, requestFormat, headers, fetch: fetchImplementation, }: {
|
|
295
|
+
readonly tokenUrl: string;
|
|
296
|
+
readonly clientId: string;
|
|
297
|
+
readonly refreshToken: string;
|
|
298
|
+
readonly requestFormat?: 'json' | 'form';
|
|
299
|
+
readonly headers?: Record<string, string>;
|
|
300
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
301
|
+
}): Promise<RefreshOAuthAccessTokenResult>;
|
|
302
|
+
|
|
303
|
+
declare function isMacOS(platform: NodeJS.Platform): boolean;
|
|
304
|
+
declare function isLinux(platform: NodeJS.Platform): boolean;
|
|
305
|
+
declare function isWindows(platform: NodeJS.Platform): boolean;
|
|
306
|
+
|
|
246
307
|
/**
|
|
247
308
|
* Connection details for a sandbox-exposed port. Headers are scoped to the
|
|
248
309
|
* returned URL and must be included when opening the connection.
|
|
@@ -639,4 +700,4 @@ declare function resolveSandboxDefaultWorkingDirectory({ sandboxSession, abortSi
|
|
|
639
700
|
|
|
640
701
|
declare function getRestrictedSandboxSession(sandboxSession: HarnessV1NetworkSandboxSession | Experimental_SandboxSession): Experimental_SandboxSession;
|
|
641
702
|
|
|
642
|
-
export { type BridgeReadyErrorContext, type BridgeReadySource, type DiskLogRecoveryMode, type Experimental_BridgeUserMessageRequest, type Experimental_BridgeUserMessageResponse, type Experimental_BridgeUserMessageSubmitter, SandboxChannel, type SandboxChannelDebugEvent, type SandboxChannelOptions, type SandboxChannelReconnectOptions, type SkillFilePathMode, type WaitForBridgeReadyOptions, type WaitForBridgeReadyResult, type WriteInstructionsOptions, type WriteInstructionsResult, type WriteSkillsOptions, type WriteSkillsResult, applyCredentialForwarding, classifyDiskLog, createBridgeErrorHandler, createBridgeStartupError, createBridgeToken, createCredentialRequestTransformation, createReadBridgeAsset, createSandboxCredentialEnvironment, drainBridgeProcessStream, experimental_createBridgeUserMessageSubmitter, formatBridgeError, forwardBridgeProcessStream, generateSandboxCredentialPlaceholder, getAiGatewayAuthFromEnv, getRestrictedSandboxSession, isHarnessAuthenticationEnvironment, isSandboxCredentialPlaceholder, logBridgeError, markBridgeStarting, maskSandboxCredentials, resolveSandboxDefaultWorkingDirectory, resolveSandboxHomeDir, shellQuote, waitForBridgeReady, warnCredentialBrokeringUnavailable, withBridgeToken, writeInstructions, writeSkills };
|
|
703
|
+
export { type BridgeReadyErrorContext, type BridgeReadySource, type DiskLogRecoveryMode, type Experimental_BridgeUserMessageRequest, type Experimental_BridgeUserMessageResponse, type Experimental_BridgeUserMessageSubmitter, type OAuthCredential, type RefreshOAuthAccessTokenResult, SandboxChannel, type SandboxChannelDebugEvent, type SandboxChannelOptions, type SandboxChannelReconnectOptions, type SkillFilePathMode, type WaitForBridgeReadyOptions, type WaitForBridgeReadyResult, type WriteInstructionsOptions, type WriteInstructionsResult, type WriteSkillsOptions, type WriteSkillsResult, applyCredentialForwarding, classifyDiskLog, createBridgeErrorHandler, createBridgeStartupError, createBridgeToken, createCredentialRequestTransformation, createReadBridgeAsset, createSandboxCredentialEnvironment, drainBridgeProcessStream, experimental_createBridgeUserMessageSubmitter, formatBridgeError, forwardBridgeProcessStream, generateSandboxCredentialPlaceholder, getAiGatewayAuthFromEnv, getJwtExpiresAt, getRestrictedSandboxSession, isAccessTokenExpiringSoon, isHarnessAuthenticationEnvironment, isLinux, isMacOS, isSandboxCredentialPlaceholder, isWindows, logBridgeError, markBridgeStarting, maskSandboxCredentials, parseJwtPayload, readLinuxSecretServicePassword, readMacOSKeychainPassword, readWindowsCredentialManagerPassword, refreshOAuthAccessToken, resolveSandboxDefaultWorkingDirectory, resolveSandboxHomeDir, shellQuote, shouldResolveNativeSubscription, waitForBridgeReady, warnCredentialBrokeringUnavailable, withBridgeToken, writeInstructions, writeSkills };
|
package/dist/utils/index.js
CHANGED
|
@@ -450,6 +450,229 @@ function isHarnessAuthenticationEnvironment(value) {
|
|
|
450
450
|
return true;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
+
// src/utils/native-subscription/jwt.ts
|
|
454
|
+
import { isRecord, safeParseJSON as safeParseJSON3 } from "@ai-sdk/provider-utils";
|
|
455
|
+
async function parseJwtPayload({
|
|
456
|
+
token
|
|
457
|
+
}) {
|
|
458
|
+
const segments = token.split(".");
|
|
459
|
+
if (segments.length !== 3) return void 0;
|
|
460
|
+
try {
|
|
461
|
+
const parsed = await safeParseJSON3({
|
|
462
|
+
text: Buffer.from(segments[1], "base64url").toString("utf8")
|
|
463
|
+
});
|
|
464
|
+
return parsed.success && isRecord(parsed.value) ? parsed.value : void 0;
|
|
465
|
+
} catch (e) {
|
|
466
|
+
return void 0;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
async function getJwtExpiresAt({
|
|
470
|
+
token
|
|
471
|
+
}) {
|
|
472
|
+
const payload = await parseJwtPayload({ token });
|
|
473
|
+
const expiresAt = payload == null ? void 0 : payload.exp;
|
|
474
|
+
return typeof expiresAt === "number" && Number.isFinite(expiresAt) ? expiresAt * 1e3 : void 0;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// src/utils/native-subscription/linux-secret-service.ts
|
|
478
|
+
import { execFile } from "child_process";
|
|
479
|
+
import { promisify } from "util";
|
|
480
|
+
var execFileAsync = promisify(execFile);
|
|
481
|
+
async function readLinuxSecretServicePassword({
|
|
482
|
+
attributes
|
|
483
|
+
}) {
|
|
484
|
+
try {
|
|
485
|
+
const result = await execFileAsync("secret-tool", [
|
|
486
|
+
"lookup",
|
|
487
|
+
...Object.entries(attributes).flatMap(([attribute, value]) => [
|
|
488
|
+
attribute,
|
|
489
|
+
value
|
|
490
|
+
])
|
|
491
|
+
]);
|
|
492
|
+
return result.stdout || void 0;
|
|
493
|
+
} catch (e) {
|
|
494
|
+
return void 0;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// src/utils/native-subscription/macos-keychain.ts
|
|
499
|
+
import { execFile as execFile2 } from "child_process";
|
|
500
|
+
import { promisify as promisify2 } from "util";
|
|
501
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
502
|
+
async function readMacOSKeychainPassword({
|
|
503
|
+
service,
|
|
504
|
+
account
|
|
505
|
+
}) {
|
|
506
|
+
try {
|
|
507
|
+
const result = await execFileAsync2("/usr/bin/security", [
|
|
508
|
+
"find-generic-password",
|
|
509
|
+
"-s",
|
|
510
|
+
service,
|
|
511
|
+
"-a",
|
|
512
|
+
account,
|
|
513
|
+
"-w"
|
|
514
|
+
]);
|
|
515
|
+
return result.stdout.trim() || void 0;
|
|
516
|
+
} catch (e) {
|
|
517
|
+
return void 0;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/utils/native-subscription/should-resolve-native.ts
|
|
522
|
+
function shouldResolveNativeSubscription({
|
|
523
|
+
auth,
|
|
524
|
+
env,
|
|
525
|
+
hasDirectCredential
|
|
526
|
+
}) {
|
|
527
|
+
return auth !== "ai-gateway" && !hasDirectCredential && (auth === "direct" || getAiGatewayAuthFromEnv({ env }).apiKey == null);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/utils/native-subscription/windows-credential-manager.ts
|
|
531
|
+
import { execFile as execFile3 } from "child_process";
|
|
532
|
+
import { promisify as promisify3 } from "util";
|
|
533
|
+
var execFileAsync3 = promisify3(execFile3);
|
|
534
|
+
var credentialManagerSource = `
|
|
535
|
+
using System;
|
|
536
|
+
using System.Runtime.InteropServices;
|
|
537
|
+
using System.Text;
|
|
538
|
+
public static class AISDKCredentialManager {
|
|
539
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
540
|
+
public struct Credential {
|
|
541
|
+
public UInt32 Flags; public UInt32 Type; public string TargetName;
|
|
542
|
+
public string Comment; public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
|
|
543
|
+
public UInt32 CredentialBlobSize; public IntPtr CredentialBlob;
|
|
544
|
+
public UInt32 Persist; public UInt32 AttributeCount; public IntPtr Attributes;
|
|
545
|
+
public string TargetAlias; public string UserName;
|
|
546
|
+
}
|
|
547
|
+
[DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
548
|
+
static extern bool CredRead(string target, UInt32 type, UInt32 flags, out IntPtr credential);
|
|
549
|
+
[DllImport("advapi32.dll", SetLastError = true)] static extern void CredFree(IntPtr credential);
|
|
550
|
+
public static string Read(string target) {
|
|
551
|
+
IntPtr pointer;
|
|
552
|
+
if (!CredRead(target, 1, 0, out pointer)) return null;
|
|
553
|
+
try {
|
|
554
|
+
Credential value = Marshal.PtrToStructure<Credential>(pointer);
|
|
555
|
+
byte[] bytes = new byte[value.CredentialBlobSize];
|
|
556
|
+
Marshal.Copy(value.CredentialBlob, bytes, 0, bytes.Length);
|
|
557
|
+
return Encoding.Unicode.GetString(bytes);
|
|
558
|
+
} finally { CredFree(pointer); }
|
|
559
|
+
}
|
|
560
|
+
}`;
|
|
561
|
+
async function readWindowsCredentialManagerPassword({
|
|
562
|
+
targetName
|
|
563
|
+
}) {
|
|
564
|
+
try {
|
|
565
|
+
const result = await execFileAsync3(
|
|
566
|
+
"powershell.exe",
|
|
567
|
+
[
|
|
568
|
+
"-NoProfile",
|
|
569
|
+
"-NonInteractive",
|
|
570
|
+
"-Command",
|
|
571
|
+
`Add-Type -TypeDefinition $env:AI_SDK_WINDOWS_CREDENTIAL_MANAGER_SOURCE; $value = [AISDKCredentialManager]::Read($env:AI_SDK_WINDOWS_CREDENTIAL_MANAGER_TARGET); if ($null -ne $value) { [Console]::Out.Write($value) }`
|
|
572
|
+
],
|
|
573
|
+
{
|
|
574
|
+
env: {
|
|
575
|
+
...process.env,
|
|
576
|
+
AI_SDK_WINDOWS_CREDENTIAL_MANAGER_SOURCE: credentialManagerSource,
|
|
577
|
+
AI_SDK_WINDOWS_CREDENTIAL_MANAGER_TARGET: targetName
|
|
578
|
+
},
|
|
579
|
+
windowsHide: true
|
|
580
|
+
}
|
|
581
|
+
);
|
|
582
|
+
return result.stdout || void 0;
|
|
583
|
+
} catch (e) {
|
|
584
|
+
return void 0;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// src/utils/oauth-access-token.ts
|
|
589
|
+
import { isRecord as isRecord2, safeParseJSON as safeParseJSON4 } from "@ai-sdk/provider-utils";
|
|
590
|
+
var DEFAULT_REFRESH_WINDOW_MS = 3e5;
|
|
591
|
+
function isAccessTokenExpiringSoon({
|
|
592
|
+
expiresAt,
|
|
593
|
+
now = Date.now(),
|
|
594
|
+
refreshWindowMs = DEFAULT_REFRESH_WINDOW_MS
|
|
595
|
+
}) {
|
|
596
|
+
return expiresAt <= now + refreshWindowMs;
|
|
597
|
+
}
|
|
598
|
+
async function refreshOAuthAccessToken({
|
|
599
|
+
tokenUrl,
|
|
600
|
+
clientId,
|
|
601
|
+
refreshToken,
|
|
602
|
+
requestFormat = "form",
|
|
603
|
+
headers,
|
|
604
|
+
fetch: fetchImplementation = globalThis.fetch
|
|
605
|
+
}) {
|
|
606
|
+
const values = {
|
|
607
|
+
grant_type: "refresh_token",
|
|
608
|
+
client_id: clientId,
|
|
609
|
+
refresh_token: refreshToken
|
|
610
|
+
};
|
|
611
|
+
const response = await fetchImplementation(tokenUrl, {
|
|
612
|
+
method: "POST",
|
|
613
|
+
headers: {
|
|
614
|
+
"content-type": requestFormat === "json" ? "application/json" : "application/x-www-form-urlencoded",
|
|
615
|
+
...headers
|
|
616
|
+
},
|
|
617
|
+
body: requestFormat === "json" ? JSON.stringify(values) : new URLSearchParams(values).toString()
|
|
618
|
+
});
|
|
619
|
+
const responseText = await response.text();
|
|
620
|
+
if (!response.ok) {
|
|
621
|
+
throw new Error(
|
|
622
|
+
`OAuth access token refresh failed with status ${response.status}.`
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
const parsed = await safeParseJSON4({ text: responseText });
|
|
626
|
+
if (!parsed.success || !isRecord2(parsed.value)) {
|
|
627
|
+
throw new Error("OAuth access token refresh returned invalid JSON.");
|
|
628
|
+
}
|
|
629
|
+
const accessToken = parsed.value.access_token;
|
|
630
|
+
if (typeof accessToken !== "string" || accessToken.length === 0) {
|
|
631
|
+
throw new Error(
|
|
632
|
+
"OAuth access token refresh response is missing access_token."
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
const expiresAt = await resolveExpiresAt({
|
|
636
|
+
accessToken,
|
|
637
|
+
expiresIn: parsed.value.expires_in
|
|
638
|
+
});
|
|
639
|
+
const rotatedRefreshToken = parsed.value.refresh_token;
|
|
640
|
+
if (rotatedRefreshToken != null && (typeof rotatedRefreshToken !== "string" || rotatedRefreshToken.length === 0)) {
|
|
641
|
+
throw new Error(
|
|
642
|
+
"OAuth access token refresh response contains an invalid refresh_token."
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
return {
|
|
646
|
+
accessToken,
|
|
647
|
+
expiresAt,
|
|
648
|
+
...typeof rotatedRefreshToken === "string" ? { refreshToken: rotatedRefreshToken } : {}
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
async function resolveExpiresAt({
|
|
652
|
+
accessToken,
|
|
653
|
+
expiresIn
|
|
654
|
+
}) {
|
|
655
|
+
if (typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn >= 0) {
|
|
656
|
+
return Date.now() + expiresIn * 1e3;
|
|
657
|
+
}
|
|
658
|
+
const jwtExpiresAt = await getJwtExpiresAt({ token: accessToken });
|
|
659
|
+
if (jwtExpiresAt != null) return jwtExpiresAt;
|
|
660
|
+
throw new Error(
|
|
661
|
+
"OAuth access token refresh response does not include a usable expiry."
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// src/utils/os.ts
|
|
666
|
+
function isMacOS(platform) {
|
|
667
|
+
return platform === "darwin";
|
|
668
|
+
}
|
|
669
|
+
function isLinux(platform) {
|
|
670
|
+
return platform === "linux";
|
|
671
|
+
}
|
|
672
|
+
function isWindows(platform) {
|
|
673
|
+
return platform === "win32";
|
|
674
|
+
}
|
|
675
|
+
|
|
453
676
|
// src/utils/sandbox-credential-brokering.ts
|
|
454
677
|
import { randomBytes } from "crypto";
|
|
455
678
|
var SANDBOX_CREDENTIAL_PLACEHOLDER_PREFIX = "aisdkhc_";
|
|
@@ -576,7 +799,7 @@ function shellQuote(value) {
|
|
|
576
799
|
// src/utils/write-instructions.ts
|
|
577
800
|
import path2 from "path";
|
|
578
801
|
import {
|
|
579
|
-
safeParseJSON as
|
|
802
|
+
safeParseJSON as safeParseJSON5
|
|
580
803
|
} from "@ai-sdk/provider-utils";
|
|
581
804
|
var INSTRUCTIONS_METADATA_VERSION = 1;
|
|
582
805
|
async function writeInstructions({
|
|
@@ -766,7 +989,7 @@ async function readInstructionsMetadata({
|
|
|
766
989
|
abortSignal
|
|
767
990
|
});
|
|
768
991
|
if (content == null) return void 0;
|
|
769
|
-
const parsed = await
|
|
992
|
+
const parsed = await safeParseJSON5({ text: content });
|
|
770
993
|
if (!parsed.success || !isInstructionsMetadata(parsed.value)) {
|
|
771
994
|
throw new Error(
|
|
772
995
|
`Invalid AI SDK harness instructions metadata: ${metadataPath}`
|
|
@@ -843,7 +1066,7 @@ async function runSandboxCommand({
|
|
|
843
1066
|
import { createHash } from "crypto";
|
|
844
1067
|
import path3 from "path";
|
|
845
1068
|
import {
|
|
846
|
-
safeParseJSON as
|
|
1069
|
+
safeParseJSON as safeParseJSON6
|
|
847
1070
|
} from "@ai-sdk/provider-utils";
|
|
848
1071
|
var SKILLS_MANIFEST_FILENAME = ".ai-sdk-harness-skills.json";
|
|
849
1072
|
var SKILLS_MANIFEST_VERSION = 1;
|
|
@@ -1056,7 +1279,7 @@ async function readSkillsManifest({
|
|
|
1056
1279
|
abortSignal
|
|
1057
1280
|
});
|
|
1058
1281
|
if (content == null) return void 0;
|
|
1059
|
-
const parsed = await
|
|
1282
|
+
const parsed = await safeParseJSON6({ text: content });
|
|
1060
1283
|
if (!parsed.success || !isSkillsManifest(parsed.value)) {
|
|
1061
1284
|
throw new Error(`Invalid AI SDK harness skills manifest: ${manifestPath}`);
|
|
1062
1285
|
}
|
|
@@ -1258,7 +1481,7 @@ function resolveSkillsRootDir({
|
|
|
1258
1481
|
|
|
1259
1482
|
// src/utils/bridge-ready.ts
|
|
1260
1483
|
import {
|
|
1261
|
-
safeParseJSON as
|
|
1484
|
+
safeParseJSON as safeParseJSON7
|
|
1262
1485
|
} from "@ai-sdk/provider-utils";
|
|
1263
1486
|
import { z as z4 } from "zod/v4";
|
|
1264
1487
|
|
|
@@ -1750,7 +1973,7 @@ async function waitForBridgeReady({
|
|
|
1750
1973
|
if (value === void 0) continue;
|
|
1751
1974
|
for (const line of decoder.push(value)) {
|
|
1752
1975
|
pushTail({ lines: stdoutTail, line });
|
|
1753
|
-
const parsed = await
|
|
1976
|
+
const parsed = await safeParseJSON7({
|
|
1754
1977
|
text: line,
|
|
1755
1978
|
schema: harnessV1BridgeReadySchema
|
|
1756
1979
|
});
|
|
@@ -1787,7 +2010,7 @@ async function readBridgeMetaReady({
|
|
|
1787
2010
|
})
|
|
1788
2011
|
).catch(() => null);
|
|
1789
2012
|
if (raw == null) return void 0;
|
|
1790
|
-
const parsed = await
|
|
2013
|
+
const parsed = await safeParseJSON7({ text: raw, schema: bridgeMetaSchema });
|
|
1791
2014
|
if (!parsed.success) return void 0;
|
|
1792
2015
|
if (parsed.value.type !== bridgeType) return void 0;
|
|
1793
2016
|
if (parsed.value.state !== "waiting") return void 0;
|
|
@@ -2072,15 +2295,26 @@ export {
|
|
|
2072
2295
|
forwardBridgeProcessStream,
|
|
2073
2296
|
generateSandboxCredentialPlaceholder,
|
|
2074
2297
|
getAiGatewayAuthFromEnv,
|
|
2298
|
+
getJwtExpiresAt,
|
|
2075
2299
|
getRestrictedSandboxSession,
|
|
2300
|
+
isAccessTokenExpiringSoon,
|
|
2076
2301
|
isHarnessAuthenticationEnvironment,
|
|
2302
|
+
isLinux,
|
|
2303
|
+
isMacOS,
|
|
2077
2304
|
isSandboxCredentialPlaceholder,
|
|
2305
|
+
isWindows,
|
|
2078
2306
|
logBridgeError,
|
|
2079
2307
|
markBridgeStarting,
|
|
2080
2308
|
maskSandboxCredentials,
|
|
2309
|
+
parseJwtPayload,
|
|
2310
|
+
readLinuxSecretServicePassword,
|
|
2311
|
+
readMacOSKeychainPassword,
|
|
2312
|
+
readWindowsCredentialManagerPassword,
|
|
2313
|
+
refreshOAuthAccessToken,
|
|
2081
2314
|
resolveSandboxDefaultWorkingDirectory,
|
|
2082
2315
|
resolveSandboxHomeDir,
|
|
2083
2316
|
shellQuote,
|
|
2317
|
+
shouldResolveNativeSubscription,
|
|
2084
2318
|
waitForBridgeReady,
|
|
2085
2319
|
warnCredentialBrokeringUnavailable,
|
|
2086
2320
|
withBridgeToken,
|