@blade-hq/agent-kit 0.5.29 → 0.5.31

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useSessionStore
3
- } from "./chunk-JWHBUVSM.js";
3
+ } from "./chunk-OPMRX65X.js";
4
4
 
5
5
  // src/react/hooks/use-session.ts
6
6
  function useSession() {
@@ -27,4 +27,4 @@ function useSession() {
27
27
  export {
28
28
  useSession
29
29
  };
30
- //# sourceMappingURL=chunk-EP5LVNO3.js.map
30
+ //# sourceMappingURL=chunk-4XBNTPVS.js.map
@@ -5,12 +5,12 @@ import {
5
5
  import {
6
6
  getSessionFilePath,
7
7
  resolveSessionFilePreviewTarget
8
- } from "./chunk-XLQZDSJ5.js";
8
+ } from "./chunk-KMQQDKGU.js";
9
9
  import {
10
10
  formatToolName,
11
11
  getAuthedUrl,
12
12
  useUiStore
13
- } from "./chunk-JWHBUVSM.js";
13
+ } from "./chunk-OPMRX65X.js";
14
14
  import {
15
15
  cn,
16
16
  copyToClipboard
@@ -1933,4 +1933,4 @@ export {
1933
1933
  PlanSummaryCard,
1934
1934
  extractLatestPlanMessages
1935
1935
  };
1936
- //# sourceMappingURL=chunk-NIWUUKD4.js.map
1936
+ //# sourceMappingURL=chunk-BUQRNLEE.js.map
@@ -8,7 +8,7 @@ import {
8
8
  getCodeLanguageFromFilename,
9
9
  parseAskUserQuestion,
10
10
  useHighlightedCodeHtml
11
- } from "./chunk-NIWUUKD4.js";
11
+ } from "./chunk-BUQRNLEE.js";
12
12
  import {
13
13
  Collapsible,
14
14
  CollapsibleContent,
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-H62LH2AG.js";
17
17
  import {
18
18
  resolveSessionFilePreviewTarget
19
- } from "./chunk-XLQZDSJ5.js";
19
+ } from "./chunk-KMQQDKGU.js";
20
20
  import {
21
21
  apiFetchResponse,
22
22
  buildMessageContent,
@@ -60,7 +60,7 @@ import {
60
60
  useUiBridgeStore,
61
61
  useUiStore,
62
62
  writeFile
63
- } from "./chunk-JWHBUVSM.js";
63
+ } from "./chunk-OPMRX65X.js";
64
64
  import {
65
65
  registerBridgeIframe,
66
66
  tapBridgeEvent
@@ -8534,4 +8534,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
8534
8534
  * Licensed under the MIT License. See License.txt in the project root for license information.
8535
8535
  *--------------------------------------------------------------------------------------------*)
8536
8536
  */
8537
- //# sourceMappingURL=chunk-UIQ35OUJ.js.map
8537
+ //# sourceMappingURL=chunk-HFVB57MR.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  apiFetchResponse,
3
3
  getAuthedUrl
4
- } from "./chunk-JWHBUVSM.js";
4
+ } from "./chunk-OPMRX65X.js";
5
5
 
6
6
  // src/react/lib/session-file-preview.ts
7
7
  var IMAGE_EXTS = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "svg", "webp", "ico", "bmp"]);
