@agent-native/core 0.90.9 → 0.90.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -28
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +18 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +3 -3
- package/corpus/core/docs/content/tracking.mdx +3 -3
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +5 -5
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +40 -8
- package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -7
- package/corpus/core/src/agent/engine/output-tokens.ts +94 -0
- package/corpus/core/src/agent/production-agent.ts +46 -7
- package/corpus/core/src/agent/types.ts +3 -2
- package/corpus/core/src/client/analytics.ts +17 -3
- package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +3 -1
- package/corpus/core/src/client/blocks/library/wireframe.tsx +6 -1
- package/corpus/core/src/db/client.ts +12 -9
- package/corpus/core/src/file-upload/builder.ts +10 -23
- package/corpus/core/src/file-upload/types.ts +3 -3
- package/corpus/core/src/shared/reasoning-effort.ts +23 -0
- package/corpus/core/src/styles/blocks.css +7 -0
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +9 -4
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +21 -7
- package/corpus/templates/analytics/app/entry.client.tsx +6 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-07-07-analytics-now-recovers-from-stale-route-chunks-after-deploys.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-07-metric-dashboard-cards-now-show-warehouse-backed-numeric-val.md +6 -0
- package/corpus/templates/clips/actions/create-recording.ts +1 -1
- package/corpus/templates/clips/actions/finalize-recording.ts +2 -2
- package/corpus/templates/clips/actions/import-loom-recording.ts +1 -1
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -1
- package/corpus/templates/clips/actions/regenerate-chapters.ts +7 -0
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +15 -5
- package/corpus/templates/clips/app/routes/download.tsx +12 -4
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
- package/corpus/templates/clips/changelog/2026-07-07-auto-generated-chapter-requests-now-open-the-matching-agent-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-clip-video-uploads-now-compress-in-the-background-while-keeping.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-desktop-settings-and-fn-dictation-are-more-reliable.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-desktop-settings-now-includes-a-manual-update-check-with-res.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-the-clips-desktop-download-page-now-uses-the-agent-native-ap.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +95 -8
- package/corpus/templates/clips/desktop/src/lib/updater.ts +60 -43
- package/corpus/templates/clips/desktop/src/styles.css +5 -0
- package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +93 -23
- package/corpus/templates/dispatch/changelog/2026-07-07-overview-is-now-just-ask-dispatch-and-a-list-of-apps.md +6 -0
- package/dist/agent/durable-background.d.ts +1 -1
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +5 -3
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +24 -4
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +13 -3
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/output-tokens.d.ts +27 -0
- package/dist/agent/engine/output-tokens.d.ts.map +1 -1
- package/dist/agent/engine/output-tokens.js +70 -0
- package/dist/agent/engine/output-tokens.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +41 -7
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/types.d.ts +3 -2
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +14 -3
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.d.ts +1 -0
- package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.js +2 -1
- package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +6 -1
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +12 -7
- package/dist/db/client.js.map +1 -1
- package/dist/file-upload/builder.d.ts.map +1 -1
- package/dist/file-upload/builder.js +9 -19
- package/dist/file-upload/builder.js.map +1 -1
- package/dist/file-upload/types.d.ts +3 -3
- package/dist/file-upload/types.d.ts.map +1 -1
- package/dist/file-upload/types.js.map +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/shared/reasoning-effort.d.ts +1 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +18 -0
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/styles/blocks.css +7 -0
- package/docs/content/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ar-SA/tracking.mdx +3 -3
- package/docs/content/locales/de-DE/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/de-DE/tracking.mdx +3 -3
- package/docs/content/locales/es-ES/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/es-ES/tracking.mdx +3 -3
- package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/fr-FR/tracking.mdx +3 -3
- package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/hi-IN/tracking.mdx +3 -3
- package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ja-JP/tracking.mdx +3 -3
- package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ko-KR/tracking.mdx +3 -3
- package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/pt-BR/tracking.mdx +3 -3
- package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/zh-CN/tracking.mdx +3 -3
- package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/zh-TW/tracking.mdx +3 -3
- package/docs/content/tracking.mdx +3 -3
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/file-upload/builder.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n FileUploadProvider,\n FileUploadInput,\n FileUploadResult,\n ResumableUploadSession,\n ResumableChunkResult,\n} from \"./types.js\";\n\nconst DEFAULT_BUILDER_APP_HOST = \"https://builder.io\";\n\n/** Files larger than this are routed through the GCS signed-URL flow. */\nconst LARGE_FILE_THRESHOLD_BYTES = 30 * 1024 * 1024;\nconst UPLOAD_TIMEOUT_MS = 120_000;\nconst SMALL_FILE_RETRY_DELAYS_MS = [600, 1800];\n\nfunction enabledFlag(value: unknown): boolean {\n return /^(true|1|yes|on)$/i.test(String(value || \"\").trim());\n}\n\nfunction stableUrlOptInEnabled(): boolean {\n return enabledFlag(process.env.CLIPS_STABLE_URL_OPTIN);\n}\n\nfunction builderUploadHost(): string {\n return (\n process.env.BUILDER_APP_HOST ||\n process.env.BUILDER_PUBLIC_APP_HOST ||\n DEFAULT_BUILDER_APP_HOST\n );\n}\n\nfunction makeBody(bytes: Uint8Array, mimeType: string): BodyInit {\n return typeof Blob !== \"undefined\"\n ? new Blob([bytes as unknown as BlobPart], { type: mimeType })\n : (bytes as unknown as BodyInit);\n}\n\nfunction shouldUseSignedUrlUpload(\n bytes: Uint8Array,\n mimeType: string,\n): boolean {\n return (\n bytes.byteLength > LARGE_FILE_THRESHOLD_BYTES || /^video\\//i.test(mimeType)\n );\n}\n\nfunction fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timer),\n );\n}\n\nfunction setSkipCompressionQueryParams(url: URL): void {\n url.searchParams.set(\"skipCompressionWait\", \"true\");\n url.searchParams.set(\"skipCompression\", \"true\");\n if (stableUrlOptInEnabled()) {\n url.searchParams.set(\"stableUrl\", \"true\");\n }\n}\n\nfunction setRecordAssetQueryParam(\n url: URL,\n recordAsset: boolean | undefined,\n): void {\n if (recordAsset === false) {\n url.searchParams.set(\"record\", \"false\");\n }\n}\n\nasync function assertOk(res: Response, label: string): Promise<void> {\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`${label} (${res.status}): ${body || res.statusText}`);\n }\n}\n\nasync function uploadLargeFileViaSignedUrl(\n input: FileUploadInput,\n privateKey: string,\n bareMimeType: string,\n bytes: Uint8Array,\n): Promise<FileUploadResult> {\n const name = input.filename ?? \"upload\";\n const mb = (bytes.byteLength / (1024 * 1024)).toFixed(1);\n\n console.log(\n `[builder-upload] large-file path: ${name} ${mb}MB ${bareMimeType}`,\n );\n\n // Step 1 — request a signed URL.\n console.log(`[builder-upload] step 1: requesting signed URL`);\n const { uploadUrl, assetId, requiredHeaders } = await requestBuilderSignedUrl(\n privateKey,\n name,\n bareMimeType,\n bytes.byteLength,\n );\n console.log(`[builder-upload] step 1 ok: assetId=${assetId}`);\n\n // Step 2 — PUT bytes directly to GCS. Only requiredHeaders; no Authorization\n // (signed URL carries its own auth — extra signed headers break the signature).\n console.log(`[builder-upload] step 2 [${assetId}]: PUT ${mb}MB to GCS`);\n const step2Res = await fetchWithTimeout(uploadUrl, {\n method: \"PUT\",\n headers: requiredHeaders,\n body: makeBody(bytes, bareMimeType),\n });\n await assertOk(step2Res, \"GCS upload failed\");\n console.log(\n `[builder-upload] step 2 ok [${assetId}]: GCS ${step2Res.status} etag=${step2Res.headers.get(\"etag\") ?? \"none\"}`,\n );\n\n // Step 3 — register the asset and get the CDN URL.\n console.log(\n `[builder-upload] step 3: registering asset - ${assetId}, ${input.filename}`,\n );\n const { url, id } = await completeBuilderUpload(\n privateKey,\n assetId,\n input.filename,\n {\n skipCompressionWait: input.skipCompressionWait,\n recordAsset: input.recordAsset,\n },\n );\n console.log(`[builder-upload] done [${assetId}]: ${url}`);\n return { url, id, provider: \"builder\" };\n}\n\nasync function requestBuilderSignedUrl(\n privateKey: string,\n filename: string,\n mimeType: string,\n size: number,\n resumable = false,\n): Promise<{\n uploadUrl: string;\n assetId: string;\n requiredHeaders: Record<string, string>;\n}> {\n const host = builderUploadHost();\n const url = new URL(\"/api/v1/upload/signed-url\", host);\n const res = await fetchWithTimeout(url.toString(), {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n fileName: filename,\n contentType: mimeType,\n size,\n resumable,\n }),\n });\n await assertOk(res, \"Builder.io signed-URL request failed\");\n const json = (await res.json()) as {\n uploadUrl?: string;\n assetId?: string;\n requiredHeaders?: Record<string, string>;\n };\n if (!json.uploadUrl || !json.assetId || !json.requiredHeaders) {\n throw new Error(\n `Builder.io signed-URL response missing required fields: ${JSON.stringify(Object.keys(json))}`,\n );\n }\n return {\n uploadUrl: json.uploadUrl,\n assetId: json.assetId,\n requiredHeaders: json.requiredHeaders,\n };\n}\n\nasync function completeBuilderUpload(\n privateKey: string,\n assetId: string,\n filename: string | undefined,\n options?: { skipCompressionWait?: boolean; recordAsset?: boolean },\n): Promise<{ url: string; id?: string }> {\n const host = builderUploadHost();\n const url = new URL(\"/api/v1/upload/complete\", host);\n if (options?.skipCompressionWait) {\n setSkipCompressionQueryParams(url);\n }\n setRecordAssetQueryParam(url, options?.recordAsset);\n const res = await fetchWithTimeout(url.toString(), {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n assetId,\n name: filename,\n ...(options?.recordAsset === false ? { record: false } : {}),\n }),\n });\n await assertOk(res, \"Builder.io upload complete failed\");\n const json = (await res.json()) as { url?: string; id?: string };\n if (!json.url) throw new Error(\"Builder.io upload/complete returned no URL\");\n return { url: json.url, id: json.id };\n}\n\n// Retry transient 5xx once with backoff. Builder.io's upload service\n// occasionally returns a bodyless 500 (\"Internal Error\") on the first\n// attempt — usually GCS write hiccups that succeed on retry.\nasync function uploadSmallFile(url: URL, init: RequestInit): Promise<Response> {\n let response: Response | null = null;\n let lastErrorBody = \"\";\n\n for (\n let attempt = 0;\n attempt <= SMALL_FILE_RETRY_DELAYS_MS.length;\n attempt++\n ) {\n const retryDelay = SMALL_FILE_RETRY_DELAYS_MS[attempt]; // undefined on last attempt\n try {\n response = await fetchWithTimeout(url.toString(), init);\n } catch (err) {\n if (!retryDelay) throw err;\n await new Promise((r) => setTimeout(r, retryDelay));\n continue;\n }\n if (response.ok) return response;\n lastErrorBody = await response.text().catch(() => \"\");\n const isTransient = response.status >= 500 && response.status !== 501;\n if (!isTransient || !retryDelay) break;\n await new Promise((r) => setTimeout(r, retryDelay));\n }\n\n const status = response?.status ?? 0;\n const statusText = response?.statusText ?? \"no response\";\n throw new Error(\n `Builder.io upload failed (${status}): ${lastErrorBody || statusText}`,\n );\n}\n\n/**\n * Built-in Builder.io file upload provider.\n * Uses the same BUILDER_PRIVATE_KEY as the browser/background-agent flows,\n * so connecting Builder once (via the sidebar \"Connect Builder\" action)\n * automatically enables file uploads.\n *\n * Upload API: https://www.builder.io/c/docs/upload-api\n */\nexport const builderFileUploadProvider: FileUploadProvider = {\n id: \"builder\",\n name: \"Builder.io\",\n isConfigured: () => !!process.env.BUILDER_PRIVATE_KEY,\n upload: async (input: FileUploadInput) => {\n const { data, filename, mimeType } = input;\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) {\n throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n }\n\n // Strip any media-type parameters (e.g. `;codecs=avc1,opus` from\n // MediaRecorder blobs) — Builder's upload API parses the body as raw\n // binary only when Content-Type is a bare MIME type. A parameterized\n // Content-Type falls through to the multipart/base64 paths which look\n // for an `image` field, and returns \"No image specified\" when it\n // doesn't find one.\n const bareMimeType = (mimeType || \"application/octet-stream\")\n .split(\";\")[0]\n .trim();\n\n const bytes =\n data instanceof Uint8Array ? data : new Uint8Array(data as any);\n const mb = (bytes.byteLength / (1024 * 1024)).toFixed(1);\n\n if (shouldUseSignedUrlUpload(bytes, bareMimeType)) {\n return uploadLargeFileViaSignedUrl(\n input,\n privateKey,\n bareMimeType,\n bytes,\n );\n }\n\n console.log(\n `[builder-upload] small-file path: ${filename ?? \"upload\"} ${mb}MB ${bareMimeType}`,\n );\n\n const url = new URL(\"/api/v1/upload\", builderUploadHost());\n if (filename) url.searchParams.set(\"name\", filename);\n if (input.skipCompressionWait) {\n setSkipCompressionQueryParams(url);\n }\n setRecordAssetQueryParam(url, input.recordAsset);\n\n const response = await uploadSmallFile(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": bareMimeType,\n },\n body: makeBody(bytes, bareMimeType),\n });\n\n const json = (await response.json().catch(() => ({}))) as {\n url?: string;\n id?: string;\n };\n if (!json.url) throw new Error(\"Builder.io upload returned no URL\");\n\n console.log(`[builder-upload] done: ${json.url}`);\n return { url: json.url, id: json.id, provider: \"builder\" };\n },\n\n resumable: {\n async startSession(filename, mimeType, maxBytes) {\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n\n console.log(\n `[builder-resumable] starting session: ${filename} ${mimeType} ${maxBytes} bytes`,\n );\n const { uploadUrl, assetId, requiredHeaders } =\n await requestBuilderSignedUrl(\n privateKey,\n filename,\n mimeType,\n maxBytes,\n true,\n );\n console.log(`[builder-resumable] session step 1 ok: assetId=${assetId}`);\n\n const initHeaders: Record<string, string> = {\n \"Content-Type\": mimeType,\n \"x-goog-resumable\": \"start\",\n };\n const contentLengthRange =\n requiredHeaders?.[\"x-goog-content-length-range\"];\n if (contentLengthRange)\n initHeaders[\"x-goog-content-length-range\"] = contentLengthRange;\n\n console.log(`[builder-resumable] session step 2: initiating GCS session`);\n const initRes = await fetchWithTimeout(uploadUrl, {\n method: \"POST\",\n headers: initHeaders,\n body: new Uint8Array(0),\n });\n if (!initRes.ok) {\n const body = await initRes.text().catch(() => \"\");\n throw new Error(\n `GCS resumable session initiation failed (${initRes.status}): ${body}`,\n );\n }\n const sessionUri = initRes.headers.get(\"location\");\n if (!sessionUri)\n throw new Error(\n \"GCS did not return a Location header for the resumable session\",\n );\n\n console.log(`[builder-resumable] session ready: assetId=${assetId}`);\n return {\n sessionId: sessionUri,\n meta: { assetId, filename, mimeType },\n } satisfies ResumableUploadSession;\n },\n\n async relayChunk(session, contentRange, bytes, options) {\n const sessionUri = session.sessionId;\n const MAX_ATTEMPTS = 4;\n const RETRYABLE = new Set([408, 429, 500, 502, 503, 504]);\n const delayMs = (attempt: number) =>\n Math.min(2000, 300 * 2 ** (attempt - 1));\n\n let lastError: unknown = null;\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n const headers: Record<string, string> = {\n \"Content-Range\": contentRange,\n };\n if (options?.mimeType) headers[\"Content-Type\"] = options.mimeType;\n const res = await fetch(sessionUri, {\n method: \"PUT\",\n headers,\n body: bytes as unknown as BodyInit,\n });\n if (res.status === 308 || res.ok)\n return {\n ok: true,\n status: res.status,\n } satisfies ResumableChunkResult;\n if (RETRYABLE.has(res.status) && attempt < MAX_ATTEMPTS) {\n await res.text().catch(() => \"\");\n console.warn(\n `[builder-resumable] transient ${res.status} on attempt ${attempt}, retrying`,\n );\n await new Promise((r) => setTimeout(r, delayMs(attempt)));\n continue;\n }\n return {\n ok: false,\n status: res.status,\n } satisfies ResumableChunkResult;\n } catch (err) {\n lastError = err;\n if (attempt >= MAX_ATTEMPTS) break;\n console.warn(\n `[builder-resumable] network error on attempt ${attempt}:`,\n err instanceof Error ? err.message : String(err),\n );\n await new Promise((r) => setTimeout(r, delayMs(attempt)));\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new Error(\"GCS PUT failed after retries\");\n },\n\n async completeSession(session, filename, options) {\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n\n const assetId = session.meta.assetId as string;\n console.log(`[builder-resumable] completing upload: assetId=${assetId}`);\n const { url } = await completeBuilderUpload(\n privateKey,\n assetId,\n filename,\n {\n skipCompressionWait:\n options?.skipCompressionWait ||\n session.meta.skipCompressionWait === true,\n recordAsset:\n options?.recordAsset ??\n (session.meta.recordAsset === false ? false : undefined),\n },\n );\n console.log(`[builder-resumable] upload complete: ${url}`);\n return url;\n },\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/file-upload/builder.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n FileUploadProvider,\n FileUploadInput,\n FileUploadResult,\n ResumableUploadSession,\n ResumableChunkResult,\n} from \"./types.js\";\n\nconst DEFAULT_BUILDER_APP_HOST = \"https://builder.io\";\n\n/** Files larger than this are routed through the GCS signed-URL flow. */\nconst LARGE_FILE_THRESHOLD_BYTES = 30 * 1024 * 1024;\nconst UPLOAD_TIMEOUT_MS = 120_000;\nconst SMALL_FILE_RETRY_DELAYS_MS = [600, 1800];\n\nfunction builderUploadHost(): string {\n return (\n process.env.BUILDER_APP_HOST ||\n process.env.BUILDER_PUBLIC_APP_HOST ||\n DEFAULT_BUILDER_APP_HOST\n );\n}\n\nfunction makeBody(bytes: Uint8Array, mimeType: string): BodyInit {\n return typeof Blob !== \"undefined\"\n ? new Blob([bytes as unknown as BlobPart], { type: mimeType })\n : (bytes as unknown as BodyInit);\n}\n\nfunction shouldUseSignedUrlUpload(\n bytes: Uint8Array,\n mimeType: string,\n): boolean {\n return (\n bytes.byteLength > LARGE_FILE_THRESHOLD_BYTES || /^video\\//i.test(mimeType)\n );\n}\n\nfunction fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timer),\n );\n}\n\nfunction setStableUrlQueryParam(url: URL): void {\n // Stable URLs let Builder compress asynchronously without changing the media URL.\n url.searchParams.set(\"stableUrl\", \"true\");\n}\n\nfunction setRecordAssetQueryParam(\n url: URL,\n recordAsset: boolean | undefined,\n): void {\n if (recordAsset === false) {\n url.searchParams.set(\"record\", \"false\");\n }\n}\n\nasync function assertOk(res: Response, label: string): Promise<void> {\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`${label} (${res.status}): ${body || res.statusText}`);\n }\n}\n\nasync function uploadLargeFileViaSignedUrl(\n input: FileUploadInput,\n privateKey: string,\n bareMimeType: string,\n bytes: Uint8Array,\n): Promise<FileUploadResult> {\n const name = input.filename ?? \"upload\";\n const mb = (bytes.byteLength / (1024 * 1024)).toFixed(1);\n\n console.log(\n `[builder-upload] large-file path: ${name} ${mb}MB ${bareMimeType}`,\n );\n\n // Step 1 — request a signed URL.\n console.log(`[builder-upload] step 1: requesting signed URL`);\n const { uploadUrl, assetId, requiredHeaders } = await requestBuilderSignedUrl(\n privateKey,\n name,\n bareMimeType,\n bytes.byteLength,\n );\n console.log(`[builder-upload] step 1 ok: assetId=${assetId}`);\n\n // Step 2 — PUT bytes directly to GCS. Only requiredHeaders; no Authorization\n // (signed URL carries its own auth — extra signed headers break the signature).\n console.log(`[builder-upload] step 2 [${assetId}]: PUT ${mb}MB to GCS`);\n const step2Res = await fetchWithTimeout(uploadUrl, {\n method: \"PUT\",\n headers: requiredHeaders,\n body: makeBody(bytes, bareMimeType),\n });\n await assertOk(step2Res, \"GCS upload failed\");\n console.log(\n `[builder-upload] step 2 ok [${assetId}]: GCS ${step2Res.status} etag=${step2Res.headers.get(\"etag\") ?? \"none\"}`,\n );\n\n // Step 3 — register the asset and get the CDN URL.\n console.log(\n `[builder-upload] step 3: registering asset - ${assetId}, ${input.filename}`,\n );\n const { url, id } = await completeBuilderUpload(\n privateKey,\n assetId,\n input.filename,\n {\n stableUrl: input.stableUrl,\n recordAsset: input.recordAsset,\n },\n );\n console.log(`[builder-upload] done [${assetId}]: ${url}`);\n return { url, id, provider: \"builder\" };\n}\n\nasync function requestBuilderSignedUrl(\n privateKey: string,\n filename: string,\n mimeType: string,\n size: number,\n resumable = false,\n): Promise<{\n uploadUrl: string;\n assetId: string;\n requiredHeaders: Record<string, string>;\n}> {\n const host = builderUploadHost();\n const url = new URL(\"/api/v1/upload/signed-url\", host);\n const res = await fetchWithTimeout(url.toString(), {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n fileName: filename,\n contentType: mimeType,\n size,\n resumable,\n }),\n });\n await assertOk(res, \"Builder.io signed-URL request failed\");\n const json = (await res.json()) as {\n uploadUrl?: string;\n assetId?: string;\n requiredHeaders?: Record<string, string>;\n };\n if (!json.uploadUrl || !json.assetId || !json.requiredHeaders) {\n throw new Error(\n `Builder.io signed-URL response missing required fields: ${JSON.stringify(Object.keys(json))}`,\n );\n }\n return {\n uploadUrl: json.uploadUrl,\n assetId: json.assetId,\n requiredHeaders: json.requiredHeaders,\n };\n}\n\nasync function completeBuilderUpload(\n privateKey: string,\n assetId: string,\n filename: string | undefined,\n options?: { stableUrl?: boolean; recordAsset?: boolean },\n): Promise<{ url: string; id?: string }> {\n const host = builderUploadHost();\n const url = new URL(\"/api/v1/upload/complete\", host);\n if (options?.stableUrl) {\n setStableUrlQueryParam(url);\n }\n setRecordAssetQueryParam(url, options?.recordAsset);\n const res = await fetchWithTimeout(url.toString(), {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n assetId,\n name: filename,\n ...(options?.recordAsset === false ? { record: false } : {}),\n }),\n });\n await assertOk(res, \"Builder.io upload complete failed\");\n const json = (await res.json()) as { url?: string; id?: string };\n if (!json.url) throw new Error(\"Builder.io upload/complete returned no URL\");\n return { url: json.url, id: json.id };\n}\n\n// Retry transient 5xx once with backoff. Builder.io's upload service\n// occasionally returns a bodyless 500 (\"Internal Error\") on the first\n// attempt — usually GCS write hiccups that succeed on retry.\nasync function uploadSmallFile(url: URL, init: RequestInit): Promise<Response> {\n let response: Response | null = null;\n let lastErrorBody = \"\";\n\n for (\n let attempt = 0;\n attempt <= SMALL_FILE_RETRY_DELAYS_MS.length;\n attempt++\n ) {\n const retryDelay = SMALL_FILE_RETRY_DELAYS_MS[attempt]; // undefined on last attempt\n try {\n response = await fetchWithTimeout(url.toString(), init);\n } catch (err) {\n if (!retryDelay) throw err;\n await new Promise((r) => setTimeout(r, retryDelay));\n continue;\n }\n if (response.ok) return response;\n lastErrorBody = await response.text().catch(() => \"\");\n const isTransient = response.status >= 500 && response.status !== 501;\n if (!isTransient || !retryDelay) break;\n await new Promise((r) => setTimeout(r, retryDelay));\n }\n\n const status = response?.status ?? 0;\n const statusText = response?.statusText ?? \"no response\";\n throw new Error(\n `Builder.io upload failed (${status}): ${lastErrorBody || statusText}`,\n );\n}\n\n/**\n * Built-in Builder.io file upload provider.\n * Uses the same BUILDER_PRIVATE_KEY as the browser/background-agent flows,\n * so connecting Builder once (via the sidebar \"Connect Builder\" action)\n * automatically enables file uploads.\n *\n * Upload API: https://www.builder.io/c/docs/upload-api\n */\nexport const builderFileUploadProvider: FileUploadProvider = {\n id: \"builder\",\n name: \"Builder.io\",\n isConfigured: () => !!process.env.BUILDER_PRIVATE_KEY,\n upload: async (input: FileUploadInput) => {\n const { data, filename, mimeType } = input;\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) {\n throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n }\n\n // Strip any media-type parameters (e.g. `;codecs=avc1,opus` from\n // MediaRecorder blobs) — Builder's upload API parses the body as raw\n // binary only when Content-Type is a bare MIME type. A parameterized\n // Content-Type falls through to the multipart/base64 paths which look\n // for an `image` field, and returns \"No image specified\" when it\n // doesn't find one.\n const bareMimeType = (mimeType || \"application/octet-stream\")\n .split(\";\")[0]\n .trim();\n\n const bytes =\n data instanceof Uint8Array ? data : new Uint8Array(data as any);\n const mb = (bytes.byteLength / (1024 * 1024)).toFixed(1);\n\n if (shouldUseSignedUrlUpload(bytes, bareMimeType)) {\n return uploadLargeFileViaSignedUrl(\n input,\n privateKey,\n bareMimeType,\n bytes,\n );\n }\n\n console.log(\n `[builder-upload] small-file path: ${filename ?? \"upload\"} ${mb}MB ${bareMimeType}`,\n );\n\n const url = new URL(\"/api/v1/upload\", builderUploadHost());\n if (filename) url.searchParams.set(\"name\", filename);\n if (input.stableUrl) {\n setStableUrlQueryParam(url);\n }\n setRecordAssetQueryParam(url, input.recordAsset);\n\n const response = await uploadSmallFile(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": bareMimeType,\n },\n body: makeBody(bytes, bareMimeType),\n });\n\n const json = (await response.json().catch(() => ({}))) as {\n url?: string;\n id?: string;\n };\n if (!json.url) throw new Error(\"Builder.io upload returned no URL\");\n\n console.log(`[builder-upload] done: ${json.url}`);\n return { url: json.url, id: json.id, provider: \"builder\" };\n },\n\n resumable: {\n async startSession(filename, mimeType, maxBytes) {\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n\n console.log(\n `[builder-resumable] starting session: ${filename} ${mimeType} ${maxBytes} bytes`,\n );\n const { uploadUrl, assetId, requiredHeaders } =\n await requestBuilderSignedUrl(\n privateKey,\n filename,\n mimeType,\n maxBytes,\n true,\n );\n console.log(`[builder-resumable] session step 1 ok: assetId=${assetId}`);\n\n const initHeaders: Record<string, string> = {\n \"Content-Type\": mimeType,\n \"x-goog-resumable\": \"start\",\n };\n const contentLengthRange =\n requiredHeaders?.[\"x-goog-content-length-range\"];\n if (contentLengthRange)\n initHeaders[\"x-goog-content-length-range\"] = contentLengthRange;\n\n console.log(`[builder-resumable] session step 2: initiating GCS session`);\n const initRes = await fetchWithTimeout(uploadUrl, {\n method: \"POST\",\n headers: initHeaders,\n body: new Uint8Array(0),\n });\n if (!initRes.ok) {\n const body = await initRes.text().catch(() => \"\");\n throw new Error(\n `GCS resumable session initiation failed (${initRes.status}): ${body}`,\n );\n }\n const sessionUri = initRes.headers.get(\"location\");\n if (!sessionUri)\n throw new Error(\n \"GCS did not return a Location header for the resumable session\",\n );\n\n console.log(`[builder-resumable] session ready: assetId=${assetId}`);\n return {\n sessionId: sessionUri,\n meta: { assetId, filename, mimeType },\n } satisfies ResumableUploadSession;\n },\n\n async relayChunk(session, contentRange, bytes, options) {\n const sessionUri = session.sessionId;\n const MAX_ATTEMPTS = 4;\n const RETRYABLE = new Set([408, 429, 500, 502, 503, 504]);\n const delayMs = (attempt: number) =>\n Math.min(2000, 300 * 2 ** (attempt - 1));\n\n let lastError: unknown = null;\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n const headers: Record<string, string> = {\n \"Content-Range\": contentRange,\n };\n if (options?.mimeType) headers[\"Content-Type\"] = options.mimeType;\n const res = await fetch(sessionUri, {\n method: \"PUT\",\n headers,\n body: bytes as unknown as BodyInit,\n });\n if (res.status === 308 || res.ok)\n return {\n ok: true,\n status: res.status,\n } satisfies ResumableChunkResult;\n if (RETRYABLE.has(res.status) && attempt < MAX_ATTEMPTS) {\n await res.text().catch(() => \"\");\n console.warn(\n `[builder-resumable] transient ${res.status} on attempt ${attempt}, retrying`,\n );\n await new Promise((r) => setTimeout(r, delayMs(attempt)));\n continue;\n }\n return {\n ok: false,\n status: res.status,\n } satisfies ResumableChunkResult;\n } catch (err) {\n lastError = err;\n if (attempt >= MAX_ATTEMPTS) break;\n console.warn(\n `[builder-resumable] network error on attempt ${attempt}:`,\n err instanceof Error ? err.message : String(err),\n );\n await new Promise((r) => setTimeout(r, delayMs(attempt)));\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new Error(\"GCS PUT failed after retries\");\n },\n\n async completeSession(session, filename, options) {\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n\n const assetId = session.meta.assetId as string;\n console.log(`[builder-resumable] completing upload: assetId=${assetId}`);\n const { url } = await completeBuilderUpload(\n privateKey,\n assetId,\n filename,\n {\n stableUrl: options?.stableUrl || session.meta.stableUrl === true,\n recordAsset:\n options?.recordAsset ??\n (session.meta.recordAsset === false ? false : undefined),\n },\n );\n console.log(`[builder-resumable] upload complete: ${url}`);\n return url;\n },\n },\n};\n"]}
|
|
@@ -15,8 +15,8 @@ export interface FileUploadInput {
|
|
|
15
15
|
mimeType?: string;
|
|
16
16
|
/** Optional owner email for per-user scoping in fallback storage. */
|
|
17
17
|
ownerEmail?: string;
|
|
18
|
-
/** Builder.io upload hint: return
|
|
19
|
-
|
|
18
|
+
/** Builder.io upload hint: return one stable URL while compression finishes asynchronously. */
|
|
19
|
+
stableUrl?: boolean;
|
|
20
20
|
/** Builder.io upload hint: set false for internal artifacts that should not appear in the asset library. */
|
|
21
21
|
recordAsset?: boolean;
|
|
22
22
|
}
|
|
@@ -67,7 +67,7 @@ export interface FileUploadProvider {
|
|
|
67
67
|
mimeType?: string;
|
|
68
68
|
}): Promise<ResumableChunkResult>;
|
|
69
69
|
completeSession(session: ResumableUploadSession, filename: string, options?: {
|
|
70
|
-
|
|
70
|
+
stableUrl?: boolean;
|
|
71
71
|
recordAsset?: boolean;
|
|
72
72
|
}): Promise<string>;
|
|
73
73
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/file-upload/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/file-upload/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4GAA4G;IAC5G,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;qFAEqF;AACrF,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf;uEACmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,YAAY,EAAE,MAAM,OAAO,CAAC;IAC5B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,wDAAwD;IACxD,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9D;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACnC,UAAU,CACR,OAAO,EAAE,sBAAsB,EAC/B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACjC,eAAe,CACb,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;YAAE,SAAS,CAAC,EAAE,OAAO,CAAC;YAAC,WAAW,CAAC,EAAE,OAAO,CAAA;SAAE,GACvD,OAAO,CAAC,MAAM,CAAC,CAAC;KACpB,CAAC;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/file-upload/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG","sourcesContent":["/**\n * File upload framework primitive.\n *\n * Templates call `uploadFile()` to upload a file and get back a URL.\n * The framework dispatches to whichever provider is registered (Builder.io\n * built-in, or a user-supplied one). If no provider is active, it falls back\n * to the SQL resources store — fine for dev, not recommended for production.\n */\n\nexport interface FileUploadInput {\n /** File contents. */\n data: Uint8Array | Buffer;\n /** Original filename, used for extension/display. */\n filename?: string;\n /** MIME type, e.g. \"image/png\". */\n mimeType?: string;\n /** Optional owner email for per-user scoping in fallback storage. */\n ownerEmail?: string;\n /** Builder.io upload hint: return
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/file-upload/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG","sourcesContent":["/**\n * File upload framework primitive.\n *\n * Templates call `uploadFile()` to upload a file and get back a URL.\n * The framework dispatches to whichever provider is registered (Builder.io\n * built-in, or a user-supplied one). If no provider is active, it falls back\n * to the SQL resources store — fine for dev, not recommended for production.\n */\n\nexport interface FileUploadInput {\n /** File contents. */\n data: Uint8Array | Buffer;\n /** Original filename, used for extension/display. */\n filename?: string;\n /** MIME type, e.g. \"image/png\". */\n mimeType?: string;\n /** Optional owner email for per-user scoping in fallback storage. */\n ownerEmail?: string;\n /** Builder.io upload hint: return one stable URL while compression finishes asynchronously. */\n stableUrl?: boolean;\n /** Builder.io upload hint: set false for internal artifacts that should not appear in the asset library. */\n recordAsset?: boolean;\n}\n\nexport interface FileUploadResult {\n /** Public URL where the file can be fetched. */\n url: string;\n /** Optional provider-specific id (e.g. resource id, Builder asset id). */\n id?: string;\n /** The provider that handled the upload. */\n provider: string;\n}\n\n/** Opaque session handle returned by {@link FileUploadProvider.resumable.startSession}.\n * `sessionId` is provider-specific (GCS Location URI, S3 UploadId, etc.).\n * `meta` holds any provider state needed for subsequent relay and complete calls. */\nexport interface ResumableUploadSession {\n sessionId: string;\n meta: Record<string, unknown>;\n}\n\nexport interface ResumableChunkResult {\n ok: boolean;\n status: number;\n /** Providers that need per-chunk state (e.g. S3 ETags) return updated meta\n * here; the chunk route merges it back into the stored session. */\n updatedMeta?: Record<string, unknown>;\n}\n\nexport interface FileUploadProvider {\n /** Unique id, e.g. \"builder\", \"s3\". */\n id: string;\n /** Human-readable name. */\n name: string;\n /** Returns true if this provider is configured from synchronous runtime state. */\n isConfigured: () => boolean;\n /**\n * Returns true if this provider is configured for the active request.\n * Use for DB-backed user/org/workspace secrets that require request context.\n */\n isConfiguredForRequest?: () => Promise<boolean>;\n /** Upload a file and return a URL. Throw on failure. */\n upload: (input: FileUploadInput) => Promise<FileUploadResult>;\n /**\n * Optional resumable/streaming upload capability.\n * When present, create-recording will initialise a session and stream chunks\n * during recording instead of assembling the full blob after stop().\n */\n resumable?: {\n startSession(\n filename: string,\n mimeType: string,\n maxBytes: number,\n ): Promise<ResumableUploadSession>;\n relayChunk(\n session: ResumableUploadSession,\n contentRange: string,\n bytes: Uint8Array,\n options?: { mimeType?: string },\n ): Promise<ResumableChunkResult>;\n completeSession(\n session: ResumableUploadSession,\n filename: string,\n options?: { stableUrl?: boolean; recordAsset?: boolean },\n ): Promise<string>;\n };\n}\n"]}
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -37,17 +37,17 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
|
|
|
37
37
|
ok?: undefined;
|
|
38
38
|
status?: undefined;
|
|
39
39
|
} | {
|
|
40
|
+
error?: undefined;
|
|
40
41
|
ok: boolean;
|
|
41
42
|
status: string;
|
|
42
|
-
error?: undefined;
|
|
43
43
|
} | {
|
|
44
44
|
ok?: undefined;
|
|
45
45
|
error: string;
|
|
46
46
|
removed?: undefined;
|
|
47
47
|
} | {
|
|
48
|
+
error?: undefined;
|
|
48
49
|
ok: boolean;
|
|
49
50
|
removed: boolean;
|
|
50
|
-
error?: undefined;
|
|
51
51
|
}>>;
|
|
52
52
|
/**
|
|
53
53
|
* POST /_agent-native/secrets/:key/test — re-run the validator against the
|
|
@@ -58,13 +58,13 @@ export declare function createTestSecretHandler(): import("h3").EventHandlerWith
|
|
|
58
58
|
error: string;
|
|
59
59
|
note?: undefined;
|
|
60
60
|
} | {
|
|
61
|
+
error?: undefined;
|
|
61
62
|
ok: boolean;
|
|
62
63
|
note?: undefined;
|
|
63
|
-
error?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
ok: boolean;
|
|
66
67
|
note: string;
|
|
67
|
-
error?: undefined;
|
|
68
68
|
} | {
|
|
69
69
|
note?: undefined;
|
|
70
70
|
ok: boolean;
|
|
@@ -95,12 +95,12 @@ export interface AdHocSecretPayload {
|
|
|
95
95
|
export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
|
|
96
96
|
error: string;
|
|
97
97
|
} | {
|
|
98
|
+
error?: undefined;
|
|
98
99
|
ok: boolean;
|
|
99
100
|
key: string;
|
|
100
|
-
error?: undefined;
|
|
101
101
|
} | {
|
|
102
|
+
error?: undefined;
|
|
102
103
|
ok: boolean;
|
|
103
104
|
removed: boolean;
|
|
104
|
-
error?: undefined;
|
|
105
105
|
}>>;
|
|
106
106
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -5,4 +5,5 @@ export declare function isReasoningEffort(value: unknown): value is ReasoningEff
|
|
|
5
5
|
export declare function getReasoningEffortOptionsForModel(model: string | undefined): ReasoningEffort[];
|
|
6
6
|
export declare function normalizeReasoningEffortForModel(model: string | undefined, effort: ReasoningEffort | undefined): ReasoningEffort | undefined;
|
|
7
7
|
export declare function reasoningEffortLabel(effort: ReasoningEffort | undefined): string;
|
|
8
|
+
export declare function stepDownReasoningEffort(effort: ReasoningEffort | undefined): ReasoningEffort | undefined;
|
|
8
9
|
//# sourceMappingURL=reasoning-effort.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning-effort.d.ts","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,YAC5B,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CASnE,CAAC;AA2BF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,eAAe,EAAE,CAcnB;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,eAAe,GAAG,SAAS,CAoB7B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,UAEvE"}
|
|
1
|
+
{"version":3,"file":"reasoning-effort.d.ts","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,YAC5B,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CASnE,CAAC;AA2BF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,eAAe,EAAE,CAcnB;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,eAAe,GAAG,SAAS,CAoB7B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,UAEvE;AAkBD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,eAAe,GAAG,SAAS,CAG7B"}
|
|
@@ -79,6 +79,24 @@ export function normalizeReasoningEffortForModel(model, effort) {
|
|
|
79
79
|
export function reasoningEffortLabel(effort) {
|
|
80
80
|
return REASONING_EFFORT_LABELS[effort ?? "auto"];
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* One tier down from each effort, stopping at "minimal" — "none"/"auto"
|
|
84
|
+
* (not really "tiers") and "minimal" itself are left unchanged. Used by the
|
|
85
|
+
* empty-final-response retry so a retried turn asks for meaningfully less
|
|
86
|
+
* reasoning instead of repeating the exact request that came back empty.
|
|
87
|
+
*/
|
|
88
|
+
const REASONING_EFFORT_STEP_DOWN = {
|
|
89
|
+
max: "xhigh",
|
|
90
|
+
xhigh: "high",
|
|
91
|
+
high: "medium",
|
|
92
|
+
medium: "low",
|
|
93
|
+
low: "minimal",
|
|
94
|
+
};
|
|
95
|
+
export function stepDownReasoningEffort(effort) {
|
|
96
|
+
if (!effort)
|
|
97
|
+
return effort;
|
|
98
|
+
return REASONING_EFFORT_STEP_DOWN[effort] ?? effort;
|
|
99
|
+
}
|
|
82
100
|
function isGPTReasoningModel(model) {
|
|
83
101
|
return /^gpt-5/.test(model) || /^o\d/.test(model);
|
|
84
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning-effort.js","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"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","sourcesContent":["export const REASONING_EFFORTS = [\n \"auto\",\n \"none\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const;\n\nexport type ReasoningEffort = (typeof REASONING_EFFORTS)[number];\n\nexport const REASONING_EFFORT_LABELS: Record<ReasoningEffort, string> = {\n auto: \"Auto\",\n none: \"None\",\n minimal: \"Minimal\",\n low: \"Low\",\n medium: \"Medium\",\n high: \"High\",\n xhigh: \"Extra High\",\n max: \"Max\",\n};\n\nconst VISIBLE_STANDARD_EFFORTS: ReasoningEffort[] = [\n \"auto\",\n \"low\",\n \"medium\",\n \"high\",\n];\n\nconst VISIBLE_GPT_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n];\n\nconst VISIBLE_CLAUDE_BUILT_IN_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n \"max\",\n];\n\nconst VISIBLE_CLAUDE_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"max\",\n];\n\nconst effortSet = new Set<string>(REASONING_EFFORTS);\n\nexport function isReasoningEffort(value: unknown): value is ReasoningEffort {\n return typeof value === \"string\" && effortSet.has(value);\n}\n\nexport function getReasoningEffortOptionsForModel(\n model: string | undefined,\n): ReasoningEffort[] {\n if (!model) return [];\n if (isGPTReasoningModel(model)) {\n return VISIBLE_GPT_EFFORTS;\n }\n if (isClaudeReasoningModel(model)) {\n return supportsClaudeXHigh(model)\n ? VISIBLE_CLAUDE_BUILT_IN_EFFORTS\n : VISIBLE_CLAUDE_EFFORTS;\n }\n if (isGeminiReasoningModel(model)) {\n return VISIBLE_STANDARD_EFFORTS;\n }\n return [];\n}\n\nexport function normalizeReasoningEffortForModel(\n model: string | undefined,\n effort: ReasoningEffort | undefined,\n): ReasoningEffort | undefined {\n if (!model || !effort || effort === \"auto\") {\n return undefined;\n }\n let normalized = effort;\n if (\n normalized === \"xhigh\" &&\n isClaudeReasoningModel(model) &&\n !supportsClaudeXHigh(model)\n ) {\n normalized = \"high\";\n }\n if (normalized === \"max\" && isGPTReasoningModel(model)) {\n normalized = \"xhigh\";\n }\n const options = getReasoningEffortOptionsForModel(model);\n if (!options.length || !options.includes(normalized)) {\n return undefined;\n }\n return normalized;\n}\n\nexport function reasoningEffortLabel(effort: ReasoningEffort | undefined) {\n return REASONING_EFFORT_LABELS[effort ?? \"auto\"];\n}\n\nfunction isGPTReasoningModel(model: string) {\n return /^gpt-5/.test(model) || /^o\\d/.test(model);\n}\n\nfunction isClaudeReasoningModel(model: string) {\n return /^claude-/.test(model);\n}\n\nfunction supportsClaudeXHigh(model: string) {\n // Models that support the xhigh effort tier (built-in extended thinking via\n // output_config.effort). Keep this version-aware so any future Claude model\n // with a higher patch/minor number is automatically included rather than\n // silently falling back to the lower \"high\" tier.\n // claude-fable-5 is a Mythos-class model and also supports xhigh.\n if (model.includes(\"fable-5\")) return true;\n // Sonnet 5 supports the expanded effort ladder through Builder/Anthropic.\n if (model.includes(\"sonnet-5\")) return true;\n // opus-4-7 introduced xhigh; all opus-4.x successors (4-8, 4-9…) should too.\n const opusMatch = model.match(/opus-4-(\\d+)/);\n if (opusMatch) {\n return parseInt(opusMatch[1], 10) >= 7;\n }\n return false;\n}\n\nfunction isGeminiReasoningModel(model: string) {\n return /^gemini-/.test(model);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reasoning-effort.js","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"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","sourcesContent":["export const REASONING_EFFORTS = [\n \"auto\",\n \"none\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const;\n\nexport type ReasoningEffort = (typeof REASONING_EFFORTS)[number];\n\nexport const REASONING_EFFORT_LABELS: Record<ReasoningEffort, string> = {\n auto: \"Auto\",\n none: \"None\",\n minimal: \"Minimal\",\n low: \"Low\",\n medium: \"Medium\",\n high: \"High\",\n xhigh: \"Extra High\",\n max: \"Max\",\n};\n\nconst VISIBLE_STANDARD_EFFORTS: ReasoningEffort[] = [\n \"auto\",\n \"low\",\n \"medium\",\n \"high\",\n];\n\nconst VISIBLE_GPT_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n];\n\nconst VISIBLE_CLAUDE_BUILT_IN_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n \"max\",\n];\n\nconst VISIBLE_CLAUDE_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"max\",\n];\n\nconst effortSet = new Set<string>(REASONING_EFFORTS);\n\nexport function isReasoningEffort(value: unknown): value is ReasoningEffort {\n return typeof value === \"string\" && effortSet.has(value);\n}\n\nexport function getReasoningEffortOptionsForModel(\n model: string | undefined,\n): ReasoningEffort[] {\n if (!model) return [];\n if (isGPTReasoningModel(model)) {\n return VISIBLE_GPT_EFFORTS;\n }\n if (isClaudeReasoningModel(model)) {\n return supportsClaudeXHigh(model)\n ? VISIBLE_CLAUDE_BUILT_IN_EFFORTS\n : VISIBLE_CLAUDE_EFFORTS;\n }\n if (isGeminiReasoningModel(model)) {\n return VISIBLE_STANDARD_EFFORTS;\n }\n return [];\n}\n\nexport function normalizeReasoningEffortForModel(\n model: string | undefined,\n effort: ReasoningEffort | undefined,\n): ReasoningEffort | undefined {\n if (!model || !effort || effort === \"auto\") {\n return undefined;\n }\n let normalized = effort;\n if (\n normalized === \"xhigh\" &&\n isClaudeReasoningModel(model) &&\n !supportsClaudeXHigh(model)\n ) {\n normalized = \"high\";\n }\n if (normalized === \"max\" && isGPTReasoningModel(model)) {\n normalized = \"xhigh\";\n }\n const options = getReasoningEffortOptionsForModel(model);\n if (!options.length || !options.includes(normalized)) {\n return undefined;\n }\n return normalized;\n}\n\nexport function reasoningEffortLabel(effort: ReasoningEffort | undefined) {\n return REASONING_EFFORT_LABELS[effort ?? \"auto\"];\n}\n\n/**\n * One tier down from each effort, stopping at \"minimal\" — \"none\"/\"auto\"\n * (not really \"tiers\") and \"minimal\" itself are left unchanged. Used by the\n * empty-final-response retry so a retried turn asks for meaningfully less\n * reasoning instead of repeating the exact request that came back empty.\n */\nconst REASONING_EFFORT_STEP_DOWN: Partial<\n Record<ReasoningEffort, ReasoningEffort>\n> = {\n max: \"xhigh\",\n xhigh: \"high\",\n high: \"medium\",\n medium: \"low\",\n low: \"minimal\",\n};\n\nexport function stepDownReasoningEffort(\n effort: ReasoningEffort | undefined,\n): ReasoningEffort | undefined {\n if (!effort) return effort;\n return REASONING_EFFORT_STEP_DOWN[effort] ?? effort;\n}\n\nfunction isGPTReasoningModel(model: string) {\n return /^gpt-5/.test(model) || /^o\\d/.test(model);\n}\n\nfunction isClaudeReasoningModel(model: string) {\n return /^claude-/.test(model);\n}\n\nfunction supportsClaudeXHigh(model: string) {\n // Models that support the xhigh effort tier (built-in extended thinking via\n // output_config.effort). Keep this version-aware so any future Claude model\n // with a higher patch/minor number is automatically included rather than\n // silently falling back to the lower \"high\" tier.\n // claude-fable-5 is a Mythos-class model and also supports xhigh.\n if (model.includes(\"fable-5\")) return true;\n // Sonnet 5 supports the expanded effort ladder through Builder/Anthropic.\n if (model.includes(\"sonnet-5\")) return true;\n // opus-4-7 introduced xhigh; all opus-4.x successors (4-8, 4-9…) should too.\n const opusMatch = model.match(/opus-4-(\\d+)/);\n if (opusMatch) {\n return parseInt(opusMatch[1], 10) >= 7;\n }\n return false;\n}\n\nfunction isGeminiReasoningModel(model: string) {\n return /^gemini-/.test(model);\n}\n"]}
|
package/dist/styles/blocks.css
CHANGED
|
@@ -1007,6 +1007,13 @@
|
|
|
1007
1007
|
min-height: 100%;
|
|
1008
1008
|
}
|
|
1009
1009
|
|
|
1010
|
+
.plan-html-frame[data-frame="hide"]:not([data-render-mode="design"])
|
|
1011
|
+
> .plan-html-frame-content
|
|
1012
|
+
> :first-child {
|
|
1013
|
+
margin: 0 !important;
|
|
1014
|
+
padding: 0 !important;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1010
1017
|
.plan-html-frame[data-prototype-live="true"] {
|
|
1011
1018
|
overflow: auto;
|
|
1012
1019
|
}
|
|
@@ -21,7 +21,7 @@ being rebuilt in slightly different ways every time.
|
|
|
21
21
|
<Screen
|
|
22
22
|
surface="desktop"
|
|
23
23
|
html={
|
|
24
|
-
"<div style='min-height:560px;box-sizing:border-box;
|
|
24
|
+
"<div style='min-height:560px;box-sizing:border-box;display:grid;grid-template-columns:200px 1fr 280px;gap:16px'><aside class='wf-card' style='display:flex;flex-direction:column;gap:8px;padding:14px'><div style='display:flex;align-items:center;gap:8px'><div style='width:26px;height:26px;border-radius:8px;background:var(--wf-accent-soft);display:flex;align-items:center;justify-content:center;font-size:12px;flex:none'>A</div><strong style='flex:1'>Acme</strong><span data-icon='chevronDown'></span></div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;background:var(--wf-accent-soft)'><span data-icon='search'></span> Home</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='edit'></span> Documents</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='user'></span> Team</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='settings'></span> Settings</div><div style='flex:1'></div><div style='display:flex;align-items:center;gap:8px;padding-top:10px;border-top:1.4px solid var(--wf-line)'><div style='width:24px;height:24px;border-radius:999px;background:var(--wf-accent-soft);flex:none'></div><small style='flex:1'>Steve</small><span data-icon='dots'></span></div></aside><main class='wf-card' style='display:flex;flex-direction:column;gap:14px'><div style='display:flex;align-items:center;gap:10px'><h2 style='margin:0'>Q3 Forecast</h2><div style='flex:1'></div><div style='display:flex'><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div></div><button class='primary'><span data-icon='user'></span> Share</button></div><div class='wf-box' style='display:flex;flex-direction:column;gap:10px'><small class='wf-muted'>Revenue by month</small><div style='display:flex;align-items:flex-end;gap:10px;height:120px'><div style='flex:1;height:45%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:65%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:55%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:80%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:95%;background:var(--wf-accent);border-radius:4px'></div></div></div><div style='display:flex;gap:10px'><div class='wf-box' style='flex:1'><small class='wf-muted'>ARR</small><br/><strong>$4.2M</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Win rate</small><br/><strong>28%</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Pipeline</small><br/><strong>3.2x</strong></div></div></main><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Agent</strong><div class='wf-box'>Summarize Q3 versus Q2 and flag risks.</div><div class='wf-box' style='background:var(--wf-accent-soft)'>Revenue up 12%. Two pipeline risks flagged.</div><div style='flex:1'></div><div class='wf-card' style='padding:10px;display:flex;flex-direction:column;gap:8px'><span class='wf-muted'>Ask about this dashboard...</span><div style='display:flex;align-items:center;gap:6px'><span class='wf-pill'>Q3 Forecast</span><span class='wf-pill'>GPT-5</span><div style='flex:1'></div><button class='primary'><span data-icon='send'></span></button></div></div></aside></div>"
|
|
25
25
|
}
|
|
26
26
|
/>
|
|
27
27
|
</WireframeBlock>
|
|
@@ -23,7 +23,7 @@ being rebuilt in slightly different ways every time.
|
|
|
23
23
|
<Screen
|
|
24
24
|
surface="desktop"
|
|
25
25
|
html={
|
|
26
|
-
"<div style='min-height:560px;box-sizing:border-box;
|
|
26
|
+
"<div style='min-height:560px;box-sizing:border-box;display:grid;grid-template-columns:200px 1fr 280px;gap:16px'><aside class='wf-card' style='display:flex;flex-direction:column;gap:8px;padding:14px'><div style='display:flex;align-items:center;gap:8px'><div style='width:26px;height:26px;border-radius:8px;background:var(--wf-accent-soft);display:flex;align-items:center;justify-content:center;font-size:12px;flex:none'>A</div><strong style='flex:1'>Acme</strong><span data-icon='chevronDown'></span></div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;background:var(--wf-accent-soft)'><span data-icon='search'></span> Home</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='edit'></span> Documents</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='user'></span> Team</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='settings'></span> Settings</div><div style='flex:1'></div><div style='display:flex;align-items:center;gap:8px;padding-top:10px;border-top:1.4px solid var(--wf-line)'><div style='width:24px;height:24px;border-radius:999px;background:var(--wf-accent-soft);flex:none'></div><small style='flex:1'>Steve</small><span data-icon='dots'></span></div></aside><main class='wf-card' style='display:flex;flex-direction:column;gap:14px'><div style='display:flex;align-items:center;gap:10px'><h2 style='margin:0'>Q3 Forecast</h2><div style='flex:1'></div><div style='display:flex'><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div></div><button class='primary'><span data-icon='user'></span> Share</button></div><div class='wf-box' style='display:flex;flex-direction:column;gap:10px'><small class='wf-muted'>Revenue by month</small><div style='display:flex;align-items:flex-end;gap:10px;height:120px'><div style='flex:1;height:45%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:65%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:55%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:80%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:95%;background:var(--wf-accent);border-radius:4px'></div></div></div><div style='display:flex;gap:10px'><div class='wf-box' style='flex:1'><small class='wf-muted'>ARR</small><br/><strong>$4.2M</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Win rate</small><br/><strong>28%</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Pipeline</small><br/><strong>3.2x</strong></div></div></main><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Agent</strong><div class='wf-box'>Summarize Q3 versus Q2 and flag risks.</div><div class='wf-box' style='background:var(--wf-accent-soft)'>Revenue up 12%. Two pipeline risks flagged.</div><div style='flex:1'></div><div class='wf-card' style='padding:10px;display:flex;flex-direction:column;gap:8px'><span class='wf-muted'>Ask about this dashboard...</span><div style='display:flex;align-items:center;gap:6px'><span class='wf-pill'>Q3 Forecast</span><span class='wf-pill'>GPT-5</span><div style='flex:1'></div><button class='primary'><span data-icon='send'></span></button></div></div></aside></div>"
|
|
27
27
|
}
|
|
28
28
|
/>
|
|
29
29
|
</WireframeBlock>
|
|
@@ -200,7 +200,7 @@ configureTracking({
|
|
|
200
200
|
endpoint: "https://analytics.example.com/api/analytics/track",
|
|
201
201
|
sessionReplay: {
|
|
202
202
|
enabled: true,
|
|
203
|
-
sampleRate:
|
|
203
|
+
sampleRate: 1,
|
|
204
204
|
},
|
|
205
205
|
getDefaultProps: (_event, props) => ({
|
|
206
206
|
...props,
|
|
@@ -218,14 +218,14 @@ configureTracking({
|
|
|
218
218
|
VITE_AGENT_NATIVE_ANALYTICS_PUBLIC_KEY=anpk_...
|
|
219
219
|
VITE_AGENT_NATIVE_ANALYTICS_ENDPOINT=https://analytics.example.com/api/analytics/track
|
|
220
220
|
VITE_AGENT_NATIVE_SESSION_REPLAY_ENABLED=true
|
|
221
|
-
VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=
|
|
221
|
+
VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=1
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
يقوم مساعد المتصفح أيضًا بإجراء قراءة غير محظِّرة وبأفضل جهد ممكن لجلسة مصادقة Agent Native الحالية. إعادة التشغيل مخصصة لتسجيل الدخول فقط بشكل افتراضي: عندما يكون `sessionReplay` مفعّلاً، لا يبدأ التسجيل ما لم تُحلّ الجلسة إلى عنوان بريد إلكتروني لمستخدم. تتضمن إعادة تشغيل الجلسات المسجَّلة `userId`/`userEmail` المدعومين بالبريد الإلكتروني بالإضافة إلى `orgId`.
|
|
225
225
|
|
|
226
226
|
اضبط `sessionReplay.requireSignedInUser: false` أو `VITE_AGENT_NATIVE_SESSION_REPLAY_REQUIRE_AUTH=false` فقط من أجل نشر إعادة تشغيل مجهولة الهوية مقصود. عندما يتم تعطيل تحكم المصادقة، تظل التسجيلات المجهولة قابلة للاستعلام حسب الزائر المجهول، والجلسة، والتطبيق/القالب، واسم المضيف، والمسار.
|
|
227
227
|
|
|
228
|
-
يتم أخذ عينات من إعادة تشغيل الجلسة بشكل حتمي لكل جلسة متصفح. يقوم `sampleRate` بقيمة `
|
|
228
|
+
يتم أخذ عينات من إعادة تشغيل الجلسة بشكل حتمي لكل جلسة متصفح. يقوم `sampleRate` بقيمة `1` بتسجيل جميع الجلسات المؤهلة؛ استخدم قيمًا أقل، مثل `0.1`، عندما تكون المجموعة المؤهلة واسعة عن قصد.
|
|
229
229
|
|
|
230
230
|
إعدادات الخصوصية الافتراضية متحفظة عن قصد لكنها لا تزال مفيدة لإعادة التشغيل:
|
|
231
231
|
|
|
@@ -23,7 +23,7 @@ being rebuilt in slightly different ways every time.
|
|
|
23
23
|
<Screen
|
|
24
24
|
surface="desktop"
|
|
25
25
|
html={
|
|
26
|
-
"<div style='min-height:560px;box-sizing:border-box;
|
|
26
|
+
"<div style='min-height:560px;box-sizing:border-box;display:grid;grid-template-columns:200px 1fr 280px;gap:16px'><aside class='wf-card' style='display:flex;flex-direction:column;gap:8px;padding:14px'><div style='display:flex;align-items:center;gap:8px'><div style='width:26px;height:26px;border-radius:8px;background:var(--wf-accent-soft);display:flex;align-items:center;justify-content:center;font-size:12px;flex:none'>A</div><strong style='flex:1'>Acme</strong><span data-icon='chevronDown'></span></div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;background:var(--wf-accent-soft)'><span data-icon='search'></span> Home</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='edit'></span> Documents</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='user'></span> Team</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='settings'></span> Settings</div><div style='flex:1'></div><div style='display:flex;align-items:center;gap:8px;padding-top:10px;border-top:1.4px solid var(--wf-line)'><div style='width:24px;height:24px;border-radius:999px;background:var(--wf-accent-soft);flex:none'></div><small style='flex:1'>Steve</small><span data-icon='dots'></span></div></aside><main class='wf-card' style='display:flex;flex-direction:column;gap:14px'><div style='display:flex;align-items:center;gap:10px'><h2 style='margin:0'>Q3 Forecast</h2><div style='flex:1'></div><div style='display:flex'><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div></div><button class='primary'><span data-icon='user'></span> Share</button></div><div class='wf-box' style='display:flex;flex-direction:column;gap:10px'><small class='wf-muted'>Revenue by month</small><div style='display:flex;align-items:flex-end;gap:10px;height:120px'><div style='flex:1;height:45%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:65%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:55%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:80%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:95%;background:var(--wf-accent);border-radius:4px'></div></div></div><div style='display:flex;gap:10px'><div class='wf-box' style='flex:1'><small class='wf-muted'>ARR</small><br/><strong>$4.2M</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Win rate</small><br/><strong>28%</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Pipeline</small><br/><strong>3.2x</strong></div></div></main><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Agent</strong><div class='wf-box'>Summarize Q3 versus Q2 and flag risks.</div><div class='wf-box' style='background:var(--wf-accent-soft)'>Revenue up 12%. Two pipeline risks flagged.</div><div style='flex:1'></div><div class='wf-card' style='padding:10px;display:flex;flex-direction:column;gap:8px'><span class='wf-muted'>Ask about this dashboard...</span><div style='display:flex;align-items:center;gap:6px'><span class='wf-pill'>Q3 Forecast</span><span class='wf-pill'>GPT-5</span><div style='flex:1'></div><button class='primary'><span data-icon='send'></span></button></div></div></aside></div>"
|
|
27
27
|
}
|
|
28
28
|
/>
|
|
29
29
|
</WireframeBlock>
|
|
@@ -200,7 +200,7 @@ configureTracking({
|
|
|
200
200
|
endpoint: "https://analytics.example.com/api/analytics/track",
|
|
201
201
|
sessionReplay: {
|
|
202
202
|
enabled: true,
|
|
203
|
-
sampleRate:
|
|
203
|
+
sampleRate: 1,
|
|
204
204
|
},
|
|
205
205
|
getDefaultProps: (_event, props) => ({
|
|
206
206
|
...props,
|
|
@@ -218,14 +218,14 @@ Agent-Native-Template-Roots rufen `configureTracking()` bereits auf. Gehostete T
|
|
|
218
218
|
VITE_AGENT_NATIVE_ANALYTICS_PUBLIC_KEY=anpk_...
|
|
219
219
|
VITE_AGENT_NATIVE_ANALYTICS_ENDPOINT=https://analytics.example.com/api/analytics/track
|
|
220
220
|
VITE_AGENT_NATIVE_SESSION_REPLAY_ENABLED=true
|
|
221
|
-
VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=
|
|
221
|
+
VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=1
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
Der Browser-Helfer führt außerdem einen nach bestem Bemühen erfolgenden, nicht blockierenden Lesevorgang der aktuellen Agent-Native-Auth-Sitzung durch. Replay ist standardmäßig nur für angemeldete Benutzer verfügbar: Wenn `sessionReplay` aktiviert ist, startet die Aufzeichnung nur, wenn die Sitzung zu einer Benutzer-E-Mail-Adresse aufgelöst werden kann. Replays angemeldeter Benutzer enthalten E-Mail-basierte `userId`/`userEmail` sowie `orgId`.
|
|
225
225
|
|
|
226
226
|
Setzen Sie `sessionReplay.requireSignedInUser: false` oder `VITE_AGENT_NATIVE_SESSION_REPLAY_REQUIRE_AUTH=false` nur für ein absichtlich anonymes Replay-Deployment. Wenn die Auth-Prüfung deaktiviert ist, bleiben anonyme Aufzeichnungen nach anonymem Besucher, Sitzung, App/Template, Hostname und Pfad abfragbar.
|
|
227
227
|
|
|
228
|
-
Session Replay wird deterministisch pro Browser-Sitzung gesampelt. Eine `sampleRate` von `
|
|
228
|
+
Session Replay wird deterministisch pro Browser-Sitzung gesampelt. Eine `sampleRate` von `1` zeichnet alle infrage kommenden Sitzungen auf; verwenden Sie niedrigere Werte wie `0.1`, wenn die infrage kommende Population absichtlich breit ist.
|
|
229
229
|
|
|
230
230
|
Die Datenschutz-Standardeinstellungen sind bewusst konservativ, aber für die Wiedergabe weiterhin nützlich:
|
|
231
231
|
|
|
@@ -23,7 +23,7 @@ being rebuilt in slightly different ways every time.
|
|
|
23
23
|
<Screen
|
|
24
24
|
surface="desktop"
|
|
25
25
|
html={
|
|
26
|
-
"<div style='min-height:560px;box-sizing:border-box;
|
|
26
|
+
"<div style='min-height:560px;box-sizing:border-box;display:grid;grid-template-columns:200px 1fr 280px;gap:16px'><aside class='wf-card' style='display:flex;flex-direction:column;gap:8px;padding:14px'><div style='display:flex;align-items:center;gap:8px'><div style='width:26px;height:26px;border-radius:8px;background:var(--wf-accent-soft);display:flex;align-items:center;justify-content:center;font-size:12px;flex:none'>A</div><strong style='flex:1'>Acme</strong><span data-icon='chevronDown'></span></div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;background:var(--wf-accent-soft)'><span data-icon='search'></span> Home</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='edit'></span> Documents</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='user'></span> Team</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='settings'></span> Settings</div><div style='flex:1'></div><div style='display:flex;align-items:center;gap:8px;padding-top:10px;border-top:1.4px solid var(--wf-line)'><div style='width:24px;height:24px;border-radius:999px;background:var(--wf-accent-soft);flex:none'></div><small style='flex:1'>Steve</small><span data-icon='dots'></span></div></aside><main class='wf-card' style='display:flex;flex-direction:column;gap:14px'><div style='display:flex;align-items:center;gap:10px'><h2 style='margin:0'>Q3 Forecast</h2><div style='flex:1'></div><div style='display:flex'><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div></div><button class='primary'><span data-icon='user'></span> Share</button></div><div class='wf-box' style='display:flex;flex-direction:column;gap:10px'><small class='wf-muted'>Revenue by month</small><div style='display:flex;align-items:flex-end;gap:10px;height:120px'><div style='flex:1;height:45%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:65%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:55%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:80%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:95%;background:var(--wf-accent);border-radius:4px'></div></div></div><div style='display:flex;gap:10px'><div class='wf-box' style='flex:1'><small class='wf-muted'>ARR</small><br/><strong>$4.2M</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Win rate</small><br/><strong>28%</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Pipeline</small><br/><strong>3.2x</strong></div></div></main><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Agent</strong><div class='wf-box'>Summarize Q3 versus Q2 and flag risks.</div><div class='wf-box' style='background:var(--wf-accent-soft)'>Revenue up 12%. Two pipeline risks flagged.</div><div style='flex:1'></div><div class='wf-card' style='padding:10px;display:flex;flex-direction:column;gap:8px'><span class='wf-muted'>Ask about this dashboard...</span><div style='display:flex;align-items:center;gap:6px'><span class='wf-pill'>Q3 Forecast</span><span class='wf-pill'>GPT-5</span><div style='flex:1'></div><button class='primary'><span data-icon='send'></span></button></div></div></aside></div>"
|
|
27
27
|
}
|
|
28
28
|
/>
|
|
29
29
|
</WireframeBlock>
|
|
@@ -200,7 +200,7 @@ configureTracking({
|
|
|
200
200
|
endpoint: "https://analytics.example.com/api/analytics/track",
|
|
201
201
|
sessionReplay: {
|
|
202
202
|
enabled: true,
|
|
203
|
-
sampleRate:
|
|
203
|
+
sampleRate: 1,
|
|
204
204
|
},
|
|
205
205
|
getDefaultProps: (_event, props) => ({
|
|
206
206
|
...props,
|
|
@@ -218,14 +218,14 @@ Las raíces de las plantillas de Agent Native ya llaman a `configureTracking()`.
|
|
|
218
218
|
VITE_AGENT_NATIVE_ANALYTICS_PUBLIC_KEY=anpk_...
|
|
219
219
|
VITE_AGENT_NATIVE_ANALYTICS_ENDPOINT=https://analytics.example.com/api/analytics/track
|
|
220
220
|
VITE_AGENT_NATIVE_SESSION_REPLAY_ENABLED=true
|
|
221
|
-
VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=
|
|
221
|
+
VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=1
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
El ayudante del navegador también realiza una lectura sin bloqueo y de mejor esfuerzo de la sesión de autenticación actual de Agent Native. La repetición es solo para usuarios con sesión iniciada de forma predeterminada: cuando `sessionReplay` está habilitado, la grabación no se inicia a menos que la sesión se resuelva en una dirección de correo electrónico de usuario. Las repeticiones de usuarios con sesión iniciada incluyen `userId`/`userEmail` respaldados por correo electrónico más `orgId`.
|
|
225
225
|
|
|
226
226
|
Configure `sessionReplay.requireSignedInUser: false` o `VITE_AGENT_NATIVE_SESSION_REPLAY_REQUIRE_AUTH=false` solo para una implementación de repetición anónima intencional. Cuando la restricción de autenticación está deshabilitada, las grabaciones anónimas siguen siendo consultables por visitante anónimo, sesión, aplicación/plantilla, nombre de host y ruta.
|
|
227
227
|
|
|
228
|
-
La repetición de sesión se muestrea de forma determinista por sesión de navegador. Un `sampleRate` de `
|
|
228
|
+
La repetición de sesión se muestrea de forma determinista por sesión de navegador. Un `sampleRate` de `1` graba todas las sesiones elegibles; use valores más bajos, como `0.1`, cuando la población elegible sea intencionalmente amplia.
|
|
229
229
|
|
|
230
230
|
Los valores predeterminados de privacidad son intencionalmente conservadores pero siguen siendo útiles para la reproducción:
|
|
231
231
|
|
|
@@ -23,7 +23,7 @@ being rebuilt in slightly different ways every time.
|
|
|
23
23
|
<Screen
|
|
24
24
|
surface="desktop"
|
|
25
25
|
html={
|
|
26
|
-
"<div style='min-height:560px;box-sizing:border-box;
|
|
26
|
+
"<div style='min-height:560px;box-sizing:border-box;display:grid;grid-template-columns:200px 1fr 280px;gap:16px'><aside class='wf-card' style='display:flex;flex-direction:column;gap:8px;padding:14px'><div style='display:flex;align-items:center;gap:8px'><div style='width:26px;height:26px;border-radius:8px;background:var(--wf-accent-soft);display:flex;align-items:center;justify-content:center;font-size:12px;flex:none'>A</div><strong style='flex:1'>Acme</strong><span data-icon='chevronDown'></span></div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;background:var(--wf-accent-soft)'><span data-icon='search'></span> Home</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='edit'></span> Documents</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='user'></span> Team</div><div style='display:flex;align-items:center;gap:8px;padding:7px 9px'><span data-icon='settings'></span> Settings</div><div style='flex:1'></div><div style='display:flex;align-items:center;gap:8px;padding-top:10px;border-top:1.4px solid var(--wf-line)'><div style='width:24px;height:24px;border-radius:999px;background:var(--wf-accent-soft);flex:none'></div><small style='flex:1'>Steve</small><span data-icon='dots'></span></div></aside><main class='wf-card' style='display:flex;flex-direction:column;gap:14px'><div style='display:flex;align-items:center;gap:10px'><h2 style='margin:0'>Q3 Forecast</h2><div style='flex:1'></div><div style='display:flex'><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent-soft);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div><div style='width:26px;height:26px;border-radius:999px;background:var(--wf-accent);border:2px solid var(--wf-card);margin-left:-8px;flex:none'></div></div><button class='primary'><span data-icon='user'></span> Share</button></div><div class='wf-box' style='display:flex;flex-direction:column;gap:10px'><small class='wf-muted'>Revenue by month</small><div style='display:flex;align-items:flex-end;gap:10px;height:120px'><div style='flex:1;height:45%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:65%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:55%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:80%;background:var(--wf-accent-soft);border-radius:4px'></div><div style='flex:1;height:95%;background:var(--wf-accent);border-radius:4px'></div></div></div><div style='display:flex;gap:10px'><div class='wf-box' style='flex:1'><small class='wf-muted'>ARR</small><br/><strong>$4.2M</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Win rate</small><br/><strong>28%</strong></div><div class='wf-box' style='flex:1'><small class='wf-muted'>Pipeline</small><br/><strong>3.2x</strong></div></div></main><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Agent</strong><div class='wf-box'>Summarize Q3 versus Q2 and flag risks.</div><div class='wf-box' style='background:var(--wf-accent-soft)'>Revenue up 12%. Two pipeline risks flagged.</div><div style='flex:1'></div><div class='wf-card' style='padding:10px;display:flex;flex-direction:column;gap:8px'><span class='wf-muted'>Ask about this dashboard...</span><div style='display:flex;align-items:center;gap:6px'><span class='wf-pill'>Q3 Forecast</span><span class='wf-pill'>GPT-5</span><div style='flex:1'></div><button class='primary'><span data-icon='send'></span></button></div></div></aside></div>"
|
|
27
27
|
}
|
|
28
28
|
/>
|
|
29
29
|
</WireframeBlock>
|