@webskill/chatbot 0.11.0 → 0.13.0

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/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { AgentLoopConfig, ApprovalScope, BridgeCapabilities, DataSourceInfo, DocxTextExtractor, ExternalSkillProvider, ExternalToolSource, FileSystemProvider, HookRunner, InteractionRequest, InteractionResponse, LifecycleEventInit, LinkedDocumentReader, LlmClient, NetworkPolicy, Page, PageQuery, PdfTextExtractor, RenderBlock, RenderResultRequest, RunSnapshot, RunSnapshotListEntry, RuntimePhase, RuntimeRun, ScriptExecutor, SessionStore, SkillCandidateMarker, SkillCatalogEntry, SkillIntegrityGuard, SkillOutcomeReporter, SkillStateGuard, UiBridge, UiSpecDrafts, UiSpecEvent, UiSpecSnapshot, UiSurfaceActionRequest, UiSurfaceActionResponse, UserProfile, UserProfileExport, WebSkillErrorCode, XlsxTextExtractor, diffUserProfile } from "@webskill/sdk";
1
+ import { AgentLoopConfig, ApprovalScope, BridgeCapabilities, DataSourceInfo, DocumentSurfaceHost, DocxTextExtractor, ExternalSkillProvider, ExternalToolSource, FileSystemProvider, HookRunner, InteractionRequest, InteractionResponse, LifecycleEventInit, LinkedDocumentReader, LlmClient, NetworkPolicy, Page, PageQuery, PdfTextExtractor, RenderBlock, RenderResultRequest, RunSnapshot, RunSnapshotListEntry, RuntimePhase, RuntimeRun, ScriptExecutor, SessionStore, SkillCandidateMarker, SkillCatalogEntry, SkillIntegrityGuard, SkillOutcomeReporter, SkillStateGuard, UiBridge, UiSpecDrafts, UiSpecEvent, UiSpecSnapshot, UiSurfaceActionRequest, UiSurfaceActionResponse, UserProfile, UserProfileExport, WebSkillErrorCode, XlsxTextExtractor, diffUserProfile } from "@webskill/sdk";
2
2
  import { SandboxMode, TypeScriptSupportOptions } from "@webskill/sdk/browser";
3
3
  import { CustomSurfaceActionEvent, ReactBridgeState, SpecInteractionChannel, SurfaceRegistry, UiSurfaceActionEvent } from "@webskill/sdk/ui-react";
4
- import { DownloadedFileConsent, DownloadedFileReader, PageActionPolicy, PagePerceptionPolicy, PerceptionPagingBudget, PerceptionRecord, SkillCandidateSink, TodoItem } from "@webskill/sdk/agent";
4
+ import { DownloadedFileConsent, DownloadedFileReader, PageActionPolicy, PagePerceptionPolicy, PerceptionPagingBudget, PerceptionRecord, SkillCandidateSink, TabWorksetPolicy, TodoItem } from "@webskill/sdk/agent";
5
5
  import "react";
6
6
  import "react/jsx-runtime";
7
7
  //#region ../ui-kit/src/i18n/types.d.ts
@@ -57,6 +57,23 @@ interface DataSourceInfo$1 {
57
57
  provenance?: 'page-declared' | 'tool-projection';
58
58
  }
59
59
  //#endregion
60
+ //#region ../runtime/src/interaction/documentSurface.d.ts
61
+ /**
62
+ * 渲染侧端口;由 chatbot 装配,`undefined` 表示本宿主没有文档面(按钮整个不渲染)。
63
+ *
64
+ * 收的是**产物文件名**,不是路径:路径由引擎按 run 拼出并做包含校验,
65
+ * 让声明树给完整路径等于凭空开一个读取面。
66
+ * @experimental
67
+ */
68
+ interface DocumentSurfacePort {
69
+ open(request: {
70
+ runId: string;
71
+ artifact: string;
72
+ style?: string;
73
+ dataSource: string;
74
+ }): Promise<void>;
75
+ }
76
+ //#endregion
60
77
  //#region ../runtime/src/sandbox/bridgeProtocol.d.ts
61
78
  /**
62
79
  * 能力模式:true 直通 / false 关闭(TOOL_UNSUPPORTED)/ 'require-approval' 调用前强制授权
@@ -201,6 +218,18 @@ interface RuntimeSandboxConfig {
201
218
  * 而本能力的「需批准」是恒定的,放进去会凭空多出一个「开且不批准」的非法组合。
202
219
  */
203
220
  downloadedFiles: boolean;
221
+ /**
222
+ * 让技能脚本读用户本轮上传的文件(0.15.0 分册 17)。缺省 `false`。
223
+ *
224
+ * **不放进 `capabilities`**,理由同 `downloadedFiles`:本能力的「需批准」是恒定的。
225
+ * 关闭时脚本上下文里连那两个成员都不存在,而不是存在但总失败。
226
+ */
227
+ uploadFiles: boolean;
228
+ /**
229
+ * 单个上传文件交给脚本的字节上限(分册 17)。超出即拒,**不截断**
230
+ * ——截一半的 xlsx / 图片解不开,而脚本看不出它残缺。
231
+ */
232
+ maxUploadFileBytes: number;
204
233
  }
205
234
  /**
206
235
  * 只做类型擦除,不做类型检查。`esbuildUrl` 为绝对 http(s) 地址时按 `remoteUrl` 判定;
@@ -477,6 +506,15 @@ interface ChatbotHostAdapter {
477
506
  * @experimental
478
507
  */
479
508
  pageActions?: PageActionPolicy;
509
+ /**
510
+ * 模型侧标签页控制(0.16.0 分册 12)。**不注入即三个工具不存在**。
511
+ *
512
+ * 与 `pageActions` 分开给,是因为它们的实现依赖不同:前者只需一条页面通道,
513
+ * 后者需要宿主真的能枚举与关闭标签页。但它们的**开关**是同一个:
514
+ * 策略自己以 `pageActions.enabled` 为前提,不能操作页面的会话里切页没有意义。
515
+ * @experimental
516
+ */
517
+ pageTabs?: TabWorksetPolicy;
480
518
  /**
481
519
  * 读页面链接指向的文档(分册 22)。实现住在 `@webskill/browser`,
482
520
  * 而 chatbot 不依赖它 —— 与 `pagePerception` 同一条装配规矩:宿主注入。
@@ -492,7 +530,7 @@ interface ChatbotHostAdapter {
492
530
  * PDF 仍然默认直传,能读的端点拿到的还是原件;不注入即没有回退能力。
493
531
  */
494
532
  pdfExtractor?: PdfTextExtractor;