@@ -26,11 +26,9 @@ function getSessionFileDownloadUrl(sessionId, filePath) {
26
26
  function isTextualContentType(contentType) {
27
27
  return contentType.startsWith("text/") || contentType.includes("json") || contentType.includes("xml") || contentType.includes("yaml") || contentType.includes("javascript");
28
28
  }
29
- function buildSessionBinaryPreviewTarget(sessionId, filePath, fileName) {
29
+ function buildBinaryPreviewTarget(fileUrl, downloadUrl, filePath, fileName) {
30
30
  const resolvedFileName = getDisplayFileName(filePath, fileName);
31
31
  const ext = getExt(resolvedFileName);
32
- const filePathUrl = getSessionFilePath(sessionId, filePath);
33
- const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath);
34
32
  if (IMAGE_EXTS.has(ext)) {
35
33
  return { type: "image", content: downloadUrl, title: resolvedFileName, key: filePath };
36
34
  }
@@ -46,7 +44,7 @@ function buildSessionBinaryPreviewTarget(sessionId, filePath, fileName) {
46
44
  if (PPT_EXTS.has(ext)) {
47
45
  return {
48
46
  type: "ppt",
49
- content: filePathUrl,
47
+ content: fileUrl,
50
48
  sourceUrl: downloadUrl,
51
49
  title: resolvedFileName,
52
50
  key: filePath
@@ -54,6 +52,11 @@ function buildSessionBinaryPreviewTarget(sessionId, filePath, fileName) {
54
52
  }
55
53
  return null;
56
54
  }
55
+ function buildSessionBinaryPreviewTarget(sessionId, filePath, fileName) {
56
+ const fileUrl = getSessionFilePath(sessionId, filePath);
57
+ const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath);
58
+ return buildBinaryPreviewTarget(fileUrl, downloadUrl, filePath, fileName);
59
+ }
57
60
  function resolveTextPreviewType(fileName) {
58
61
  const ext = getExt(fileName);
59
62
  if (MARKDOWN_EXTS.has(ext)) return "markdown";
@@ -93,8 +96,9 @@ async function resolveSessionFilePreviewTarget(sessionId, filePath, fileName) {
93
96
 
94
97
  export {
95
98
  getSessionFilePath,
99
+ buildBinaryPreviewTarget,
96
100
  buildSessionBinaryPreviewTarget,
97
101
  resolveTextPreviewType,
98
102
  resolveSessionFilePreviewTarget
99
103
  };
100
- //# sourceMappingURL=chunk-XLQZDSJ5.js.map
104
+ //# sourceMappingURL=chunk-KMQQDKGU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/lib/session-file-preview.ts"],"sourcesContent":["import { apiFetchResponse, getAuthedUrl } from \"../api/client\"\nimport type { PreviewTarget } from \"../stores/ui-store\"\n\nconst IMAGE_EXTS = new Set([\"png\", \"jpg\", \"jpeg\", \"gif\", \"svg\", \"webp\", \"ico\", \"bmp\"])\nconst DOCX_EXTS = new Set([\"docx\", \"doc\"])\nconst EXCEL_EXTS = new Set([\"xlsx\", \"xls\", \"xlsm\", \"xlsb\"])\nconst PPT_EXTS = new Set([\"pptx\", \"ppt\"])\nconst CSV_EXTS = new Set([\"csv\"])\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\"])\nconst HTML_EXTS = new Set([\"html\", \"htm\"])\n\nfunction getExt(fileName: string): string {\n return fileName.split(\".\").pop()?.toLowerCase() ?? \"\"\n}\n\nfunction getDisplayFileName(filePath: string, fileName?: string): string {\n return fileName?.trim() || filePath.split(\"/\").pop() || filePath\n}\n\nexport function getSessionFilePath(sessionId: string, filePath: string): string {\n return `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`\n}\n\nfunction getSessionFileDownloadUrl(sessionId: string, filePath: string): string {\n return getAuthedUrl(getSessionFilePath(sessionId, filePath))\n}\n\n/**\n * 后端把可解码为 UTF-8 的文件返回为 text/plain,二进制文件返回各自的 MIME。\n * 只有文本类内容才能安全地整体读进内存渲染——其余一律不能读 body。\n */\nfunction isTextualContentType(contentType: string): boolean {\n return (\n contentType.startsWith(\"text/\") ||\n contentType.includes(\"json\") ||\n contentType.includes(\"xml\") ||\n contentType.includes(\"yaml\") ||\n contentType.includes(\"javascript\")\n )\n}\n\nexport function buildBinaryPreviewTarget(\n fileUrl: string,\n downloadUrl: string,\n filePath: string,\n fileName?: string,\n): PreviewTarget | null {\n const resolvedFileName = getDisplayFileName(filePath, fileName)\n const ext = getExt(resolvedFileName)\n\n if (IMAGE_EXTS.has(ext)) {\n return { type: \"image\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (ext === \"pdf\") {\n return { type: \"pdf\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (DOCX_EXTS.has(ext)) {\n return { type: \"docx\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (EXCEL_EXTS.has(ext)) {\n return { type: \"excel\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (PPT_EXTS.has(ext)) {\n return {\n type: \"ppt\",\n content: fileUrl,\n sourceUrl: downloadUrl,\n title: resolvedFileName,\n key: filePath,\n }\n }\n\n return null\n}\n\nexport function buildSessionBinaryPreviewTarget(\n sessionId: string,\n filePath: string,\n fileName?: string,\n): PreviewTarget | null {\n const fileUrl = getSessionFilePath(sessionId, filePath)\n const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath)\n return buildBinaryPreviewTarget(fileUrl, downloadUrl, filePath, fileName)\n}\n\nexport function resolveTextPreviewType(fileName: string): PreviewTarget[\"type\"] {\n const ext = getExt(fileName)\n if (MARKDOWN_EXTS.has(ext)) return \"markdown\"\n if (CSV_EXTS.has(ext)) return \"csv\"\n if (HTML_EXTS.has(ext)) return \"html\"\n return \"file\"\n}\n\nexport async function resolveSessionFilePreviewTarget(\n sessionId: string,\n filePath: string,\n fileName?: string,\n): Promise<PreviewTarget> {\n const resolvedFileName = getDisplayFileName(filePath, fileName)\n const binaryTarget = buildSessionBinaryPreviewTarget(sessionId, filePath, resolvedFileName)\n if (binaryTarget) {\n return binaryTarget\n }\n\n const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath)\n\n // 其余文件按后端返回的 Content-Type 分派,而不是猜扩展名:\n // 视频/音频/压缩包等二进制文件绝不能读 body(整体读进内存会卡死页面),\n // 改为把下载 URL 交给原生 <video>/<audio> 流式播放,或回退为下载。\n const res = await apiFetchResponse(getSessionFilePath(sessionId, filePath))\n const contentType = (res.headers.get(\"content-type\") ?? \"\").toLowerCase()\n\n if (contentType.startsWith(\"video/\")) {\n void res.body?.cancel()\n return { type: \"video\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (contentType.startsWith(\"audio/\")) {\n void res.body?.cancel()\n return { type: \"audio\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (!isTextualContentType(contentType)) {\n void res.body?.cancel()\n return { type: \"download\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n const content = await res.text()\n\n return {\n type: resolveTextPreviewType(resolvedFileName),\n content,\n title: resolvedFileName,\n key: filePath,\n }\n}\n"],"mappings":"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","names":[]}
@@ -905,7 +905,11 @@ function upsertArtifactState(state, target, options) {
905
905
  const targetKey = target.key ?? target.title;
906
906
  const applyUiState = (partial) => ({
907
907
  ...partial,
908
- ...reveal ? { rightPanelCollapsed: false, activeRightTab: "preview" } : {}
908
+ ...reveal ? {
909
+ rightPanelCollapsed: false,
910
+ activeRightTab: "preview",
911
+ rightTabActivationId: state.rightTabActivationId + 1
912
+ } : {}
909
913
  });
910
914
  const existing = state.artifacts.findIndex((artifact) => targetKey && (artifact.key ?? artifact.title) === targetKey);
911
915
  if (existing >= 0) {
@@ -929,6 +933,7 @@ var useUiStore = create2()((set) => ({
929
933
  leftPanelCollapsed: false,
930
934
  rightPanelCollapsed: false,
931
935
  activeRightTab: "situation",
936
+ rightTabActivationId: 0,
932
937
  artifacts: [],
933
938
  activeArtifactIndex: -1,
934
939
  theme: storedTheme,
@@ -938,7 +943,10 @@ var useUiStore = create2()((set) => ({
938
943
  setRightPanelCollapsed: (collapsed) => set({ rightPanelCollapsed: collapsed }),
939
944
  toggleLeftPanel: () => set((s) => ({ leftPanelCollapsed: !s.leftPanelCollapsed })),
940
945
  toggleRightPanel: () => set((s) => ({ rightPanelCollapsed: !s.rightPanelCollapsed })),
941
- setActiveRightTab: (tab) => set({ activeRightTab: tab }),
946
+ setActiveRightTab: (tab) => set((state) => ({
947
+ activeRightTab: tab,
948
+ rightTabActivationId: state.rightTabActivationId + 1
949
+ })),
942
950
  pushArtifact: (target) => set((state) => upsertArtifactState(state, target)),
943
951
  upsertArtifact: (target, options) => set((state) => upsertArtifactState(state, target, options)),
944
952
  setActiveArtifact: (index) => set({ activeArtifactIndex: index }),
@@ -949,7 +957,7 @@ var useUiStore = create2()((set) => ({
949
957
  return removeArtifactAtIndex(state, index);
950
958
  }),
951
959
  clearArtifacts: () => set({ artifacts: [], activeArtifactIndex: -1 }),
952
- setPreviewTarget: (target) => set(() => {
960
+ setPreviewTarget: (target) => set((state) => {
953
961
  if (target === null) {
954
962
  return { artifacts: [], activeArtifactIndex: -1 };
955
963
  }
@@ -957,7 +965,8 @@ var useUiStore = create2()((set) => ({
957
965
  artifacts: [target],
958
966
  activeArtifactIndex: 0,
959
967
  rightPanelCollapsed: false,
960
- activeRightTab: "preview"
968
+ activeRightTab: "preview",
969
+ rightTabActivationId: state.rightTabActivationId + 1
961
970
  };
962
971
  }),
963
972
  setTheme: (theme) => {
@@ -2105,19 +2114,6 @@ function invalidateFileTree(sessionId) {
2105
2114
  if (!queryClient) return;
2106
2115
  void queryClient.invalidateQueries({ queryKey: ["file-tree", sessionId] });
2107
2116
  }
2108
- function shouldSuppressOptimisticUserMessage(sessionId, askuserAnswer) {
2109
- if (askuserAnswer && typeof askuserAnswer.tool_call_id === "string") {
2110
- return true;
2111
- }
2112
- const session = useSessionStore.getState().sessions.find((item) => item.id === sessionId);
2113
- if (session?.status !== "waiting_for_input") {
2114
- return false;
2115
- }
2116
- const messages = useChatStore.getState().messages[sessionId] ?? [];
2117
- return messages.some(
2118
- (message) => (message.tool_calls ?? []).some((toolCall) => toolCall.status === "awaiting_answer")
2119
- );
2120
- }
2121
2117
  function invalidateSkillStats2(sessionId) {
2122
2118
  const queryClient = globalThis.__agentQueryClient;
2123
2119
  if (!queryClient) return;
@@ -2914,13 +2910,6 @@ var AgentSocket = class {
2914
2910
  }
2915
2911
  send(sessionId, message, mode, askuserAnswer, extras) {
2916
2912
  this._ensureConnected();
2917
- const suppressOptimisticUserMessage = shouldSuppressOptimisticUserMessage(
2918
- sessionId,
2919
- askuserAnswer
2920
- );
2921
- if (!suppressOptimisticUserMessage) {
2922
- useChatStore.getState().addUserMessage(sessionId, message);
2923
- }
2924
2913
  useChatStore.getState().setStreaming(sessionId, true);
2925
2914
  if (askuserAnswer && typeof askuserAnswer.tool_call_id === "string") {
2926
2915
  const { tool_call_id, ...rest } = askuserAnswer;
@@ -2930,14 +2919,12 @@ var AgentSocket = class {
2930
2919
  [tool_call_id]: rest
2931
2920
  });
2932
2921
  }
2933
- if (!suppressOptimisticUserMessage) {
2934
- useRuntimeStore.getState().addEvent(sessionId, {
2935
- type: "chat:start",
2936
- title: "User prompt sent",
2937
- status: "running",
2938
- detail: contentPreview(message)
2939
- });
2940
- }
2922
+ useRuntimeStore.getState().addEvent(sessionId, {
2923
+ type: "chat:start",
2924
+ title: "User prompt sent",
2925
+ status: "running",
2926
+ detail: contentPreview(message)
2927
+ });
2941
2928
  if (!extras?.replay_decision) {
2942
2929
  this.pendingReplayMessages.set(sessionId, message);
2943
2930
  this.pendingReplayModes.set(sessionId, mode);
@@ -3261,4 +3248,4 @@ export {
3261
3248
  bootstrapBladeClient,
3262
3249
  getBootstrappedClient
3263
3250
  };
3264
- //# sourceMappingURL=chunk-JWHBUVSM.js.map
3251
+ //# sourceMappingURL=chunk-OPMRX65X.js.map