@blade-hq/agent-client 2612.0.0-beta.2 → 2612.0.0-beta.20

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.
Files changed (89) hide show
  1. package/README.md +203 -19
  2. package/dist/blade-client.d.ts +12 -1
  3. package/dist/{chunk-PWJJJATA.js → chunk-2VIJBVAC.js} +1676 -680
  4. package/dist/chunk-2VIJBVAC.js.map +1 -0
  5. package/dist/index.d.ts +12 -3
  6. package/dist/index.js +9 -1
  7. package/dist/internal.d.ts +8 -3
  8. package/dist/internal.js +9 -1
  9. package/dist/internal.js.map +1 -1
  10. package/dist/resources/chat-groups.d.ts +92 -0
  11. package/dist/resources/headless.d.ts +5 -0
  12. package/dist/resources/plugins.d.ts +1 -0
  13. package/dist/resources/sessions.d.ts +94 -11
  14. package/dist/schemas/context-attachments.d.ts +16 -0
  15. package/dist/schemas/event.d.ts +2 -0
  16. package/dist/schemas/message-utils.d.ts +3 -9
  17. package/dist/schemas/message.d.ts +18 -1
  18. package/dist/schemas/plugin-refs.d.ts +15 -0
  19. package/dist/schemas/projection.d.ts +31 -0
  20. package/dist/schemas/session.d.ts +2 -42
  21. package/dist/schemas/topic-assets.d.ts +7 -0
  22. package/dist/session/agent-session.d.ts +51 -7
  23. package/dist/session/background.d.ts +14 -0
  24. package/dist/session/events.d.ts +0 -1
  25. package/dist/session/hub.d.ts +3 -0
  26. package/dist/session/log-cursor.d.ts +14 -0
  27. package/dist/session/state.d.ts +2 -1
  28. package/dist/session/workflow.d.ts +10 -3
  29. package/dist/shared/projection/builder.d.ts +5 -0
  30. package/dist/shared/projection/helpers.d.ts +2 -0
  31. package/dist/shared/projection/index.d.ts +1 -0
  32. package/dist/shared/projection/workflow.d.ts +24 -0
  33. package/dist/tool-provider.d.ts +51 -0
  34. package/dist/types/socket-events.d.ts +177 -6
  35. package/node_modules/engine.io-client/build/cjs/globals.node.d.ts +2 -3
  36. package/node_modules/engine.io-client/build/cjs/index.d.ts +3 -3
  37. package/node_modules/engine.io-client/build/cjs/index.js +1 -4
  38. package/node_modules/engine.io-client/build/cjs/socket.d.ts +39 -82
  39. package/node_modules/engine.io-client/build/cjs/socket.js +151 -218
  40. package/node_modules/engine.io-client/build/cjs/transport.d.ts +1 -1
  41. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.d.ts +4 -4
  42. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.js +2 -2
  43. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.node.js +17 -7
  44. package/node_modules/engine.io-client/build/cjs/transports/websocket.node.js +17 -7
  45. package/node_modules/engine.io-client/build/esm/globals.node.d.ts +2 -3
  46. package/node_modules/engine.io-client/build/esm/index.d.ts +3 -3
  47. package/node_modules/engine.io-client/build/esm/index.js +1 -2
  48. package/node_modules/engine.io-client/build/esm/socket.d.ts +39 -82
  49. package/node_modules/engine.io-client/build/esm/socket.js +141 -206
  50. package/node_modules/engine.io-client/build/esm/transport.d.ts +1 -1
  51. package/node_modules/engine.io-client/build/esm/transports/polling-xhr.d.ts +4 -4
  52. package/node_modules/engine.io-client/build/esm/transports/polling-xhr.js +2 -2
  53. package/node_modules/engine.io-client/build/esm-debug/globals.node.d.ts +2 -3
  54. package/node_modules/engine.io-client/build/esm-debug/index.d.ts +3 -3
  55. package/node_modules/engine.io-client/build/esm-debug/index.js +1 -2
  56. package/node_modules/engine.io-client/build/esm-debug/socket.d.ts +39 -82
  57. package/node_modules/engine.io-client/build/esm-debug/socket.js +150 -215
  58. package/node_modules/engine.io-client/build/esm-debug/transport.d.ts +1 -1
  59. package/node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.d.ts +4 -4
  60. package/node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.js +2 -2
  61. package/node_modules/engine.io-client/dist/engine.io.esm.min.js +3 -3
  62. package/node_modules/engine.io-client/dist/engine.io.esm.min.js.map +1 -1
  63. package/node_modules/engine.io-client/dist/engine.io.js +164 -239
  64. package/node_modules/engine.io-client/dist/engine.io.js.map +1 -1
  65. package/node_modules/engine.io-client/dist/engine.io.min.js +3 -3
  66. package/node_modules/engine.io-client/dist/engine.io.min.js.map +1 -1
  67. package/node_modules/engine.io-client/package.json +2 -2
  68. package/node_modules/socket.io-parser/build/cjs/binary.js +4 -1
  69. package/node_modules/socket.io-parser/build/cjs/index.d.ts +14 -4
  70. package/node_modules/socket.io-parser/build/cjs/index.js +18 -11
  71. package/node_modules/socket.io-parser/build/esm/binary.js +4 -1
  72. package/node_modules/socket.io-parser/build/esm/index.d.ts +14 -4
  73. package/node_modules/socket.io-parser/build/esm/index.js +14 -10
  74. package/node_modules/socket.io-parser/build/esm-debug/binary.js +4 -1
  75. package/node_modules/socket.io-parser/build/esm-debug/index.d.ts +14 -4
  76. package/node_modules/socket.io-parser/build/esm-debug/index.js +14 -10
  77. package/node_modules/socket.io-parser/package.json +1 -1
  78. package/node_modules/ws/index.js +15 -6
  79. package/node_modules/ws/lib/constants.js +1 -0
  80. package/node_modules/ws/lib/permessage-deflate.js +9 -7
  81. package/node_modules/ws/lib/receiver.js +37 -0
  82. package/node_modules/ws/lib/sender.js +6 -1
  83. package/node_modules/ws/lib/websocket-server.js +18 -6
  84. package/node_modules/ws/lib/websocket.js +50 -17
  85. package/node_modules/ws/package.json +8 -3
  86. package/node_modules/ws/wrapper.mjs +14 -1
  87. package/package.json +4 -4
  88. package/public-api.md +329 -26
  89. package/dist/chunk-PWJJJATA.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { BladeApiError } from "./rest";
4
4
  export type { LoginOptions, LoginResult, TokenStorageMode } from "./auth-login";
5
5
  export { SDK_NAME, SDK_VERSION } from "./version";
6
6
  export { AgentSession } from "./session/agent-session";
7
- export type { AttachAppOptions, SendOptions } from "./session/agent-session";
7
+ export type { AttachAppOptions, SendOptions, PreparedSend, PreparedSendOptions, DeliveryReceipt } from "./session/agent-session";
8
8
  export { AgentSessionError } from "./session/errors";
9
9
  export type { AgentSessionEvents, AgentSessionEventName } from "./session/events";
10
10
  export type { WorkflowRunEntry, WorkflowRunState } from "./session/workflow";
@@ -20,10 +20,19 @@ export type { RunOptions, RunResult, RunTrace } from "./types/sdk-profile";
20
20
  export type { ModelsResource, ModelCatalog, ModelOption } from "./resources/models";
21
21
  export type { ComputersResource } from "./resources/computers";
22
22
  export type { AccountComputer, SessionComputer } from "./resources/computers";