495
- /** 文档读取留痕出口(FR-22.6 */
533
+ /** 文档读取留痕出口(FR-22.6);分册 17 的 `upload.file.read` 也走这条 */
496
534
  documentAudit?: {
497
535
  append(event: {
498
536
  type: string;
@@ -513,6 +551,15 @@ interface ChatbotHostAdapter {
513
551
  /** 「不再询问」的记忆端口;不注入即每次都问 */
514
552
  consent?: DownloadedFileConsent;
515
553
  };
554
+ /**
555
+ * 文档投放面(0.15.0 分册 13)。宿主交出 viewer 页地址、投放前确认与审计出口,
556
+ * 三件都在 `createDocumentSurfaceHost` 的选项里。
557
+ *
558
+ * **不注入即 `OpenDocument` 按钮整个不渲染**——与 `pagePerception` 同一条装配规矩,
559
+ * 设置抽屉里没有也不会有开关。技能可经 `context.documentSurface` 提前探测。
560
+ * @experimental
561
+ */
562
+ documentSurface?: DocumentSurfaceHost;
516
563
  }
517
564
  //#endregion
518
565
  //#region src/core/chatEngine.d.ts
@@ -646,6 +693,16 @@ declare class ChatEngine {
646
693
  setRenderer(renderer: RendererKind): void;
647
694
  /** 非 native 三档共用的交互通道(Chatbot 的 SpecInteraction 订阅/attach;core 只产出 catalog 节点树) */
648
695
  get interactionChannel(): SpecInteractionChannel;
696
+ /**
697
+ * 文档投放端口(0.15.0 分册 13)。宿主没注入 `adapter.documentSurface` 时为 `undefined`,
698
+ * 渲染侧据此整个不渲染按钮。
699
+ *
700
+ * 端口实现落在引擎里而不是宿主里,是因为「产物在哪、技能叫什么」这两件事只有引擎知道:
701
+ * 交给宿主就等于把产物目录布局变成宿主必须复刻的知识,两个宿主各抄一份必然分叉,
702
+ * 而那正是本册要消灭的东西。
703
+ * @experimental
704
+ */
705
+ get documentSurface(): DocumentSurfacePort | undefined;
649
706
  /** 探测 @a2ui/lit 是否安装(Appearance/设置区 A2UI 档置灰判定) */
650
707
  probeA2uiAvailability(): Promise<boolean>;
651
708
  onEvent(listener: (event: ChatEvent) => void): () => void;
@@ -1435,15 +1492,19 @@ declare const chatbotDictionary: {
1435
1492
  'interaction.pageAction.select': string;
1436
1493
  'interaction.pageAction.set': string;
1437
1494
  'interaction.pageAction.attach': string;
1495
+ 'interaction.pageAction.back': string;
1438
1496
  'interaction.pageAction.role.click': string;
1439
1497
  'interaction.pageAction.role.fill': string;
1440
1498
  'interaction.pageAction.role.submit': string;
1441
1499
  'interaction.pageAction.role.select': string;
1442
1500
  'interaction.pageAction.role.set': string;
1443
1501
  'interaction.pageAction.role.attach': string;
1502
+ 'interaction.pageAction.role.back': string;
1444
1503
  'interaction.pageAction.remember': string;
1445
1504
  'interaction.pageAction.frame': string;
1446
1505
  'interaction.pageAction.elevated': string;
1506
+ 'interaction.downloadedFile.list': string;
1507
+ 'interaction.downloadedFile.read': string;
1447
1508
  'interaction.downloadedFile.file': string;
1448
1509
  'interaction.downloadedFile.remember': string;
1449
1510
  'interaction.traceEvidence.title': string;
@@ -1467,6 +1528,7 @@ declare const chatbotDictionary: {
1467
1528
  'surface.readOnlySnapshot': string;
1468
1529
  'surface.suggested': string;
1469
1530
  'surface.useSuggestion': string;
1531
+ 'surface.openDocument': string;
1470
1532
  'surface.control.previousPage': string;
1471
1533
  'surface.control.previous': string;
1472
1534
  'surface.control.nextPage': string;
@@ -1796,15 +1858,19 @@ declare const chatbotDictionary: {
1796
1858
  'interaction.pageAction.select': string;
1797
1859
  'interaction.pageAction.set': string;
1798
1860
  'interaction.pageAction.attach': string;
1861
+ 'interaction.pageAction.back': string;
1799
1862
  'interaction.pageAction.role.click': string;
1800
1863
  'interaction.pageAction.role.fill': string;
1801
1864
  'interaction.pageAction.role.submit': string;
1802
1865
  'interaction.pageAction.role.select': string;
1803
1866
  'interaction.pageAction.role.set': string;
1804
1867
  'interaction.pageAction.role.attach': string;
1868
+ 'interaction.pageAction.role.back': string;
1805
1869
  'interaction.pageAction.remember': string;
1806
1870
  'interaction.pageAction.frame': string;
1807
1871
  'interaction.pageAction.elevated': string;
1872
+ 'interaction.downloadedFile.list': string;
1873
+ 'interaction.downloadedFile.read': string;
1808
1874
  'interaction.downloadedFile.file': string;
1809
1875
  'interaction.downloadedFile.remember': string;
1810
1876
  'interaction.traceEvidence.title': string;
@@ -1828,6 +1894,7 @@ declare const chatbotDictionary: {
1828
1894
  'surface.readOnlySnapshot': string;
1829
1895
  'surface.suggested': string;
1830
1896
  'surface.useSuggestion': string;
1897
+ 'surface.openDocument': string;
1831
1898
  'surface.control.previousPage': string;
1832
1899
  'surface.control.previous': string;
1833
1900
  'surface.control.nextPage': string;
@@ -2160,15 +2227,19 @@ declare const useT: () => TranslateFn<{
2160
2227
  'interaction.pageAction.select': string;
2161
2228
  'interaction.pageAction.set': string;
2162
2229
  'interaction.pageAction.attach': string;
2230
+ 'interaction.pageAction.back': string;
2163
2231
  'interaction.pageAction.role.click': string;
2164
2232
  'interaction.pageAction.role.fill': string;
2165
2233
  'interaction.pageAction.role.submit': string;
2166
2234
  'interaction.pageAction.role.select': string;
2167
2235
  'interaction.pageAction.role.set': string;
2168
2236
  'interaction.pageAction.role.attach': string;
2237
+ 'interaction.pageAction.role.back': string;
2169
2238
  'interaction.pageAction.remember': string;
2170
2239
  'interaction.pageAction.frame': string;
2171
2240
  'interaction.pageAction.elevated': string;
2241
+ 'interaction.downloadedFile.list': string;
2242
+ 'interaction.downloadedFile.read': string;
2172
2243
  'interaction.downloadedFile.file': string;
2173
2244
  'interaction.downloadedFile.remember': string;
2174
2245
  'interaction.traceEvidence.title': string;
@@ -2192,6 +2263,7 @@ declare const useT: () => TranslateFn<{
2192
2263
  'surface.readOnlySnapshot': string;
2193
2264
  'surface.suggested': string;
2194
2265
  'surface.useSuggestion': string;
2266
+ 'surface.openDocument': string;
2195
2267
  'surface.control.previousPage': string;
2196
2268
  'surface.control.previous': string;
2197
2269
  'surface.control.nextPage': string;
@@ -2521,15 +2593,19 @@ declare const useT: () => TranslateFn<{
2521
2593
  'interaction.pageAction.select': string;
2522
2594
  'interaction.pageAction.set': string;
2523
2595
  'interaction.pageAction.attach': string;
2596
+ 'interaction.pageAction.back': string;
2524
2597
  'interaction.pageAction.role.click': string;
2525
2598
  'interaction.pageAction.role.fill': string;
2526
2599
  'interaction.pageAction.role.submit': string;
2527
2600
  'interaction.pageAction.role.select': string;
2528
2601
  'interaction.pageAction.role.set': string;
2529
2602
  'interaction.pageAction.role.attach': string;
2603
+ 'interaction.pageAction.role.back': string;
2530
2604
  'interaction.pageAction.remember': string;
2531
2605
  'interaction.pageAction.frame': string;
2532
2606
  'interaction.pageAction.elevated': string;
2607
+ 'interaction.downloadedFile.list': string;
2608
+ 'interaction.downloadedFile.read': string;
2533
2609
  'interaction.downloadedFile.file': string;
2534
2610
  'interaction.downloadedFile.remember': string;
2535
2611
  'interaction.traceEvidence.title': string;
@@ -2553,6 +2629,7 @@ declare const useT: () => TranslateFn<{
2553
2629
  'surface.readOnlySnapshot': string;
2554
2630
  'surface.suggested': string;
2555
2631
  'surface.useSuggestion': string;
2632
+ 'surface.openDocument': string;
2556
2633
  'surface.control.previousPage': string;
2557
2634
  'surface.control.previous': string;
2558
2635
  'surface.control.nextPage': string;
@@ -3019,6 +3096,6 @@ declare function ErrorCard({ code, message, loopLimits, onOpenSettings, onDismis
3019
3096
  * Version of the published `@webskill/chatbot` package, injected at build time.
3020
3097
  * @stable
3021
3098
  */
3022
- declare const CHATBOT_VERSION = "0.11.0";
3099
+ declare const CHATBOT_VERSION = "0.13.0";
3023
3100
  //#endregion
3024
3101
  export { A2uiSurfaceHost, type A2uiSurfaceHostProps, A2uiSurfaceSnapshotHost, type A2uiSurfaceSnapshotHostProps, type AppearanceChange, CHATBOT_VERSION, type ChatAttachmentInput, type ChatAttachmentMeta, type ChatContentPart, ChatEngine, type ChatEngineOptions, type ChatEvent, type ChatInteractionRecord, type ChatLayout, type ChatMessage, type ChatRunPhase, type ChatSessionListResult, type ChatSessionMeta, type ChatTheme, type ChatThinking, type ChatTokenUsage, type ChatToolCall, Chatbot, type ChatbotConfig, type ChatbotGovernancePorts, type ChatbotHostAdapter, type ChatbotProps, CompositeUiBridge, type CompositeUiBridgeDeps, DEFAULT_RENDERER_CAPABILITIES, DEFAULT_RUNTIME_CONFIG_STORAGE_KEY, type DownloadableFile, ErrorCard, type ErrorCardProps, InteractionCard, type InteractionCardProps, InterruptedBanner, type InterruptedBannerProps, type Locale, type LocalizedText, OpenUiSurfaceHost, type OpenUiSurfaceHostProps, OpenUiSurfaceSnapshotHost, type OpenUiSurfaceSnapshotHostProps, type QuickPrompt, type QuickPromptIconName, type RendererCapability, type RendererKind, type ResolvedChatLayout, ResultBlockList, type ResultBlockListProps, ResultBlocksPro, type ResultBlocksProProps, type RunSnapshot, type RuntimeAppearanceConfig, type RuntimeConfig, type RuntimeConfigStore, type RuntimeQuickPrompt, type RuntimeRendererId, type SandboxExecutorDeps, type SettingsSectionId, SkillBadges, SpecInteraction, type SpecInteractionProps, VercelPayloadPreview, type VercelPayloadPreviewProps, VercelSurfaceHost, type VercelSurfaceHostProps, VercelSurfaceSnapshotHost, type VercelSurfaceSnapshotHostProps, chatbotDictionary, configureA2uiMarkdown, createLocalStorageRuntimeConfigStore, createMemoryRuntimeConfigStore, isLlmEntryUsable, pickUsableLlmEntry, probeA2uiAvailability, probeOpenUiAvailability, sandboxExecutorDeps, useT };
package/dist/index.js CHANGED
@@ -6,11 +6,11 @@ import { t as yaml } from "./yaml-C888tCbJ.js";
6
6
  import { t as json } from "./json-BOcU6nei.js";
7
7
  import { t as typescript } from "./typescript-DAau_Qyl.js";
8
8
  import { t as jsx$1 } from "./jsx-D2Jv0wvt.js";
9
- import { BEHAVIOR_RECORDS_KEY, DEFAULT_LOOP_LIMITS, DEFAULT_USER_PROFILE_LIMITS, EventBus, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FsRunTraceStore, FsSessionStore, FsToolStepStore, FullDisclosureRouter, SUPPORTED_DOCUMENT_MIME, SerializingMemoryStore, SkillDiscovery, USER_PROFILE_KEY, WebSkillError, WebSkillRuntime, applyUserProfileImport, assertRemoteUrlAllowed, atomicWriteText, diffUserProfile, exportUserProfile, formatAttachmentText, isUnsupportedRunSnapshot, messageOf, readBehaviorRecords, readUserProfile, refineUserProfile, summarizeRunUsage, summarizeToolCalls, textParts } from "@webskill/sdk";
9
+ import { BEHAVIOR_RECORDS_KEY, DEFAULT_LOOP_LIMITS, DEFAULT_USER_PROFILE_LIMITS, EventBus, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FsRunTraceStore, FsSessionStore, FsToolStepStore, FullDisclosureRouter, SUPPORTED_DOCUMENT_MIME, SerializingMemoryStore, SkillDiscovery, USER_PROFILE_KEY, WebSkillError, WebSkillRuntime, applyUserProfileImport, assertRemoteUrlAllowed, assertSafePathSegment, atomicWriteText, diffUserProfile, exportUserProfile, formatAttachmentText, isUnsupportedRunSnapshot, messageOf, readBehaviorRecords, readUserProfile, refineUserProfile, resolveInsideRoot, sanitizeUntrustedLine, summarizeRunUsage, summarizeToolCalls, textParts } from "@webskill/sdk";
10
10
  import { BrowserWorkerScriptExecutor, checkDictationAvailability, compressImageToBudget, createEncryptedMemoryStore, createLlmClient, deleteMemoryEncryptionKey, openMemoryEncryptionKey, probeChromeBuiltinAvailability, startDictation } from "@webskill/sdk/browser";
11
11
  import { JsonRenderSpecSurface, NativeSpecSurface, OpenUiSpecSurface, ReactBridgeState, SpecInteractionChannel, SurfaceFormTextsProvider, UiSurfaceSnapshotList, probeJsonRenderAvailability } from "@webskill/sdk/ui-react";
12
12
  import { A2UI_SPEC_FORM_PATH, collectFormScopes, createUiCatalogToolSource, fromA2uiSpecAction, fromA2uiSurfaceAction, interactionToFormModel, interactionToUiSpec, loadOpenUiPeers, loadWebSkillLitCatalog, renderMiniChart, shapeInteractionValue, toA2uiSpecMessages, toA2uiSurfaceAction, toVercelToolInvocation, uiCatalog } from "@webskill/sdk/ui";
13
- import { DownloadedFilePolicy, PAGE_ACTION_KINDS, TodoStore, createDelegationToolSource, createDownloadedFileToolSource, createPageActionToolSource, createPagePerceptionToolSource, createSkillGenerationToolSource, createTodoToolSource, withDelegationOrigin } from "@webskill/sdk/agent";
13
+ import { DownloadedFilePolicy, PAGE_ACTION_KINDS, TodoStore, createDelegationToolSource, createDownloadedFileToolSource, createPageActionToolSource, createPagePerceptionToolSource, createSkillGenerationToolSource, createTabWorksetToolSource, createTodoToolSource, withDelegationOrigin } from "@webskill/sdk/agent";
14
14
  import * as React$1 from "react";
15
15
  import React, { Children, Component, Fragment, createContext, createElement, forwardRef, isValidElement, memo, useCallback, useContext, useDeferredValue, useEffect, useEffectEvent, useId, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
16
16
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -30416,6 +30416,11 @@ const DEFAULT_MAX_DOCUMENT_TEXT_BYTES = 512e3;
30416
30416
  * 结构化数据不是文档,量级差一个数量级;超出**只拒不截**——截断的 JSON 解不出来。
30417
30417
  */
30418
30418
  const DEFAULT_MAX_DATA_SOURCE_BYTES = 1024e3;
30419
+ /**
30420
+ * 单个上传文件交给脚本的字节上限(0.15.0 分册 17,FR-17.5):20 MB。
30421
+ * 取得比模型图片预算宽:字节不进模型上下文,只进脚本,护的是内存不是 token。
30422
+ */
30423
+ const DEFAULT_MAX_UPLOAD_FILE_BYTES = 20 * 1024 * 1024;
30419
30424
 
30420
30425
  //#endregion
30421
30426
  //#region ../runtime/src/engine/limits.ts
@@ -30589,7 +30594,9 @@ function defaultRuntimeConfig() {
30589
30594
  allowPrivateHosts: false
30590
30595
  },
30591
30596
  typescript: { enabled: false },
30592
- downloadedFiles: false
30597
+ downloadedFiles: false,
30598
+ uploadFiles: false,
30599
+ maxUploadFileBytes: DEFAULT_MAX_UPLOAD_FILE_BYTES
30593
30600
  },
30594
30601
  llm: { entries: [] },
30595
30602
  agentCapabilities: {
@@ -31676,15 +31683,19 @@ const chatbotDictionary = defineDictionary({
31676
31683
  "interaction.pageAction.select": "Allow the assistant to select an option in “{target}”?",
31677
31684
  "interaction.pageAction.set": "Allow the assistant to toggle “{target}”?",
31678
31685
  "interaction.pageAction.attach": "Allow the assistant to attach a file to “{target}”?",
31686
+ "interaction.pageAction.back": "Allow the assistant to go back to the previous page on “{target}”?",
31679
31687
  "interaction.pageAction.role.click": "this control",
31680
31688
  "interaction.pageAction.role.fill": "this field",
31681
31689
  "interaction.pageAction.role.submit": "this form",
31682
31690
  "interaction.pageAction.role.select": "this list",
31683
31691
  "interaction.pageAction.role.set": "this switch",
31684
31692
  "interaction.pageAction.role.attach": "this upload field",
31693
+ "interaction.pageAction.role.back": "this page",
31685
31694
  "interaction.pageAction.remember": "Don’t ask again for this kind of action",
31686
31695
  "interaction.pageAction.frame": "The target is in the embedded frame \"{frame}\".",
31687
31696
  "interaction.pageAction.elevated": "This dialog is outside the usual allowlist; it was opened by this task.",
31697
+ "interaction.downloadedFile.list": "Allow the assistant to see the list of files you recently downloaded?",
31698
+ "interaction.downloadedFile.read": "Allow the assistant to read this file from your downloads?",
31688
31699
  "interaction.downloadedFile.file": "{name} · {size}",
31689
31700
  "interaction.downloadedFile.remember": "Don’t ask again for this kind of access",
31690
31701
  "interaction.traceEvidence.title": "Steps this skill claims",
@@ -31708,6 +31719,7 @@ const chatbotDictionary = defineDictionary({
31708
31719
  "surface.readOnlySnapshot": "This is a saved record — its actions are no longer available.",
31709
31720
  "surface.suggested": "Suggested:",
31710
31721
  "surface.useSuggestion": "Use",
31722
+ "surface.openDocument": "Open document",
31711
31723
  "surface.control.previousPage": "Previous page",
31712
31724
  "surface.control.previous": "Previous",
31713
31725
  "surface.control.nextPage": "Next page",
@@ -32037,15 +32049,19 @@ const chatbotDictionary = defineDictionary({
32037
32049
  "interaction.pageAction.select": "允许助手在「{target}」中选择选项吗?",
32038
32050
  "interaction.pageAction.set": "允许助手切换「{target}」吗?",
32039
32051
  "interaction.pageAction.attach": "允许助手向「{target}」附加文件吗?",
32052
+ "interaction.pageAction.back": "允许助手在「{target}」上返回上一页吗?",
32040
32053
  "interaction.pageAction.role.click": "这个控件",
32041
32054
  "interaction.pageAction.role.fill": "这个输入框",
32042
32055
  "interaction.pageAction.role.submit": "这个表单",
32043
32056
  "interaction.pageAction.role.select": "这个选择框",
32044
32057
  "interaction.pageAction.role.set": "这个开关",
32045
32058
  "interaction.pageAction.role.attach": "这个上传控件",
32059
+ "interaction.pageAction.role.back": "这个页面",
32046
32060
  "interaction.pageAction.remember": "以后不再询问此类操作",
32047
32061
  "interaction.pageAction.frame": "目标位于嵌入帧「{frame}」中。",
32048
32062
  "interaction.pageAction.elevated": "该对话框不在常规允许清单内,是本次任务打开的。",
32063
+ "interaction.downloadedFile.list": "允许助手查看你最近下载的文件列表吗?",
32064
+ "interaction.downloadedFile.read": "允许助手读取你下载目录里的这份文件吗?",
32049
32065
  "interaction.downloadedFile.file": "{name} · {size}",
32050
32066
  "interaction.downloadedFile.remember": "以后不再询问此类访问",
32051
32067
  "interaction.traceEvidence.title": "该技能声称的步骤",
@@ -32069,6 +32085,7 @@ const chatbotDictionary = defineDictionary({
32069
32085
  "surface.readOnlySnapshot": "这是已保存的记录,其中的操作已不可用。",
32070
32086
  "surface.suggested": "建议:",
32071
32087
  "surface.useSuggestion": "使用",
32088
+ "surface.openDocument": "打开文档",
32072
32089
  "surface.control.previousPage": "上一页",
32073
32090
  "surface.control.previous": "上一页",
32074
32091
  "surface.control.nextPage": "下一页",
@@ -32597,11 +32614,18 @@ var ChatEngine = class {
32597
32614
  #ready;
32598
32615
  /** 已装配的 runtime(cancel 等同步委托用;未装配时为 undefined) */
32599
32616
  #runtime;
32617
+ /**
32618
+ * 每轮 `send()` 开头刷新的运行时配置快照(0.15.0 分册 15 · FR-15.6)。
32619
+ * 只给那些必须同步回答、又不能等到重建运行时的开关用。
32620
+ */
32621
+ #liveConfig;
32600
32622
  #handles = /* @__PURE__ */ new Map();
32601
32623
  #currentSessionId;
32602
32624
  #listeners = /* @__PURE__ */ new Set();
32603
32625
  /** runId → 已激活技能累积(skill-activated 事件用;终态清理) */
32604
32626
  #runSkills = /* @__PURE__ */ new Map();
32627
+ /** 文档投放端口只构造一次:渲染侧把它放进 memo 依赖,每次取新对象会触发无谓重渲染 */
32628
+ #documentSurfacePort;
32605
32629
  /** 当前渲染框架档(复合 uiBridge 分发;setRenderer 热切换) */
32606
32630
  #renderer;
32607
32631
  /** 非 native 三档共用的交互通道(Chatbot 的 SpecInteraction attach 后生效) */
@@ -32810,6 +32834,52 @@ var ChatEngine = class {
32810
32834
  get interactionChannel() {
32811
32835
  return this.#interactionChannel;
32812
32836
  }
32837
+ /**
32838
+ * 文档投放端口(0.15.0 分册 13)。宿主没注入 `adapter.documentSurface` 时为 `undefined`,
32839
+ * 渲染侧据此整个不渲染按钮。
32840
+ *
32841
+ * 端口实现落在引擎里而不是宿主里,是因为「产物在哪、技能叫什么」这两件事只有引擎知道:
32842
+ * 交给宿主就等于把产物目录布局变成宿主必须复刻的知识,两个宿主各抄一份必然分叉,
32843
+ * 而那正是本册要消灭的东西。
32844
+ * @experimental
32845
+ */
32846
+ get documentSurface() {
32847
+ const host = this.#adapter.documentSurface;
32848
+ if (!host) return void 0;
32849
+ return this.#documentSurfacePort ??= { open: async ({ runId, artifact, style, dataSource }) => {
32850
+ const dir = `${this.#chatRoot}/artifacts/${runId}`;
32851
+ const html = await this.#adapter.storage.readText(this.#artifactPath(dir, artifact));
32852
+ const css = style === void 0 ? void 0 : await this.#adapter.storage.readText(this.#artifactPath(dir, style));
32853
+ await host.open({
32854
+ skillName: await this.#skillNamesOfRun(runId),
32855
+ dataSource: sanitizeUntrustedLine(dataSource),
32856
+ document: {
32857
+ html,
32858
+ ...css === void 0 ? {} : { css }
32859
+ }
32860
+ });
32861
+ } };
32862
+ }
32863
+ /**
32864
+ * 产物名 → 绝对路径。`assertSafePathSegment` + `resolveInsideRoot` 两道都不是可选写法:
32865
+ * 少了它们,「组件只收产物名」就退化成「组件收完整路径」,凭空开出一个读取面。
32866
+ */
32867
+ #artifactPath(dir, artifact) {
32868
+ assertSafePathSegment(artifact, "artifact");
32869
+ return resolveInsideRoot(dir, artifact);
32870
+ }
32871
+ /**
32872
+ * 这次 run 激活过的技能名。它是授权告知的主语,因此**不能**由发出 surface 的技能自报——
32873
+ * 那等于让被授权方自己写授权提示。
32874
+ *
32875
+ * 进行中的 run 读内存累积;已结束的(历史消息里的按钮就是这种)读 trace,
32876
+ * 只读内存会在 run 收尾清表后得到空串。
32877
+ */
32878
+ async #skillNamesOfRun(runId) {
32879
+ const live = this.#runSkills.get(runId);
32880
+ if (live && live.size > 0) return [...live].sort().join(", ");
32881
+ return [...(await this.#traceStore.get(runId).catch(() => void 0))?.activeSkills ?? []].sort().join(", ");
32882
+ }
32813
32883
  /** 探测 @a2ui/lit 是否安装(Appearance/设置区 A2UI 档置灰判定) */
32814
32884
  probeA2uiAvailability() {
32815
32885
  return probeA2uiAvailability();
@@ -33007,6 +33077,7 @@ var ChatEngine = class {
33007
33077
  async send(text, attachments = []) {
33008
33078
  if (this.#disposed) throw new WebSkillError("RUN_FAILED", "This ChatEngine was disposed; create a new one to keep chatting.");
33009
33079
  if (text.trim() === "" && attachments.length === 0) return;
33080
+ this.#liveConfig = await this.#runtimeConfigStore()?.load();
33010
33081
  const admitted = await this.#admitAttachments(attachments);
33011
33082
  const runtime = await this.#ensureReady();
33012
33083
  const sessionId = this.#currentSessionId ?? (await this.createSession({ title: truncateTitle(text) })).id;
@@ -33034,12 +33105,48 @@ var ChatEngine = class {
33034
33105
  });
33035
33106
  const handle = this.#sessionHandle(runtime, sessionId);
33036
33107
  try {
33037
- const result = await handle.run(prompt);
33108
+ const uploadFiles = this.#uploadFilesFor(admitted.accepted);
33109
+ const result = await handle.run(prompt, uploadFiles ? { uploadFiles } : {});
33038
33110
  await this.#finishRun(sessionId, result);
33039
33111
  } catch (e) {
33040
33112
  this.#emitError(e);
33113
+ } finally {
33114
+ this.#releaseTabWorkset();
33041
33115
  }
33042
33116
  }
33117
+ /**
33118
+ * run 结束就丢掉标签页工作集(0.16.0 FR-11.4 / FR-12.7)。
33119
+ *
33120
+ * 放在 `finally` 而不是 `#finishRun` 里:完成、失败、中断、取消四条路径必须清得一样干净,
33121
+ * 而异常路径根本不经过 `#finishRun`——漏一条就是让上一轮的句柄活到下一轮,
33122
+ * 那正是 SC-2 要堵的口子。它**不关闭任何标签页**:模型开出来的页归用户处置。
33123
+ */
33124
+ #releaseTabWorkset() {
33125
+ Promise.resolve(this.#adapter.pageTabs?.reset()).catch(() => void 0);
33126
+ }
33127
+ /**
33128
+ * 本轮触发消息里的附件,包成只对这一次 run 生效的读取端口(0.15.0 分册 17)。
33129
+ * 开关关着就返回 undefined → 脚本上下文里那两个成员整个不存在,
33130
+ * 与「本轮没传附件」(空数组)分得开。
33131
+ */
33132
+ #uploadFilesFor(attachments) {
33133
+ if (!(this.#liveConfig?.sandbox.uploadFiles ?? false)) return void 0;
33134
+ const files = attachments.map((a) => ({ ...a }));
33135
+ const infos = files.map((a) => ({
33136
+ id: a.id,
33137
+ name: a.name,
33138
+ contentType: a.contentType,
33139
+ size: a.size
33140
+ }));
33141
+ return {
33142
+ list: async () => infos,
33143
+ read: async (id) => {
33144
+ const attachment = files.find((a) => a.id === id);
33145
+ if (!attachment) throw new WebSkillError("UPLOAD_FILE_NOT_FOUND", `Upload file "${id}" is not part of the message that started this run`);
33146
+ return this.#adapter.storage.readBinary(`${this.attachmentsRoot}/${attachment.path}`);
33147
+ }
33148
+ };
33149
+ }
33043
33150
  /** 附件落盘根目录(composer 附件适配器写入,send 时读回) */
33044
33151
  get attachmentsRoot() {
33045
33152
  return `${this.#chatRoot}/attachments`;
@@ -33146,6 +33253,8 @@ var ChatEngine = class {
33146
33253
  await this.#finishRun(sessionId, result);
33147
33254
  } catch (e) {
33148
33255
  this.#emitError(e);
33256
+ } finally {
33257
+ this.#releaseTabWorkset();
33149
33258
  }
33150
33259
  }
33151
33260
  async #persistSurfaceDraft(runId, surfaceId, value) {
@@ -33185,6 +33294,13 @@ var ChatEngine = class {
33185
33294
  return this.#ready;
33186
33295
  }
33187
33296
  /**
33297
+ * `sandbox.downloadedFiles` 的实时取值(分册 15 · FR-15.6)。
33298
+ * 优先读每轮 `send()` 刷新的快照;还没发过消息时回落到装配期的那一份。
33299
+ */
33300
+ #sandboxDownloadedFiles(assembled) {
33301
+ return (this.#liveConfig ?? assembled)?.sandbox.downloadedFiles === true;
33302
+ }
33303
+ /**
33188
33304
  * LLM 选择链:options.llm(demo/测试)→ `RuntimeConfig.llm` 里选中/默认的条目
33189
33305
  * → 内置演示。streaming=false 时包装掉 stream(AgentLoop 走 complete)。
33190
33306
  */
@@ -33447,10 +33563,11 @@ var ChatEngine = class {
33447
33563
  }
33448
33564
  })] : [],
33449
33565
  ...this.#adapter.pageActions ? [createPageActionToolSource({ policy: this.#adapter.pageActions })] : [],
33566
+ ...this.#adapter.pageTabs ? [createTabWorksetToolSource({ policy: this.#adapter.pageTabs })] : [],
33450
33567
  ...this.#adapter.downloads ? [createDownloadedFileToolSource({ policy: new DownloadedFilePolicy({
33451
33568
  reader: this.#adapter.downloads.reader,
33452
33569
  ui: this.#uiBridge,
33453
- capabilityEnabled: () => rc?.sandbox.downloadedFiles === true,
33570
+ capabilityEnabled: () => this.#sandboxDownloadedFiles(rc),
33454
33571
  imageCapable: async () => {
33455
33572
  return entryCapabilities(pickLlmEntry(await this.#runtimeConfigStore()?.load(), this.#selectedModelId)).image;
33456
33573
  },
@@ -33499,6 +33616,9 @@ var ChatEngine = class {
33499
33616
  ...this.#adapter.xlsxExtractor ? { xlsxExtractor: this.#adapter.xlsxExtractor } : {},
33500
33617
  ...this.#adapter.pdfExtractor ? { pdfExtractor: this.#adapter.pdfExtractor } : {},
33501
33618
  ...this.#adapter.documentAudit ? { documentAudit: this.#adapter.documentAudit } : {},
33619
+ ...this.#adapter.documentAudit ? { uploadFileAudit: this.#adapter.documentAudit } : {},
33620
+ maxUploadFileBytes: rc?.sandbox.maxUploadFileBytes ?? defaultRuntimeConfig().sandbox.maxUploadFileBytes,
33621
+ ...this.#adapter.documentSurface ? { documentSurface: true } : {},
33502
33622
  ...toolStepStore ? { toolSteps: toolStepStore } : {}
33503
33623
  };
33504
33624
  const runtime = new WebSkillRuntime({
@@ -33801,7 +33921,8 @@ function ChatbotSurfaceTexts({ children }) {
33801
33921
  arrayFirstItemOnly: t("surface.arrayFirstItemOnly"),
33802
33922
  readOnlySnapshot: t("surface.readOnlySnapshot"),
33803
33923
  suggested: t("surface.suggested"),
33804
- useSuggestion: t("surface.useSuggestion")
33924
+ useSuggestion: t("surface.useSuggestion"),
33925
+ openDocument: t("surface.openDocument")
33805
33926
  }), [t]),
33806
33927
  hostControlTexts: useMemo(() => ({
33807
33928
  previousPage: t("surface.control.previousPage"),
@@ -45665,7 +45786,7 @@ function resolveByNonce(bridge, snapshots, event) {
45665
45786
  * 一组 surface 快照 → 当前渲染档的宿主(分册 17)。
45666
45787
  * 四档与原 `HistoricalSurfaces` 一一对应;差别只在 `bridge` 存在时补上动作/草稿回接。
45667
45788
  */
45668
- function SurfaceByRenderer({ snapshots, renderer, registry, bridge }) {
45789
+ function SurfaceByRenderer({ snapshots, renderer, registry, bridge, documentSurface }) {
45669
45790
  const drafts = bridge && snapshots[0]?.runId ? bridge.surfaceDrafts(snapshots[0].runId) : void 0;
45670
45791
  const onDraftChange = bridge ? (event) => bridge.setSurfaceDraft(event.runId, event.surfaceId, event.value) : void 0;
45671
45792
  if (renderer === "a2ui") {
@@ -45704,6 +45825,7 @@ function SurfaceByRenderer({ snapshots, renderer, registry, bridge }) {
45704
45825
  return /* @__PURE__ */ jsx(UiSurfaceSnapshotList, {
45705
45826
  snapshots,
45706
45827
  ...registry ? { registry } : {},
45828
+ ...documentSurface ? { documentSurface } : {},
45707
45829
  ...bridge ? { onAction: (event) => resolveByNonce(bridge, snapshots, event) } : {},
45708
45830
  ...drafts ? { drafts } : {},
45709
45831
  ...onDraftChange ? { onDraftChange } : {}
@@ -45738,6 +45860,7 @@ function InlineSurface({ surfaceId }) {
45738
45860
  snapshots: [snapshot],
45739
45861
  ...ctx.renderer ? { renderer: ctx.renderer } : {},
45740
45862
  ...ctx.registry ? { registry: ctx.registry } : {},
45863
+ ...ctx.documentSurface ? { documentSurface: ctx.documentSurface } : {},
45741
45864
  ...!persisted && bridge ? { bridge } : {}
45742
45865
  })
45743
45866
  });
@@ -45760,6 +45883,14 @@ function InlineBlocks() {
45760
45883
 
45761
45884
  //#endregion
45762
45885
  //#region src/react/interactionLabels.ts
45886
+ /**
45887
+ * 这两类的次要按钮是「不同意」而非「中止这次运行」(UI-UX8 D14):
45888
+ * 报成 cancelled 会让运行整个结束,工具拿不到否决结果,也就不会留下否决的审计。
45889
+ * native 卡与 spec 三档共用本判定,不得各写一份(分册 15 缺陷 C 就是两份逐渐走歧)。
45890
+ */
45891
+ function declinesOnCancel(request) {
45892
+ return request.type === "confirm" || request.type === "authorize";
45893
+ }
45763
45894
  /** 交互类型 → 标题字典键。徽章与声明树共用,避免两处各写一份映射。 */
45764
45895
  function interactionTitleKey(request) {
45765
45896
  return request.type === "file-pick" ? "interaction.filePick.title" : `interaction.${request.type}.title`;
@@ -46571,7 +46702,7 @@ function SkillBadges({ skills }) {
46571
46702
  //#endregion
46572
46703
  //#region src/react/WebSkillMessageExtensions.tsx
46573
46704
  /** WebSkill domain content rendered beneath a Base message without choosing its chat layout. */
46574
- function WebSkillMessageExtensions({ message, onDownload, surfaceRegistry, renderer }) {
46705
+ function WebSkillMessageExtensions({ message, onDownload, surfaceRegistry, documentSurface, renderer }) {
46575
46706
  const t = useT();
46576
46707
  if (message.role === "user") return null;
46577
46708
  const contentParts = message.contentParts ?? [];
@@ -46592,7 +46723,8 @@ function WebSkillMessageExtensions({ message, onDownload, surfaceRegistry, rende
46592
46723
  children: /* @__PURE__ */ jsx(SurfaceByRenderer, {
46593
46724
  snapshots: renderable,
46594
46725
  ...renderer ? { renderer } : {},
46595
- ...surfaceRegistry ? { registry: surfaceRegistry } : {}
46726
+ ...surfaceRegistry ? { registry: surfaceRegistry } : {},
46727
+ ...documentSurface ? { documentSurface } : {}
46596
46728
  })
46597
46729
  }) : null,
46598
46730
  renderable.length < surfaces.filter((snapshot) => !inlineIds.has(snapshot.id)).length ? /* @__PURE__ */ jsx("p", {
@@ -46719,6 +46851,7 @@ function AssistantUiMessage(props) {
46719
46851
  ...props.bridge ? { bridge: props.bridge } : {},
46720
46852
  ...props.renderer ? { renderer: props.renderer } : {},
46721
46853
  ...props.surfaceRegistry ? { registry: props.surfaceRegistry } : {},
46854
+ ...props.documentSurface ? { documentSurface: props.documentSurface } : {},
46722
46855
  ...props.onDownload ? { onDownload: props.onDownload } : {}
46723
46856
  }), [
46724
46857
  message?.surfaces,
@@ -46727,6 +46860,7 @@ function AssistantUiMessage(props) {
46727
46860
  props.bridge,
46728
46861
  props.renderer,
46729
46862
  props.surfaceRegistry,
46863
+ props.documentSurface,
46730
46864
  props.onDownload
46731
46865
  ]);
46732
46866
  if (role === "user") return /* @__PURE__ */ jsxs("div", {
@@ -46782,6 +46916,7 @@ function AssistantUiMessage(props) {
46782
46916
  message,
46783
46917
  ...props.onDownload ? { onDownload: props.onDownload } : {},
46784
46918
  ...props.surfaceRegistry ? { surfaceRegistry: props.surfaceRegistry } : {},
46919
+ ...props.documentSurface ? { documentSurface: props.documentSurface } : {},
46785
46920
  ...props.renderer ? { renderer: props.renderer } : {}
46786
46921
  }) : null,
46787
46922
  /* @__PURE__ */ jsx(AssistantUiMessageActions, { ...props })
@@ -47386,7 +47521,8 @@ function ActiveInteractionCard({ request, bridge }) {
47386
47521
  const pageAction = isAuthorize && request.capability === "pageAction" ? pageActionDetails(request.details) : void 0;
47387
47522
  const downloadedFile = isAuthorize && request.capability === "readDownloadedFile" ? downloadedFileDetails(request.details) : void 0;
47388
47523
  const traceEvidence = isAuthorize ? traceEvidenceDetails(request.details) : void 0;
47389
- const spec = interactionToUiSpec(request.type === "authorize" && pageAction !== void 0 ? {
47524
+ const localized = pageAction !== void 0 || downloadedFile !== void 0;
47525
+ const spec = interactionToUiSpec(request.type === "authorize" && localized ? {
47390
47526
  ...request,
47391
47527
  message: ""
47392
47528
  } : request, {
@@ -47396,7 +47532,7 @@ function ActiveInteractionCard({ request, bridge }) {
47396
47532
  const preview = isAuthorize && typeof request.details === "object" && request.details !== null ? request.details["preview"] : void 0;
47397
47533
  const handleAction = (event) => {
47398
47534
  if (event.intent !== "submit") {
47399
- if (request.type === "confirm" || request.type === "authorize") {
47535
+ if (declinesOnCancel(request)) {
47400
47536
  bridge.resolve({
47401
47537
  id: request.id,
47402
47538
  value: false
@@ -47500,22 +47636,30 @@ function ActiveInteractionCard({ request, bridge }) {
47500
47636
  }), pageAction.rememberLabel ?? t("interaction.pageAction.remember")]
47501
47637
  }) : null
47502
47638
  ] }) : null,
47503
- downloadedFile ? /* @__PURE__ */ jsxs(Fragment$1, { children: [downloadedFile.file ? /* @__PURE__ */ jsx("p", {
47504
- "data-testid": "interaction-downloaded-file",
47505
- className: "text-sm text-ink",
47506
- children: t("interaction.downloadedFile.file", {
47507
- name: downloadedFile.file.name,
47508
- size: formatBytes(downloadedFile.file.size)
47509
- })
47510
- }) : null, downloadedFile.rememberable === true ? /* @__PURE__ */ jsxs("label", {
47511
- className: "flex items-center gap-2 text-sm text-ink",
47512
- children: [/* @__PURE__ */ jsx("input", {
47513
- type: "checkbox",
47514
- "data-testid": "interaction-downloaded-file-remember",
47515
- checked: remember,
47516
- onChange: (event) => setRemember(event.currentTarget.checked)
47517
- }), downloadedFile.rememberLabel ?? t("interaction.downloadedFile.remember")]
47518
- }) : null] }) : null,
47639
+ downloadedFile ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
47640
+ /* @__PURE__ */ jsx("p", {
47641
+ "data-testid": "interaction-downloaded-file-action",
47642
+ className: "text-sm text-ink",
47643
+ children: t(`interaction.downloadedFile.${downloadedFile.action}`)
47644
+ }),
47645
+ downloadedFile.file ? /* @__PURE__ */ jsx("p", {
47646
+ "data-testid": "interaction-downloaded-file",
47647
+ className: "text-sm text-ink",
47648
+ children: t("interaction.downloadedFile.file", {
47649
+ name: downloadedFile.file.name,
47650
+ size: formatBytes(downloadedFile.file.size)
47651
+ })
47652
+ }) : null,
47653
+ downloadedFile.rememberable === true ? /* @__PURE__ */ jsxs("label", {
47654
+ className: "flex items-center gap-2 text-sm text-ink",
47655
+ children: [/* @__PURE__ */ jsx("input", {
47656
+ type: "checkbox",
47657
+ "data-testid": "interaction-downloaded-file-remember",
47658
+ checked: remember,
47659
+ onChange: (event) => setRemember(event.currentTarget.checked)
47660
+ }), downloadedFile.rememberLabel ?? t("interaction.downloadedFile.remember")]
47661
+ }) : null
47662
+ ] }) : null,
47519
47663
  traceEvidence ? /* @__PURE__ */ jsxs("div", {
47520
47664
  "data-testid": "interaction-trace-evidence",
47521
47665
  children: [/* @__PURE__ */ jsx("div", {
@@ -47563,7 +47707,7 @@ function ActiveInteractionCard({ request, bridge }) {
47563
47707
  }, `${step.tool}-${index}`))
47564
47708
  })]
47565
47709
  }) : null,
47566
- request.details !== void 0 && pageAction === void 0 ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
47710
+ request.details !== void 0 && !localized ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
47567
47711
  className: "mb-1 text-xs font-medium text-muted",
47568
47712
  children: t("interaction.authorize.details")
47569
47713
  }), /* @__PURE__ */ jsx("pre", {
@@ -47844,11 +47988,15 @@ function SpecInteraction({ channel, renderer }) {
47844
47988
  }, [channel, renderer]);
47845
47989
  if (!session) return null;
47846
47990
  const Surface = SURFACES[renderer];
47991
+ const { request } = session;
47847
47992
  return /* @__PURE__ */ jsx(Surface, {
47848
- surfaceId: session.request.id,
47993
+ surfaceId: request.id,
47849
47994
  spec: session.spec,
47850
47995
  actions: INTERACTION_ACTIONS,
47851
- onAction: (event) => channel.handleAction(event)
47996
+ onAction: (event) => {
47997
+ if (event.intent !== "submit" && declinesOnCancel(request)) channel.decline(request.id);
47998
+ else channel.handleAction(event);
47999
+ }
47852
48000
  });
47853
48001
  }
47854
48002
 
@@ -48621,6 +48769,7 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
48621
48769
  modelLabels,
48622
48770
  resolveAttachmentUrl,
48623
48771
  ...surfaceRegistry ? { surfaceRegistry } : {},
48772
+ ...engine.documentSurface ? { documentSurface: engine.documentSurface } : {},
48624
48773
  renderer,
48625
48774
  bridge: engine.bridge,
48626
48775
  ...adapter.navigation.openConsoleTrace ? { onViewTrace: adapter.navigation.openConsoleTrace } : {},
@@ -48756,7 +48905,7 @@ function VercelPayloadPreview({ bridge }) {
48756
48905
  * Version of the published `@webskill/chatbot` package, injected at build time.
48757
48906
  * @stable
48758
48907
  */
48759
- const CHATBOT_VERSION = "0.11.0";
48908
+ const CHATBOT_VERSION = "0.13.0";
48760
48909
 
48761
48910
  //#endregion
48762
48911
  export { A2uiSurfaceHost, A2uiSurfaceSnapshotHost, CHATBOT_VERSION, ChatEngine, Chatbot, CompositeUiBridge, DEFAULT_RENDERER_CAPABILITIES, DEFAULT_RUNTIME_CONFIG_STORAGE_KEY, ErrorCard, InteractionCard, InterruptedBanner, OpenUiSurfaceHost, OpenUiSurfaceSnapshotHost, ResultBlockList, ResultBlocksPro, SkillBadges, SpecInteraction, VercelPayloadPreview, VercelSurfaceHost, VercelSurfaceSnapshotHost, chatbotDictionary, configureA2uiMarkdown, createLocalStorageRuntimeConfigStore, createMemoryRuntimeConfigStore, isLlmEntryUsable, pickUsableLlmEntry, probeA2uiAvailability, probeOpenUiAvailability, sandboxExecutorDeps, useT };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webskill/chatbot",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -26,7 +26,7 @@
26
26
  "@a2ui/web_core": "^0.10.5",
27
27
  "@lit/context": "^1.1.0",
28
28
  "@openuidev/react-lang": "0.2.8",
29
- "@webskill/sdk": "^0.14.0",
29
+ "@webskill/sdk": "^0.16.0",
30
30
  "react": ">=19.0.0",
31
31
  "react-dom": ">=19.0.0",
32
32
  "zod": "^3.25.0 || ^4.0.0"