@ai-sdk/sandbox-vercel 1.0.87 → 1.0.90
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 +27 -0
- package/README.md +5 -2
- package/dist/index.js +34 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/vercel-network-policy-manager.ts +45 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @ai-sdk/sandbox-vercel
|
|
2
2
|
|
|
3
|
+
## 1.0.90
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0e590d2: feat(harness): harden credential brokering to only apply with correct ephemeral secret
|
|
8
|
+
- Updated dependencies [3e125ba]
|
|
9
|
+
- Updated dependencies [0e590d2]
|
|
10
|
+
- @ai-sdk/provider-utils@5.0.32
|
|
11
|
+
- @ai-sdk/harness@1.0.90
|
|
12
|
+
|
|
13
|
+
## 1.0.89
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- @ai-sdk/harness@1.0.89
|
|
18
|
+
|
|
19
|
+
## 1.0.88
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [32349cc]
|
|
24
|
+
- Updated dependencies [a9782e1]
|
|
25
|
+
- Updated dependencies [35841f5]
|
|
26
|
+
- Updated dependencies [d2f3353]
|
|
27
|
+
- @ai-sdk/harness@1.0.88
|
|
28
|
+
- @ai-sdk/provider-utils@5.0.31
|
|
29
|
+
|
|
3
30
|
## 1.0.87
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -94,5 +94,8 @@ await networkSandboxSession.setNetworkPolicy?.({
|
|
|
94
94
|
|
|
95
95
|
Vercel Sandbox supports outbound request transformations for use cases such as
|
|
96
96
|
credential brokering. `setRequestTransformations()` replaces the managed rules,
|
|
97
|
-
while `addRequestTransformations()` adds rules without replacing
|
|
98
|
-
|
|
97
|
+
while `addRequestTransformations()` adds rules without replacing unrelated
|
|
98
|
+
rules. Re-adding a managed rule with the same request matcher and transformed
|
|
99
|
+
header names refreshes that rule in place, which keeps resumed credential
|
|
100
|
+
brokering idempotent. Network access policies remain authoritative over which
|
|
101
|
+
hosts can be reached.
|
package/dist/index.js
CHANGED
|
@@ -84,12 +84,10 @@ var VercelNetworkPolicyManager = class {
|
|
|
84
84
|
}
|
|
85
85
|
await __privateMethod(this, _VercelNetworkPolicyManager_instances, applyState_fn).call(this, {
|
|
86
86
|
accessPolicy: inspection.accessPolicy,
|
|
87
|
-
requestTransformations: __privateGet(this, _state) == null ? incomingTransformations :
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
...incomingTransformations
|
|
92
|
-
],
|
|
87
|
+
requestTransformations: __privateGet(this, _state) == null ? incomingTransformations : mergeRequestTransformations({
|
|
88
|
+
existing: __privateGet(this, _state).requestTransformations,
|
|
89
|
+
incoming: incomingTransformations
|
|
90
|
+
}),
|
|
93
91
|
forwardRules: inspection.forwardRules.map(cloneForwardRule),
|
|
94
92
|
currentPolicy: inspection.currentPolicy
|
|
95
93
|
});
|
|
@@ -396,6 +394,36 @@ function areNetworkPoliciesEqual({
|
|
|
396
394
|
}) {
|
|
397
395
|
return stableSerialize(first) === stableSerialize(second);
|
|
398
396
|
}
|
|
397
|
+
function mergeRequestTransformations({
|
|
398
|
+
existing,
|
|
399
|
+
incoming
|
|
400
|
+
}) {
|
|
401
|
+
const merged = existing.map(cloneRequestTransformation);
|
|
402
|
+
const identities = new Map(
|
|
403
|
+
merged.map((transformation, index) => [
|
|
404
|
+
getRequestTransformationIdentity(transformation),
|
|
405
|
+
index
|
|
406
|
+
])
|
|
407
|
+
);
|
|
408
|
+
for (const transformation of incoming) {
|
|
409
|
+
const clonedTransformation = cloneRequestTransformation(transformation);
|
|
410
|
+
const identity = getRequestTransformationIdentity(clonedTransformation);
|
|
411
|
+
const existingIndex = identities.get(identity);
|
|
412
|
+
if (existingIndex == null) {
|
|
413
|
+
identities.set(identity, merged.length);
|
|
414
|
+
merged.push(clonedTransformation);
|
|
415
|
+
} else {
|
|
416
|
+
merged[existingIndex] = clonedTransformation;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return merged;
|
|
420
|
+
}
|
|
421
|
+
function getRequestTransformationIdentity(transformation) {
|
|
422
|
+
return stableSerialize({
|
|
423
|
+
match: transformation.match,
|
|
424
|
+
transformedHeaderNames: Object.keys(transformation.transform.headers).map((name) => name.toLowerCase()).sort()
|
|
425
|
+
});
|
|
426
|
+
}
|
|
399
427
|
function stableSerialize(value) {
|
|
400
428
|
if (Array.isArray(value)) {
|
|
401
429
|
return `[${value.map(stableSerialize).join(",")}]`;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vercel-sandbox.ts","../src/vercel-network-sandbox-session.ts","../src/vercel-network-policy-manager.ts","../src/vercel-sandbox-session.ts"],"sourcesContent":["import {\n HarnessSandboxAuthenticationError,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1SandboxProvider,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { Sandbox } from '@vercel/sandbox';\nimport { VercelNetworkSandboxSession } from './vercel-network-sandbox-session';\nimport { VercelSandboxSession } from './vercel-sandbox-session';\n\n/**\n * Flattens an intersection of object types into a single object type so the\n * resolved shape displays as its named properties rather than a chain of\n * `A & B & C`.\n */\ntype Prettify<T> = { [K in keyof T]: T[K] } & {};\n\n/**\n * Distributes `Omit` across each member of a union instead of collapsing the\n * union to its common keys. `Sandbox.create`'s parameter is a union (a\n * git/tarball/no-source create variant and a snapshot-source create variant),\n * so a plain `Omit` would discard keys absent from any one member (e.g.\n * `runtime`, which the snapshot variant lacks) and merge the `source` shapes.\n * Applying `Omit` per-member preserves every variant intact; the `Prettify`\n * wrapper collapses each member's intersections into a readable object shape.\n */\ntype DistributiveOmit<T, K extends keyof any> = T extends unknown\n ? Prettify<Omit<T, K>>\n : never;\n\n/**\n * Parameters forwarded to `@vercel/sandbox`'s `Sandbox.create` when creating\n * a sandbox from scratch. Aliased directly from the underlying SDK so the\n * full surface — every option Vercel supports, including its native\n * `NetworkPolicy` — is available without us re-declaring it.\n */\ntype VercelSandboxCreateParams = DistributiveOmit<\n NonNullable<Parameters<typeof Sandbox.create>[0]>,\n 'onResume'\n>;\n\n/**\n * Settings for {@link createVercelSandbox}. Two mutually-exclusive shapes:\n *\n * - `{ sandbox }` — wrap an already-created `@vercel/sandbox` `Sandbox`. The\n * caller owns its lifecycle; the provider's `stop()` and `destroy()` are\n * no-ops.\n * - {@link VercelSandboxCreateParams} fields — provider creates the underlying\n * sandbox. When the adapter declares a bootstrap recipe the provider uses\n * `Sandbox.getOrCreate` to maintain a persistent named template snapshot\n * keyed by the recipe identity, and forks an ephemeral sandbox per session\n * from the snapshot. Use `name` to override the auto-derived template name.\n */\nexport type VercelSandboxSettings =\n | { sandbox: Sandbox }\n | (VercelSandboxCreateParams & {\n sandbox?: never;\n name?: string;\n });\n\n/**\n * 30 minutes. The `@vercel/sandbox` SDK defaults to 5 minutes which is\n * too short for multi-step workflows — the VM expires between steps.\n */\nconst DEFAULT_SANDBOX_TIMEOUT_MS = 30 * 60 * 1_000;\nconst DEFAULT_SANDBOX_RUNTIME = 'node24';\n\nconst VERCEL_PROVIDER_ID = 'vercel-sandbox';\nconst TEMPLATE_NAME_PREFIX = 'ai-sdk-harness';\nconst SESSION_NAME_PREFIX = 'ai-sdk-harness-session';\nconst SNAPSHOT_POLL_INTERVAL_MS = 500;\nconst SNAPSHOT_POLL_TIMEOUT_MS = 30_000;\n\nfunction sessionSandboxName(sessionId: string): string {\n return `${SESSION_NAME_PREFIX}-${sessionId}`;\n}\n\nfunction hasExplicitSandboxEnvironment(params: object): boolean {\n return (\n ('runtime' in params && params.runtime != null) ||\n ('image' in params && params.image != null) ||\n ('source' in params &&\n typeof params.source === 'object' &&\n params.source != null &&\n 'type' in params.source &&\n params.source.type === 'snapshot')\n );\n}\n\nexport function createVercelSandbox(\n settings: VercelSandboxSettings = {} as VercelSandboxSettings,\n): HarnessV1SandboxProvider {\n return new VercelSandboxProvider(settings);\n}\n\n/**\n * `HarnessV1SandboxProvider` implementation backed by `@vercel/sandbox`.\n * Construct one via {@link createVercelSandbox} at module scope and pass it\n * to a `HarnessAgent` (or call `createSession()` directly if you want raw\n * access to a network sandbox session).\n */\nexport class VercelSandboxProvider implements HarnessV1SandboxProvider {\n readonly specificationVersion = 'harness-sandbox-v1' as const;\n readonly providerId = VERCEL_PROVIDER_ID;\n\n constructor(private readonly settings: VercelSandboxSettings) {}\n\n createSession = async (options?: {\n sessionId?: string;\n abortSignal?: AbortSignal;\n identity?: string;\n onFirstCreate?: (\n session: SandboxSession,\n opts: { abortSignal?: AbortSignal },\n ) => Promise<void>;\n }): Promise<HarnessV1NetworkSandboxSession> => {\n options?.abortSignal?.throwIfAborted();\n\n if ('sandbox' in this.settings && this.settings.sandbox != null) {\n return new VercelNetworkSandboxSession({\n sandbox: this.settings.sandbox,\n ownsLifecycle: false,\n });\n }\n\n type CreateNewBranch = BaseCreateSandboxParams & {\n sandbox?: never;\n name?: string;\n };\n const settings = this.settings as CreateNewBranch;\n const {\n sandbox: _ignoredSandbox,\n name: explicitName,\n ...createParams\n } = settings;\n // Sandbox v3 changed its implicit default from the Node 24 runtime to the\n // Universal managed image. Keep this adapter's existing default stable while\n // allowing callers to opt into managed images explicitly.\n const baseParams = {\n ...(hasExplicitSandboxEnvironment(createParams)\n ? {}\n : { runtime: DEFAULT_SANDBOX_RUNTIME }),\n ...createParams,\n timeout: createParams.timeout ?? DEFAULT_SANDBOX_TIMEOUT_MS,\n } as BaseCreateSandboxParams;\n\n const identity = options?.identity;\n const onFirstCreate = options?.onFirstCreate;\n\n // When sessionId is supplied, name the per-session sandbox deterministically\n // so a future `resumeSession({ sessionId })` can locate it via\n // `Sandbox.get({ name })`. Absent sessionId (e.g. prewarm), fall back to\n // Vercel's auto-naming.\n const sessionNameOverride = options?.sessionId\n ? { name: sessionSandboxName(options.sessionId) }\n : {};\n\n if (identity == null || onFirstCreate == null) {\n const sandbox = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.create({\n ...baseParams,\n ...sessionNameOverride,\n ...(options?.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n return new VercelNetworkSandboxSession({ sandbox, ownsLifecycle: true });\n }\n\n const templateName = explicitName ?? `${TEMPLATE_NAME_PREFIX}-${identity}`;\n const cache = getSnapshotCache();\n let snapshotId = cache.get(templateName);\n\n if (snapshotId == null) {\n const template = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.getOrCreate({\n ...baseParams,\n name: templateName,\n persistent: true,\n snapshotExpiration: baseParams.snapshotExpiration ?? 0,\n onCreate: async sbx => {\n await onFirstCreate(new VercelSandboxSession(sbx), {\n abortSignal: options?.abortSignal,\n });\n },\n ...(options?.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n\n let resolvedId: string | undefined = template.currentSnapshotId;\n if (resolvedId == null) {\n const stopResult = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n template.stop(\n options?.abortSignal\n ? { signal: options.abortSignal }\n : undefined,\n ),\n });\n resolvedId = stopResult.snapshot?.id;\n if (resolvedId == null) {\n resolvedId = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n pollForTemplateSnapshot({\n name: templateName,\n lookupParams: getSandboxLookupParams(baseParams),\n abortSignal: options?.abortSignal,\n }),\n });\n }\n }\n\n cache.set(templateName, resolvedId);\n snapshotId = resolvedId;\n }\n\n const {\n runtime: _ignoredRuntime,\n image: _ignoredImage,\n source: _ignoredSource,\n persistent: _ignoredPersistent,\n ...forkParams\n } = baseParams;\n\n const fork = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.create({\n ...forkParams,\n source: { type: 'snapshot', snapshotId },\n ...sessionNameOverride,\n ...(options?.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n return new VercelNetworkSandboxSession({\n sandbox: fork,\n ownsLifecycle: true,\n });\n };\n\n resumeSession = async (options: {\n sessionId: string;\n abortSignal?: AbortSignal;\n }): Promise<HarnessV1NetworkSandboxSession> => {\n options.abortSignal?.throwIfAborted();\n\n // Wrap-existing case: caller owns the sandbox. Same session as createSession.\n if ('sandbox' in this.settings && this.settings.sandbox != null) {\n return new VercelNetworkSandboxSession({\n sandbox: this.settings.sandbox,\n ownsLifecycle: false,\n });\n }\n\n const sandbox = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.get({\n ...getSandboxLookupParams(this.settings),\n name: sessionSandboxName(options.sessionId),\n ...(options.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n return new VercelNetworkSandboxSession({ sandbox, ownsLifecycle: true });\n };\n}\n\n/**\n * Base shape of `Sandbox.create` params extracted from the union (excludes\n * the `source: { type: 'snapshot' }` variant) so all create-time fields\n * are typed as present.\n */\ntype BaseCreateSandboxParams = Exclude<\n VercelSandboxCreateParams,\n { source: { type: 'snapshot'; snapshotId: string } }\n>;\n\nconst SNAPSHOT_CACHE_KEY = Symbol.for(\n 'ai-sdk.harness.vercel-template-snapshots',\n);\n\ntype SnapshotCache = Map<string, string>;\ntype SandboxLookupParams = {\n fetch?: typeof fetch;\n projectId?: string;\n teamId?: string;\n token?: string;\n};\n\nfunction getSandboxLookupParams(\n settings: VercelSandboxSettings,\n): SandboxLookupParams {\n if ('sandbox' in settings && settings.sandbox != null) {\n return {};\n }\n\n const { fetch, projectId, teamId, token } = settings as SandboxLookupParams;\n return {\n ...(fetch ? { fetch } : {}),\n ...(projectId ? { projectId } : {}),\n ...(teamId ? { teamId } : {}),\n ...(token ? { token } : {}),\n };\n}\n\nfunction getSnapshotCache(): SnapshotCache {\n const globals = globalThis as {\n [SNAPSHOT_CACHE_KEY]?: SnapshotCache;\n };\n let cache = globals[SNAPSHOT_CACHE_KEY];\n if (cache == null) {\n cache = new Map();\n globals[SNAPSHOT_CACHE_KEY] = cache;\n }\n return cache;\n}\n\nconst VERCEL_SANDBOX_AUTHENTICATION_MESSAGE =\n 'Vercel Sandbox authentication failed. Set VERCEL_OIDC_TOKEN, or pass token, teamId, and projectId to createVercelSandbox(), then verify that they can access Vercel Sandbox.';\n\nasync function withVercelSandboxAuthenticationError<T>({\n settings,\n operation,\n}: {\n settings: VercelSandboxSettings;\n operation: () => Promise<T>;\n}): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (\n !isVercelSandboxAuthenticationFailure({\n error,\n hasConfiguredCredentials: hasConfiguredCredentials(settings),\n })\n ) {\n throw error;\n }\n throw new HarnessSandboxAuthenticationError({\n message: VERCEL_SANDBOX_AUTHENTICATION_MESSAGE,\n sandboxProviderId: VERCEL_PROVIDER_ID,\n cause: error,\n });\n }\n}\n\nfunction hasConfiguredCredentials(settings: VercelSandboxSettings): boolean {\n if (process.env.VERCEL_OIDC_TOKEN) return true;\n if ('sandbox' in settings && settings.sandbox != null) return true;\n const { token, teamId, projectId } = getSandboxLookupParams(settings);\n return Boolean(token && teamId && projectId);\n}\n\nfunction isVercelSandboxAuthenticationFailure({\n error,\n hasConfiguredCredentials,\n}: {\n error: unknown;\n hasConfiguredCredentials: boolean;\n}): boolean {\n const seen = new Set<unknown>();\n let current = error;\n while (current != null && !seen.has(current)) {\n seen.add(current);\n if (typeof current === 'object') {\n const candidate = current as {\n name?: unknown;\n message?: unknown;\n code?: unknown;\n cause?: unknown;\n response?: { status?: unknown; statusCode?: unknown };\n };\n if (\n candidate.response?.status === 401 ||\n candidate.response?.status === 403 ||\n candidate.response?.statusCode === 401 ||\n candidate.response?.statusCode === 403\n ) {\n return true;\n }\n if (\n typeof candidate.name === 'string' &&\n VERCEL_AUTHENTICATION_ERROR_NAMES.has(candidate.name)\n ) {\n return true;\n }\n if (\n typeof candidate.message === 'string' &&\n VERCEL_AUTHENTICATION_ERROR_MESSAGE.test(candidate.message)\n ) {\n return true;\n }\n if (\n !hasConfiguredCredentials &&\n candidate.code === 'ERR_INVALID_ARG_TYPE' &&\n typeof candidate.message === 'string' &&\n candidate.message.includes('\"path\" argument') &&\n candidate.message.includes('Received undefined')\n ) {\n return true;\n }\n current = candidate.cause;\n continue;\n }\n break;\n }\n return false;\n}\n\nconst VERCEL_AUTHENTICATION_ERROR_NAMES = new Set([\n 'AccessTokenMissingError',\n 'LocalOidcContextError',\n 'OAuthError',\n 'RefreshAccessTokenFailedError',\n 'VercelOidcContextError',\n 'VercelOidcTokenError',\n]);\n\nconst VERCEL_AUTHENTICATION_ERROR_MESSAGE =\n /Could not get credentials from OIDC context|No authentication found|Failed to (?:retrieve|refresh) authentication token|Missing credentials parameters to access the Vercel API|Authentication failed/i;\n\nasync function pollForTemplateSnapshot({\n name,\n lookupParams,\n abortSignal,\n}: {\n name: string;\n lookupParams: ReturnType<typeof getSandboxLookupParams>;\n abortSignal: AbortSignal | undefined;\n}): Promise<string> {\n const deadline = Date.now() + SNAPSHOT_POLL_TIMEOUT_MS;\n while (Date.now() < deadline) {\n abortSignal?.throwIfAborted();\n const refreshed = await Sandbox.get({\n ...lookupParams,\n name,\n resume: false,\n ...(abortSignal ? { signal: abortSignal } : {}),\n });\n if (refreshed.currentSnapshotId) {\n return refreshed.currentSnapshotId;\n }\n await new Promise<void>(resolve =>\n setTimeout(resolve, SNAPSHOT_POLL_INTERVAL_MS),\n );\n }\n throw new Error(\n `Timed out waiting for snapshot of template \"${name}\" to publish.`,\n );\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkPolicy,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PortEndpoint,\n type HarnessV1RequestTransformation,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport type { Sandbox } from '@vercel/sandbox';\nimport { VercelNetworkPolicyManager } from './vercel-network-policy-manager';\nimport { VercelSandboxSession } from './vercel-sandbox-session';\n\nconst VERCEL_PROVIDER_ID = 'vercel-sandbox';\n\n/**\n * `HarnessV1NetworkSandboxSession` backed by a `@vercel/sandbox` `Sandbox`. The\n * provider's `create()` returns one of these. It extends\n * {@link VercelSandboxSession} with the infra surface (ports, lifecycle,\n * network policy). It owns the sandbox's lifecycle only when the provider\n * created it; when the provider was given an existing sandbox, `stop()` and\n * `destroy()` are no-ops (caller retains ownership).\n */\nexport class VercelNetworkSandboxSession\n extends VercelSandboxSession\n implements HarnessV1NetworkSandboxSession\n{\n readonly id: string;\n readonly defaultWorkingDirectory: string;\n private readonly ownsLifecycle: boolean;\n readonly #networkPolicyManager: VercelNetworkPolicyManager;\n\n constructor(input: { sandbox: Sandbox; ownsLifecycle: boolean }) {\n super(input.sandbox);\n this.ownsLifecycle = input.ownsLifecycle;\n this.id = input.sandbox.name;\n this.defaultWorkingDirectory = input.sandbox.currentSession().cwd;\n this.#networkPolicyManager = new VercelNetworkPolicyManager({\n sandbox: input.sandbox,\n });\n }\n\n get ports(): ReadonlyArray<number> {\n return this.sandbox.routes.map(route => route.port);\n }\n\n restricted(): SandboxSession {\n return new VercelSandboxSession(this.sandbox);\n }\n\n getPortEndpoint = async (options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<HarnessV1PortEndpoint> => {\n const exposedPorts = this.ports;\n if (!exposedPorts.includes(options.port)) {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: VERCEL_PROVIDER_ID,\n message: `Port ${options.port} is not exposed on this sandbox. Exposed ports: [${exposedPorts.join(', ')}].`,\n });\n }\n const protocol = options.protocol ?? 'https';\n const url = new URL(this.sandbox.domain(options.port));\n const isSecure = url.protocol === 'https:';\n switch (protocol) {\n case 'http':\n url.protocol = isSecure ? 'https:' : 'http:';\n break;\n case 'https':\n url.protocol = 'https:';\n break;\n case 'ws':\n url.protocol = isSecure ? 'wss:' : 'ws:';\n break;\n }\n return { url: url.toString() };\n };\n\n /**\n * @deprecated Use `getPortEndpoint` instead.\n */\n getPortUrl = async (options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<string> => {\n return (await this.getPortEndpoint(options)).url;\n };\n\n setNetworkPolicy = async (policy: HarnessV1NetworkPolicy): Promise<void> => {\n await this.#networkPolicyManager.setNetworkPolicy(policy);\n };\n\n setRequestTransformations = async (\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> => {\n await this.#networkPolicyManager.setRequestTransformations(transformations);\n };\n\n addRequestTransformations = async (\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> => {\n await this.#networkPolicyManager.addRequestTransformations(transformations);\n };\n\n setPorts = async (\n ports: ReadonlyArray<number>,\n options?: { abortSignal?: AbortSignal },\n ): Promise<void> => {\n await this.sandbox.update(\n { ports: [...ports] },\n options?.abortSignal ? { signal: options.abortSignal } : undefined,\n );\n };\n\n stop = async (): Promise<void> => {\n if (!this.ownsLifecycle) return;\n await this.sandbox.stop();\n };\n\n destroy = async (): Promise<void> => {\n if (!this.ownsLifecycle) return;\n await this.sandbox.stop().catch(() => {});\n await this.sandbox.delete();\n };\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkPolicy,\n type HarnessV1RequestTransformation,\n} from '@ai-sdk/harness';\nimport type {\n NetworkPolicy,\n NetworkPolicyKeyValueMatcher,\n NetworkPolicyMatcher,\n NetworkPolicyRule,\n Sandbox,\n} from '@vercel/sandbox';\n\nconst VERCEL_PROVIDER_ID = 'vercel-sandbox';\n\ntype NetworkAccessPolicy =\n | { readonly mode: 'allow-all' }\n | { readonly mode: 'deny-all' }\n | {\n readonly mode: 'custom';\n readonly allowedHosts: ReadonlyArray<string>;\n readonly allowedCIDRs: ReadonlyArray<string>;\n readonly deniedCIDRs: ReadonlyArray<string>;\n };\n\ntype ForwardRule = {\n readonly host: string;\n readonly match?: NetworkPolicyRule['match'];\n readonly forwardURL: string;\n};\n\ntype ManagedPolicyState = {\n readonly accessPolicy: NetworkAccessPolicy;\n readonly requestTransformations: ReadonlyArray<HarnessV1RequestTransformation>;\n readonly forwardRules: ReadonlyArray<ForwardRule>;\n readonly effectivePolicy: NetworkPolicy;\n};\n\ntype CurrentPolicyInspection = {\n readonly accessPolicy: NetworkAccessPolicy;\n readonly forwardRules: ReadonlyArray<ForwardRule>;\n readonly requestTransformationHosts: ReadonlyArray<string>;\n readonly currentPolicy: NetworkPolicy;\n};\n\n/**\n * Owns the complete Vercel Sandbox network-policy value for one live session.\n * Vercel combines network access, request transformations, and forwarding in a\n * single structure, so every mutation must be composed here before replacing\n * that structure through `sandbox.update()`.\n */\nexport class VercelNetworkPolicyManager {\n readonly #sandbox: Sandbox;\n #state: ManagedPolicyState | undefined;\n #mutationQueue: Promise<void> = Promise.resolve();\n\n constructor({ sandbox }: { sandbox: Sandbox }) {\n this.#sandbox = sandbox;\n }\n\n setNetworkPolicy(policy: HarnessV1NetworkPolicy): Promise<void> {\n return this.#enqueueMutation(async () => {\n const inspection = this.#inspectPolicy();\n if (\n this.#state == null &&\n inspection.requestTransformationHosts.length > 0\n ) {\n throw createPolicyConflictError(\n 'Cannot set the network policy because the current Vercel Sandbox policy contains request transformations whose redacted values cannot be preserved safely. Replace them explicitly with setRequestTransformations() or rehydrate them with addRequestTransformations() first.',\n );\n }\n\n await this.#applyState({\n accessPolicy: toNetworkAccessPolicy(policy),\n requestTransformations:\n this.#state?.requestTransformations.map(cloneRequestTransformation) ??\n [],\n forwardRules: inspection.forwardRules.map(cloneForwardRule),\n currentPolicy: inspection.currentPolicy,\n });\n });\n }\n\n setRequestTransformations(\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> {\n return this.#enqueueMutation(async () => {\n const inspection = this.#inspectPolicy();\n await this.#applyState({\n accessPolicy: inspection.accessPolicy,\n requestTransformations: transformations.map(cloneRequestTransformation),\n forwardRules: inspection.forwardRules.map(cloneForwardRule),\n currentPolicy: inspection.currentPolicy,\n });\n });\n }\n\n addRequestTransformations(\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> {\n return this.#enqueueMutation(async () => {\n const inspection = this.#inspectPolicy();\n const incomingTransformations = transformations.map(\n cloneRequestTransformation,\n );\n\n if (this.#state == null) {\n const incomingPolicy = composeNetworkPolicy({\n accessPolicy: inspection.accessPolicy,\n requestTransformations: incomingTransformations,\n forwardRules: inspection.forwardRules,\n });\n const incomingHosts = getRequestTransformationHosts(incomingPolicy);\n\n /*\n * Vercel redacts transformed header values when a policy is read back.\n * It can also normalize rule details, so initialization and resume can\n * only attribute existing transformations by their materialized hosts.\n * External transformations for the same hosts are indistinguishable\n * and are necessarily treated as managed by this call.\n */\n if (\n !isHostSetSubset({\n subset: inspection.requestTransformationHosts,\n superset: incomingHosts,\n })\n ) {\n throw createPolicyConflictError(\n 'Cannot add request transformations because the current Vercel Sandbox policy contains request transformations that cannot be attributed to this call. Their header values are redacted, so preserving them safely is not possible.',\n );\n }\n }\n\n await this.#applyState({\n accessPolicy: inspection.accessPolicy,\n requestTransformations:\n this.#state == null\n ? incomingTransformations\n : [\n ...this.#state.requestTransformations.map(\n cloneRequestTransformation,\n ),\n ...incomingTransformations,\n ],\n forwardRules: inspection.forwardRules.map(cloneForwardRule),\n currentPolicy: inspection.currentPolicy,\n });\n });\n }\n\n #enqueueMutation(operation: () => Promise<void>): Promise<void> {\n /*\n * Each mutation derives a complete replacement from private state. The\n * whole inspect, compose, update, and commit sequence must therefore run in\n * invocation order, while a failed operation must not poison the queue.\n */\n const result = this.#mutationQueue.then(operation);\n this.#mutationQueue = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n }\n\n #inspectPolicy(): CurrentPolicyInspection {\n /*\n * Once initialized, this manager is the sole supported owner of the\n * session's network policy. Direct native Sandbox policy mutations can\n * make the private desired state stale and are intentionally not tracked.\n */\n if (this.#state != null) {\n return {\n accessPolicy: this.#state.accessPolicy,\n forwardRules: this.#state.forwardRules,\n requestTransformationHosts: [],\n currentPolicy: this.#state.effectivePolicy,\n };\n }\n\n return inspectCurrentPolicy(\n this.#sandbox.currentSession().networkPolicy ?? 'allow-all',\n );\n }\n\n async #applyState({\n accessPolicy,\n requestTransformations,\n forwardRules,\n currentPolicy,\n }: {\n accessPolicy: NetworkAccessPolicy;\n requestTransformations: ReadonlyArray<HarnessV1RequestTransformation>;\n forwardRules: ReadonlyArray<ForwardRule>;\n currentPolicy: NetworkPolicy;\n }): Promise<void> {\n const effectivePolicy = composeNetworkPolicy({\n accessPolicy,\n requestTransformations,\n forwardRules,\n });\n\n if (\n !areNetworkPoliciesEqual({\n first: currentPolicy,\n second: effectivePolicy,\n })\n ) {\n await this.#sandbox.update({ networkPolicy: effectivePolicy });\n }\n\n this.#state = {\n accessPolicy: cloneNetworkAccessPolicy(accessPolicy),\n requestTransformations: requestTransformations.map(\n cloneRequestTransformation,\n ),\n forwardRules: forwardRules.map(cloneForwardRule),\n effectivePolicy,\n };\n }\n}\n\nfunction inspectCurrentPolicy(policy: NetworkPolicy): CurrentPolicyInspection {\n if (policy === 'allow-all' || policy === 'deny-all') {\n return {\n accessPolicy: { mode: policy },\n forwardRules: [],\n requestTransformationHosts: [],\n currentPolicy: policy,\n };\n }\n\n const allowedHosts = Array.isArray(policy.allow)\n ? [...policy.allow]\n : Object.keys(policy.allow ?? {});\n const forwardRules: ForwardRule[] = [];\n const requestTransformationHosts = new Set<string>();\n\n /*\n * Forwarding URLs and matchers survive Vercel's policy readback and can be\n * retained verbatim. Transformed header values do not, so transformations\n * are represented only by fingerprints until a caller supplies the values.\n */\n if (policy.allow != null && !Array.isArray(policy.allow)) {\n for (const [host, rules] of Object.entries(policy.allow)) {\n for (const rule of rules) {\n if (hasRequestTransformation(rule)) {\n requestTransformationHosts.add(host.toLowerCase());\n }\n if (rule.forwardURL != null) {\n forwardRules.push({\n host,\n ...(rule.match == null ? {} : { match: cloneMatch(rule.match) }),\n forwardURL: rule.forwardURL,\n });\n }\n }\n }\n }\n\n return {\n accessPolicy: {\n mode: 'custom',\n allowedHosts: minimizeHostPatterns(allowedHosts),\n allowedCIDRs: [...(policy.subnets?.allow ?? [])],\n deniedCIDRs: [...(policy.subnets?.deny ?? [])],\n },\n forwardRules,\n requestTransformationHosts: [...requestTransformationHosts],\n currentPolicy: cloneNetworkPolicy(policy),\n };\n}\n\nfunction toNetworkAccessPolicy(\n policy: HarnessV1NetworkPolicy,\n): NetworkAccessPolicy {\n switch (policy.mode) {\n case 'allow-all':\n return { mode: 'allow-all' };\n case 'deny-all':\n return { mode: 'deny-all' };\n case 'custom': {\n const allowedHosts = [...(policy.allowedHosts ?? [])];\n const allowedCIDRs = [...(policy.allowedCIDRs ?? [])];\n const deniedCIDRs = [...(policy.deniedCIDRs ?? [])];\n if (\n allowedHosts.length === 0 &&\n allowedCIDRs.length === 0 &&\n deniedCIDRs.length === 0\n ) {\n throw createPolicyConflictError(\n 'Custom network policy requires at least one of allowedHosts, allowedCIDRs, or deniedCIDRs to be non-empty.',\n );\n }\n return {\n mode: 'custom',\n allowedHosts,\n allowedCIDRs,\n deniedCIDRs,\n };\n }\n }\n}\n\nfunction composeNetworkPolicy({\n accessPolicy,\n requestTransformations,\n forwardRules,\n}: {\n accessPolicy: NetworkAccessPolicy;\n requestTransformations: ReadonlyArray<HarnessV1RequestTransformation>;\n forwardRules: ReadonlyArray<ForwardRule>;\n}): NetworkPolicy {\n /*\n * Access is authoritative even though Vercel stores all three concepts in\n * one allow map. Rules without a hostname intersection are omitted from the\n * effective policy but remain in private desired state, so a later access\n * change can activate them. CIDR access never activates hostname rules.\n */\n if (accessPolicy.mode === 'deny-all') {\n return 'deny-all';\n }\n\n const rulesByHost = new Map<string, NetworkPolicyRule[]>();\n const allowedHosts =\n accessPolicy.mode === 'allow-all' ? ['*'] : accessPolicy.allowedHosts;\n\n for (const host of allowedHosts) {\n rulesByHost.set(host, []);\n }\n\n for (const transformation of requestTransformations) {\n for (const host of getActiveHostPatterns({\n allowedHosts,\n ruleHost: transformation.match.host,\n })) {\n appendRule({\n rulesByHost,\n host,\n rule: toVercelRequestTransformationRule(transformation),\n });\n }\n }\n\n /*\n * Transformations and forwarding rules for one host must share the same\n * Vercel allow-map array. Transformations are inserted first to match the\n * ordering produced when the Vercel SDK reconstructs a policy.\n */\n for (const forwardRule of forwardRules) {\n for (const host of getActiveHostPatterns({\n allowedHosts,\n ruleHost: forwardRule.host,\n })) {\n appendRule({\n rulesByHost,\n host,\n rule: {\n ...(forwardRule.match == null\n ? {}\n : { match: cloneMatch(forwardRule.match) }),\n forwardURL: forwardRule.forwardURL,\n },\n });\n }\n }\n\n const hasActiveRules = [...rulesByHost.values()].some(\n rules => rules.length > 0,\n );\n if (!hasActiveRules) {\n return toVercelAccessPolicy(accessPolicy);\n }\n\n return {\n allow: Object.fromEntries(rulesByHost),\n ...(accessPolicy.mode !== 'custom' ? {} : toVercelSubnets(accessPolicy)),\n };\n}\n\nfunction toVercelAccessPolicy(\n accessPolicy: NetworkAccessPolicy,\n): NetworkPolicy {\n if (accessPolicy.mode === 'allow-all' || accessPolicy.mode === 'deny-all') {\n return accessPolicy.mode;\n }\n\n return {\n ...(accessPolicy.allowedHosts.length === 0\n ? {}\n : { allow: [...accessPolicy.allowedHosts] }),\n ...toVercelSubnets(accessPolicy),\n };\n}\n\nfunction toVercelSubnets(\n accessPolicy: Extract<NetworkAccessPolicy, { mode: 'custom' }>,\n): Pick<Exclude<NetworkPolicy, string>, 'subnets'> {\n if (\n accessPolicy.allowedCIDRs.length === 0 &&\n accessPolicy.deniedCIDRs.length === 0\n ) {\n return {};\n }\n return {\n subnets: {\n ...(accessPolicy.allowedCIDRs.length === 0\n ? {}\n : { allow: [...accessPolicy.allowedCIDRs] }),\n ...(accessPolicy.deniedCIDRs.length === 0\n ? {}\n : { deny: [...accessPolicy.deniedCIDRs] }),\n },\n };\n}\n\nfunction getActiveHostPatterns({\n allowedHosts,\n ruleHost,\n}: {\n allowedHosts: ReadonlyArray<string>;\n ruleHost: string;\n}): ReadonlyArray<string> {\n return minimizeHostPatterns(\n allowedHosts.flatMap(allowedHost => {\n const intersection = intersectHostPatterns({\n first: allowedHost,\n second: ruleHost,\n });\n return intersection == null ? [] : [intersection];\n }),\n );\n}\n\nfunction intersectHostPatterns({\n first,\n second,\n}: {\n first: string;\n second: string;\n}): string | undefined {\n if (isHostPatternSubset({ candidate: first, container: second })) {\n return first;\n }\n if (isHostPatternSubset({ candidate: second, container: first })) {\n return second;\n }\n return undefined;\n}\n\nfunction isHostPatternSubset({\n candidate,\n container,\n}: {\n candidate: string;\n container: string;\n}): boolean {\n const normalizedCandidate = candidate.toLowerCase();\n const normalizedContainer = container.toLowerCase();\n if (\n normalizedCandidate === normalizedContainer ||\n normalizedContainer === '*'\n ) {\n return true;\n }\n if (normalizedCandidate === '*' || !normalizedContainer.startsWith('*')) {\n return false;\n }\n\n const containerSuffix = normalizedContainer.slice(1);\n return normalizedCandidate.startsWith('*')\n ? normalizedCandidate.slice(1).endsWith(containerSuffix)\n : normalizedCandidate.endsWith(containerSuffix);\n}\n\nfunction minimizeHostPatterns(\n patterns: ReadonlyArray<string>,\n): ReadonlyArray<string> {\n const uniquePatterns = [...new Set(patterns)];\n return uniquePatterns.filter(\n pattern =>\n !uniquePatterns.some(\n other =>\n other !== pattern &&\n isHostPatternSubset({ candidate: pattern, container: other }),\n ),\n );\n}\n\nfunction appendRule({\n rulesByHost,\n host,\n rule,\n}: {\n rulesByHost: Map<string, NetworkPolicyRule[]>;\n host: string;\n rule: NetworkPolicyRule;\n}): void {\n const rules = rulesByHost.get(host) ?? [];\n rules.push(rule);\n rulesByHost.set(host, rules);\n}\n\nfunction toVercelRequestTransformationRule(\n transformation: HarnessV1RequestTransformation,\n): NetworkPolicyRule {\n const {\n host: _host,\n method,\n path,\n queryString,\n headers,\n } = transformation.match;\n const match = {\n ...(path == null ? {} : { path: cloneMatcher(path) }),\n ...(method == null ? {} : { method: [...method] }),\n ...(queryString == null\n ? {}\n : { queryString: queryString.map(cloneKeyValueMatcher) }),\n ...(headers == null ? {} : { headers: headers.map(cloneKeyValueMatcher) }),\n };\n\n return {\n ...(Object.keys(match).length === 0 ? {} : { match }),\n transform: [{ headers: { ...transformation.transform.headers } }],\n };\n}\n\nfunction hasRequestTransformation(rule: NetworkPolicyRule): boolean {\n return (\n rule.transform?.some(\n transformation =>\n transformation.headers != null &&\n Object.keys(transformation.headers).length > 0,\n ) ?? false\n );\n}\n\nfunction getRequestTransformationHosts(\n policy: NetworkPolicy,\n): ReadonlyArray<string> {\n if (\n policy === 'allow-all' ||\n policy === 'deny-all' ||\n policy.allow == null ||\n Array.isArray(policy.allow)\n ) {\n return [];\n }\n\n const hosts = new Set<string>();\n for (const [host, rules] of Object.entries(policy.allow)) {\n for (const rule of rules) {\n if (hasRequestTransformation(rule)) {\n hosts.add(host.toLowerCase());\n }\n }\n }\n return [...hosts];\n}\n\nfunction isHostSetSubset({\n subset,\n superset,\n}: {\n subset: ReadonlyArray<string>;\n superset: ReadonlyArray<string>;\n}): boolean {\n const allowedHosts = new Set(superset.map(host => host.toLowerCase()));\n return subset.every(host => allowedHosts.has(host.toLowerCase()));\n}\n\nfunction areNetworkPoliciesEqual({\n first,\n second,\n}: {\n first: NetworkPolicy;\n second: NetworkPolicy;\n}): boolean {\n return stableSerialize(first) === stableSerialize(second);\n}\n\nfunction stableSerialize(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map(stableSerialize).join(',')}]`;\n }\n if (value != null && typeof value === 'object') {\n return `{${Object.entries(value)\n .filter(([, entryValue]) => entryValue !== undefined)\n .sort(([firstKey], [secondKey]) => firstKey.localeCompare(secondKey))\n .map(\n ([key, entryValue]) =>\n `${JSON.stringify(key)}:${stableSerialize(entryValue)}`,\n )\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction cloneRequestTransformation(\n transformation: HarnessV1RequestTransformation,\n): HarnessV1RequestTransformation {\n return {\n match: {\n host: transformation.match.host,\n ...(transformation.match.path == null\n ? {}\n : { path: cloneHarnessMatcher(transformation.match.path) }),\n ...(transformation.match.method == null\n ? {}\n : { method: [...transformation.match.method] }),\n ...(transformation.match.queryString == null\n ? {}\n : {\n queryString: transformation.match.queryString.map(\n cloneHarnessKeyValueMatcher,\n ),\n }),\n ...(transformation.match.headers == null\n ? {}\n : {\n headers: transformation.match.headers.map(\n cloneHarnessKeyValueMatcher,\n ),\n }),\n },\n transform: { headers: { ...transformation.transform.headers } },\n };\n}\n\nfunction cloneForwardRule(rule: ForwardRule): ForwardRule {\n return {\n host: rule.host,\n ...(rule.match == null ? {} : { match: cloneMatch(rule.match) }),\n forwardURL: rule.forwardURL,\n };\n}\n\nfunction cloneNetworkAccessPolicy(\n policy: NetworkAccessPolicy,\n): NetworkAccessPolicy {\n if (policy.mode === 'allow-all' || policy.mode === 'deny-all') {\n return { mode: policy.mode };\n }\n return {\n mode: 'custom',\n allowedHosts: [...policy.allowedHosts],\n allowedCIDRs: [...policy.allowedCIDRs],\n deniedCIDRs: [...policy.deniedCIDRs],\n };\n}\n\nfunction cloneNetworkPolicy(policy: NetworkPolicy): NetworkPolicy {\n return structuredClone(policy);\n}\n\nfunction cloneMatch(\n match: NonNullable<NetworkPolicyRule['match']>,\n): NonNullable<NetworkPolicyRule['match']> {\n return {\n ...(match.path == null ? {} : { path: cloneMatcher(match.path) }),\n ...(match.method == null ? {} : { method: [...match.method] }),\n ...(match.queryString == null\n ? {}\n : { queryString: match.queryString.map(cloneKeyValueMatcher) }),\n ...(match.headers == null\n ? {}\n : { headers: match.headers.map(cloneKeyValueMatcher) }),\n };\n}\n\nfunction cloneKeyValueMatcher(\n matcher: NetworkPolicyKeyValueMatcher,\n): NetworkPolicyKeyValueMatcher {\n return {\n ...(matcher.key == null ? {} : { key: cloneMatcher(matcher.key) }),\n ...(matcher.value == null ? {} : { value: cloneMatcher(matcher.value) }),\n };\n}\n\nfunction cloneMatcher(matcher: NetworkPolicyMatcher): NetworkPolicyMatcher {\n return { ...matcher };\n}\n\nfunction cloneHarnessKeyValueMatcher(\n matcher: NonNullable<\n HarnessV1RequestTransformation['match']['headers']\n >[number],\n): NonNullable<HarnessV1RequestTransformation['match']['headers']>[number] {\n return {\n ...(matcher.key == null ? {} : { key: cloneHarnessMatcher(matcher.key) }),\n ...(matcher.value == null\n ? {}\n : { value: cloneHarnessMatcher(matcher.value) }),\n };\n}\n\nfunction cloneHarnessMatcher(\n matcher: NonNullable<HarnessV1RequestTransformation['match']['path']>,\n): NonNullable<HarnessV1RequestTransformation['match']['path']> {\n if ('exact' in matcher) {\n return { exact: matcher.exact };\n }\n if ('startsWith' in matcher) {\n return { startsWith: matcher.startsWith };\n }\n return { regex: matcher.regex };\n}\n\nfunction createPolicyConflictError(\n message: string,\n): HarnessCapabilityUnsupportedError {\n return new HarnessCapabilityUnsupportedError({\n harnessId: VERCEL_PROVIDER_ID,\n message,\n });\n}\n","import { posix } from 'node:path';\nimport {\n extractLines,\n type Experimental_SandboxSession,\n type Experimental_SandboxProcess,\n} from '@ai-sdk/provider-utils';\nimport type { Sandbox, Command } from '@vercel/sandbox';\n\n/**\n * `Experimental_SandboxSession` implementation backed by a `@vercel/sandbox`\n * `Sandbox` instance. This is the tool-safe surface (file I/O, exec, spawn);\n * it is what `VercelNetworkSandboxSession.restricted()` returns and is not\n * constructed directly by consumers. The network sandbox session owns the\n * lifetime of the underlying sandbox.\n */\nexport class VercelSandboxSession implements Experimental_SandboxSession {\n constructor(protected readonly sandbox: Sandbox) {}\n\n get description(): string {\n return [\n `Vercel Sandbox (name: ${this.sandbox.name}).`,\n 'Filesystem changes persist for the lifetime of the sandbox.',\n ].join('\\n');\n }\n\n async run({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n abortSignal?.throwIfAborted();\n\n const finished = await this.sandbox.runCommand({\n cmd: 'bash',\n args: ['-c', command],\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(env !== undefined ? { env } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n const [stdout, stderr] = await Promise.all([\n finished.stdout(),\n finished.stderr(),\n ]);\n\n return {\n exitCode: finished.exitCode,\n stdout,\n stderr,\n };\n }\n\n async spawn({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<Experimental_SandboxProcess> {\n abortSignal?.throwIfAborted();\n\n const live = await this.sandbox.runCommand({\n cmd: 'bash',\n args: ['-c', command],\n detached: true,\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(env !== undefined ? { env } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n return createSandboxProcess(live, abortSignal);\n }\n\n async readFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<ReadableStream<Uint8Array> | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n return bytesToStream(bytes);\n }\n\n async readBinaryFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<Uint8Array | null> {\n abortSignal?.throwIfAborted();\n try {\n const buffer = await this.sandbox.readFileToBuffer(\n { path },\n abortSignal ? { signal: abortSignal } : undefined,\n );\n if (buffer == null) return null;\n return new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n );\n } catch (error) {\n if (isFileNotFoundError(error)) return null;\n throw error;\n }\n }\n\n async readTextFile({\n path,\n encoding = 'utf-8',\n startLine,\n endLine,\n abortSignal,\n }: {\n path: string;\n encoding?: string;\n startLine?: number;\n endLine?: number;\n abortSignal?: AbortSignal;\n }): Promise<string | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n const text = Buffer.from(bytes).toString(encoding as BufferEncoding);\n return extractLines({ text, startLine, endLine });\n }\n\n async writeFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: ReadableStream<Uint8Array>;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const bytes = await collectStream(content);\n await this.writeBinaryFile({ path, content: bytes, abortSignal });\n }\n\n async writeBinaryFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: Uint8Array;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n abortSignal?.throwIfAborted();\n const parent = posix.dirname(path);\n if (parent && parent !== '.' && parent !== '/') {\n await this.sandbox.runCommand({\n cmd: 'mkdir',\n args: ['-p', parent],\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n }\n await this.sandbox.writeFiles(\n [{ path, content }],\n abortSignal ? { signal: abortSignal } : undefined,\n );\n }\n\n async writeTextFile({\n path,\n content,\n encoding = 'utf-8',\n abortSignal,\n }: {\n path: string;\n content: string;\n encoding?: string;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const buffer = Buffer.from(content, encoding as BufferEncoding);\n await this.writeBinaryFile({\n path,\n content: new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ),\n abortSignal,\n });\n }\n}\n\nfunction createSandboxProcess(\n command: Command,\n abortSignal: AbortSignal | undefined,\n): Experimental_SandboxProcess {\n const encoder = new TextEncoder();\n const controllers: {\n stdout?: ReadableStreamDefaultController<Uint8Array>;\n stderr?: ReadableStreamDefaultController<Uint8Array>;\n } = {};\n\n const stdout = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stdout = controller;\n },\n });\n\n const stderr = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stderr = controller;\n },\n });\n\n const drained = (async () => {\n try {\n const iterator = abortSignal\n ? command.logs({ signal: abortSignal })\n : command.logs();\n for await (const message of iterator) {\n const target =\n message.stream === 'stdout' ? controllers.stdout : controllers.stderr;\n target?.enqueue(encoder.encode(message.data));\n }\n controllers.stdout?.close();\n controllers.stderr?.close();\n } catch (error) {\n controllers.stdout?.error(error);\n controllers.stderr?.error(error);\n }\n })();\n\n return {\n stdout,\n stderr,\n async wait(): Promise<{ exitCode: number }> {\n const finished = await command.wait();\n await drained;\n if (abortSignal?.aborted) {\n throw abortSignal.reason ?? new DOMException('Aborted', 'AbortError');\n }\n return { exitCode: finished.exitCode };\n },\n async kill(): Promise<void> {\n await command.kill();\n },\n };\n}\n\nfunction bytesToStream(bytes: Uint8Array): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(bytes);\n controller.close();\n },\n });\n}\n\nasync function collectStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n total += value.byteLength;\n }\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (error == null || typeof error !== 'object') return false;\n const code = (error as { code?: unknown }).code;\n if (code === 'ENOENT') return true;\n const message = (error as { message?: unknown }).message;\n return (\n typeof message === 'string' &&\n /no such file|not found|does not exist|ENOENT/i.test(message)\n );\n}\n"],"mappings":"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","names":["HarnessCapabilityUnsupportedError","VERCEL_PROVIDER_ID","HarnessCapabilityUnsupportedError","VERCEL_PROVIDER_ID","_a","hasConfiguredCredentials"]}
|
|
1
|
+
{"version":3,"sources":["../src/vercel-sandbox.ts","../src/vercel-network-sandbox-session.ts","../src/vercel-network-policy-manager.ts","../src/vercel-sandbox-session.ts"],"sourcesContent":["import {\n HarnessSandboxAuthenticationError,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1SandboxProvider,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { Sandbox } from '@vercel/sandbox';\nimport { VercelNetworkSandboxSession } from './vercel-network-sandbox-session';\nimport { VercelSandboxSession } from './vercel-sandbox-session';\n\n/**\n * Flattens an intersection of object types into a single object type so the\n * resolved shape displays as its named properties rather than a chain of\n * `A & B & C`.\n */\ntype Prettify<T> = { [K in keyof T]: T[K] } & {};\n\n/**\n * Distributes `Omit` across each member of a union instead of collapsing the\n * union to its common keys. `Sandbox.create`'s parameter is a union (a\n * git/tarball/no-source create variant and a snapshot-source create variant),\n * so a plain `Omit` would discard keys absent from any one member (e.g.\n * `runtime`, which the snapshot variant lacks) and merge the `source` shapes.\n * Applying `Omit` per-member preserves every variant intact; the `Prettify`\n * wrapper collapses each member's intersections into a readable object shape.\n */\ntype DistributiveOmit<T, K extends keyof any> = T extends unknown\n ? Prettify<Omit<T, K>>\n : never;\n\n/**\n * Parameters forwarded to `@vercel/sandbox`'s `Sandbox.create` when creating\n * a sandbox from scratch. Aliased directly from the underlying SDK so the\n * full surface — every option Vercel supports, including its native\n * `NetworkPolicy` — is available without us re-declaring it.\n */\ntype VercelSandboxCreateParams = DistributiveOmit<\n NonNullable<Parameters<typeof Sandbox.create>[0]>,\n 'onResume'\n>;\n\n/**\n * Settings for {@link createVercelSandbox}. Two mutually-exclusive shapes:\n *\n * - `{ sandbox }` — wrap an already-created `@vercel/sandbox` `Sandbox`. The\n * caller owns its lifecycle; the provider's `stop()` and `destroy()` are\n * no-ops.\n * - {@link VercelSandboxCreateParams} fields — provider creates the underlying\n * sandbox. When the adapter declares a bootstrap recipe the provider uses\n * `Sandbox.getOrCreate` to maintain a persistent named template snapshot\n * keyed by the recipe identity, and forks an ephemeral sandbox per session\n * from the snapshot. Use `name` to override the auto-derived template name.\n */\nexport type VercelSandboxSettings =\n | { sandbox: Sandbox }\n | (VercelSandboxCreateParams & {\n sandbox?: never;\n name?: string;\n });\n\n/**\n * 30 minutes. The `@vercel/sandbox` SDK defaults to 5 minutes which is\n * too short for multi-step workflows — the VM expires between steps.\n */\nconst DEFAULT_SANDBOX_TIMEOUT_MS = 30 * 60 * 1_000;\nconst DEFAULT_SANDBOX_RUNTIME = 'node24';\n\nconst VERCEL_PROVIDER_ID = 'vercel-sandbox';\nconst TEMPLATE_NAME_PREFIX = 'ai-sdk-harness';\nconst SESSION_NAME_PREFIX = 'ai-sdk-harness-session';\nconst SNAPSHOT_POLL_INTERVAL_MS = 500;\nconst SNAPSHOT_POLL_TIMEOUT_MS = 30_000;\n\nfunction sessionSandboxName(sessionId: string): string {\n return `${SESSION_NAME_PREFIX}-${sessionId}`;\n}\n\nfunction hasExplicitSandboxEnvironment(params: object): boolean {\n return (\n ('runtime' in params && params.runtime != null) ||\n ('image' in params && params.image != null) ||\n ('source' in params &&\n typeof params.source === 'object' &&\n params.source != null &&\n 'type' in params.source &&\n params.source.type === 'snapshot')\n );\n}\n\nexport function createVercelSandbox(\n settings: VercelSandboxSettings = {} as VercelSandboxSettings,\n): HarnessV1SandboxProvider {\n return new VercelSandboxProvider(settings);\n}\n\n/**\n * `HarnessV1SandboxProvider` implementation backed by `@vercel/sandbox`.\n * Construct one via {@link createVercelSandbox} at module scope and pass it\n * to a `HarnessAgent` (or call `createSession()` directly if you want raw\n * access to a network sandbox session).\n */\nexport class VercelSandboxProvider implements HarnessV1SandboxProvider {\n readonly specificationVersion = 'harness-sandbox-v1' as const;\n readonly providerId = VERCEL_PROVIDER_ID;\n\n constructor(private readonly settings: VercelSandboxSettings) {}\n\n createSession = async (options?: {\n sessionId?: string;\n abortSignal?: AbortSignal;\n identity?: string;\n onFirstCreate?: (\n session: SandboxSession,\n opts: { abortSignal?: AbortSignal },\n ) => Promise<void>;\n }): Promise<HarnessV1NetworkSandboxSession> => {\n options?.abortSignal?.throwIfAborted();\n\n if ('sandbox' in this.settings && this.settings.sandbox != null) {\n return new VercelNetworkSandboxSession({\n sandbox: this.settings.sandbox,\n ownsLifecycle: false,\n });\n }\n\n type CreateNewBranch = BaseCreateSandboxParams & {\n sandbox?: never;\n name?: string;\n };\n const settings = this.settings as CreateNewBranch;\n const {\n sandbox: _ignoredSandbox,\n name: explicitName,\n ...createParams\n } = settings;\n // Sandbox v3 changed its implicit default from the Node 24 runtime to the\n // Universal managed image. Keep this adapter's existing default stable while\n // allowing callers to opt into managed images explicitly.\n const baseParams = {\n ...(hasExplicitSandboxEnvironment(createParams)\n ? {}\n : { runtime: DEFAULT_SANDBOX_RUNTIME }),\n ...createParams,\n timeout: createParams.timeout ?? DEFAULT_SANDBOX_TIMEOUT_MS,\n } as BaseCreateSandboxParams;\n\n const identity = options?.identity;\n const onFirstCreate = options?.onFirstCreate;\n\n // When sessionId is supplied, name the per-session sandbox deterministically\n // so a future `resumeSession({ sessionId })` can locate it via\n // `Sandbox.get({ name })`. Absent sessionId (e.g. prewarm), fall back to\n // Vercel's auto-naming.\n const sessionNameOverride = options?.sessionId\n ? { name: sessionSandboxName(options.sessionId) }\n : {};\n\n if (identity == null || onFirstCreate == null) {\n const sandbox = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.create({\n ...baseParams,\n ...sessionNameOverride,\n ...(options?.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n return new VercelNetworkSandboxSession({ sandbox, ownsLifecycle: true });\n }\n\n const templateName = explicitName ?? `${TEMPLATE_NAME_PREFIX}-${identity}`;\n const cache = getSnapshotCache();\n let snapshotId = cache.get(templateName);\n\n if (snapshotId == null) {\n const template = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.getOrCreate({\n ...baseParams,\n name: templateName,\n persistent: true,\n snapshotExpiration: baseParams.snapshotExpiration ?? 0,\n onCreate: async sbx => {\n await onFirstCreate(new VercelSandboxSession(sbx), {\n abortSignal: options?.abortSignal,\n });\n },\n ...(options?.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n\n let resolvedId: string | undefined = template.currentSnapshotId;\n if (resolvedId == null) {\n const stopResult = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n template.stop(\n options?.abortSignal\n ? { signal: options.abortSignal }\n : undefined,\n ),\n });\n resolvedId = stopResult.snapshot?.id;\n if (resolvedId == null) {\n resolvedId = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n pollForTemplateSnapshot({\n name: templateName,\n lookupParams: getSandboxLookupParams(baseParams),\n abortSignal: options?.abortSignal,\n }),\n });\n }\n }\n\n cache.set(templateName, resolvedId);\n snapshotId = resolvedId;\n }\n\n const {\n runtime: _ignoredRuntime,\n image: _ignoredImage,\n source: _ignoredSource,\n persistent: _ignoredPersistent,\n ...forkParams\n } = baseParams;\n\n const fork = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.create({\n ...forkParams,\n source: { type: 'snapshot', snapshotId },\n ...sessionNameOverride,\n ...(options?.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n return new VercelNetworkSandboxSession({\n sandbox: fork,\n ownsLifecycle: true,\n });\n };\n\n resumeSession = async (options: {\n sessionId: string;\n abortSignal?: AbortSignal;\n }): Promise<HarnessV1NetworkSandboxSession> => {\n options.abortSignal?.throwIfAborted();\n\n // Wrap-existing case: caller owns the sandbox. Same session as createSession.\n if ('sandbox' in this.settings && this.settings.sandbox != null) {\n return new VercelNetworkSandboxSession({\n sandbox: this.settings.sandbox,\n ownsLifecycle: false,\n });\n }\n\n const sandbox = await withVercelSandboxAuthenticationError({\n settings: this.settings,\n operation: () =>\n Sandbox.get({\n ...getSandboxLookupParams(this.settings),\n name: sessionSandboxName(options.sessionId),\n ...(options.abortSignal ? { signal: options.abortSignal } : {}),\n }),\n });\n return new VercelNetworkSandboxSession({ sandbox, ownsLifecycle: true });\n };\n}\n\n/**\n * Base shape of `Sandbox.create` params extracted from the union (excludes\n * the `source: { type: 'snapshot' }` variant) so all create-time fields\n * are typed as present.\n */\ntype BaseCreateSandboxParams = Exclude<\n VercelSandboxCreateParams,\n { source: { type: 'snapshot'; snapshotId: string } }\n>;\n\nconst SNAPSHOT_CACHE_KEY = Symbol.for(\n 'ai-sdk.harness.vercel-template-snapshots',\n);\n\ntype SnapshotCache = Map<string, string>;\ntype SandboxLookupParams = {\n fetch?: typeof fetch;\n projectId?: string;\n teamId?: string;\n token?: string;\n};\n\nfunction getSandboxLookupParams(\n settings: VercelSandboxSettings,\n): SandboxLookupParams {\n if ('sandbox' in settings && settings.sandbox != null) {\n return {};\n }\n\n const { fetch, projectId, teamId, token } = settings as SandboxLookupParams;\n return {\n ...(fetch ? { fetch } : {}),\n ...(projectId ? { projectId } : {}),\n ...(teamId ? { teamId } : {}),\n ...(token ? { token } : {}),\n };\n}\n\nfunction getSnapshotCache(): SnapshotCache {\n const globals = globalThis as {\n [SNAPSHOT_CACHE_KEY]?: SnapshotCache;\n };\n let cache = globals[SNAPSHOT_CACHE_KEY];\n if (cache == null) {\n cache = new Map();\n globals[SNAPSHOT_CACHE_KEY] = cache;\n }\n return cache;\n}\n\nconst VERCEL_SANDBOX_AUTHENTICATION_MESSAGE =\n 'Vercel Sandbox authentication failed. Set VERCEL_OIDC_TOKEN, or pass token, teamId, and projectId to createVercelSandbox(), then verify that they can access Vercel Sandbox.';\n\nasync function withVercelSandboxAuthenticationError<T>({\n settings,\n operation,\n}: {\n settings: VercelSandboxSettings;\n operation: () => Promise<T>;\n}): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (\n !isVercelSandboxAuthenticationFailure({\n error,\n hasConfiguredCredentials: hasConfiguredCredentials(settings),\n })\n ) {\n throw error;\n }\n throw new HarnessSandboxAuthenticationError({\n message: VERCEL_SANDBOX_AUTHENTICATION_MESSAGE,\n sandboxProviderId: VERCEL_PROVIDER_ID,\n cause: error,\n });\n }\n}\n\nfunction hasConfiguredCredentials(settings: VercelSandboxSettings): boolean {\n if (process.env.VERCEL_OIDC_TOKEN) return true;\n if ('sandbox' in settings && settings.sandbox != null) return true;\n const { token, teamId, projectId } = getSandboxLookupParams(settings);\n return Boolean(token && teamId && projectId);\n}\n\nfunction isVercelSandboxAuthenticationFailure({\n error,\n hasConfiguredCredentials,\n}: {\n error: unknown;\n hasConfiguredCredentials: boolean;\n}): boolean {\n const seen = new Set<unknown>();\n let current = error;\n while (current != null && !seen.has(current)) {\n seen.add(current);\n if (typeof current === 'object') {\n const candidate = current as {\n name?: unknown;\n message?: unknown;\n code?: unknown;\n cause?: unknown;\n response?: { status?: unknown; statusCode?: unknown };\n };\n if (\n candidate.response?.status === 401 ||\n candidate.response?.status === 403 ||\n candidate.response?.statusCode === 401 ||\n candidate.response?.statusCode === 403\n ) {\n return true;\n }\n if (\n typeof candidate.name === 'string' &&\n VERCEL_AUTHENTICATION_ERROR_NAMES.has(candidate.name)\n ) {\n return true;\n }\n if (\n typeof candidate.message === 'string' &&\n VERCEL_AUTHENTICATION_ERROR_MESSAGE.test(candidate.message)\n ) {\n return true;\n }\n if (\n !hasConfiguredCredentials &&\n candidate.code === 'ERR_INVALID_ARG_TYPE' &&\n typeof candidate.message === 'string' &&\n candidate.message.includes('\"path\" argument') &&\n candidate.message.includes('Received undefined')\n ) {\n return true;\n }\n current = candidate.cause;\n continue;\n }\n break;\n }\n return false;\n}\n\nconst VERCEL_AUTHENTICATION_ERROR_NAMES = new Set([\n 'AccessTokenMissingError',\n 'LocalOidcContextError',\n 'OAuthError',\n 'RefreshAccessTokenFailedError',\n 'VercelOidcContextError',\n 'VercelOidcTokenError',\n]);\n\nconst VERCEL_AUTHENTICATION_ERROR_MESSAGE =\n /Could not get credentials from OIDC context|No authentication found|Failed to (?:retrieve|refresh) authentication token|Missing credentials parameters to access the Vercel API|Authentication failed/i;\n\nasync function pollForTemplateSnapshot({\n name,\n lookupParams,\n abortSignal,\n}: {\n name: string;\n lookupParams: ReturnType<typeof getSandboxLookupParams>;\n abortSignal: AbortSignal | undefined;\n}): Promise<string> {\n const deadline = Date.now() + SNAPSHOT_POLL_TIMEOUT_MS;\n while (Date.now() < deadline) {\n abortSignal?.throwIfAborted();\n const refreshed = await Sandbox.get({\n ...lookupParams,\n name,\n resume: false,\n ...(abortSignal ? { signal: abortSignal } : {}),\n });\n if (refreshed.currentSnapshotId) {\n return refreshed.currentSnapshotId;\n }\n await new Promise<void>(resolve =>\n setTimeout(resolve, SNAPSHOT_POLL_INTERVAL_MS),\n );\n }\n throw new Error(\n `Timed out waiting for snapshot of template \"${name}\" to publish.`,\n );\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkPolicy,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PortEndpoint,\n type HarnessV1RequestTransformation,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport type { Sandbox } from '@vercel/sandbox';\nimport { VercelNetworkPolicyManager } from './vercel-network-policy-manager';\nimport { VercelSandboxSession } from './vercel-sandbox-session';\n\nconst VERCEL_PROVIDER_ID = 'vercel-sandbox';\n\n/**\n * `HarnessV1NetworkSandboxSession` backed by a `@vercel/sandbox` `Sandbox`. The\n * provider's `create()` returns one of these. It extends\n * {@link VercelSandboxSession} with the infra surface (ports, lifecycle,\n * network policy). It owns the sandbox's lifecycle only when the provider\n * created it; when the provider was given an existing sandbox, `stop()` and\n * `destroy()` are no-ops (caller retains ownership).\n */\nexport class VercelNetworkSandboxSession\n extends VercelSandboxSession\n implements HarnessV1NetworkSandboxSession\n{\n readonly id: string;\n readonly defaultWorkingDirectory: string;\n private readonly ownsLifecycle: boolean;\n readonly #networkPolicyManager: VercelNetworkPolicyManager;\n\n constructor(input: { sandbox: Sandbox; ownsLifecycle: boolean }) {\n super(input.sandbox);\n this.ownsLifecycle = input.ownsLifecycle;\n this.id = input.sandbox.name;\n this.defaultWorkingDirectory = input.sandbox.currentSession().cwd;\n this.#networkPolicyManager = new VercelNetworkPolicyManager({\n sandbox: input.sandbox,\n });\n }\n\n get ports(): ReadonlyArray<number> {\n return this.sandbox.routes.map(route => route.port);\n }\n\n restricted(): SandboxSession {\n return new VercelSandboxSession(this.sandbox);\n }\n\n getPortEndpoint = async (options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<HarnessV1PortEndpoint> => {\n const exposedPorts = this.ports;\n if (!exposedPorts.includes(options.port)) {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: VERCEL_PROVIDER_ID,\n message: `Port ${options.port} is not exposed on this sandbox. Exposed ports: [${exposedPorts.join(', ')}].`,\n });\n }\n const protocol = options.protocol ?? 'https';\n const url = new URL(this.sandbox.domain(options.port));\n const isSecure = url.protocol === 'https:';\n switch (protocol) {\n case 'http':\n url.protocol = isSecure ? 'https:' : 'http:';\n break;\n case 'https':\n url.protocol = 'https:';\n break;\n case 'ws':\n url.protocol = isSecure ? 'wss:' : 'ws:';\n break;\n }\n return { url: url.toString() };\n };\n\n /**\n * @deprecated Use `getPortEndpoint` instead.\n */\n getPortUrl = async (options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<string> => {\n return (await this.getPortEndpoint(options)).url;\n };\n\n setNetworkPolicy = async (policy: HarnessV1NetworkPolicy): Promise<void> => {\n await this.#networkPolicyManager.setNetworkPolicy(policy);\n };\n\n setRequestTransformations = async (\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> => {\n await this.#networkPolicyManager.setRequestTransformations(transformations);\n };\n\n addRequestTransformations = async (\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> => {\n await this.#networkPolicyManager.addRequestTransformations(transformations);\n };\n\n setPorts = async (\n ports: ReadonlyArray<number>,\n options?: { abortSignal?: AbortSignal },\n ): Promise<void> => {\n await this.sandbox.update(\n { ports: [...ports] },\n options?.abortSignal ? { signal: options.abortSignal } : undefined,\n );\n };\n\n stop = async (): Promise<void> => {\n if (!this.ownsLifecycle) return;\n await this.sandbox.stop();\n };\n\n destroy = async (): Promise<void> => {\n if (!this.ownsLifecycle) return;\n await this.sandbox.stop().catch(() => {});\n await this.sandbox.delete();\n };\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkPolicy,\n type HarnessV1RequestTransformation,\n} from '@ai-sdk/harness';\nimport type {\n NetworkPolicy,\n NetworkPolicyKeyValueMatcher,\n NetworkPolicyMatcher,\n NetworkPolicyRule,\n Sandbox,\n} from '@vercel/sandbox';\n\nconst VERCEL_PROVIDER_ID = 'vercel-sandbox';\n\ntype NetworkAccessPolicy =\n | { readonly mode: 'allow-all' }\n | { readonly mode: 'deny-all' }\n | {\n readonly mode: 'custom';\n readonly allowedHosts: ReadonlyArray<string>;\n readonly allowedCIDRs: ReadonlyArray<string>;\n readonly deniedCIDRs: ReadonlyArray<string>;\n };\n\ntype ForwardRule = {\n readonly host: string;\n readonly match?: NetworkPolicyRule['match'];\n readonly forwardURL: string;\n};\n\ntype ManagedPolicyState = {\n readonly accessPolicy: NetworkAccessPolicy;\n readonly requestTransformations: ReadonlyArray<HarnessV1RequestTransformation>;\n readonly forwardRules: ReadonlyArray<ForwardRule>;\n readonly effectivePolicy: NetworkPolicy;\n};\n\ntype CurrentPolicyInspection = {\n readonly accessPolicy: NetworkAccessPolicy;\n readonly forwardRules: ReadonlyArray<ForwardRule>;\n readonly requestTransformationHosts: ReadonlyArray<string>;\n readonly currentPolicy: NetworkPolicy;\n};\n\n/**\n * Owns the complete Vercel Sandbox network-policy value for one live session.\n * Vercel combines network access, request transformations, and forwarding in a\n * single structure, so every mutation must be composed here before replacing\n * that structure through `sandbox.update()`.\n */\nexport class VercelNetworkPolicyManager {\n readonly #sandbox: Sandbox;\n #state: ManagedPolicyState | undefined;\n #mutationQueue: Promise<void> = Promise.resolve();\n\n constructor({ sandbox }: { sandbox: Sandbox }) {\n this.#sandbox = sandbox;\n }\n\n setNetworkPolicy(policy: HarnessV1NetworkPolicy): Promise<void> {\n return this.#enqueueMutation(async () => {\n const inspection = this.#inspectPolicy();\n if (\n this.#state == null &&\n inspection.requestTransformationHosts.length > 0\n ) {\n throw createPolicyConflictError(\n 'Cannot set the network policy because the current Vercel Sandbox policy contains request transformations whose redacted values cannot be preserved safely. Replace them explicitly with setRequestTransformations() or rehydrate them with addRequestTransformations() first.',\n );\n }\n\n await this.#applyState({\n accessPolicy: toNetworkAccessPolicy(policy),\n requestTransformations:\n this.#state?.requestTransformations.map(cloneRequestTransformation) ??\n [],\n forwardRules: inspection.forwardRules.map(cloneForwardRule),\n currentPolicy: inspection.currentPolicy,\n });\n });\n }\n\n setRequestTransformations(\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> {\n return this.#enqueueMutation(async () => {\n const inspection = this.#inspectPolicy();\n await this.#applyState({\n accessPolicy: inspection.accessPolicy,\n requestTransformations: transformations.map(cloneRequestTransformation),\n forwardRules: inspection.forwardRules.map(cloneForwardRule),\n currentPolicy: inspection.currentPolicy,\n });\n });\n }\n\n addRequestTransformations(\n transformations: ReadonlyArray<HarnessV1RequestTransformation>,\n ): Promise<void> {\n return this.#enqueueMutation(async () => {\n const inspection = this.#inspectPolicy();\n const incomingTransformations = transformations.map(\n cloneRequestTransformation,\n );\n\n if (this.#state == null) {\n const incomingPolicy = composeNetworkPolicy({\n accessPolicy: inspection.accessPolicy,\n requestTransformations: incomingTransformations,\n forwardRules: inspection.forwardRules,\n });\n const incomingHosts = getRequestTransformationHosts(incomingPolicy);\n\n /*\n * Vercel redacts transformed header values when a policy is read back.\n * It can also normalize rule details, so initialization and resume can\n * only attribute existing transformations by their materialized hosts.\n * External transformations for the same hosts are indistinguishable\n * and are necessarily treated as managed by this call.\n */\n if (\n !isHostSetSubset({\n subset: inspection.requestTransformationHosts,\n superset: incomingHosts,\n })\n ) {\n throw createPolicyConflictError(\n 'Cannot add request transformations because the current Vercel Sandbox policy contains request transformations that cannot be attributed to this call. Their header values are redacted, so preserving them safely is not possible.',\n );\n }\n }\n\n await this.#applyState({\n accessPolicy: inspection.accessPolicy,\n requestTransformations:\n this.#state == null\n ? incomingTransformations\n : mergeRequestTransformations({\n existing: this.#state.requestTransformations,\n incoming: incomingTransformations,\n }),\n forwardRules: inspection.forwardRules.map(cloneForwardRule),\n currentPolicy: inspection.currentPolicy,\n });\n });\n }\n\n #enqueueMutation(operation: () => Promise<void>): Promise<void> {\n /*\n * Each mutation derives a complete replacement from private state. The\n * whole inspect, compose, update, and commit sequence must therefore run in\n * invocation order, while a failed operation must not poison the queue.\n */\n const result = this.#mutationQueue.then(operation);\n this.#mutationQueue = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n }\n\n #inspectPolicy(): CurrentPolicyInspection {\n /*\n * Once initialized, this manager is the sole supported owner of the\n * session's network policy. Direct native Sandbox policy mutations can\n * make the private desired state stale and are intentionally not tracked.\n */\n if (this.#state != null) {\n return {\n accessPolicy: this.#state.accessPolicy,\n forwardRules: this.#state.forwardRules,\n requestTransformationHosts: [],\n currentPolicy: this.#state.effectivePolicy,\n };\n }\n\n return inspectCurrentPolicy(\n this.#sandbox.currentSession().networkPolicy ?? 'allow-all',\n );\n }\n\n async #applyState({\n accessPolicy,\n requestTransformations,\n forwardRules,\n currentPolicy,\n }: {\n accessPolicy: NetworkAccessPolicy;\n requestTransformations: ReadonlyArray<HarnessV1RequestTransformation>;\n forwardRules: ReadonlyArray<ForwardRule>;\n currentPolicy: NetworkPolicy;\n }): Promise<void> {\n const effectivePolicy = composeNetworkPolicy({\n accessPolicy,\n requestTransformations,\n forwardRules,\n });\n\n if (\n !areNetworkPoliciesEqual({\n first: currentPolicy,\n second: effectivePolicy,\n })\n ) {\n await this.#sandbox.update({ networkPolicy: effectivePolicy });\n }\n\n this.#state = {\n accessPolicy: cloneNetworkAccessPolicy(accessPolicy),\n requestTransformations: requestTransformations.map(\n cloneRequestTransformation,\n ),\n forwardRules: forwardRules.map(cloneForwardRule),\n effectivePolicy,\n };\n }\n}\n\nfunction inspectCurrentPolicy(policy: NetworkPolicy): CurrentPolicyInspection {\n if (policy === 'allow-all' || policy === 'deny-all') {\n return {\n accessPolicy: { mode: policy },\n forwardRules: [],\n requestTransformationHosts: [],\n currentPolicy: policy,\n };\n }\n\n const allowedHosts = Array.isArray(policy.allow)\n ? [...policy.allow]\n : Object.keys(policy.allow ?? {});\n const forwardRules: ForwardRule[] = [];\n const requestTransformationHosts = new Set<string>();\n\n /*\n * Forwarding URLs and matchers survive Vercel's policy readback and can be\n * retained verbatim. Transformed header values do not, so transformations\n * are represented only by fingerprints until a caller supplies the values.\n */\n if (policy.allow != null && !Array.isArray(policy.allow)) {\n for (const [host, rules] of Object.entries(policy.allow)) {\n for (const rule of rules) {\n if (hasRequestTransformation(rule)) {\n requestTransformationHosts.add(host.toLowerCase());\n }\n if (rule.forwardURL != null) {\n forwardRules.push({\n host,\n ...(rule.match == null ? {} : { match: cloneMatch(rule.match) }),\n forwardURL: rule.forwardURL,\n });\n }\n }\n }\n }\n\n return {\n accessPolicy: {\n mode: 'custom',\n allowedHosts: minimizeHostPatterns(allowedHosts),\n allowedCIDRs: [...(policy.subnets?.allow ?? [])],\n deniedCIDRs: [...(policy.subnets?.deny ?? [])],\n },\n forwardRules,\n requestTransformationHosts: [...requestTransformationHosts],\n currentPolicy: cloneNetworkPolicy(policy),\n };\n}\n\nfunction toNetworkAccessPolicy(\n policy: HarnessV1NetworkPolicy,\n): NetworkAccessPolicy {\n switch (policy.mode) {\n case 'allow-all':\n return { mode: 'allow-all' };\n case 'deny-all':\n return { mode: 'deny-all' };\n case 'custom': {\n const allowedHosts = [...(policy.allowedHosts ?? [])];\n const allowedCIDRs = [...(policy.allowedCIDRs ?? [])];\n const deniedCIDRs = [...(policy.deniedCIDRs ?? [])];\n if (\n allowedHosts.length === 0 &&\n allowedCIDRs.length === 0 &&\n deniedCIDRs.length === 0\n ) {\n throw createPolicyConflictError(\n 'Custom network policy requires at least one of allowedHosts, allowedCIDRs, or deniedCIDRs to be non-empty.',\n );\n }\n return {\n mode: 'custom',\n allowedHosts,\n allowedCIDRs,\n deniedCIDRs,\n };\n }\n }\n}\n\nfunction composeNetworkPolicy({\n accessPolicy,\n requestTransformations,\n forwardRules,\n}: {\n accessPolicy: NetworkAccessPolicy;\n requestTransformations: ReadonlyArray<HarnessV1RequestTransformation>;\n forwardRules: ReadonlyArray<ForwardRule>;\n}): NetworkPolicy {\n /*\n * Access is authoritative even though Vercel stores all three concepts in\n * one allow map. Rules without a hostname intersection are omitted from the\n * effective policy but remain in private desired state, so a later access\n * change can activate them. CIDR access never activates hostname rules.\n */\n if (accessPolicy.mode === 'deny-all') {\n return 'deny-all';\n }\n\n const rulesByHost = new Map<string, NetworkPolicyRule[]>();\n const allowedHosts =\n accessPolicy.mode === 'allow-all' ? ['*'] : accessPolicy.allowedHosts;\n\n for (const host of allowedHosts) {\n rulesByHost.set(host, []);\n }\n\n for (const transformation of requestTransformations) {\n for (const host of getActiveHostPatterns({\n allowedHosts,\n ruleHost: transformation.match.host,\n })) {\n appendRule({\n rulesByHost,\n host,\n rule: toVercelRequestTransformationRule(transformation),\n });\n }\n }\n\n /*\n * Transformations and forwarding rules for one host must share the same\n * Vercel allow-map array. Transformations are inserted first to match the\n * ordering produced when the Vercel SDK reconstructs a policy.\n */\n for (const forwardRule of forwardRules) {\n for (const host of getActiveHostPatterns({\n allowedHosts,\n ruleHost: forwardRule.host,\n })) {\n appendRule({\n rulesByHost,\n host,\n rule: {\n ...(forwardRule.match == null\n ? {}\n : { match: cloneMatch(forwardRule.match) }),\n forwardURL: forwardRule.forwardURL,\n },\n });\n }\n }\n\n const hasActiveRules = [...rulesByHost.values()].some(\n rules => rules.length > 0,\n );\n if (!hasActiveRules) {\n return toVercelAccessPolicy(accessPolicy);\n }\n\n return {\n allow: Object.fromEntries(rulesByHost),\n ...(accessPolicy.mode !== 'custom' ? {} : toVercelSubnets(accessPolicy)),\n };\n}\n\nfunction toVercelAccessPolicy(\n accessPolicy: NetworkAccessPolicy,\n): NetworkPolicy {\n if (accessPolicy.mode === 'allow-all' || accessPolicy.mode === 'deny-all') {\n return accessPolicy.mode;\n }\n\n return {\n ...(accessPolicy.allowedHosts.length === 0\n ? {}\n : { allow: [...accessPolicy.allowedHosts] }),\n ...toVercelSubnets(accessPolicy),\n };\n}\n\nfunction toVercelSubnets(\n accessPolicy: Extract<NetworkAccessPolicy, { mode: 'custom' }>,\n): Pick<Exclude<NetworkPolicy, string>, 'subnets'> {\n if (\n accessPolicy.allowedCIDRs.length === 0 &&\n accessPolicy.deniedCIDRs.length === 0\n ) {\n return {};\n }\n return {\n subnets: {\n ...(accessPolicy.allowedCIDRs.length === 0\n ? {}\n : { allow: [...accessPolicy.allowedCIDRs] }),\n ...(accessPolicy.deniedCIDRs.length === 0\n ? {}\n : { deny: [...accessPolicy.deniedCIDRs] }),\n },\n };\n}\n\nfunction getActiveHostPatterns({\n allowedHosts,\n ruleHost,\n}: {\n allowedHosts: ReadonlyArray<string>;\n ruleHost: string;\n}): ReadonlyArray<string> {\n return minimizeHostPatterns(\n allowedHosts.flatMap(allowedHost => {\n const intersection = intersectHostPatterns({\n first: allowedHost,\n second: ruleHost,\n });\n return intersection == null ? [] : [intersection];\n }),\n );\n}\n\nfunction intersectHostPatterns({\n first,\n second,\n}: {\n first: string;\n second: string;\n}): string | undefined {\n if (isHostPatternSubset({ candidate: first, container: second })) {\n return first;\n }\n if (isHostPatternSubset({ candidate: second, container: first })) {\n return second;\n }\n return undefined;\n}\n\nfunction isHostPatternSubset({\n candidate,\n container,\n}: {\n candidate: string;\n container: string;\n}): boolean {\n const normalizedCandidate = candidate.toLowerCase();\n const normalizedContainer = container.toLowerCase();\n if (\n normalizedCandidate === normalizedContainer ||\n normalizedContainer === '*'\n ) {\n return true;\n }\n if (normalizedCandidate === '*' || !normalizedContainer.startsWith('*')) {\n return false;\n }\n\n const containerSuffix = normalizedContainer.slice(1);\n return normalizedCandidate.startsWith('*')\n ? normalizedCandidate.slice(1).endsWith(containerSuffix)\n : normalizedCandidate.endsWith(containerSuffix);\n}\n\nfunction minimizeHostPatterns(\n patterns: ReadonlyArray<string>,\n): ReadonlyArray<string> {\n const uniquePatterns = [...new Set(patterns)];\n return uniquePatterns.filter(\n pattern =>\n !uniquePatterns.some(\n other =>\n other !== pattern &&\n isHostPatternSubset({ candidate: pattern, container: other }),\n ),\n );\n}\n\nfunction appendRule({\n rulesByHost,\n host,\n rule,\n}: {\n rulesByHost: Map<string, NetworkPolicyRule[]>;\n host: string;\n rule: NetworkPolicyRule;\n}): void {\n const rules = rulesByHost.get(host) ?? [];\n rules.push(rule);\n rulesByHost.set(host, rules);\n}\n\nfunction toVercelRequestTransformationRule(\n transformation: HarnessV1RequestTransformation,\n): NetworkPolicyRule {\n const {\n host: _host,\n method,\n path,\n queryString,\n headers,\n } = transformation.match;\n const match = {\n ...(path == null ? {} : { path: cloneMatcher(path) }),\n ...(method == null ? {} : { method: [...method] }),\n ...(queryString == null\n ? {}\n : { queryString: queryString.map(cloneKeyValueMatcher) }),\n ...(headers == null ? {} : { headers: headers.map(cloneKeyValueMatcher) }),\n };\n\n return {\n ...(Object.keys(match).length === 0 ? {} : { match }),\n transform: [{ headers: { ...transformation.transform.headers } }],\n };\n}\n\nfunction hasRequestTransformation(rule: NetworkPolicyRule): boolean {\n return (\n rule.transform?.some(\n transformation =>\n transformation.headers != null &&\n Object.keys(transformation.headers).length > 0,\n ) ?? false\n );\n}\n\nfunction getRequestTransformationHosts(\n policy: NetworkPolicy,\n): ReadonlyArray<string> {\n if (\n policy === 'allow-all' ||\n policy === 'deny-all' ||\n policy.allow == null ||\n Array.isArray(policy.allow)\n ) {\n return [];\n }\n\n const hosts = new Set<string>();\n for (const [host, rules] of Object.entries(policy.allow)) {\n for (const rule of rules) {\n if (hasRequestTransformation(rule)) {\n hosts.add(host.toLowerCase());\n }\n }\n }\n return [...hosts];\n}\n\nfunction isHostSetSubset({\n subset,\n superset,\n}: {\n subset: ReadonlyArray<string>;\n superset: ReadonlyArray<string>;\n}): boolean {\n const allowedHosts = new Set(superset.map(host => host.toLowerCase()));\n return subset.every(host => allowedHosts.has(host.toLowerCase()));\n}\n\nfunction areNetworkPoliciesEqual({\n first,\n second,\n}: {\n first: NetworkPolicy;\n second: NetworkPolicy;\n}): boolean {\n return stableSerialize(first) === stableSerialize(second);\n}\n\nfunction mergeRequestTransformations({\n existing,\n incoming,\n}: {\n existing: ReadonlyArray<HarnessV1RequestTransformation>;\n incoming: ReadonlyArray<HarnessV1RequestTransformation>;\n}): HarnessV1RequestTransformation[] {\n const merged = existing.map(cloneRequestTransformation);\n const identities = new Map(\n merged.map((transformation, index) => [\n getRequestTransformationIdentity(transformation),\n index,\n ]),\n );\n\n for (const transformation of incoming) {\n const clonedTransformation = cloneRequestTransformation(transformation);\n const identity = getRequestTransformationIdentity(clonedTransformation);\n const existingIndex = identities.get(identity);\n if (existingIndex == null) {\n identities.set(identity, merged.length);\n merged.push(clonedTransformation);\n } else {\n merged[existingIndex] = clonedTransformation;\n }\n }\n\n return merged;\n}\n\nfunction getRequestTransformationIdentity(\n transformation: HarnessV1RequestTransformation,\n): string {\n return stableSerialize({\n match: transformation.match,\n transformedHeaderNames: Object.keys(transformation.transform.headers)\n .map(name => name.toLowerCase())\n .sort(),\n });\n}\n\nfunction stableSerialize(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map(stableSerialize).join(',')}]`;\n }\n if (value != null && typeof value === 'object') {\n return `{${Object.entries(value)\n .filter(([, entryValue]) => entryValue !== undefined)\n .sort(([firstKey], [secondKey]) => firstKey.localeCompare(secondKey))\n .map(\n ([key, entryValue]) =>\n `${JSON.stringify(key)}:${stableSerialize(entryValue)}`,\n )\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction cloneRequestTransformation(\n transformation: HarnessV1RequestTransformation,\n): HarnessV1RequestTransformation {\n return {\n match: {\n host: transformation.match.host,\n ...(transformation.match.path == null\n ? {}\n : { path: cloneHarnessMatcher(transformation.match.path) }),\n ...(transformation.match.method == null\n ? {}\n : { method: [...transformation.match.method] }),\n ...(transformation.match.queryString == null\n ? {}\n : {\n queryString: transformation.match.queryString.map(\n cloneHarnessKeyValueMatcher,\n ),\n }),\n ...(transformation.match.headers == null\n ? {}\n : {\n headers: transformation.match.headers.map(\n cloneHarnessKeyValueMatcher,\n ),\n }),\n },\n transform: { headers: { ...transformation.transform.headers } },\n };\n}\n\nfunction cloneForwardRule(rule: ForwardRule): ForwardRule {\n return {\n host: rule.host,\n ...(rule.match == null ? {} : { match: cloneMatch(rule.match) }),\n forwardURL: rule.forwardURL,\n };\n}\n\nfunction cloneNetworkAccessPolicy(\n policy: NetworkAccessPolicy,\n): NetworkAccessPolicy {\n if (policy.mode === 'allow-all' || policy.mode === 'deny-all') {\n return { mode: policy.mode };\n }\n return {\n mode: 'custom',\n allowedHosts: [...policy.allowedHosts],\n allowedCIDRs: [...policy.allowedCIDRs],\n deniedCIDRs: [...policy.deniedCIDRs],\n };\n}\n\nfunction cloneNetworkPolicy(policy: NetworkPolicy): NetworkPolicy {\n return structuredClone(policy);\n}\n\nfunction cloneMatch(\n match: NonNullable<NetworkPolicyRule['match']>,\n): NonNullable<NetworkPolicyRule['match']> {\n return {\n ...(match.path == null ? {} : { path: cloneMatcher(match.path) }),\n ...(match.method == null ? {} : { method: [...match.method] }),\n ...(match.queryString == null\n ? {}\n : { queryString: match.queryString.map(cloneKeyValueMatcher) }),\n ...(match.headers == null\n ? {}\n : { headers: match.headers.map(cloneKeyValueMatcher) }),\n };\n}\n\nfunction cloneKeyValueMatcher(\n matcher: NetworkPolicyKeyValueMatcher,\n): NetworkPolicyKeyValueMatcher {\n return {\n ...(matcher.key == null ? {} : { key: cloneMatcher(matcher.key) }),\n ...(matcher.value == null ? {} : { value: cloneMatcher(matcher.value) }),\n };\n}\n\nfunction cloneMatcher(matcher: NetworkPolicyMatcher): NetworkPolicyMatcher {\n return { ...matcher };\n}\n\nfunction cloneHarnessKeyValueMatcher(\n matcher: NonNullable<\n HarnessV1RequestTransformation['match']['headers']\n >[number],\n): NonNullable<HarnessV1RequestTransformation['match']['headers']>[number] {\n return {\n ...(matcher.key == null ? {} : { key: cloneHarnessMatcher(matcher.key) }),\n ...(matcher.value == null\n ? {}\n : { value: cloneHarnessMatcher(matcher.value) }),\n };\n}\n\nfunction cloneHarnessMatcher(\n matcher: NonNullable<HarnessV1RequestTransformation['match']['path']>,\n): NonNullable<HarnessV1RequestTransformation['match']['path']> {\n if ('exact' in matcher) {\n return { exact: matcher.exact };\n }\n if ('startsWith' in matcher) {\n return { startsWith: matcher.startsWith };\n }\n return { regex: matcher.regex };\n}\n\nfunction createPolicyConflictError(\n message: string,\n): HarnessCapabilityUnsupportedError {\n return new HarnessCapabilityUnsupportedError({\n harnessId: VERCEL_PROVIDER_ID,\n message,\n });\n}\n","import { posix } from 'node:path';\nimport {\n extractLines,\n type Experimental_SandboxSession,\n type Experimental_SandboxProcess,\n} from '@ai-sdk/provider-utils';\nimport type { Sandbox, Command } from '@vercel/sandbox';\n\n/**\n * `Experimental_SandboxSession` implementation backed by a `@vercel/sandbox`\n * `Sandbox` instance. This is the tool-safe surface (file I/O, exec, spawn);\n * it is what `VercelNetworkSandboxSession.restricted()` returns and is not\n * constructed directly by consumers. The network sandbox session owns the\n * lifetime of the underlying sandbox.\n */\nexport class VercelSandboxSession implements Experimental_SandboxSession {\n constructor(protected readonly sandbox: Sandbox) {}\n\n get description(): string {\n return [\n `Vercel Sandbox (name: ${this.sandbox.name}).`,\n 'Filesystem changes persist for the lifetime of the sandbox.',\n ].join('\\n');\n }\n\n async run({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n abortSignal?.throwIfAborted();\n\n const finished = await this.sandbox.runCommand({\n cmd: 'bash',\n args: ['-c', command],\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(env !== undefined ? { env } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n const [stdout, stderr] = await Promise.all([\n finished.stdout(),\n finished.stderr(),\n ]);\n\n return {\n exitCode: finished.exitCode,\n stdout,\n stderr,\n };\n }\n\n async spawn({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<Experimental_SandboxProcess> {\n abortSignal?.throwIfAborted();\n\n const live = await this.sandbox.runCommand({\n cmd: 'bash',\n args: ['-c', command],\n detached: true,\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(env !== undefined ? { env } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n return createSandboxProcess(live, abortSignal);\n }\n\n async readFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<ReadableStream<Uint8Array> | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n return bytesToStream(bytes);\n }\n\n async readBinaryFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<Uint8Array | null> {\n abortSignal?.throwIfAborted();\n try {\n const buffer = await this.sandbox.readFileToBuffer(\n { path },\n abortSignal ? { signal: abortSignal } : undefined,\n );\n if (buffer == null) return null;\n return new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n );\n } catch (error) {\n if (isFileNotFoundError(error)) return null;\n throw error;\n }\n }\n\n async readTextFile({\n path,\n encoding = 'utf-8',\n startLine,\n endLine,\n abortSignal,\n }: {\n path: string;\n encoding?: string;\n startLine?: number;\n endLine?: number;\n abortSignal?: AbortSignal;\n }): Promise<string | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n const text = Buffer.from(bytes).toString(encoding as BufferEncoding);\n return extractLines({ text, startLine, endLine });\n }\n\n async writeFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: ReadableStream<Uint8Array>;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const bytes = await collectStream(content);\n await this.writeBinaryFile({ path, content: bytes, abortSignal });\n }\n\n async writeBinaryFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: Uint8Array;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n abortSignal?.throwIfAborted();\n const parent = posix.dirname(path);\n if (parent && parent !== '.' && parent !== '/') {\n await this.sandbox.runCommand({\n cmd: 'mkdir',\n args: ['-p', parent],\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n }\n await this.sandbox.writeFiles(\n [{ path, content }],\n abortSignal ? { signal: abortSignal } : undefined,\n );\n }\n\n async writeTextFile({\n path,\n content,\n encoding = 'utf-8',\n abortSignal,\n }: {\n path: string;\n content: string;\n encoding?: string;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const buffer = Buffer.from(content, encoding as BufferEncoding);\n await this.writeBinaryFile({\n path,\n content: new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ),\n abortSignal,\n });\n }\n}\n\nfunction createSandboxProcess(\n command: Command,\n abortSignal: AbortSignal | undefined,\n): Experimental_SandboxProcess {\n const encoder = new TextEncoder();\n const controllers: {\n stdout?: ReadableStreamDefaultController<Uint8Array>;\n stderr?: ReadableStreamDefaultController<Uint8Array>;\n } = {};\n\n const stdout = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stdout = controller;\n },\n });\n\n const stderr = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stderr = controller;\n },\n });\n\n const drained = (async () => {\n try {\n const iterator = abortSignal\n ? command.logs({ signal: abortSignal })\n : command.logs();\n for await (const message of iterator) {\n const target =\n message.stream === 'stdout' ? controllers.stdout : controllers.stderr;\n target?.enqueue(encoder.encode(message.data));\n }\n controllers.stdout?.close();\n controllers.stderr?.close();\n } catch (error) {\n controllers.stdout?.error(error);\n controllers.stderr?.error(error);\n }\n })();\n\n return {\n stdout,\n stderr,\n async wait(): Promise<{ exitCode: number }> {\n const finished = await command.wait();\n await drained;\n if (abortSignal?.aborted) {\n throw abortSignal.reason ?? new DOMException('Aborted', 'AbortError');\n }\n return { exitCode: finished.exitCode };\n },\n async kill(): Promise<void> {\n await command.kill();\n },\n };\n}\n\nfunction bytesToStream(bytes: Uint8Array): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(bytes);\n controller.close();\n },\n });\n}\n\nasync function collectStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n total += value.byteLength;\n }\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (error == null || typeof error !== 'object') return false;\n const code = (error as { code?: unknown }).code;\n if (code === 'ENOENT') return true;\n const message = (error as { message?: unknown }).message;\n return (\n typeof message === 'string' &&\n /no such file|not found|does not exist|ENOENT/i.test(message)\n );\n}\n"],"mappings":";;;;;;;;;;AAAA;AAAA,EACE;AAAA,OAGK;AAEP,SAAS,eAAe;;;ACNxB;AAAA,EACE,qCAAAA;AAAA,OAKK;;;ACNP;AAAA,EACE;AAAA,OAGK;AASP,IAAM,qBAAqB;AAb3B;AAmDO,IAAM,6BAAN,MAAiC;AAAA,EAKtC,YAAY,EAAE,QAAQ,GAAyB;AAL1C;AACL,uBAAS;AACT;AACA,uCAAgC,QAAQ,QAAQ;AAG9C,uBAAK,UAAW;AAAA,EAClB;AAAA,EAEA,iBAAiB,QAA+C;AAC9D,WAAO,sBAAK,2DAAL,WAAsB,YAAY;AA7D7C;AA8DM,YAAM,aAAa,sBAAK,yDAAL;AACnB,UACE,mBAAK,WAAU,QACf,WAAW,2BAA2B,SAAS,GAC/C;AACA,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAEA,YAAM,sBAAK,sDAAL,WAAiB;AAAA,QACrB,cAAc,sBAAsB,MAAM;AAAA,QAC1C,yBACE,8BAAK,YAAL,mBAAa,uBAAuB,IAAI,gCAAxC,YACA,CAAC;AAAA,QACH,cAAc,WAAW,aAAa,IAAI,gBAAgB;AAAA,QAC1D,eAAe,WAAW;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,0BACE,iBACe;AACf,WAAO,sBAAK,2DAAL,WAAsB,YAAY;AACvC,YAAM,aAAa,sBAAK,yDAAL;AACnB,YAAM,sBAAK,sDAAL,WAAiB;AAAA,QACrB,cAAc,WAAW;AAAA,QACzB,wBAAwB,gBAAgB,IAAI,0BAA0B;AAAA,QACtE,cAAc,WAAW,aAAa,IAAI,gBAAgB;AAAA,QAC1D,eAAe,WAAW;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,0BACE,iBACe;AACf,WAAO,sBAAK,2DAAL,WAAsB,YAAY;AACvC,YAAM,aAAa,sBAAK,yDAAL;AACnB,YAAM,0BAA0B,gBAAgB;AAAA,QAC9C;AAAA,MACF;AAEA,UAAI,mBAAK,WAAU,MAAM;AACvB,cAAM,iBAAiB,qBAAqB;AAAA,UAC1C,cAAc,WAAW;AAAA,UACzB,wBAAwB;AAAA,UACxB,cAAc,WAAW;AAAA,QAC3B,CAAC;AACD,cAAM,gBAAgB,8BAA8B,cAAc;AASlE,YACE,CAAC,gBAAgB;AAAA,UACf,QAAQ,WAAW;AAAA,UACnB,UAAU;AAAA,QACZ,CAAC,GACD;AACA,gBAAM;AAAA,YACJ;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,sBAAK,sDAAL,WAAiB;AAAA,QACrB,cAAc,WAAW;AAAA,QACzB,wBACE,mBAAK,WAAU,OACX,0BACA,4BAA4B;AAAA,UAC1B,UAAU,mBAAK,QAAO;AAAA,UACtB,UAAU;AAAA,QACZ,CAAC;AAAA,QACP,cAAc,WAAW,aAAa,IAAI,gBAAgB;AAAA,QAC1D,eAAe,WAAW;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAuEF;AArKW;AACT;AACA;AAHK;AAiGL,qBAAgB,SAAC,WAA+C;AAM9D,QAAM,SAAS,mBAAK,gBAAe,KAAK,SAAS;AACjD,qBAAK,gBAAiB,OAAO;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACA,SAAO;AACT;AAEA,mBAAc,WAA4B;AAlK5C;AAwKI,MAAI,mBAAK,WAAU,MAAM;AACvB,WAAO;AAAA,MACL,cAAc,mBAAK,QAAO;AAAA,MAC1B,cAAc,mBAAK,QAAO;AAAA,MAC1B,4BAA4B,CAAC;AAAA,MAC7B,eAAe,mBAAK,QAAO;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AAAA,KACL,wBAAK,UAAS,eAAe,EAAE,kBAA/B,YAAgD;AAAA,EAClD;AACF;AAEM,gBAAW,eAAC;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKkB;AAChB,QAAM,kBAAkB,qBAAqB;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MACE,CAAC,wBAAwB;AAAA,IACvB,OAAO;AAAA,IACP,QAAQ;AAAA,EACV,CAAC,GACD;AACA,UAAM,mBAAK,UAAS,OAAO,EAAE,eAAe,gBAAgB,CAAC;AAAA,EAC/D;AAEA,qBAAK,QAAS;AAAA,IACZ,cAAc,yBAAyB,YAAY;AAAA,IACnD,wBAAwB,uBAAuB;AAAA,MAC7C;AAAA,IACF;AAAA,IACA,cAAc,aAAa,IAAI,gBAAgB;AAAA,IAC/C;AAAA,EACF;AACF;AAGF,SAAS,qBAAqB,QAAgD;AA3N9E;AA4NE,MAAI,WAAW,eAAe,WAAW,YAAY;AACnD,WAAO;AAAA,MACL,cAAc,EAAE,MAAM,OAAO;AAAA,MAC7B,cAAc,CAAC;AAAA,MACf,4BAA4B,CAAC;AAAA,MAC7B,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,QAAQ,OAAO,KAAK,IAC3C,CAAC,GAAG,OAAO,KAAK,IAChB,OAAO,MAAK,YAAO,UAAP,YAAgB,CAAC,CAAC;AAClC,QAAM,eAA8B,CAAC;AACrC,QAAM,6BAA6B,oBAAI,IAAY;AAOnD,MAAI,OAAO,SAAS,QAAQ,CAAC,MAAM,QAAQ,OAAO,KAAK,GAAG;AACxD,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,KAAK,GAAG;AACxD,iBAAW,QAAQ,OAAO;AACxB,YAAI,yBAAyB,IAAI,GAAG;AAClC,qCAA2B,IAAI,KAAK,YAAY,CAAC;AAAA,QACnD;AACA,YAAI,KAAK,cAAc,MAAM;AAC3B,uBAAa,KAAK;AAAA,YAChB;AAAA,YACA,GAAI,KAAK,SAAS,OAAO,CAAC,IAAI,EAAE,OAAO,WAAW,KAAK,KAAK,EAAE;AAAA,YAC9D,YAAY,KAAK;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,cAAc,qBAAqB,YAAY;AAAA,MAC/C,cAAc,CAAC,IAAI,kBAAO,YAAP,mBAAgB,UAAhB,YAAyB,CAAC,CAAE;AAAA,MAC/C,aAAa,CAAC,IAAI,kBAAO,YAAP,mBAAgB,SAAhB,YAAwB,CAAC,CAAE;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,4BAA4B,CAAC,GAAG,0BAA0B;AAAA,IAC1D,eAAe,mBAAmB,MAAM;AAAA,EAC1C;AACF;AAEA,SAAS,sBACP,QACqB;AAhRvB;AAiRE,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,MAAM,YAAY;AAAA,IAC7B,KAAK;AACH,aAAO,EAAE,MAAM,WAAW;AAAA,IAC5B,KAAK,UAAU;AACb,YAAM,eAAe,CAAC,IAAI,YAAO,iBAAP,YAAuB,CAAC,CAAE;AACpD,YAAM,eAAe,CAAC,IAAI,YAAO,iBAAP,YAAuB,CAAC,CAAE;AACpD,YAAM,cAAc,CAAC,IAAI,YAAO,gBAAP,YAAsB,CAAC,CAAE;AAClD,UACE,aAAa,WAAW,KACxB,aAAa,WAAW,KACxB,YAAY,WAAW,GACvB;AACA,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAIkB;AAOhB,MAAI,aAAa,SAAS,YAAY;AACpC,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,oBAAI,IAAiC;AACzD,QAAM,eACJ,aAAa,SAAS,cAAc,CAAC,GAAG,IAAI,aAAa;AAE3D,aAAW,QAAQ,cAAc;AAC/B,gBAAY,IAAI,MAAM,CAAC,CAAC;AAAA,EAC1B;AAEA,aAAW,kBAAkB,wBAAwB;AACnD,eAAW,QAAQ,sBAAsB;AAAA,MACvC;AAAA,MACA,UAAU,eAAe,MAAM;AAAA,IACjC,CAAC,GAAG;AACF,iBAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,MAAM,kCAAkC,cAAc;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF;AAOA,aAAW,eAAe,cAAc;AACtC,eAAW,QAAQ,sBAAsB;AAAA,MACvC;AAAA,MACA,UAAU,YAAY;AAAA,IACxB,CAAC,GAAG;AACF,iBAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,MAAM;AAAA,UACJ,GAAI,YAAY,SAAS,OACrB,CAAC,IACD,EAAE,OAAO,WAAW,YAAY,KAAK,EAAE;AAAA,UAC3C,YAAY,YAAY;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,GAAG,YAAY,OAAO,CAAC,EAAE;AAAA,IAC/C,WAAS,MAAM,SAAS;AAAA,EAC1B;AACA,MAAI,CAAC,gBAAgB;AACnB,WAAO,qBAAqB,YAAY;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,YAAY,WAAW;AAAA,IACrC,GAAI,aAAa,SAAS,WAAW,CAAC,IAAI,gBAAgB,YAAY;AAAA,EACxE;AACF;AAEA,SAAS,qBACP,cACe;AACf,MAAI,aAAa,SAAS,eAAe,aAAa,SAAS,YAAY;AACzE,WAAO,aAAa;AAAA,EACtB;AAEA,SAAO;AAAA,IACL,GAAI,aAAa,aAAa,WAAW,IACrC,CAAC,IACD,EAAE,OAAO,CAAC,GAAG,aAAa,YAAY,EAAE;AAAA,IAC5C,GAAG,gBAAgB,YAAY;AAAA,EACjC;AACF;AAEA,SAAS,gBACP,cACiD;AACjD,MACE,aAAa,aAAa,WAAW,KACrC,aAAa,YAAY,WAAW,GACpC;AACA,WAAO,CAAC;AAAA,EACV;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP,GAAI,aAAa,aAAa,WAAW,IACrC,CAAC,IACD,EAAE,OAAO,CAAC,GAAG,aAAa,YAAY,EAAE;AAAA,MAC5C,GAAI,aAAa,YAAY,WAAW,IACpC,CAAC,IACD,EAAE,MAAM,CAAC,GAAG,aAAa,WAAW,EAAE;AAAA,IAC5C;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AACF,GAG0B;AACxB,SAAO;AAAA,IACL,aAAa,QAAQ,iBAAe;AAClC,YAAM,eAAe,sBAAsB;AAAA,QACzC,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,CAAC;AACD,aAAO,gBAAgB,OAAO,CAAC,IAAI,CAAC,YAAY;AAAA,IAClD,CAAC;AAAA,EACH;AACF;AAEA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AACF,GAGuB;AACrB,MAAI,oBAAoB,EAAE,WAAW,OAAO,WAAW,OAAO,CAAC,GAAG;AAChE,WAAO;AAAA,EACT;AACA,MAAI,oBAAoB,EAAE,WAAW,QAAQ,WAAW,MAAM,CAAC,GAAG;AAChE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AACF,GAGY;AACV,QAAM,sBAAsB,UAAU,YAAY;AAClD,QAAM,sBAAsB,UAAU,YAAY;AAClD,MACE,wBAAwB,uBACxB,wBAAwB,KACxB;AACA,WAAO;AAAA,EACT;AACA,MAAI,wBAAwB,OAAO,CAAC,oBAAoB,WAAW,GAAG,GAAG;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,oBAAoB,MAAM,CAAC;AACnD,SAAO,oBAAoB,WAAW,GAAG,IACrC,oBAAoB,MAAM,CAAC,EAAE,SAAS,eAAe,IACrD,oBAAoB,SAAS,eAAe;AAClD;AAEA,SAAS,qBACP,UACuB;AACvB,QAAM,iBAAiB,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC;AAC5C,SAAO,eAAe;AAAA,IACpB,aACE,CAAC,eAAe;AAAA,MACd,WACE,UAAU,WACV,oBAAoB,EAAE,WAAW,SAAS,WAAW,MAAM,CAAC;AAAA,IAChE;AAAA,EACJ;AACF;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,GAIS;AA9eT;AA+eE,QAAM,SAAQ,iBAAY,IAAI,IAAI,MAApB,YAAyB,CAAC;AACxC,QAAM,KAAK,IAAI;AACf,cAAY,IAAI,MAAM,KAAK;AAC7B;AAEA,SAAS,kCACP,gBACmB;AACnB,QAAM;AAAA,IACJ,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,eAAe;AACnB,QAAM,QAAQ;AAAA,IACZ,GAAI,QAAQ,OAAO,CAAC,IAAI,EAAE,MAAM,aAAa,IAAI,EAAE;AAAA,IACnD,GAAI,UAAU,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE;AAAA,IAChD,GAAI,eAAe,OACf,CAAC,IACD,EAAE,aAAa,YAAY,IAAI,oBAAoB,EAAE;AAAA,IACzD,GAAI,WAAW,OAAO,CAAC,IAAI,EAAE,SAAS,QAAQ,IAAI,oBAAoB,EAAE;AAAA,EAC1E;AAEA,SAAO;AAAA,IACL,GAAI,OAAO,KAAK,KAAK,EAAE,WAAW,IAAI,CAAC,IAAI,EAAE,MAAM;AAAA,IACnD,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,eAAe,UAAU,QAAQ,EAAE,CAAC;AAAA,EAClE;AACF;AAEA,SAAS,yBAAyB,MAAkC;AA7gBpE;AA8gBE,UACE,gBAAK,cAAL,mBAAgB;AAAA,IACd,oBACE,eAAe,WAAW,QAC1B,OAAO,KAAK,eAAe,OAAO,EAAE,SAAS;AAAA,QAHjD,YAIK;AAET;AAEA,SAAS,8BACP,QACuB;AACvB,MACE,WAAW,eACX,WAAW,cACX,OAAO,SAAS,QAChB,MAAM,QAAQ,OAAO,KAAK,GAC1B;AACA,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,KAAK,GAAG;AACxD,eAAW,QAAQ,OAAO;AACxB,UAAI,yBAAyB,IAAI,GAAG;AAClC,cAAM,IAAI,KAAK,YAAY,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,KAAK;AAClB;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AACF,GAGY;AACV,QAAM,eAAe,IAAI,IAAI,SAAS,IAAI,UAAQ,KAAK,YAAY,CAAC,CAAC;AACrE,SAAO,OAAO,MAAM,UAAQ,aAAa,IAAI,KAAK,YAAY,CAAC,CAAC;AAClE;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AACF,GAGY;AACV,SAAO,gBAAgB,KAAK,MAAM,gBAAgB,MAAM;AAC1D;AAEA,SAAS,4BAA4B;AAAA,EACnC;AAAA,EACA;AACF,GAGqC;AACnC,QAAM,SAAS,SAAS,IAAI,0BAA0B;AACtD,QAAM,aAAa,IAAI;AAAA,IACrB,OAAO,IAAI,CAAC,gBAAgB,UAAU;AAAA,MACpC,iCAAiC,cAAc;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,kBAAkB,UAAU;AACrC,UAAM,uBAAuB,2BAA2B,cAAc;AACtE,UAAM,WAAW,iCAAiC,oBAAoB;AACtE,UAAM,gBAAgB,WAAW,IAAI,QAAQ;AAC7C,QAAI,iBAAiB,MAAM;AACzB,iBAAW,IAAI,UAAU,OAAO,MAAM;AACtC,aAAO,KAAK,oBAAoB;AAAA,IAClC,OAAO;AACL,aAAO,aAAa,IAAI;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,iCACP,gBACQ;AACR,SAAO,gBAAgB;AAAA,IACrB,OAAO,eAAe;AAAA,IACtB,wBAAwB,OAAO,KAAK,eAAe,UAAU,OAAO,EACjE,IAAI,UAAQ,KAAK,YAAY,CAAC,EAC9B,KAAK;AAAA,EACV,CAAC;AACH;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,IAAI,MAAM,IAAI,eAAe,EAAE,KAAK,GAAG,CAAC;AAAA,EACjD;AACA,MAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;AAC9C,WAAO,IAAI,OAAO,QAAQ,KAAK,EAC5B,OAAO,CAAC,CAAC,EAAE,UAAU,MAAM,eAAe,MAAS,EACnD,KAAK,CAAC,CAAC,QAAQ,GAAG,CAAC,SAAS,MAAM,SAAS,cAAc,SAAS,CAAC,EACnE;AAAA,MACC,CAAC,CAAC,KAAK,UAAU,MACf,GAAG,KAAK,UAAU,GAAG,CAAC,IAAI,gBAAgB,UAAU,CAAC;AAAA,IACzD,EACC,KAAK,GAAG,CAAC;AAAA,EACd;AACA,SAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,2BACP,gBACgC;AAChC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,eAAe,MAAM;AAAA,MAC3B,GAAI,eAAe,MAAM,QAAQ,OAC7B,CAAC,IACD,EAAE,MAAM,oBAAoB,eAAe,MAAM,IAAI,EAAE;AAAA,MAC3D,GAAI,eAAe,MAAM,UAAU,OAC/B,CAAC,IACD,EAAE,QAAQ,CAAC,GAAG,eAAe,MAAM,MAAM,EAAE;AAAA,MAC/C,GAAI,eAAe,MAAM,eAAe,OACpC,CAAC,IACD;AAAA,QACE,aAAa,eAAe,MAAM,YAAY;AAAA,UAC5C;AAAA,QACF;AAAA,MACF;AAAA,MACJ,GAAI,eAAe,MAAM,WAAW,OAChC,CAAC,IACD;AAAA,QACE,SAAS,eAAe,MAAM,QAAQ;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACN;AAAA,IACA,WAAW,EAAE,SAAS,EAAE,GAAG,eAAe,UAAU,QAAQ,EAAE;AAAA,EAChE;AACF;AAEA,SAAS,iBAAiB,MAAgC;AACxD,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,GAAI,KAAK,SAAS,OAAO,CAAC,IAAI,EAAE,OAAO,WAAW,KAAK,KAAK,EAAE;AAAA,IAC9D,YAAY,KAAK;AAAA,EACnB;AACF;AAEA,SAAS,yBACP,QACqB;AACrB,MAAI,OAAO,SAAS,eAAe,OAAO,SAAS,YAAY;AAC7D,WAAO,EAAE,MAAM,OAAO,KAAK;AAAA,EAC7B;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,CAAC,GAAG,OAAO,YAAY;AAAA,IACrC,cAAc,CAAC,GAAG,OAAO,YAAY;AAAA,IACrC,aAAa,CAAC,GAAG,OAAO,WAAW;AAAA,EACrC;AACF;AAEA,SAAS,mBAAmB,QAAsC;AAChE,SAAO,gBAAgB,MAAM;AAC/B;AAEA,SAAS,WACP,OACyC;AACzC,SAAO;AAAA,IACL,GAAI,MAAM,QAAQ,OAAO,CAAC,IAAI,EAAE,MAAM,aAAa,MAAM,IAAI,EAAE;AAAA,IAC/D,GAAI,MAAM,UAAU,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,MAAM,MAAM,EAAE;AAAA,IAC5D,GAAI,MAAM,eAAe,OACrB,CAAC,IACD,EAAE,aAAa,MAAM,YAAY,IAAI,oBAAoB,EAAE;AAAA,IAC/D,GAAI,MAAM,WAAW,OACjB,CAAC,IACD,EAAE,SAAS,MAAM,QAAQ,IAAI,oBAAoB,EAAE;AAAA,EACzD;AACF;AAEA,SAAS,qBACP,SAC8B;AAC9B,SAAO;AAAA,IACL,GAAI,QAAQ,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,aAAa,QAAQ,GAAG,EAAE;AAAA,IAChE,GAAI,QAAQ,SAAS,OAAO,CAAC,IAAI,EAAE,OAAO,aAAa,QAAQ,KAAK,EAAE;AAAA,EACxE;AACF;AAEA,SAAS,aAAa,SAAqD;AACzE,SAAO,EAAE,GAAG,QAAQ;AACtB;AAEA,SAAS,4BACP,SAGyE;AACzE,SAAO;AAAA,IACL,GAAI,QAAQ,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,oBAAoB,QAAQ,GAAG,EAAE;AAAA,IACvE,GAAI,QAAQ,SAAS,OACjB,CAAC,IACD,EAAE,OAAO,oBAAoB,QAAQ,KAAK,EAAE;AAAA,EAClD;AACF;AAEA,SAAS,oBACP,SAC8D;AAC9D,MAAI,WAAW,SAAS;AACtB,WAAO,EAAE,OAAO,QAAQ,MAAM;AAAA,EAChC;AACA,MAAI,gBAAgB,SAAS;AAC3B,WAAO,EAAE,YAAY,QAAQ,WAAW;AAAA,EAC1C;AACA,SAAO,EAAE,OAAO,QAAQ,MAAM;AAChC;AAEA,SAAS,0BACP,SACmC;AACnC,SAAO,IAAI,kCAAkC;AAAA,IAC3C,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AACH;;;AClvBA,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,OAGK;AAUA,IAAM,uBAAN,MAAkE;AAAA,EACvE,YAA+B,SAAkB;AAAlB;AAAA,EAAmB;AAAA,EAElD,IAAI,cAAsB;AACxB,WAAO;AAAA,MACL,yBAAyB,KAAK,QAAQ,IAAI;AAAA,MAC1C;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,IAAI;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKkE;AAChE,+CAAa;AAEb,UAAM,WAAW,MAAM,KAAK,QAAQ,WAAW;AAAA,MAC7C,KAAK;AAAA,MACL,MAAM,CAAC,MAAM,OAAO;AAAA,MACpB,GAAI,qBAAqB,SAAY,EAAE,KAAK,iBAAiB,IAAI,CAAC;AAAA,MAClE,GAAI,QAAQ,SAAY,EAAE,IAAI,IAAI,CAAC;AAAA,MACnC,GAAI,gBAAgB,SAAY,EAAE,QAAQ,YAAY,IAAI,CAAC;AAAA,IAC7D,CAAC;AAED,UAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,MACzC,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB,CAAC;AAED,WAAO;AAAA,MACL,UAAU,SAAS;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MAAM;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKyC;AACvC,+CAAa;AAEb,UAAM,OAAO,MAAM,KAAK,QAAQ,WAAW;AAAA,MACzC,KAAK;AAAA,MACL,MAAM,CAAC,MAAM,OAAO;AAAA,MACpB,UAAU;AAAA,MACV,GAAI,qBAAqB,SAAY,EAAE,KAAK,iBAAiB,IAAI,CAAC;AAAA,MAClE,GAAI,QAAQ,SAAY,EAAE,IAAI,IAAI,CAAC;AAAA,MACnC,GAAI,gBAAgB,SAAY,EAAE,QAAQ,YAAY,IAAI,CAAC;AAAA,IAC7D,CAAC;AAED,WAAO,qBAAqB,MAAM,WAAW;AAAA,EAC/C;AAAA,EAEA,MAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,EACF,GAG+C;AAC7C,UAAM,QAAQ,MAAM,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,QAAI,SAAS,KAAM,QAAO;AAC1B,WAAO,cAAc,KAAK;AAAA,EAC5B;AAAA,EAEA,MAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,EACF,GAG+B;AAC7B,+CAAa;AACb,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,QAAQ;AAAA,QAChC,EAAE,KAAK;AAAA,QACP,cAAc,EAAE,QAAQ,YAAY,IAAI;AAAA,MAC1C;AACA,UAAI,UAAU,KAAM,QAAO;AAC3B,aAAO,IAAI;AAAA,QACT,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AACd,UAAI,oBAAoB,KAAK,EAAG,QAAO;AACvC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,aAAa;AAAA,IACjB;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAM2B;AACzB,UAAM,QAAQ,MAAM,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,QAAI,SAAS,KAAM,QAAO;AAC1B,UAAM,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAA0B;AACnE,WAAO,aAAa,EAAE,MAAM,WAAW,QAAQ,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIkB;AAChB,UAAM,QAAQ,MAAM,cAAc,OAAO;AACzC,UAAM,KAAK,gBAAgB,EAAE,MAAM,SAAS,OAAO,YAAY,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,gBAAgB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIkB;AAChB,+CAAa;AACb,UAAM,SAAS,MAAM,QAAQ,IAAI;AACjC,QAAI,UAAU,WAAW,OAAO,WAAW,KAAK;AAC9C,YAAM,KAAK,QAAQ,WAAW;AAAA,QAC5B,KAAK;AAAA,QACL,MAAM,CAAC,MAAM,MAAM;AAAA,QACnB,GAAI,gBAAgB,SAAY,EAAE,QAAQ,YAAY,IAAI,CAAC;AAAA,MAC7D,CAAC;AAAA,IACH;AACA,UAAM,KAAK,QAAQ;AAAA,MACjB,CAAC,EAAE,MAAM,QAAQ,CAAC;AAAA,MAClB,cAAc,EAAE,QAAQ,YAAY,IAAI;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,MAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF,GAKkB;AAChB,UAAM,SAAS,OAAO,KAAK,SAAS,QAA0B;AAC9D,UAAM,KAAK,gBAAgB;AAAA,MACzB;AAAA,MACA,SAAS,IAAI;AAAA,QACX,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,qBACP,SACA,aAC6B;AAC7B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,cAGF,CAAC;AAEL,QAAM,SAAS,IAAI,eAA2B;AAAA,IAC5C,MAAM,YAAY;AAChB,kBAAY,SAAS;AAAA,IACvB;AAAA,EACF,CAAC;AAED,QAAM,SAAS,IAAI,eAA2B;AAAA,IAC5C,MAAM,YAAY;AAChB,kBAAY,SAAS;AAAA,IACvB;AAAA,EACF,CAAC;AAED,QAAM,WAAW,YAAY;AA9N/B;AA+NI,QAAI;AACF,YAAM,WAAW,cACb,QAAQ,KAAK,EAAE,QAAQ,YAAY,CAAC,IACpC,QAAQ,KAAK;AACjB,uBAAiB,WAAW,UAAU;AACpC,cAAM,SACJ,QAAQ,WAAW,WAAW,YAAY,SAAS,YAAY;AACjE,yCAAQ,QAAQ,QAAQ,OAAO,QAAQ,IAAI;AAAA,MAC7C;AACA,wBAAY,WAAZ,mBAAoB;AACpB,wBAAY,WAAZ,mBAAoB;AAAA,IACtB,SAAS,OAAO;AACd,wBAAY,WAAZ,mBAAoB,MAAM;AAC1B,wBAAY,WAAZ,mBAAoB,MAAM;AAAA,IAC5B;AAAA,EACF,GAAG;AAEH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,OAAsC;AAnPhD;AAoPM,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC,YAAM;AACN,UAAI,2CAAa,SAAS;AACxB,eAAM,iBAAY,WAAZ,YAAsB,IAAI,aAAa,WAAW,YAAY;AAAA,MACtE;AACA,aAAO,EAAE,UAAU,SAAS,SAAS;AAAA,IACvC;AAAA,IACA,MAAM,OAAsB;AAC1B,YAAM,QAAQ,KAAK;AAAA,IACrB;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAA+C;AACpE,SAAO,IAAI,eAA2B;AAAA,IACpC,MAAM,YAAY;AAChB,iBAAW,QAAQ,KAAK;AACxB,iBAAW,MAAM;AAAA,IACnB;AAAA,EACF,CAAC;AACH;AAEA,eAAe,cACb,QACqB;AACrB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,SAAO,MAAM;AACX,UAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,KAAM;AACV,QAAI,OAAO;AACT,aAAO,KAAK,KAAK;AACjB,eAAS,MAAM;AAAA,IACjB;AAAA,EACF;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAyB;AACpD,MAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO;AACvD,QAAM,OAAQ,MAA6B;AAC3C,MAAI,SAAS,SAAU,QAAO;AAC9B,QAAM,UAAW,MAAgC;AACjD,SACE,OAAO,YAAY,YACnB,gDAAgD,KAAK,OAAO;AAEhE;;;AF9RA,IAAMC,sBAAqB;AAZ3B;AAsBO,IAAM,8BAAN,cACG,qBAEV;AAAA,EAME,YAAY,OAAqD;AAC/D,UAAM,MAAM,OAAO;AAHrB,uBAAS;AAoBT,2BAAkB,OAAO,YAGa;AApDxC;AAqDI,YAAM,eAAe,KAAK;AAC1B,UAAI,CAAC,aAAa,SAAS,QAAQ,IAAI,GAAG;AACxC,cAAM,IAAIC,mCAAkC;AAAA,UAC1C,WAAWD;AAAA,UACX,SAAS,QAAQ,QAAQ,IAAI,oDAAoD,aAAa,KAAK,IAAI,CAAC;AAAA,QAC1G,CAAC;AAAA,MACH;AACA,YAAM,YAAW,aAAQ,aAAR,YAAoB;AACrC,YAAM,MAAM,IAAI,IAAI,KAAK,QAAQ,OAAO,QAAQ,IAAI,CAAC;AACrD,YAAM,WAAW,IAAI,aAAa;AAClC,cAAQ,UAAU;AAAA,QAChB,KAAK;AACH,cAAI,WAAW,WAAW,WAAW;AACrC;AAAA,QACF,KAAK;AACH,cAAI,WAAW;AACf;AAAA,QACF,KAAK;AACH,cAAI,WAAW,WAAW,SAAS;AACnC;AAAA,MACJ;AACA,aAAO,EAAE,KAAK,IAAI,SAAS,EAAE;AAAA,IAC/B;AAKA;AAAA;AAAA;AAAA,sBAAa,OAAO,YAGG;AACrB,cAAQ,MAAM,KAAK,gBAAgB,OAAO,GAAG;AAAA,IAC/C;AAEA,4BAAmB,OAAO,WAAkD;AAC1E,YAAM,mBAAK,uBAAsB,iBAAiB,MAAM;AAAA,IAC1D;AAEA,qCAA4B,OAC1B,oBACkB;AAClB,YAAM,mBAAK,uBAAsB,0BAA0B,eAAe;AAAA,IAC5E;AAEA,qCAA4B,OAC1B,oBACkB;AAClB,YAAM,mBAAK,uBAAsB,0BAA0B,eAAe;AAAA,IAC5E;AAEA,oBAAW,OACT,OACA,YACkB;AAClB,YAAM,KAAK,QAAQ;AAAA,QACjB,EAAE,OAAO,CAAC,GAAG,KAAK,EAAE;AAAA,SACpB,mCAAS,eAAc,EAAE,QAAQ,QAAQ,YAAY,IAAI;AAAA,MAC3D;AAAA,IACF;AAEA,gBAAO,YAA2B;AAChC,UAAI,CAAC,KAAK,cAAe;AACzB,YAAM,KAAK,QAAQ,KAAK;AAAA,IAC1B;AAEA,mBAAU,YAA2B;AACnC,UAAI,CAAC,KAAK,cAAe;AACzB,YAAM,KAAK,QAAQ,KAAK,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACxC,YAAM,KAAK,QAAQ,OAAO;AAAA,IAC5B;AAzFE,SAAK,gBAAgB,MAAM;AAC3B,SAAK,KAAK,MAAM,QAAQ;AACxB,SAAK,0BAA0B,MAAM,QAAQ,eAAe,EAAE;AAC9D,uBAAK,uBAAwB,IAAI,2BAA2B;AAAA,MAC1D,SAAS,MAAM;AAAA,IACjB,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,QAA+B;AACjC,WAAO,KAAK,QAAQ,OAAO,IAAI,WAAS,MAAM,IAAI;AAAA,EACpD;AAAA,EAEA,aAA6B;AAC3B,WAAO,IAAI,qBAAqB,KAAK,OAAO;AAAA,EAC9C;AA4EF;AA9FW;;;ADmCX,IAAM,6BAA6B,KAAK,KAAK;AAC7C,IAAM,0BAA0B;AAEhC,IAAME,sBAAqB;AAC3B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,2BAA2B;AAEjC,SAAS,mBAAmB,WAA2B;AACrD,SAAO,GAAG,mBAAmB,IAAI,SAAS;AAC5C;AAEA,SAAS,8BAA8B,QAAyB;AAC9D,SACG,aAAa,UAAU,OAAO,WAAW,QACzC,WAAW,UAAU,OAAO,SAAS,QACrC,YAAY,UACX,OAAO,OAAO,WAAW,YACzB,OAAO,UAAU,QACjB,UAAU,OAAO,UACjB,OAAO,OAAO,SAAS;AAE7B;AAEO,SAAS,oBACd,WAAkC,CAAC,GACT;AAC1B,SAAO,IAAI,sBAAsB,QAAQ;AAC3C;AAQO,IAAM,wBAAN,MAAgE;AAAA,EAIrE,YAA6B,UAAiC;AAAjC;AAH7B,SAAS,uBAAuB;AAChC,SAAS,aAAaA;AAItB,yBAAgB,OAAO,YAQwB;AAnHjD;AAoHI,+CAAS,gBAAT,mBAAsB;AAEtB,UAAI,aAAa,KAAK,YAAY,KAAK,SAAS,WAAW,MAAM;AAC/D,eAAO,IAAI,4BAA4B;AAAA,UACrC,SAAS,KAAK,SAAS;AAAA,UACvB,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAMA,YAAM,WAAW,KAAK;AACtB,YAAM;AAAA,QACJ,SAAS;AAAA,QACT,MAAM;AAAA,QACN,GAAG;AAAA,MACL,IAAI;AAIJ,YAAM,aAAa;AAAA,QACjB,GAAI,8BAA8B,YAAY,IAC1C,CAAC,IACD,EAAE,SAAS,wBAAwB;AAAA,QACvC,GAAG;AAAA,QACH,UAAS,kBAAa,YAAb,YAAwB;AAAA,MACnC;AAEA,YAAM,WAAW,mCAAS;AAC1B,YAAM,gBAAgB,mCAAS;AAM/B,YAAM,uBAAsB,mCAAS,aACjC,EAAE,MAAM,mBAAmB,QAAQ,SAAS,EAAE,IAC9C,CAAC;AAEL,UAAI,YAAY,QAAQ,iBAAiB,MAAM;AAC7C,cAAM,UAAU,MAAM,qCAAqC;AAAA,UACzD,UAAU,KAAK;AAAA,UACf,WAAW,MACT,QAAQ,OAAO;AAAA,YACb,GAAG;AAAA,YACH,GAAG;AAAA,YACH,IAAI,mCAAS,eAAc,EAAE,QAAQ,QAAQ,YAAY,IAAI,CAAC;AAAA,UAChE,CAAC;AAAA,QACL,CAAC;AACD,eAAO,IAAI,4BAA4B,EAAE,SAAS,eAAe,KAAK,CAAC;AAAA,MACzE;AAEA,YAAM,eAAe,sCAAgB,GAAG,oBAAoB,IAAI,QAAQ;AACxE,YAAM,QAAQ,iBAAiB;AAC/B,UAAI,aAAa,MAAM,IAAI,YAAY;AAEvC,UAAI,cAAc,MAAM;AACtB,cAAM,WAAW,MAAM,qCAAqC;AAAA,UAC1D,UAAU,KAAK;AAAA,UACf,WAAW,MAAG;AAjLtB,gBAAAC;AAkLU,2BAAQ,YAAY;AAAA,cAClB,GAAG;AAAA,cACH,MAAM;AAAA,cACN,YAAY;AAAA,cACZ,qBAAoBA,MAAA,WAAW,uBAAX,OAAAA,MAAiC;AAAA,cACrD,UAAU,OAAM,QAAO;AACrB,sBAAM,cAAc,IAAI,qBAAqB,GAAG,GAAG;AAAA,kBACjD,aAAa,mCAAS;AAAA,gBACxB,CAAC;AAAA,cACH;AAAA,cACA,IAAI,mCAAS,eAAc,EAAE,QAAQ,QAAQ,YAAY,IAAI,CAAC;AAAA,YAChE,CAAC;AAAA;AAAA,QACL,CAAC;AAED,YAAI,aAAiC,SAAS;AAC9C,YAAI,cAAc,MAAM;AACtB,gBAAM,aAAa,MAAM,qCAAqC;AAAA,YAC5D,UAAU,KAAK;AAAA,YACf,WAAW,MACT,SAAS;AAAA,eACP,mCAAS,eACL,EAAE,QAAQ,QAAQ,YAAY,IAC9B;AAAA,YACN;AAAA,UACJ,CAAC;AACD,wBAAa,gBAAW,aAAX,mBAAqB;AAClC,cAAI,cAAc,MAAM;AACtB,yBAAa,MAAM,qCAAqC;AAAA,cACtD,UAAU,KAAK;AAAA,cACf,WAAW,MACT,wBAAwB;AAAA,gBACtB,MAAM;AAAA,gBACN,cAAc,uBAAuB,UAAU;AAAA,gBAC/C,aAAa,mCAAS;AAAA,cACxB,CAAC;AAAA,YACL,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,IAAI,cAAc,UAAU;AAClC,qBAAa;AAAA,MACf;AAEA,YAAM;AAAA,QACJ,SAAS;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,GAAG;AAAA,MACL,IAAI;AAEJ,YAAM,OAAO,MAAM,qCAAqC;AAAA,QACtD,UAAU,KAAK;AAAA,QACf,WAAW,MACT,QAAQ,OAAO;AAAA,UACb,GAAG;AAAA,UACH,QAAQ,EAAE,MAAM,YAAY,WAAW;AAAA,UACvC,GAAG;AAAA,UACH,IAAI,mCAAS,eAAc,EAAE,QAAQ,QAAQ,YAAY,IAAI,CAAC;AAAA,QAChE,CAAC;AAAA,MACL,CAAC;AACD,aAAO,IAAI,4BAA4B;AAAA,QACrC,SAAS;AAAA,QACT,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,yBAAgB,OAAO,YAGwB;AAxPjD;AAyPI,oBAAQ,gBAAR,mBAAqB;AAGrB,UAAI,aAAa,KAAK,YAAY,KAAK,SAAS,WAAW,MAAM;AAC/D,eAAO,IAAI,4BAA4B;AAAA,UACrC,SAAS,KAAK,SAAS;AAAA,UACvB,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,YAAM,UAAU,MAAM,qCAAqC;AAAA,QACzD,UAAU,KAAK;AAAA,QACf,WAAW,MACT,QAAQ,IAAI;AAAA,UACV,GAAG,uBAAuB,KAAK,QAAQ;AAAA,UACvC,MAAM,mBAAmB,QAAQ,SAAS;AAAA,UAC1C,GAAI,QAAQ,cAAc,EAAE,QAAQ,QAAQ,YAAY,IAAI,CAAC;AAAA,QAC/D,CAAC;AAAA,MACL,CAAC;AACD,aAAO,IAAI,4BAA4B,EAAE,SAAS,eAAe,KAAK,CAAC;AAAA,IACzE;AAAA,EApK+D;AAqKjE;AAYA,IAAM,qBAAqB,uBAAO;AAAA,EAChC;AACF;AAUA,SAAS,uBACP,UACqB;AACrB,MAAI,aAAa,YAAY,SAAS,WAAW,MAAM;AACrD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,EAAE,OAAO,WAAW,QAAQ,MAAM,IAAI;AAC5C,SAAO;AAAA,IACL,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC3B;AACF;AAEA,SAAS,mBAAkC;AACzC,QAAM,UAAU;AAGhB,MAAI,QAAQ,QAAQ,kBAAkB;AACtC,MAAI,SAAS,MAAM;AACjB,YAAQ,oBAAI,IAAI;AAChB,YAAQ,kBAAkB,IAAI;AAAA,EAChC;AACA,SAAO;AACT;AAEA,IAAM,wCACJ;AAEF,eAAe,qCAAwC;AAAA,EACrD;AAAA,EACA;AACF,GAGe;AACb,MAAI;AACF,WAAO,MAAM,UAAU;AAAA,EACzB,SAAS,OAAO;AACd,QACE,CAAC,qCAAqC;AAAA,MACpC;AAAA,MACA,0BAA0B,yBAAyB,QAAQ;AAAA,IAC7D,CAAC,GACD;AACA,YAAM;AAAA,IACR;AACA,UAAM,IAAI,kCAAkC;AAAA,MAC1C,SAAS;AAAA,MACT,mBAAmBD;AAAA,MACnB,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,SAAS,yBAAyB,UAA0C;AAC1E,MAAI,QAAQ,IAAI,kBAAmB,QAAO;AAC1C,MAAI,aAAa,YAAY,SAAS,WAAW,KAAM,QAAO;AAC9D,QAAM,EAAE,OAAO,QAAQ,UAAU,IAAI,uBAAuB,QAAQ;AACpE,SAAO,QAAQ,SAAS,UAAU,SAAS;AAC7C;AAEA,SAAS,qCAAqC;AAAA,EAC5C;AAAA,EACA,0BAAAE;AACF,GAGY;AA5WZ;AA6WE,QAAM,OAAO,oBAAI,IAAa;AAC9B,MAAI,UAAU;AACd,SAAO,WAAW,QAAQ,CAAC,KAAK,IAAI,OAAO,GAAG;AAC5C,SAAK,IAAI,OAAO;AAChB,QAAI,OAAO,YAAY,UAAU;AAC/B,YAAM,YAAY;AAOlB,YACE,eAAU,aAAV,mBAAoB,YAAW,SAC/B,eAAU,aAAV,mBAAoB,YAAW,SAC/B,eAAU,aAAV,mBAAoB,gBAAe,SACnC,eAAU,aAAV,mBAAoB,gBAAe,KACnC;AACA,eAAO;AAAA,MACT;AACA,UACE,OAAO,UAAU,SAAS,YAC1B,kCAAkC,IAAI,UAAU,IAAI,GACpD;AACA,eAAO;AAAA,MACT;AACA,UACE,OAAO,UAAU,YAAY,YAC7B,oCAAoC,KAAK,UAAU,OAAO,GAC1D;AACA,eAAO;AAAA,MACT;AACA,UACE,CAACA,6BACD,UAAU,SAAS,0BACnB,OAAO,UAAU,YAAY,YAC7B,UAAU,QAAQ,SAAS,iBAAiB,KAC5C,UAAU,QAAQ,SAAS,oBAAoB,GAC/C;AACA,eAAO;AAAA,MACT;AACA,gBAAU,UAAU;AACpB;AAAA,IACF;AACA;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,oCAAoC,oBAAI,IAAI;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,sCACJ;AAEF,eAAe,wBAAwB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,GAIoB;AAClB,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,+CAAa;AACb,UAAM,YAAY,MAAM,QAAQ,IAAI;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,MACA,QAAQ;AAAA,MACR,GAAI,cAAc,EAAE,QAAQ,YAAY,IAAI,CAAC;AAAA,IAC/C,CAAC;AACD,QAAI,UAAU,mBAAmB;AAC/B,aAAO,UAAU;AAAA,IACnB;AACA,UAAM,IAAI;AAAA,MAAc,aACtB,WAAW,SAAS,yBAAyB;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR,+CAA+C,IAAI;AAAA,EACrD;AACF;","names":["HarnessCapabilityUnsupportedError","VERCEL_PROVIDER_ID","HarnessCapabilityUnsupportedError","VERCEL_PROVIDER_ID","_a","hasConfiguredCredentials"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/sandbox-vercel",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.90",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ai-sdk/harness": "1.0.
|
|
30
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
29
|
+
"@ai-sdk/harness": "1.0.90",
|
|
30
|
+
"@ai-sdk/provider-utils": "5.0.32",
|
|
31
31
|
"@vercel/sandbox": "^2.0.1 || ^3.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
@@ -136,12 +136,10 @@ export class VercelNetworkPolicyManager {
|
|
|
136
136
|
requestTransformations:
|
|
137
137
|
this.#state == null
|
|
138
138
|
? incomingTransformations
|
|
139
|
-
:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
...incomingTransformations,
|
|
144
|
-
],
|
|
139
|
+
: mergeRequestTransformations({
|
|
140
|
+
existing: this.#state.requestTransformations,
|
|
141
|
+
incoming: incomingTransformations,
|
|
142
|
+
}),
|
|
145
143
|
forwardRules: inspection.forwardRules.map(cloneForwardRule),
|
|
146
144
|
currentPolicy: inspection.currentPolicy,
|
|
147
145
|
});
|
|
@@ -579,6 +577,47 @@ function areNetworkPoliciesEqual({
|
|
|
579
577
|
return stableSerialize(first) === stableSerialize(second);
|
|
580
578
|
}
|
|
581
579
|
|
|
580
|
+
function mergeRequestTransformations({
|
|
581
|
+
existing,
|
|
582
|
+
incoming,
|
|
583
|
+
}: {
|
|
584
|
+
existing: ReadonlyArray<HarnessV1RequestTransformation>;
|
|
585
|
+
incoming: ReadonlyArray<HarnessV1RequestTransformation>;
|
|
586
|
+
}): HarnessV1RequestTransformation[] {
|
|
587
|
+
const merged = existing.map(cloneRequestTransformation);
|
|
588
|
+
const identities = new Map(
|
|
589
|
+
merged.map((transformation, index) => [
|
|
590
|
+
getRequestTransformationIdentity(transformation),
|
|
591
|
+
index,
|
|
592
|
+
]),
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
for (const transformation of incoming) {
|
|
596
|
+
const clonedTransformation = cloneRequestTransformation(transformation);
|
|
597
|
+
const identity = getRequestTransformationIdentity(clonedTransformation);
|
|
598
|
+
const existingIndex = identities.get(identity);
|
|
599
|
+
if (existingIndex == null) {
|
|
600
|
+
identities.set(identity, merged.length);
|
|
601
|
+
merged.push(clonedTransformation);
|
|
602
|
+
} else {
|
|
603
|
+
merged[existingIndex] = clonedTransformation;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return merged;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function getRequestTransformationIdentity(
|
|
611
|
+
transformation: HarnessV1RequestTransformation,
|
|
612
|
+
): string {
|
|
613
|
+
return stableSerialize({
|
|
614
|
+
match: transformation.match,
|
|
615
|
+
transformedHeaderNames: Object.keys(transformation.transform.headers)
|
|
616
|
+
.map(name => name.toLowerCase())
|
|
617
|
+
.sort(),
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
|
|
582
621
|
function stableSerialize(value: unknown): string {
|
|
583
622
|
if (Array.isArray(value)) {
|
|
584
623
|
return `[${value.map(stableSerialize).join(',')}]`;
|