23
- export type { AppCliAttachment, AppCliDefinition, CreateSessionRequest, FileEntry, PaginatedSessionsResult, SessionsResource, SessionTurnsPage, SessionTurnsQuery, UploadFileEntry, UploadFilesOptions, } from "./resources/sessions";
23
+ export type { AppCliAttachment, AppCliDefinition, CreateSessionRequest, UpdateSessionConfigurationRequest, SessionConfiguration, McpSourceConfig, FileEntry, PaginatedSessionsResult, SessionsResource, SessionTurnsPage, SessionTurnsQuery, UploadFileEntry, UploadFilesOptions, } from "./resources/sessions";
24
24
  export { DEFAULT_REPLAY_SPEED, SessionInfo, SessionStatus } from "./schemas/session";
25
25
  export type { ReplaySpeed, ReplayState, SessionDetail } from "./schemas/session";
26
- export type { ChatMessage, FileContentPart, ImageUrlContentPart, MemoryRefInfo, MessageContent, MessageContentPart, TextContentPart, ToolCallInfo, } from "./schemas/message";
26
+ export type { ChatMessage, FileContentPart, ImageUrlContentPart, MemoryRefInfo, MessageContent, MessageContentPart, TextContentPart, ToolCallInfo, WorkflowStepInfo, } from "./schemas/message";
27
27
  export { chatErrorForDisplay, contentPreview, getFileParts, getImageParts, getTextContent, groupMessagesByLoop, transformSlashCommand, } from "./schemas/message-utils";
28
28
  export type { SkillMentionAvailability } from "./schemas/message-utils";
29
29
  export { userFacingErrorText } from "./shared/oom";
30
+ export { normalizeTopicAssetRefs } from "./schemas/topic-assets";
31
+ export type { TopicAssetRef } from "./schemas/topic-assets";
32
+ export type { ChatGroup, ChatGroupRole, ChatGroupMember, ChatGroupTask, CreateChatGroupTask, UpdateChatGroupTask, ChatGroupAsset, ChatGroupAssetList } from "./resources/chat-groups";
33
+ export { normalizePluginRefs, normalizeMessageRefs } from "./schemas/plugin-refs";
34
+ export type { PluginRef, SkillRef, MessageRef } from "./schemas/plugin-refs";
35
+ export type { ToolEvidence } from "./schemas/projection";
36
+ export { ToolProvider } from "./tool-provider";
37
+ export type { ToolProviderOptions, ProviderTool, ProviderToolResult } from "./tool-provider";
38
+ export type { ContextAttachment } from "./schemas/context-attachments";
package/dist/index.js CHANGED
@@ -9,15 +9,19 @@ import {
9
9
  SessionInfo,
10
10
  SessionSetupError,
11
11
  SessionStatus,
12
+ ToolProvider,
12
13
  chatErrorForDisplay,
13
14
  contentPreview,
14
15
  getFileParts,
15
16
  getImageParts,
16
17
  getTextContent,
17
18
  groupMessagesByLoop,
19
+ normalizeMessageRefs,
20
+ normalizePluginRefs,
21
+ normalizeTopicAssetRefs,
18
22
  transformSlashCommand,
19
23
  userFacingErrorText
20
- } from "./chunk-PWJJJATA.js";
24
+ } from "./chunk-2VIJBVAC.js";
21
25
  export {
22
26
  AgentSession,
23
27
  AgentSessionError,
@@ -29,12 +33,16 @@ export {
29
33
  SessionInfo,
30
34
  SessionSetupError,
31
35
  SessionStatus,
36
+ ToolProvider,
32
37
  chatErrorForDisplay,
33
38
  contentPreview,
34
39
  getFileParts,
35
40
  getImageParts,
36
41
  getTextContent,
37
42
  groupMessagesByLoop,
43
+ normalizeMessageRefs,
44
+ normalizePluginRefs,
45
+ normalizeTopicAssetRefs,
38
46
  transformSlashCommand,
39
47
  userFacingErrorText
40
48
  };
@@ -24,7 +24,7 @@ export { ComputersResource } from "./resources/computers";
24
24
  export type { SessionPlugin, SessionPluginActivation } from "./resources/sessions";
25
25
  export type { SessionPluginConfigError, SessionPluginConfigSet, SessionPluginConfigState, SessionPluginConfigStateName, SessionPluginConfigSummary, SessionPluginConfigUpdate, } from "./resources/sessions";
26
26
  export { ChatGroupsResource } from "./resources/chat-groups";
27
- export type { ChatGroup } from "./resources/chat-groups";
27
+ export type { ChatGroup, ChatGroupRole, ChatGroupMember, ChatGroupTask, CreateChatGroupTask, UpdateChatGroupTask, ChatGroupAsset, ChatGroupAssetList } from "./resources/chat-groups";
28
28
  export { PluginsResource } from "./resources/plugins";
29
29
  export type { PluginCatalogEntry } from "./resources/plugins";
30
30
  export type { SiteVisitsResource, SiteVisitsSummary } from "./resources/site-visits";
@@ -36,11 +36,11 @@ export { buildMessageContent, extractTextAttachments, isBackgroundWakeMessage, i
36
36
  export type { ParsedTextAttachment, ParsedTextContext } from "./schemas/message-utils";
37
37
  export { contextProjectionData, getContextDisplayState, getContextGroupDisplayState, groupAdjacentContextRuns, } from "./schemas/context";
38
38
  export type { ContextAction, ContextDisplayState, ContextGroupDisplayState, ContextProjectionData, ContextProjectionFields, ContextSourceInfo, } from "./schemas/context";
39
- export type { ContentBlock, FinalArtifact, MemoryRef, PatchEnvelope, PendingQuestionRef, PostChatFollowup, RunTiming, ToolCallProjection, TurnProjection, } from "./schemas/projection";
39
+ export type { ContentBlock, FinalArtifact, MemoryRef, PatchEnvelope, PendingQuestionRef, PostChatFollowup, RunTiming, ToolCallProjection, WorkflowStepProjection, TurnProjection, } from "./schemas/projection";
40
40
  export { latestPostChatFollowup } from "./schemas/projection-utils";
41
41
  export { buildToolUiCardKey, collectInlineToolUiCards, collectPreviewToolUiCards, isAppDevToolUiCard, isInternalStatusToolUiCard, isToolUiCard, resolveToolUiCardContent, } from "./shared/tool-ui-card";
42
42
  export type { InlineToolUiCardEntry, PreviewToolUiCardEntry, ToolUiCard, ToolUiCardContentType, } from "./shared/tool-ui-card";
43
- export type { ModeId, PrimarySkillParallelMode, PrimarySkillSnapshot, PrimarySkillStageSpec, PrimarySkillStepSpec, PublishedSolutionRef, ReplayPreview, SessionPortMapping, SessionSearchMatch, SkillEditorTemplateId, TemplateId, } from "./schemas/session";
43
+ export type { ModeId, PublishedSolutionRef, ReplayPreview, SessionPortMapping, SessionSearchMatch, } from "./schemas/session";
44
44
  export { LayoutType } from "./schemas/solution";
45
45
  export type { BizRole, Solution, SolutionAppField, SolutionAppState, SolutionAppUiConfig, } from "./schemas/solution";
46
46
  export { Task, TaskStatus } from "./schemas/task";
@@ -53,3 +53,8 @@ export { isOomText, OOM_MESSAGE } from "./shared/oom";
53
53
  export { createSocket } from "./socket";
54
54
  export type { CreateSocketOptions, TypedSocket } from "./socket";
55
55
  export type { AsrAudioPayload } from "./types/socket-events";
56
+ export { normalizeTopicAssetRefs } from "./schemas/topic-assets";
57
+ export type { TopicAssetRef } from "./schemas/topic-assets";
58
+ export { normalizePluginRefs } from "./schemas/plugin-refs";
59
+ export type { PluginRef } from "./schemas/plugin-refs";
60
+ export type { ToolEvidence } from "./schemas/projection";
package/dist/internal.js CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  SessionInfo,
19
19
  SessionSetupError,
20
20
  SessionStatus,
21
+ ToolProvider,
21
22
  acceptedPostChatFollowupCompletesLatestRun,
22
23
  acknowledgeTurnEvents,
23
24
  applyTurnPatch,
@@ -61,6 +62,9 @@ import {
61
62
  isToolUiCard,
62
63
  isWorkflowRunToolName,
63
64
  normalizeMessageContent,
65
+ normalizeMessageRefs,
66
+ normalizePluginRefs,
67
+ normalizeTopicAssetRefs,
64
68
  parentForkToolCallIdFromTurn,
65
69
  parseQueueAck,
66
70
  prependOlder,
@@ -80,7 +84,7 @@ import {
80
84
  withTurns,
81
85
  workflowEntriesFromOutput,
82
86
  workflowNameFromArguments
83
- } from "./chunk-PWJJJATA.js";
87
+ } from "./chunk-2VIJBVAC.js";
84
88
 
85
89
  // src/polling-backoff.ts
86
90
  var MAX_BACKOFF_MS = 6e4;
@@ -270,6 +274,7 @@ export {
270
274
  SessionStatus,
271
275
  Task,
272
276
  TaskStatus,
277
+ ToolProvider,
273
278
  acceptedPostChatFollowupCompletesLatestRun,
274
279
  acknowledgeTurnEvents,
275
280
  applyTurnPatch,
@@ -316,6 +321,9 @@ export {
316
321
  latestPostChatFollowup,
317
322
  loadPlatformEndpoints,
318
323
  normalizeMessageContent,
324
+ normalizeMessageRefs,
325
+ normalizePluginRefs,
326
+ normalizeTopicAssetRefs,
319
327
  parentForkToolCallIdFromTurn,
320
328
  parseQueueAck,
321
329
  prependOlder,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/polling-backoff.ts","../src/platform-endpoints.ts","../src/commands/protocol.ts","../src/schemas/projection-utils.ts","../src/schemas/solution.ts","../src/schemas/task.ts"],"sourcesContent":["import { BladeApiError } from \"./rest\"\n\nconst MAX_BACKOFF_MS = 60_000\nconst MAX_TIMER_MS = 2_147_483_647\n\n/** Scheduling policy for read-only polling; never sends or replays a request. */\nexport class PollingBackoff {\n private failures = 0\n private nextAt: number | false = 0\n\n constructor(private readonly intervalMs: number) {\n if (!Number.isFinite(intervalMs) || intervalMs <= 0 || intervalMs > MAX_BACKOFF_MS) {\n throw new RangeError(\"Polling interval must be between 0 and 60000 ms\")\n }\n }\n\n reset(): void {\n this.failures = 0\n this.nextAt = 0\n }\n\n failed(error: unknown): void {\n if (\n (error instanceof Error && error.name === \"AbortError\") ||\n (error instanceof BladeApiError && error.status < 500 &&\n error.status !== 408 && error.status !== 429)\n ) {\n this.nextAt = false\n return\n }\n this.failures = Math.min(this.failures + 1, 10)\n const ceiling = Math.min(MAX_BACKOFF_MS, this.intervalMs * 2 ** this.failures)\n const backoff = Math.max(this.intervalMs, ceiling * (0.5 + Math.random() * 0.5))\n const header = error instanceof BladeApiError\n ? error.response.headers.get(\"Retry-After\")?.trim()\n : undefined\n const retryAfter = header\n ? /^\\d+$/.test(header) ? Number(header) * 1000 : Date.parse(header) - Date.now()\n : 0\n const delay = Math.max(backoff, Number.isNaN(retryAfter) ? 0 : retryAfter)\n // Oversized server delays must not overflow browser timers into a hot loop.\n this.nextAt = delay > MAX_TIMER_MS ? false : Date.now() + delay\n }\n\n /** Zero means ready, false means stop, otherwise wait at least this many ms. */\n waitMs(): number | false {\n return this.nextAt === false ? false : Math.max(0, this.nextAt - Date.now())\n }\n}\n","import { isRecord } from \"./shared/type-guards\"\n\nexport const PLATFORM_SERVICE_NAMES = [\n \"os\",\n \"hub\",\n \"agent\",\n \"oauth\",\n \"llmGateway\",\n \"gitea\",\n \"tile\",\n] as const\n\nexport type PlatformServiceName = (typeof PLATFORM_SERVICE_NAMES)[number]\n\nexport interface PlatformEndpoints {\n services: Partial<Record<PlatformServiceName, string>>\n}\n\nexport const EMPTY_PLATFORM_ENDPOINTS: PlatformEndpoints = Object.freeze({\n services: Object.freeze({}),\n})\n\nexport interface LoadPlatformEndpointsOptions {\n baseUrl?: string\n fetchImpl?: typeof fetch\n timeoutMs?: number\n}\n\nfunction defaultDocumentBaseUrl(): string | undefined {\n if (typeof document === \"undefined\") return undefined\n if (document.querySelector(\"base[href]\")) return document.baseURI\n if (typeof location !== \"undefined\" && location.origin) return `${location.origin}/`\n return document.baseURI\n}\n\nfunction normalizeServiceUrl(value: unknown): string | null {\n if (typeof value !== \"string\" || !value.trim()) return null\n if (value.includes(\"?\") || value.includes(\"#\")) return null\n try {\n const url = new URL(value.trim())\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return null\n if (url.username || url.password || url.search || url.hash) return null\n return url.toString().replace(/\\/$/, \"\")\n } catch {\n return null\n }\n}\n\nexport function parsePlatformEndpoints(value: unknown): PlatformEndpoints | null {\n if (!isRecord(value) || !isRecord(value.services)) return null\n\n const services: Partial<Record<PlatformServiceName, string>> = {}\n for (const name of PLATFORM_SERVICE_NAMES) {\n if (!(name in value.services)) continue\n const url = normalizeServiceUrl(value.services[name])\n if (!url) return null\n if (name === \"agent\" && new URL(url).pathname !== \"/\") return null\n services[name] = url\n }\n\n return { services }\n}\n\nexport async function loadPlatformEndpoints(\n options: LoadPlatformEndpointsOptions = {},\n): Promise<PlatformEndpoints> {\n const fetchImpl = options.fetchImpl ?? globalThis.fetch\n const baseUrl = options.baseUrl ?? defaultDocumentBaseUrl()\n if (!fetchImpl || !baseUrl) return EMPTY_PLATFORM_ENDPOINTS\n\n const controller = new AbortController()\n const timeout = globalThis.setTimeout(() => controller.abort(), options.timeoutMs ?? 3_000)\n try {\n const response = await fetchImpl(new URL(\"config.json\", baseUrl), {\n cache: \"no-store\",\n credentials: \"same-origin\",\n headers: { Accept: \"application/json\" },\n signal: controller.signal,\n })\n if (!response.ok) return EMPTY_PLATFORM_ENDPOINTS\n return parsePlatformEndpoints(await response.json()) ?? EMPTY_PLATFORM_ENDPOINTS\n } catch {\n return EMPTY_PLATFORM_ENDPOINTS\n } finally {\n globalThis.clearTimeout(timeout)\n }\n}\n\nexport function resolveServiceUrl(\n endpoints: PlatformEndpoints,\n name: PlatformServiceName,\n path = \"\",\n): string | null {\n const baseUrl = endpoints.services[name]\n if (!baseUrl) return null\n if (!path) return baseUrl\n const pathReference = path.trimStart()\n if (\n path.includes(\"\\\\\") ||\n pathReference.startsWith(\"//\") ||\n /^[a-z][a-z0-9+.-]*:/i.test(pathReference)\n ) {\n return null\n }\n const base = new URL(`${baseUrl}/`)\n const target = new URL(path.replace(/^\\/+/, \"\"), base)\n if (target.origin !== base.origin || !target.pathname.startsWith(base.pathname)) {\n return null\n }\n return target.toString()\n}\n","/**\n * 页面协作协议(对应后端 `_meta.bridge` 通道,见 docs/specs/260417-embed-bridge)。\n *\n * ## action 从哪里来\n *\n * 智能体 → 宿主方向的每一条指令,都源自**技能作者写的工具代码**:工具返回值\n * JSON 里带 `_meta.bridge: { action, payload }`,后端在持久化前把它剥离成独立\n * 事件送达前端(LLM 的对话历史里读不到它)。因此:\n *\n * - action 字符串(如 \"map.highlight\")是**技能作者与宿主页面开发者之间的业务\n * 契约**,LLM 不参与协议、SDK 不做枚举校验;\n * - 宿主页面用 `session.onCommand(\"map.highlight\", fn)` 消费;\n * - 未注册 handler 的 action 会进入有限缓冲等待注册,超限后丢弃并 console 告警。\n *\n * 宿主 → 智能体方向只有三个白名单动作:attach(附件入输入框)/ insertText\n * (追加输入文本)/ send(直接发消息),对应协议层的 addContext / appendInput /\n * sendMessage。\n */\n\nexport interface CommandEnvelope {\n __bladeBridge: true\n direction: \"agent-to-host\"\n action: string\n payload: unknown\n meta: {\n sessionId: string\n toolCallId?: string\n timestamp: number\n }\n}\n\nexport type InboundAction = \"addContext\" | \"appendInput\" | \"sendMessage\"\n\nexport interface InboundEnvelope {\n __bladeBridge: true\n direction: \"host-to-agent\"\n action: InboundAction\n payload: unknown\n}\n\nexport function isCommandEnvelope(value: unknown): value is CommandEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"agent-to-host\" &&\n typeof record.action === \"string\"\n )\n}\n\nexport function isInboundEnvelope(value: unknown): value is InboundEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"host-to-agent\" &&\n (record.action === \"addContext\" || record.action === \"appendInput\" || record.action === \"sendMessage\")\n )\n}\n","import type { PostChatFollowup, TurnProjection } from \"./projection\"\n\n/** 返回最新根会话轮次的小结;新用户消息到达后旧小结立即失效。 */\nexport function latestPostChatFollowup(turns: TurnProjection[]): PostChatFollowup | null {\n for (let index = turns.length - 1; index >= 0; index -= 1) {\n const turn = turns[index]\n if (\n turn.loop_id === \"root\" &&\n (turn.role === \"user\" || turn.role === \"assistant\") &&\n (turn.kind ?? \"message\") === \"message\" &&\n !turn.blocks.some((block) =>\n [\"mode_change\", \"plan_status\", \"ask_user_answer\"].includes(block.type),\n )\n ) {\n return turn.role === \"assistant\" ? (turn.post_chat_followup ?? null) : null\n }\n }\n return null\n}\n","export enum LayoutType {\n Default = \"default\",\n SkillEditor = \"skill-editor\",\n SolutionEditor = \"solution-editor\",\n SolutionApp = \"solution-app\",\n Custom = \"custom\",\n}\n\nexport interface Solution {\n id: string\n name: string\n version: string\n description?: string | null\n source?: \"builtin\" | \"personal\" | string | null\n layout_type: LayoutType | string\n initial_mode?: \"planning\" | \"executing\" | string | null\n initial_message?: string | null\n preview?: { url: string; title?: string | null } | null\n layout?: {\n available?: boolean\n source_dir?: string\n entry?: string\n export?: string\n } | null\n roles?: BizRole[] | null\n data?: Record<string, unknown> | null\n ui_config?: SolutionAppUiConfig | null\n}\n\nexport interface SolutionAppUiConfig {\n branding: {\n name: string\n subtitle?: string\n icon_text: string\n icon_gradient?: string\n }\n list: {\n title: string\n create_button: string\n card?: {\n subtitle?: string\n stats?: Array<{\n label: string\n value: string\n color?: string\n }>\n }\n }\n create: {\n title: string\n description?: string\n submit_button: string\n sections: Array<{\n id: string\n title: string\n description?: string\n fields: Array<SolutionAppField>\n }>\n }\n}\n\nexport type SolutionAppField =\n | {\n id: string\n kind: \"textarea\"\n label: string\n placeholder?: string\n }\n | {\n id: string\n kind: \"file-upload\"\n accept?: string[]\n categories?: Array<{\n label: string\n description: string\n color: string\n }>\n }\n\nexport interface SolutionAppState {\n pipeline: Array<{\n id: string\n label: string\n status: \"done\" | \"active\" | \"pending\" | \"error\"\n }>\n meta: Record<\n string,\n {\n label: string\n value: string\n color?: string\n }\n >\n}\n\nexport interface BizRole {\n id: string\n name: string\n description?: string | null\n preview?: { url: string; title?: string | null } | null\n}\n","import { type } from \"arktype\"\n\nexport const TaskStatus = type(\"'pending' | 'in_progress' | 'done' | 'failed' | 'skipped'\")\nexport type TaskStatus = typeof TaskStatus.infer\n\nexport const Task = type({\n id: \"string\",\n goal: \"string\",\n skills: \"string[]\",\n depends_on: \"string[]\",\n status: TaskStatus,\n result_summary: \"string\",\n number: \"string\",\n})\nexport type Task = typeof Task.infer\n"],"mappings":"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","names":["LayoutType"]}
1
+ {"version":3,"sources":["../src/polling-backoff.ts","../src/platform-endpoints.ts","../src/commands/protocol.ts","../src/schemas/projection-utils.ts","../src/schemas/solution.ts","../src/schemas/task.ts"],"sourcesContent":["import { BladeApiError } from \"./rest\"\n\nconst MAX_BACKOFF_MS = 60_000\nconst MAX_TIMER_MS = 2_147_483_647\n\n/** Scheduling policy for read-only polling; never sends or replays a request. */\nexport class PollingBackoff {\n private failures = 0\n private nextAt: number | false = 0\n\n constructor(private readonly intervalMs: number) {\n if (!Number.isFinite(intervalMs) || intervalMs <= 0 || intervalMs > MAX_BACKOFF_MS) {\n throw new RangeError(\"Polling interval must be between 0 and 60000 ms\")\n }\n }\n\n reset(): void {\n this.failures = 0\n this.nextAt = 0\n }\n\n failed(error: unknown): void {\n if (\n (error instanceof Error && error.name === \"AbortError\") ||\n (error instanceof BladeApiError && error.status < 500 &&\n error.status !== 408 && error.status !== 429)\n ) {\n this.nextAt = false\n return\n }\n this.failures = Math.min(this.failures + 1, 10)\n const ceiling = Math.min(MAX_BACKOFF_MS, this.intervalMs * 2 ** this.failures)\n const backoff = Math.max(this.intervalMs, ceiling * (0.5 + Math.random() * 0.5))\n const header = error instanceof BladeApiError\n ? error.response.headers.get(\"Retry-After\")?.trim()\n : undefined\n const retryAfter = header\n ? /^\\d+$/.test(header) ? Number(header) * 1000 : Date.parse(header) - Date.now()\n : 0\n const delay = Math.max(backoff, Number.isNaN(retryAfter) ? 0 : retryAfter)\n // Oversized server delays must not overflow browser timers into a hot loop.\n this.nextAt = delay > MAX_TIMER_MS ? false : Date.now() + delay\n }\n\n /** Zero means ready, false means stop, otherwise wait at least this many ms. */\n waitMs(): number | false {\n return this.nextAt === false ? false : Math.max(0, this.nextAt - Date.now())\n }\n}\n","import { isRecord } from \"./shared/type-guards\"\n\nexport const PLATFORM_SERVICE_NAMES = [\n \"os\",\n \"hub\",\n \"agent\",\n \"oauth\",\n \"llmGateway\",\n \"gitea\",\n \"tile\",\n] as const\n\nexport type PlatformServiceName = (typeof PLATFORM_SERVICE_NAMES)[number]\n\nexport interface PlatformEndpoints {\n services: Partial<Record<PlatformServiceName, string>>\n}\n\nexport const EMPTY_PLATFORM_ENDPOINTS: PlatformEndpoints = Object.freeze({\n services: Object.freeze({}),\n})\n\nexport interface LoadPlatformEndpointsOptions {\n baseUrl?: string\n fetchImpl?: typeof fetch\n timeoutMs?: number\n}\n\nfunction defaultDocumentBaseUrl(): string | undefined {\n if (typeof document === \"undefined\") return undefined\n if (document.querySelector(\"base[href]\")) return document.baseURI\n if (typeof location !== \"undefined\" && location.origin) return `${location.origin}/`\n return document.baseURI\n}\n\nfunction normalizeServiceUrl(value: unknown): string | null {\n if (typeof value !== \"string\" || !value.trim()) return null\n if (value.includes(\"?\") || value.includes(\"#\")) return null\n try {\n const url = new URL(value.trim())\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return null\n if (url.username || url.password || url.search || url.hash) return null\n return url.toString().replace(/\\/$/, \"\")\n } catch {\n return null\n }\n}\n\nexport function parsePlatformEndpoints(value: unknown): PlatformEndpoints | null {\n if (!isRecord(value) || !isRecord(value.services)) return null\n\n const services: Partial<Record<PlatformServiceName, string>> = {}\n for (const name of PLATFORM_SERVICE_NAMES) {\n if (!(name in value.services)) continue\n const url = normalizeServiceUrl(value.services[name])\n if (!url) return null\n if (name === \"agent\" && new URL(url).pathname !== \"/\") return null\n services[name] = url\n }\n\n return { services }\n}\n\nexport async function loadPlatformEndpoints(\n options: LoadPlatformEndpointsOptions = {},\n): Promise<PlatformEndpoints> {\n const fetchImpl = options.fetchImpl ?? globalThis.fetch\n const baseUrl = options.baseUrl ?? defaultDocumentBaseUrl()\n if (!fetchImpl || !baseUrl) return EMPTY_PLATFORM_ENDPOINTS\n\n const controller = new AbortController()\n const timeout = globalThis.setTimeout(() => controller.abort(), options.timeoutMs ?? 3_000)\n try {\n const response = await fetchImpl(new URL(\"config.json\", baseUrl), {\n cache: \"no-store\",\n credentials: \"same-origin\",\n headers: { Accept: \"application/json\" },\n signal: controller.signal,\n })\n if (!response.ok) return EMPTY_PLATFORM_ENDPOINTS\n return parsePlatformEndpoints(await response.json()) ?? EMPTY_PLATFORM_ENDPOINTS\n } catch {\n return EMPTY_PLATFORM_ENDPOINTS\n } finally {\n globalThis.clearTimeout(timeout)\n }\n}\n\nexport function resolveServiceUrl(\n endpoints: PlatformEndpoints,\n name: PlatformServiceName,\n path = \"\",\n): string | null {\n const baseUrl = endpoints.services[name]\n if (!baseUrl) return null\n if (!path) return baseUrl\n const pathReference = path.trimStart()\n if (\n path.includes(\"\\\\\") ||\n pathReference.startsWith(\"//\") ||\n /^[a-z][a-z0-9+.-]*:/i.test(pathReference)\n ) {\n return null\n }\n const base = new URL(`${baseUrl}/`)\n const target = new URL(path.replace(/^\\/+/, \"\"), base)\n if (target.origin !== base.origin || !target.pathname.startsWith(base.pathname)) {\n return null\n }\n return target.toString()\n}\n","/**\n * 页面协作协议(对应后端 `_meta.bridge` 通道,见 docs/specs/260417-embed-bridge)。\n *\n * ## action 从哪里来\n *\n * 智能体 → 宿主方向的每一条指令,都源自**技能作者写的工具代码**:工具返回值\n * JSON 里带 `_meta.bridge: { action, payload }`,后端在持久化前把它剥离成独立\n * 事件送达前端(LLM 的对话历史里读不到它)。因此:\n *\n * - action 字符串(如 \"map.highlight\")是**技能作者与宿主页面开发者之间的业务\n * 契约**,LLM 不参与协议、SDK 不做枚举校验;\n * - 宿主页面用 `session.onCommand(\"map.highlight\", fn)` 消费;\n * - 未注册 handler 的 action 会进入有限缓冲等待注册,超限后丢弃并 console 告警。\n *\n * 宿主 → 智能体方向只有三个白名单动作:attach(附件入输入框)/ insertText\n * (追加输入文本)/ send(直接发消息),对应协议层的 addContext / appendInput /\n * sendMessage。\n */\n\nexport interface CommandEnvelope {\n __bladeBridge: true\n direction: \"agent-to-host\"\n action: string\n payload: unknown\n meta: {\n sessionId: string\n toolCallId?: string\n timestamp: number\n }\n}\n\nexport type InboundAction = \"addContext\" | \"appendInput\" | \"sendMessage\"\n\nexport interface InboundEnvelope {\n __bladeBridge: true\n direction: \"host-to-agent\"\n action: InboundAction\n payload: unknown\n}\n\nexport function isCommandEnvelope(value: unknown): value is CommandEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"agent-to-host\" &&\n typeof record.action === \"string\"\n )\n}\n\nexport function isInboundEnvelope(value: unknown): value is InboundEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"host-to-agent\" &&\n (record.action === \"addContext\" || record.action === \"appendInput\" || record.action === \"sendMessage\")\n )\n}\n","import type { PostChatFollowup, TurnProjection } from \"./projection\"\n\n/** 返回最新根会话轮次的小结;新用户消息到达后旧小结立即失效。 */\nexport function latestPostChatFollowup(turns: TurnProjection[]): PostChatFollowup | null {\n for (let index = turns.length - 1; index >= 0; index -= 1) {\n const turn = turns[index]\n if (\n turn.loop_id === \"root\" &&\n (turn.role === \"user\" || turn.role === \"assistant\") &&\n (turn.kind ?? \"message\") === \"message\" &&\n !turn.blocks.some((block) =>\n [\"mode_change\", \"plan_status\", \"ask_user_answer\"].includes(block.type),\n )\n ) {\n return turn.role === \"assistant\" ? (turn.post_chat_followup ?? null) : null\n }\n }\n return null\n}\n","export enum LayoutType {\n Default = \"default\",\n SkillEditor = \"skill-editor\",\n SolutionEditor = \"solution-editor\",\n SolutionApp = \"solution-app\",\n Custom = \"custom\",\n}\n\nexport interface Solution {\n id: string\n name: string\n version: string\n description?: string | null\n source?: \"builtin\" | \"personal\" | string | null\n layout_type: LayoutType | string\n initial_mode?: \"planning\" | \"executing\" | string | null\n initial_message?: string | null\n preview?: { url: string; title?: string | null } | null\n layout?: {\n available?: boolean\n source_dir?: string\n entry?: string\n export?: string\n } | null\n roles?: BizRole[] | null\n data?: Record<string, unknown> | null\n ui_config?: SolutionAppUiConfig | null\n}\n\nexport interface SolutionAppUiConfig {\n branding: {\n name: string\n subtitle?: string\n icon_text: string\n icon_gradient?: string\n }\n list: {\n title: string\n create_button: string\n card?: {\n subtitle?: string\n stats?: Array<{\n label: string\n value: string\n color?: string\n }>\n }\n }\n create: {\n title: string\n description?: string\n submit_button: string\n sections: Array<{\n id: string\n title: string\n description?: string\n fields: Array<SolutionAppField>\n }>\n }\n}\n\nexport type SolutionAppField =\n | {\n id: string\n kind: \"textarea\"\n label: string\n placeholder?: string\n }\n | {\n id: string\n kind: \"file-upload\"\n accept?: string[]\n categories?: Array<{\n label: string\n description: string\n color: string\n }>\n }\n\nexport interface SolutionAppState {\n pipeline: Array<{\n id: string\n label: string\n status: \"done\" | \"active\" | \"pending\" | \"error\"\n }>\n meta: Record<\n string,\n {\n label: string\n value: string\n color?: string\n }\n >\n}\n\nexport interface BizRole {\n id: string\n name: string\n description?: string | null\n preview?: { url: string; title?: string | null } | null\n}\n","import { type } from \"arktype\"\n\nexport const TaskStatus = type(\"'pending' | 'in_progress' | 'done' | 'failed' | 'skipped'\")\nexport type TaskStatus = typeof TaskStatus.infer\n\nexport const Task = type({\n id: \"string\",\n goal: \"string\",\n skills: \"string[]\",\n depends_on: \"string[]\",\n status: TaskStatus,\n result_summary: \"string\",\n number: \"string\",\n})\nexport type Task = typeof Task.infer\n"],"mappings":"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","names":["LayoutType"]}
@@ -1,4 +1,5 @@
1
1
  import type { BladeClient } from "../blade-client";
2
+ export type ChatGroupRole = "owner" | "editor" | "viewer";
2
3
  export interface ChatGroup {
3
4
  id: string;
4
5
  name: string;
@@ -6,12 +7,67 @@ export interface ChatGroup {
6
7
  created_at: string;
7
8
  updated_at: string;
8
9
  session_count: number;
10
+ member_count: number;
11
+ role: ChatGroupRole;
9
12
  initiator: "ui" | "sdk" | null;
10
13
  workspace_path: string;
11
14
  }
15
+ export interface ChatGroupMember {
16
+ user_id: string;
17
+ display_name: string | null;
18
+ username: string;
19
+ role: ChatGroupRole;
20
+ added_by: string;
21
+ added_at: string;
22
+ }
23
+ export interface ChatGroupTask {
24
+ id: string;
25
+ group_id: string;
26
+ number: number;
27
+ title: string;
28
+ description: string;
29
+ owner_user_id: string;
30
+ owner_display_name: string;
31
+ owner_left: boolean;
32
+ due_date: string | null;
33
+ status: "todo" | "doing" | "done";
34
+ /** Only returned to the owner of this private session. */
35
+ session_id: string | null;
36
+ can_open_session: boolean;
37
+ agent_started: boolean;
38
+ created_by: string;
39
+ created_at: string;
40
+ updated_at: string;
41
+ }
42
+ export interface CreateChatGroupTask {
43
+ title: string;
44
+ description?: string;
45
+ owner_user_id: string;
46
+ due_date?: string | null;
47
+ start_agent?: boolean;
48
+ }
49
+ export interface UpdateChatGroupTask extends Partial<Omit<CreateChatGroupTask, "start_agent">> {
50
+ status?: ChatGroupTask["status"];
51
+ }
52
+ export interface ChatGroupAsset {
53
+ path: string;
54
+ is_dir: boolean;
55
+ size: number;
56
+ sha256: string;
57
+ submitted_by: string;
58
+ submitted_by_name: string;
59
+ session_id: string | null;
60
+ message: string;
61
+ updated_at: string;
62
+ }
63
+ export interface ChatGroupAssetList {
64
+ group_id: string;
65
+ items: ChatGroupAsset[];
66
+ }
12
67
  export declare class ChatGroupsResource {
13
68
  private readonly client;
14
69
  constructor(client: BladeClient);
70
+ private path;
15
71
  list(): Promise<ChatGroup[]>;
16
72
  create(payload: {
17
73
  name: string;
@@ -28,4 +84,40 @@ export declare class ChatGroupsResource {
28
84
  deleted: boolean;
29
85
  deleted_sessions: number;
30
86
  }>;
87
+ listMembers(groupId: string): Promise<ChatGroupMember[]>;
88
+ addMembers(groupId: string, userIds: string[], role: "editor" | "viewer"): Promise<ChatGroupMember[]>;
89
+ updateMember(groupId: string, userId: string, role: "editor" | "viewer"): Promise<ChatGroupMember>;
90
+ removeMember(groupId: string, userId: string): Promise<{
91
+ deleted: boolean;
92
+ }>;
93
+ listTasks(groupId: string): Promise<ChatGroupTask[]>;
94
+ createTask(groupId: string, payload: CreateChatGroupTask): Promise<ChatGroupTask>;
95
+ updateTask(groupId: string, taskId: string, payload: UpdateChatGroupTask): Promise<ChatGroupTask>;
96
+ deleteTask(groupId: string, taskId: string): Promise<{
97
+ deleted: boolean;
98
+ }>;
99
+ listAssets(groupId: string): Promise<ChatGroupAssetList>;
100
+ readAsset(groupId: string, path: string, signal?: AbortSignal): Promise<Blob>;
101
+ /** Read at most the first 1 MiB. Full downloads continue to use readAsset. */
102
+ readAssetPreview(groupId: string, path: string, signal?: AbortSignal): Promise<{
103
+ blob: Blob;
104
+ truncated: boolean;
105
+ }>;
106
+ uploadAsset(groupId: string, file: File, path: string, message?: string): Promise<{
107
+ file: ChatGroupAsset;
108
+ }>;
109
+ createAssetFolder(groupId: string, path: string): Promise<{
110
+ file: ChatGroupAsset;
111
+ }>;
112
+ deleteAsset(groupId: string, path: string): Promise<{
113
+ deleted: boolean;
114
+ }>;
115
+ submitSessionAsset(payload: {
116
+ session_id: string;
117
+ path: string;
118
+ target_path: string;
119
+ message?: string;
120
+ }): Promise<{
121
+ file: ChatGroupAsset;
122
+ }>;
31
123
  }
@@ -1,9 +1,13 @@
1
+ import type { TopicAssetRef } from "../schemas/topic-assets";
1
2
  import type { BladeClient } from "../blade-client";
2
3
  export type JsonSchemaObject = Record<string, unknown>;
3
4
  export interface HeadlessRunOptions {
4
5
  schema?: JsonSchemaObject | null;
5
6
  model?: string | null;
6
7
  timeoutMs?: number;
8
+ /** Assets explicitly selected for this message in a topic-linked session. */
9
+ refs?: import("../schemas/plugin-refs").MessageRef[];
10
+ topicAssetRefs?: TopicAssetRef[];
7
11
  }
8
12
  export interface HeadlessRunInSessionResult<T = unknown> {
9
13
  session_id: string;
@@ -16,6 +20,7 @@ export declare class HeadlessError extends Error {
16
20
  }
17
21
  export declare class HeadlessResource {
18
22
  private client;
23
+ private readonly subscriptions;
19
24
  constructor(client: BladeClient);
20
25
  run<T = unknown>(prompt: string, options: HeadlessRunOptions & {
21
26
  schema: JsonSchemaObject;
@@ -16,6 +16,7 @@ export interface PluginCatalogEntry {
16
16
  */
17
17
  icon: string | null;
18
18
  /** 当前用户是否安装了它。 */
19
+ auth_status?: "login_required" | "ready" | "expired" | "unavailable";
19
20
  installed: boolean;
20
21
  }
21
22
  /**
@@ -1,7 +1,7 @@
1
1
  import type { BackgroundTask, BackgroundTaskStopResult } from "../schemas/background";
2
2
  import type { TurnProjection } from "../schemas/projection";
3
3
  import type { McpAppArchive } from "../schemas/mcp-app";
4
- import type { PublishedSolutionRef, ReplayPreview, ReplaySpeed, SessionDetail, SessionInfo, TemplateId } from "../schemas/session";
4
+ import type { PublishedSolutionRef, ReplayPreview, ReplaySpeed, SessionDetail, SessionInfo } from "../schemas/session";
5
5
  import type { McpAppContextState, McpAppContextUpdate } from "../schemas/mcp-app";
6
6
  import type { Task } from "../schemas/task";
7
7
  import type { BladeClient, UploadProgress } from "../blade-client";
@@ -52,6 +52,14 @@ export interface SessionPluginConfigError {
52
52
  /** Value-free message; the platform never echoes submitted secrets. */
53
53
  message: string;
54
54
  }
55
+ export interface SessionPluginHostState {
56
+ digest: string;
57
+ revision: string;
58
+ state: string;
59
+ reason: string;
60
+ restarts: number;
61
+ recent?: string[];
62
+ }
55
63
  export interface SessionPluginConfigState {
56
64
  state: SessionPluginConfigStateName;
57
65
  reason: string | null;
@@ -64,6 +72,8 @@ export interface SessionPluginConfigState {
64
72
  /** Opaque revision for optimistic concurrency; null when nothing is stored. */
65
73
  revision: string | null;
66
74
  errors: SessionPluginConfigError[];
75
+ auth_status?: "login_required" | "ready" | "expired";
76
+ global_ready?: boolean;
67
77
  }
68
78
  export interface SessionPluginConfigSet {
69
79
  /** JSON Pointer; arrays are replaced as a whole. */
@@ -77,8 +87,11 @@ export interface SessionPluginConfigUpdate {
77
87
  remove?: string[];
78
88
  }
79
89
  export interface CreateSessionRequest {
90
+ /** Notification owner. Built-in Web declares ui; external applications default to sdk. */
91
+ initiator?: "ui" | "sdk";
92
+ /** 认证创建独立匿名沙盒;链接持有者可继续聊天,不继承个人资源。 */
93
+ anonymous?: boolean;
80
94
  intent?: string;
81
- template_id?: TemplateId;
82
95
  /** 正式 Solution 来源。Hub 使用 { source: "hub", org, name }。 */
83
96
  solution_ref?: PublishedSolutionRef;
84
97
  /** @deprecated 请使用结构化的 solution_ref;继续支持以保证现有 SDK 调用无感升级。 */
@@ -86,12 +99,14 @@ export interface CreateSessionRequest {
86
99
  /** 从已有会话复制其不可变 Solution 与 Skill 运行快照。 */
87
100
  solution_snapshot_session_id?: string;
88
101
  biz_role_id?: string | null;
89
- primary_skill_id?: string | null;
90
102
  model?: string | null;
91
103
  enable_thinking?: boolean | null;
92
104
  memory_enabled?: boolean | null;
93
105
  env?: Record<string, string>;
94
106
  disable_tools?: string[] | null;
107
+ mcp_sources?: McpSourceConfig[];
108
+ /** 此会话的所有普通轮次直接执行工具,不弹审批。 */
109
+ skip_confirmations?: boolean;
95
110
  session_solution_asset_id?: string | null;
96
111
  compaction_ratio?: number | null;
97
112
  runtime_type?: "sandbox" | "daemon" | "native" | null;
@@ -100,6 +115,50 @@ export interface CreateSessionRequest {
100
115
  agent_runtime_id?: string | null;
101
116
  chat_group_id?: string | null;
102
117
  }
118
+ export interface McpSourceConfig {
119
+ id: string;
120
+ url: string;
121
+ bearer_token?: string | null;
122
+ exposure?: "lazy" | "eager";
123
+ include_tools?: string[] | null;
124
+ eager_tools?: string[];
125
+ }
126
+ /** Sandbox only. Omitted fields are retained; lists/maps replace their previous value. */
127
+ export interface UpdateSessionConfigurationRequest {
128
+ version: string;
129
+ expected_revision?: number;
130
+ solution_ref?: PublishedSolutionRef;
131
+ solution_id?: string;
132
+ session_solution_asset_id?: string;
133
+ biz_role_id?: string;
134
+ model?: string;
135
+ enable_thinking?: boolean | null;
136
+ memory_enabled?: boolean;
137
+ env?: Record<string, string>;
138
+ disable_tools?: string[];
139
+ mcp_sources?: McpSourceConfig[];
140
+ skip_confirmations?: boolean;
141
+ compaction_ratio?: number | null;
142
+ }
143
+ export interface SessionConfiguration {
144
+ session_id: string;
145
+ version: string | null;
146
+ revision: number;
147
+ configuration: {
148
+ solution_identity: Record<string, unknown> | null;
149
+ solution_version: string | null;
150
+ biz_role_id: string | null;
151
+ biz_role_version: string | null;
152
+ model: string | null;
153
+ enable_thinking: boolean | null;
154
+ memory_enabled: boolean;
155
+ env: Record<string, string>;
156
+ disable_tools: string[];
157
+ mcp_sources: Omit<McpSourceConfig, "bearer_token">[];
158
+ skip_confirmations: boolean;
159
+ compaction_ratio: number | null;
160
+ };
161
+ }
103
162
  export interface CheckpointNode {
104
163
  id: string;
105
164
  parent_id: string | null;
@@ -281,6 +340,7 @@ export interface ImportPreviewSkill {
281
340
  description: string;
282
341
  path: string;
283
342
  }
343
+ /** Legacy archive decode shape only; custom scenario scripts are never executed. */
284
344
  export interface ImportPreviewScenario {
285
345
  scenario?: {
286
346
  name?: string;
@@ -294,6 +354,7 @@ export interface ImportPreview {
294
354
  user_messages: string[];
295
355
  turn_count: number;
296
356
  skills: ImportPreviewSkill[];
357
+ /** Retained for older responses. Current servers always return null. */
297
358
  scenario: ImportPreviewScenario | null;
298
359
  }
299
360
  export interface ImportSessionOptions {
@@ -360,32 +421,36 @@ export declare class SessionsResource {
360
421
  *
361
422
  * Secrets are never returned: `write_only` lists the pointers that hold one.
362
423
  */
363
- getSessionPluginConfig(sessionId: string, name: string, init?: RequestInit): Promise<{
424
+ getSessionPluginConfig(sessionId: string, name: string, init?: RequestInit, scope?: "personal" | "global"): Promise<{
364
425
  plugin: string;
365
426
  config: SessionPluginConfigState;
427
+ can_configure_global?: boolean;
428
+ host?: SessionPluginHostState | null;
366
429
  }>;
367
430
  /**
368
- * Publish explicit set/remove operations to the user's keychain file.
431
+ * Save explicit set/remove operations to encrypted server storage.
369
432
  *
370
433
  * Fields absent from both lists keep their stored value, so a form never has
371
- * to round-trip a secret. Rejections leave the previous file untouched; the
372
- * call never restarts MCP servers.
434
+ * to round-trip a secret. Rejections preserve the previous values; the
435
+ * shared settings restart only the affected hosted plugin.
373
436
  */
374
- updateSessionPluginConfig(sessionId: string, name: string, update: SessionPluginConfigUpdate, init?: RequestInit): Promise<{
437
+ updateSessionPluginConfig(sessionId: string, name: string, update: SessionPluginConfigUpdate, init?: RequestInit, scope?: "personal" | "global"): Promise<{
375
438
  plugin: string;
376
439
  config: SessionPluginConfigState;
377
440
  }>;
441
+ restartSessionPluginHost(sessionId: string, name: string): Promise<{
442
+ host: SessionPluginHostState | null;
443
+ }>;
378
444
  /** 创建新会话并直接连接,返回可收发消息的 AgentSession。 */
379
445
  create(request?: CreateSessionRequest | SessionDefinition): Promise<AgentSession>;
380
446
  private createDeclared;
381
447
  private prepareSolution;
382
448
  private cleanupSolutionAsset;
383
449
  private fetchSessionsPage;
384
- listSessions(template_id_prefix?: string, solution_id?: string): Promise<SessionInfo[]>;
450
+ listSessions(solution_id?: string): Promise<SessionInfo[]>;
385
451
  listSessionsPaginated(params: {
386
452
  limit: number;
387
453
  offset: number;
388
- template_id_prefix?: string;
389
454
  solution_id?: string;
390
455
  solution_registry_id?: string;
391
456
  q?: string;
@@ -396,7 +461,7 @@ export declare class SessionsResource {
396
461
  q: string;
397
462
  limit?: number;
398
463
  }): Promise<GlobalSearchResult>;
399
- createSession(intent?: string, template_id?: TemplateId, primary_skill_id?: string | null): Promise<{
464
+ createSession(intent?: string): Promise<{
400
465
  session_id: string;
401
466
  }>;
402
467
  createSessionWithRequest(request: CreateSessionRequest): Promise<{
@@ -413,6 +478,9 @@ export declare class SessionsResource {
413
478
  intent?: string;
414
479
  chat_group_id?: string | null;
415
480
  }): Promise<SessionDetail>;
481
+ getSessionConfiguration(sessionId: string, init?: RequestInit): Promise<SessionConfiguration>;
482
+ /** Updates atomically between turns. A running/handoff session returns HTTP 409. */
483
+ updateSessionConfiguration(sessionId: string, request: UpdateSessionConfigurationRequest): Promise<SessionConfiguration>;
416
484
  setSessionEnv(sessionId: string, env: Record<string, string>): Promise<SessionDetail>;
417
485
  pinSession(sessionId: string, pinned: boolean): Promise<SessionInfo>;
418
486
  startReplaySession(sourceSessionId: string, speed?: ReplaySpeed): Promise<{
@@ -478,15 +546,30 @@ export declare class SessionsResource {
478
546
  mode?: string;
479
547
  files_restored?: boolean;
480
548
  linear?: boolean;
549
+ history_committed?: boolean;
550
+ file_checkpoint_cleanup_failed?: boolean;
551
+ warning?: string;
481
552
  }>;
482
553
  rewindSession(sessionId: string, checkpointId: string): Promise<{
483
554
  id: string;
484
555
  content: string;
556
+ history_committed?: boolean;
557
+ file_checkpoint_cleanup_failed?: boolean;
558
+ warning?: string;
485
559
  }>;
486
560
  switchBranch(sessionId: string, checkpointId: string): Promise<{
487
561
  id: string;
488
562
  leaf_id: string;
489
563
  }>;
564
+ listAnonymousSessions(): Promise<Array<{
565
+ id: string;
566
+ intent: string;
567
+ created_at: string;
568
+ status: string;
569
+ }>>;
570
+ deleteAnonymousSession(sessionId: string): Promise<{
571
+ deleted: boolean;
572
+ }>;
490
573
  deleteSession(sessionId: string, options?: {
491
574
  deleteWorkspace?: boolean;
492
575
  }): Promise<{
@@ -0,0 +1,16 @@
1
+ /** Frozen application data belonging to one message. The server does not interpret business types. */
2
+ export interface ContextAttachment {
3
+ id: string;
4
+ label: string;
5
+ content: string;
6
+ data?: Record<string, unknown> | null;
7
+ files?: Array<{
8
+ name: string;
9
+ session_id?: string;
10
+ path?: string;
11
+ }>;
12
+ }
13
+ /** Validate before persisting a reliable request. JSON cloning also rejects cycles. */
14
+ export declare function snapshotContextAttachments(value: ContextAttachment[]): ContextAttachment[];
15
+ /** Server-owned snapshots travel unchanged through stream and history projections. */
16
+ export declare function normalizeContextAttachments(value: unknown): ContextAttachment[];
@@ -1,3 +1,4 @@
1
+ import type { ToolEvidence } from "./projection";
1
2
  export interface ContentDelta {
2
3
  content: string;
3
4
  loop_name?: string;
@@ -21,6 +22,7 @@ export interface ToolCallArgumentsDelta {
21
22
  arguments_delta: string;
22
23
  }
23
24
  export interface ToolResultDone {
25
+ evidence?: ToolEvidence[];
24
26
  tool_call_id: string;
25
27
  loop_name?: string;
26
28
  function: {
@@ -24,21 +24,15 @@ export declare function buildMessageContent(text: string, attachments: Array<{
24
24
  mimeType?: string;
25
25
  }>): MessageContent;
26
26
  export declare function contentPreview(content: MessageContent, maxLen?: number): string;
27
- /** `/` 选中的技能当前处于什么状态,决定智能体要不要先装、先加载。 */
27
+ /** @deprecated 技能可用状态由运行时解析,发送身份请使用 SkillRef。 */
28
28
  export interface SkillMentionAvailability {
29
29
  /** 本地已有(内置 / 技能目录 / 会话已加载),直接可用。 */
30
30
  local?: boolean;
31
31
  /** Blade Hub 上该账号是否已安装。本地技能恒为 true。 */
32
32
  installed?: boolean;
33
33
  }
34
- /**
35
- * Transform a skill mention into a natural language skill invocation.
36
- * Strips the `<skill>name</skill>` tag from the raw input and prepends the instruction.
37
- *
38
- * Hub 技能装没装、加载没加载,用户不需要知道,但智能体需要——所以把状态翻译
39
- * 成它能直接照做的 CLI 步骤。不传 availability 时按本地技能处理,与旧行为一致。
40
- */
41
- export declare function transformSlashCommand(skillName: string, rawInput: string, { local, installed }?: SkillMentionAvailability): string;
34
+ /** Serialize a skill marker as user text. Send its identity separately in refs. */
35
+ export declare function transformSlashCommand(skillName: string, rawInput: string, _availability?: SkillMentionAvailability): string;
42
36
  export interface ParsedTextAttachment {
43
37
  name: string;
44
38
  uploadedPath?: string;