@blade-hq/agent-kit 0.4.8 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/{SkillStatusBar-CDmaNuOE.d.ts → SkillStatusBar-CHnXqybx.d.ts} +2 -2
  2. package/dist/{blade-client-X5TOnkQa.d.ts → blade-client-BfYaHLco.d.ts} +44 -2
  3. package/dist/{chunk-MAMDVXTM.js → chunk-3LCNDPP6.js} +2 -2
  4. package/dist/{chunk-SAKSQ7OO.js → chunk-4XID5JVK.js} +2 -2
  5. package/dist/{chunk-TWZHUASA.js → chunk-CDSCC4OQ.js} +86 -17
  6. package/dist/chunk-CDSCC4OQ.js.map +1 -0
  7. package/dist/{chunk-QO6CO372.js → chunk-O2BVC7QE.js} +119 -86
  8. package/dist/chunk-O2BVC7QE.js.map +1 -0
  9. package/dist/{chunk-I5BTVM3C.js → chunk-PJJ3Y3DZ.js} +2 -2
  10. package/dist/{chunk-DNT6RM5E.js → chunk-VCCMO7G5.js} +59 -5
  11. package/dist/chunk-VCCMO7G5.js.map +1 -0
  12. package/dist/{chunk-YFKHSFRB.js → chunk-Z4FPELIQ.js} +228 -82
  13. package/dist/chunk-Z4FPELIQ.js.map +1 -0
  14. package/dist/client/index.d.ts +297 -29
  15. package/dist/client/index.js +1 -1
  16. package/dist/{licenses-DWJmNvpn.d.ts → licenses-BGw5jiC4.d.ts} +1 -1
  17. package/dist/react/api/licenses.d.ts +3 -3
  18. package/dist/react/api/licenses.js +3 -3
  19. package/dist/react/api/vibe-coding.d.ts +3 -3
  20. package/dist/react/api/vibe-coding.js +2 -2
  21. package/dist/react/components/chat/index.d.ts +4 -4
  22. package/dist/react/components/chat/index.js +5 -5
  23. package/dist/react/components/plan/index.js +3 -3
  24. package/dist/react/components/session/index.d.ts +1 -1
  25. package/dist/react/components/session/index.js +3 -3
  26. package/dist/react/components/workspace/index.js +3 -3
  27. package/dist/react/index.d.ts +42 -13
  28. package/dist/react/index.js +21 -7
  29. package/dist/react/index.js.map +1 -1
  30. package/dist/{session-CDeiO81j.d.ts → session-BKOc2lsz.d.ts} +9 -1
  31. package/dist/style.css +1 -1
  32. package/package.json +2 -1
  33. package/dist/chunk-DNT6RM5E.js.map +0 -1
  34. package/dist/chunk-QO6CO372.js.map +0 -1
  35. package/dist/chunk-TWZHUASA.js.map +0 -1
  36. package/dist/chunk-YFKHSFRB.js.map +0 -1
  37. /package/dist/{chunk-MAMDVXTM.js.map → chunk-3LCNDPP6.js.map} +0 -0
  38. /package/dist/{chunk-SAKSQ7OO.js.map → chunk-4XID5JVK.js.map} +0 -0
  39. /package/dist/{chunk-I5BTVM3C.js.map → chunk-PJJ3Y3DZ.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  CollapsibleContent,
4
4
  CollapsibleTrigger,
5
5
  resolveSessionFilePreviewTarget
6
- } from "./chunk-MAMDVXTM.js";
6
+ } from "./chunk-3LCNDPP6.js";
7
7
  import {
8
8
  AskUserQuestionBlock,
9
9
  CardCodeBlock,
@@ -11,9 +11,10 @@ import {
11
11
  MarkdownContent,
12
12
  PlanSummaryCard,
13
13
  extractLatestPlanMessages,
14
+ getCodeLanguageFromFilename,
14
15
  parseAskUserQuestion,
15
16
  useHighlightedCodeHtml
16
- } from "./chunk-YFKHSFRB.js";
17
+ } from "./chunk-Z4FPELIQ.js";
17
18
  import {
18
19
  buildMessageContent,
19
20
  buildToolPreviewKey,
@@ -55,7 +56,7 @@ import {
55
56
  useUiBridgeStore,
56
57
  useUiStore,
57
58
  writeFile
58
- } from "./chunk-TWZHUASA.js";
59
+ } from "./chunk-CDSCC4OQ.js";
59
60
  import {
60
61
  registerBridgeIframe,
61
62
  tapBridgeEvent
@@ -64,7 +65,7 @@ import {
64
65
  ModelOption,
65
66
  ModelsConfig,
66
67
  ModelsResource
67
- } from "./chunk-DNT6RM5E.js";
68
+ } from "./chunk-VCCMO7G5.js";
68
69
  import {
69
70
  cn,
70
71
  copyToClipboard
@@ -177,7 +178,7 @@ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
177
178
  import {
178
179
  useEffect as useEffect7,
179
180
  useEffectEvent as useEffectEvent2,
180
- useMemo as useMemo6,
181
+ useMemo as useMemo7,
181
182
  useRef as useRef4,
182
183
  useState as useState6
183
184
  } from "react";
@@ -636,12 +637,22 @@ var getModelsConfig = (...args) => r().getModelsConfig(...args);
636
637
  // src/react/api/user-preferences.ts
637
638
  var user_preferences_exports = {};
638
639
  __export(user_preferences_exports, {
640
+ getComputerUpgradeStatus: () => getComputerUpgradeStatus,
641
+ getPersistentDefault: () => getPersistentDefault,
639
642
  getUserPreference: () => getUserPreference,
640
- setUserPreference: () => setUserPreference
643
+ resetComputer: () => resetComputer,
644
+ setPersistentDefault: () => setPersistentDefault,
645
+ setUserPreference: () => setUserPreference,
646
+ upgradeComputer: () => upgradeComputer
641
647
  });
642
648
  var r2 = () => getClient().userPreferences;
643
649
  var getUserPreference = (...args) => r2().getUserPreference(...args);
644
650
  var setUserPreference = (...args) => r2().setUserPreference(...args);
651
+ var getPersistentDefault = (...args) => r2().getPersistentDefault(...args);
652
+ var setPersistentDefault = (...args) => r2().setPersistentDefault(...args);
653
+ var resetComputer = (...args) => r2().resetComputer(...args);
654
+ var getComputerUpgradeStatus = (...args) => r2().getComputerUpgradeStatus(...args);
655
+ var upgradeComputer = (...args) => r2().upgradeComputer(...args);
645
656
 
646
657
  // src/react/hooks/use-model-preferences.ts
647
658
  var PREFERRED_MODEL_KEY = "preferred_model";
@@ -723,7 +734,7 @@ function ModelSelector({
723
734
  const canSelect = models.length > 0;
724
735
  const selectedLabel = models.find((model) => model.id === value)?.label;
725
736
  const defaultLabel = models.find((model) => model.id === defaultModel)?.label;
726
- const label = isLoading ? "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B..." : selectedLabel || defaultLabel || value.trim() || defaultModel || "\u672A\u8FDE\u63A5\u5230\u6A21\u578B";
737
+ const label = isLoading ? "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B..." : models.length === 0 ? "\u65E0\u53EF\u7528\u6A21\u578B" : selectedLabel || defaultLabel || value.trim() || "\u672A\u8FDE\u63A5\u5230\u6A21\u578B";
727
738
  const dropdownPosition = placement === "top" ? "bottom-[calc(100%+8px)]" : "top-[calc(100%+8px)]";
728
739
  if (!canSelect) {
729
740
  return /* @__PURE__ */ jsxs(
@@ -885,6 +896,38 @@ function useInputHistory(sessionId) {
885
896
  };
886
897
  }
887
898
 
899
+ // src/react/hooks/use-resolved-model.ts
900
+ import { useMemo as useMemo3 } from "react";
901
+ function useResolvedModel(activeSessionModel) {
902
+ const { models, defaultModel, isLoading } = useModelConfig();
903
+ const { preferredModel } = usePreferredModel();
904
+ return useMemo3(() => {
905
+ if (isLoading) {
906
+ const optimistic = activeSessionModel || preferredModel || defaultModel || "";
907
+ return {
908
+ resolvedModel: optimistic,
909
+ hasAvailableModel: !!optimistic,
910
+ isLoading
911
+ };
912
+ }
913
+ const ids = models.map((model) => model.id);
914
+ const inList = (id) => !!id && ids.includes(id);
915
+ if (inList(activeSessionModel)) {
916
+ return { resolvedModel: activeSessionModel, hasAvailableModel: true, isLoading };
917
+ }
918
+ if (inList(preferredModel)) {
919
+ return { resolvedModel: preferredModel, hasAvailableModel: true, isLoading };
920
+ }
921
+ if (inList(defaultModel)) {
922
+ return { resolvedModel: defaultModel, hasAvailableModel: true, isLoading };
923
+ }
924
+ if (ids.length > 0) {
925
+ return { resolvedModel: ids[0], hasAvailableModel: true, isLoading };
926
+ }
927
+ return { resolvedModel: "", hasAvailableModel: false, isLoading };
928
+ }, [activeSessionModel, preferredModel, defaultModel, models, isLoading]);
929
+ }
930
+
888
931
  // src/react/lib/attachment-upload.ts
889
932
  var ATTACHMENT_SIZE_LIMIT_BYTES = 1e3 * 1024 * 1024;
890
933
  function formatFileSize(size) {
@@ -923,7 +966,7 @@ function skillDisplayName(skill) {
923
966
 
924
967
  // src/react/components/chat/FileCompletionMenu.tsx
925
968
  import { ChevronRight, File, Folder } from "lucide-react";
926
- import { forwardRef, useCallback as useCallback5, useImperativeHandle, useMemo as useMemo3, useState as useState4 } from "react";
969
+ import { forwardRef, useCallback as useCallback5, useImperativeHandle, useMemo as useMemo4, useState as useState4 } from "react";
927
970
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
928
971
  var ROOT_DIR = ".";
929
972
  function isVisibleEntry(entry) {
@@ -1009,7 +1052,7 @@ var FileCompletionMenu = forwardRef(
1009
1052
  function FileCompletionMenu2({ command, editor, items, onExit, query, range, sessionId: sessionIdProp }, ref) {
1010
1053
  const activeSessionId = useSessionStore((state) => state.activeSessionId);
1011
1054
  const sessionId = sessionIdProp ?? activeSessionId;
1012
- const { dirPath, filterQuery } = useMemo3(() => parseSuggestionQuery(query), [query]);
1055
+ const { dirPath, filterQuery } = useMemo4(() => parseSuggestionQuery(query), [query]);
1013
1056
  return /* @__PURE__ */ jsx3(
1014
1057
  FileCompletionMenuContent,
1015
1058
  {
@@ -1028,7 +1071,7 @@ var FileCompletionMenu = forwardRef(
1028
1071
  );
1029
1072
  var FileCompletionMenuContent = forwardRef(function FileCompletionMenuContent2({ command, editor, filterQuery, items, onExit, range, sessionId }, ref) {
1030
1073
  const [rawSelectedIndex, setRawSelectedIndex] = useState4(0);
1031
- const filteredEntries = useMemo3(() => filterEntries(items, filterQuery), [filterQuery, items]);
1074
+ const filteredEntries = useMemo4(() => filterEntries(items, filterQuery), [filterQuery, items]);
1032
1075
  const selectedIndex = filteredEntries.length === 0 ? 0 : Math.min(rawSelectedIndex, filteredEntries.length - 1);
1033
1076
  const handleSelect = useCallback5(
1034
1077
  (entry) => {
@@ -1313,7 +1356,7 @@ function FileSizeLimitDialog({
1313
1356
  // src/react/components/chat/SkillStatusBar.tsx
1314
1357
  import { useQuery as useQuery5 } from "@tanstack/react-query";
1315
1358
  import { RefreshCw } from "lucide-react";
1316
- import { useMemo as useMemo5 } from "react";
1359
+ import { useMemo as useMemo6 } from "react";
1317
1360
 
1318
1361
  // src/react/hooks/use-background-tasks.ts
1319
1362
  import { useQuery as useQuery2 } from "@tanstack/react-query";
@@ -1384,7 +1427,7 @@ function useSkillStats(sessionId) {
1384
1427
  }
1385
1428
 
1386
1429
  // src/react/hooks/use-token-pressure.ts
1387
- import { useMemo as useMemo4 } from "react";
1430
+ import { useMemo as useMemo5 } from "react";
1388
1431
  function clampRatio(value) {
1389
1432
  return Math.min(1, Math.max(0, value));
1390
1433
  }
@@ -1402,7 +1445,7 @@ function resolveLevel(ratio, compactionRatio) {
1402
1445
  }
1403
1446
  function useTokenPressure(sessionId) {
1404
1447
  const { data } = useContextStats(sessionId);
1405
- return useMemo4(() => {
1448
+ return useMemo5(() => {
1406
1449
  const ratio = data.context_window > 0 ? clampRatio(data.tokens_used / data.context_window) : 0;
1407
1450
  return {
1408
1451
  ratio,
@@ -1558,7 +1601,7 @@ function SkillStatusBar({
1558
1601
  const runningTasks = runningTaskItems.length;
1559
1602
  const statsReady = !loading && !error;
1560
1603
  const skillStoreConnected = statsReady && skillStats.remote_connected;
1561
- const connectionMeta = useMemo5(
1604
+ const connectionMeta = useMemo6(
1562
1605
  () => getConnectionMeta(
1563
1606
  connectionStatus,
1564
1607
  reconnectAttempt,
@@ -1583,7 +1626,7 @@ function SkillStatusBar({
1583
1626
  text: skillStoreConnected ? `\u5DF2\u5B89\u88C5 ${skillStats.installed_skill_count} \u4E2A\u6280\u80FD` : "\u5C1A\u672A\u767B\u5F55\u6280\u80FD\u5546\u5E97"
1584
1627
  }
1585
1628
  ].filter((item) => item.key !== "total" || skillStats.remote_configured);
1586
- const tokenSummary = useMemo5(() => {
1629
+ const tokenSummary = useMemo6(() => {
1587
1630
  return {
1588
1631
  detail: /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
1589
1632
  /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3 border-t border-slate-800 pt-1", children: [
@@ -2440,7 +2483,6 @@ function ChatInput({
2440
2483
  const [isEditorFocused, setIsEditorFocused] = useState6(false);
2441
2484
  const [oversizedFiles, setOversizedFiles] = useState6([]);
2442
2485
  const [selectedModel, setSelectedModel] = useState6("");
2443
- const { defaultModel } = useModelConfig();
2444
2486
  const { setPreferredModel } = usePreferredModel();
2445
2487
  const queryClient = useQueryClient2();
2446
2488
  const actionMenuRef = useRef4(null);
@@ -2450,7 +2492,7 @@ function ChatInput({
2450
2492
  const localImageUrlsRef = useRef4(/* @__PURE__ */ new Map());
2451
2493
  const activeSessionId = useSessionStore((state) => state.activeSessionId);
2452
2494
  const sessions = useSessionStore((state) => state.sessions);
2453
- const activeSessionModel = useMemo6(
2495
+ const activeSessionModel = useMemo7(
2454
2496
  () => sessions.find((session) => session.id === activeSessionId)?.model ?? null,
2455
2497
  [activeSessionId, sessions]
2456
2498
  );
@@ -2465,9 +2507,10 @@ function ChatInput({
2465
2507
  const draftAppends = useUiBridgeStore(
2466
2508
  (state) => activeSessionId ? state.draftAppends[activeSessionId] : void 0
2467
2509
  );
2510
+ const { resolvedModel } = useResolvedModel(activeSessionModel);
2468
2511
  useEffect7(() => {
2469
- setSelectedModel(activeSessionModel || defaultModel);
2470
- }, [activeSessionModel, defaultModel]);
2512
+ setSelectedModel(resolvedModel);
2513
+ }, [resolvedModel]);
2471
2514
  const sendRequests = useUiBridgeStore(
2472
2515
  (state) => activeSessionId ? state.sendRequests[activeSessionId] : void 0
2473
2516
  );
@@ -3458,13 +3501,13 @@ import {
3458
3501
  useCallback as useCallback12,
3459
3502
  useEffect as useEffect16,
3460
3503
  useEffectEvent as useEffectEvent4,
3461
- useMemo as useMemo16,
3504
+ useMemo as useMemo17,
3462
3505
  useRef as useRef11,
3463
3506
  useState as useState19
3464
3507
  } from "react";
3465
3508
 
3466
3509
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
3467
- import { useCallback as useCallback7, useMemo as useMemo7, useRef as useRef5, useState as useState7 } from "react";
3510
+ import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef5, useState as useState7 } from "react";
3468
3511
  var DEFAULT_SPRING_ANIMATION = {
3469
3512
  /**
3470
3513
  * A value from 0 to 1, on how much to damp the animation.
@@ -3525,7 +3568,7 @@ var useStickToBottom = (options = {}) => {
3525
3568
  state.escapedFromLock = escapedFromLock2;
3526
3569
  updateEscapedFromLock(escapedFromLock2);
3527
3570
  }, []);
3528
- const state = useMemo7(() => {
3571
+ const state = useMemo8(() => {
3529
3572
  let lastCalculation;
3530
3573
  return {
3531
3574
  escapedFromLock,
@@ -3808,7 +3851,7 @@ function mergeAnimations(...animations) {
3808
3851
 
3809
3852
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js
3810
3853
  import * as React from "react";
3811
- import { createContext, useContext, useEffect as useEffect8, useImperativeHandle as useImperativeHandle3, useLayoutEffect, useMemo as useMemo8, useRef as useRef6 } from "react";
3854
+ import { createContext, useContext, useEffect as useEffect8, useImperativeHandle as useImperativeHandle3, useLayoutEffect, useMemo as useMemo9, useRef as useRef6 } from "react";
3812
3855
  var StickToBottomContext = createContext(null);
3813
3856
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect8;
3814
3857
  function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {
@@ -3826,7 +3869,7 @@ function StickToBottom({ instance, children, resize, initial, mass, damping, sti
3826
3869
  targetScrollTop
3827
3870
  });
3828
3871
  const { scrollRef, contentRef, scrollToBottom, stopScroll, isAtBottom, escapedFromLock, state } = instance ?? defaultInstance;
3829
- const context = useMemo8(() => ({
3872
+ const context = useMemo9(() => ({
3830
3873
  scrollToBottom,
3831
3874
  stopScroll,
3832
3875
  scrollRef,
@@ -3889,7 +3932,7 @@ function useStickToBottomContext() {
3889
3932
 
3890
3933
  // src/react/components/chat/AssistantTurnBlock.tsx
3891
3934
  import { AlertCircle, BookOpen, Check as Check4, ChevronRight as ChevronRight5 } from "lucide-react";
3892
- import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo14, useRef as useRef10, useState as useState16 } from "react";
3935
+ import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as useRef10, useState as useState16 } from "react";
3893
3936
 
3894
3937
  // src/react/routes.ts
3895
3938
  var MEMORIES_ROUTE = "/memories";
@@ -3906,7 +3949,7 @@ import {
3906
3949
  useCallback as useCallback9,
3907
3950
  useContext as useContext2,
3908
3951
  useEffect as useEffect9,
3909
- useMemo as useMemo10,
3952
+ useMemo as useMemo11,
3910
3953
  useRef as useRef7,
3911
3954
  useState as useState8
3912
3955
  } from "react";
@@ -3915,7 +3958,7 @@ import { Streamdown } from "streamdown";
3915
3958
 
3916
3959
  // src/react/components/ai-elements/shimmer.tsx
3917
3960
  import { motion } from "motion/react";
3918
- import { memo, useMemo as useMemo9 } from "react";
3961
+ import { memo, useMemo as useMemo10 } from "react";
3919
3962
  import { jsx as jsx10 } from "react/jsx-runtime";
3920
3963
  var motionComponentCache = /* @__PURE__ */ new Map();
3921
3964
  var getMotionComponent = (element) => {
@@ -3936,7 +3979,7 @@ var ShimmerComponent = ({
3936
3979
  const MotionComponent = getMotionComponent(
3937
3980
  Component2
3938
3981
  );
3939
- const dynamicSpread = useMemo9(
3982
+ const dynamicSpread = useMemo10(
3940
3983
  () => (children?.length ?? 0) * spread,
3941
3984
  [children, spread]
3942
3985
  );
@@ -4033,7 +4076,7 @@ var Reasoning = memo2(
4033
4076
  },
4034
4077
  [setIsOpen]
4035
4078
  );
4036
- const contextValue = useMemo10(
4079
+ const contextValue = useMemo11(
4037
4080
  () => ({ duration, isOpen, isStreaming, setIsOpen }),
4038
4081
  [duration, isOpen, isStreaming, setIsOpen]
4039
4082
  );
@@ -4193,7 +4236,7 @@ ReasoningContent.displayName = "ReasoningContent";
4193
4236
 
4194
4237
  // src/react/components/chat/AgentLoopBlock.tsx
4195
4238
  import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText5, Loader2 as Loader24, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
4196
- import { useEffect as useEffect13, useMemo as useMemo13, useState as useState15 } from "react";
4239
+ import { useEffect as useEffect13, useMemo as useMemo14, useState as useState15 } from "react";
4197
4240
 
4198
4241
  // src/react/components/chat/ResourceIframe.tsx
4199
4242
  import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef8, useState as useState9 } from "react";
@@ -4325,30 +4368,10 @@ function ResourceIframe({ ui, sessionId }) {
4325
4368
 
4326
4369
  // src/react/components/chat/ToolCallBlock.tsx
4327
4370
  import { Check, ChevronRight as ChevronRight3, Loader2 as Loader23, MessageSquareMore, PanelRightOpen, X as X4 } from "lucide-react";
4328
- import { useMemo as useMemo11, useState as useState12 } from "react";
4371
+ import { useMemo as useMemo12, useState as useState12 } from "react";
4329
4372
 
4330
4373
  // src/react/components/chat/tool-renderers/shared.tsx
4331
4374
  import { jsx as jsx13 } from "react/jsx-runtime";
4332
- var EXT_TO_LANG = {
4333
- ".bash": "bash",
4334
- ".css": "css",
4335
- ".go": "go",
4336
- ".htm": "html",
4337
- ".html": "html",
4338
- ".js": "javascript",
4339
- ".json": "json",
4340
- ".jsx": "jsx",
4341
- ".md": "markdown",
4342
- ".py": "python",
4343
- ".rs": "rust",
4344
- ".scss": "css",
4345
- ".sh": "bash",
4346
- ".ts": "typescript",
4347
- ".tsx": "tsx",
4348
- ".yaml": "yaml",
4349
- ".yml": "yaml",
4350
- ".zsh": "bash"
4351
- };
4352
4375
  function getResultText(result) {
4353
4376
  if (typeof result === "string") return result;
4354
4377
  if (Array.isArray(result)) {
@@ -4399,10 +4422,7 @@ function getFileName(filePath) {
4399
4422
  return filePath.split("/").pop() ?? filePath;
4400
4423
  }
4401
4424
  function getCodeLanguage(filePath) {
4402
- if (!filePath) return null;
4403
- const dotIndex = filePath.lastIndexOf(".");
4404
- if (dotIndex < 0) return null;
4405
- return EXT_TO_LANG[filePath.slice(dotIndex).toLowerCase()] ?? null;
4425
+ return getCodeLanguageFromFilename(filePath);
4406
4426
  }
4407
4427
  function formatBytes(size) {
4408
4428
  if (typeof size !== "number" || !Number.isFinite(size) || size < 0) return null;
@@ -5290,7 +5310,7 @@ function ToolCallBlock({
5290
5310
  const resolvedAnswerData = answerData ?? storedAnswerData;
5291
5311
  const resolvedAnswered = answered ?? (!!resolvedAnswerData && resolvedSessionStatus !== "waiting_for_input");
5292
5312
  const resolvedOnAnswer = onAnswer ?? answerCallback;
5293
- const uiMeta = useMemo11(() => {
5313
+ const uiMeta = useMemo12(() => {
5294
5314
  const block = turnBlocks?.find(
5295
5315
  (item) => item.type === "tool_ui" && item.tool_call_id === toolCall.id && isUiMeta(item.content)
5296
5316
  );
@@ -5884,14 +5904,14 @@ function TextAttachmentPills({ attachments, onPreview }) {
5884
5904
  import { RefreshCcw } from "lucide-react";
5885
5905
 
5886
5906
  // src/react/components/chat/whatif-quote-context.tsx
5887
- import { createContext as createContext3, useContext as useContext3, useMemo as useMemo12 } from "react";
5907
+ import { createContext as createContext3, useContext as useContext3, useMemo as useMemo13 } from "react";
5888
5908
  import { jsx as jsx25 } from "react/jsx-runtime";
5889
5909
  var WhatIfQuoteContext = createContext3({});
5890
5910
  function WhatIfQuoteProvider({
5891
5911
  onJumpToStep,
5892
5912
  children
5893
5913
  }) {
5894
- const value = useMemo12(() => ({ onJumpToStep }), [onJumpToStep]);
5914
+ const value = useMemo13(() => ({ onJumpToStep }), [onJumpToStep]);
5895
5915
  return /* @__PURE__ */ jsx25(WhatIfQuoteContext.Provider, { value, children });
5896
5916
  }
5897
5917
  function useWhatIfQuoteContext() {
@@ -6148,7 +6168,7 @@ function stripFileExtension(fileName) {
6148
6168
  function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6149
6169
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId] ?? EMPTY_AGENT_LOOPS);
6150
6170
  const messages = useChatStore((state) => state.messages[sessionId] ?? EMPTY_MESSAGES2);
6151
- const loopEntry = useMemo13(() => {
6171
+ const loopEntry = useMemo14(() => {
6152
6172
  for (const [loopName, info] of Object.entries(agentLoops)) {
6153
6173
  if (info.toolCallId === toolCall.id) {
6154
6174
  return { loopName, info };
@@ -6156,24 +6176,24 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6156
6176
  }
6157
6177
  return null;
6158
6178
  }, [agentLoops, toolCall.id]);
6159
- const childMessages = useMemo13(() => {
6179
+ const childMessages = useMemo14(() => {
6160
6180
  if (!loopEntry) return [];
6161
6181
  return messages.filter((message) => (message.loop_name ?? "root") === loopEntry.loopName);
6162
6182
  }, [loopEntry, messages]);
6163
- const loopToolCalls = useMemo13(
6183
+ const loopToolCalls = useMemo14(
6164
6184
  () => childMessages.flatMap((message) => message.tool_calls ?? []),
6165
6185
  [childMessages]
6166
6186
  );
6167
- const visibleLoopToolCalls = useMemo13(
6187
+ const visibleLoopToolCalls = useMemo14(
6168
6188
  () => loopToolCalls.filter((childToolCall) => formatToolName(childToolCall.name) !== "Agent"),
6169
6189
  [loopToolCalls]
6170
6190
  );
6171
- const hasAwaitingAnswer = useMemo13(
6191
+ const hasAwaitingAnswer = useMemo14(
6172
6192
  () => visibleLoopToolCalls.some((childToolCall) => childToolCall.status === "awaiting_answer"),
6173
6193
  [visibleLoopToolCalls]
6174
6194
  );
6175
6195
  const [expanded, setExpanded] = useState15(hasAwaitingAnswer);
6176
- const completedToolLabels = useMemo13(
6196
+ const completedToolLabels = useMemo14(
6177
6197
  () => visibleLoopToolCalls.flatMap((childToolCall) => {
6178
6198
  const isCompleted = childToolCall.status === "done" || childToolCall.status !== "pending" && childToolCall.status !== "awaiting_answer" && childToolCall.status !== "error" && childToolCall.status !== "cancelled";
6179
6199
  if (!isCompleted) return [];
@@ -6201,7 +6221,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6201
6221
  }),
6202
6222
  [visibleLoopToolCalls]
6203
6223
  );
6204
- const inlineToolUiBlocks = useMemo13(
6224
+ const inlineToolUiBlocks = useMemo14(
6205
6225
  () => childMessages.flatMap(
6206
6226
  (message) => (message.blocks ?? []).flatMap(
6207
6227
  (block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? [{ key: `${message.entry_id ?? message.timestamp ?? "message"}-${block.tool_call_id}-${index}`, ui: block.content }] : []
@@ -6528,6 +6548,18 @@ function getLoopCardStyles(status) {
6528
6548
 
6529
6549
  // src/react/components/chat/AssistantTurnBlock.tsx
6530
6550
  import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
6551
+ function defaultTurnDisplayMode({
6552
+ forceExpanded,
6553
+ hasActionableToolCall
6554
+ }) {
6555
+ return forceExpanded || hasActionableToolCall ? "detail" : "compact";
6556
+ }
6557
+ function resolveTurnDisplayMode({
6558
+ isStreaming,
6559
+ displayMode
6560
+ }) {
6561
+ return isStreaming ? "detail" : displayMode;
6562
+ }
6531
6563
  function getMessageText(message) {
6532
6564
  return typeof message.content === "string" ? message.content.trim() : message.content.filter((part) => part.type === "text").map((part) => part.text).join("").trim();
6533
6565
  }
@@ -6662,33 +6694,33 @@ function AssistantTurnBlock({
6662
6694
  customization
6663
6695
  }) {
6664
6696
  const messages = Array.isArray(rawMessages) ? rawMessages : [];
6665
- const allToolCalls = useMemo14(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
6666
- const hasActionableToolCall = useMemo14(
6697
+ const allToolCalls = useMemo15(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
6698
+ const hasActionableToolCall = useMemo15(
6667
6699
  () => allToolCalls.some(
6668
6700
  (tc) => tc.status === "error" || tc.status === "cancelled" || formatToolName(tc.name) === "AskUserQuestion" && tc.status === "awaiting_answer"
6669
6701
  ),
6670
6702
  [allToolCalls]
6671
6703
  );
6672
6704
  const [displayMode, setDisplayMode] = useState16(
6673
- forceExpanded ? "detail" : "compact"
6705
+ defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall })
6674
6706
  );
6675
6707
  const wasStreamingRef = useRef10(isStreaming);
6676
6708
  useEffect14(() => {
6677
6709
  if (wasStreamingRef.current && !isStreaming && !forceExpanded) {
6678
- setDisplayMode("compact");
6710
+ setDisplayMode(defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall }));
6679
6711
  }
6680
6712
  wasStreamingRef.current = isStreaming;
6681
- }, [forceExpanded, isStreaming]);
6713
+ }, [forceExpanded, hasActionableToolCall, isStreaming]);
6682
6714
  const sessionMessages = useChatStore((state) => state.messages[sessionId] ?? []);
6683
6715
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId] ?? {});
6684
- const turnMessages = useMemo14(
6716
+ const turnMessages = useMemo15(
6685
6717
  () => collectTurnMessages({ rootMessages: messages, sessionMessages, agentLoops }),
6686
6718
  [agentLoops, messages, sessionMessages]
6687
6719
  );
6688
- const resourceBlocks = useMemo14(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
6689
- const finalMessage = useMemo14(() => getLastTextMessage(turnMessages), [turnMessages]);
6720
+ const resourceBlocks = useMemo15(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
6721
+ const finalMessage = useMemo15(() => getLastTextMessage(turnMessages), [turnMessages]);
6690
6722
  const hasInterruptedState = messages.some((message) => message.status === "interrupted");
6691
- const effectiveMode = isStreaming ? "detail" : displayMode === "compact" && hasActionableToolCall ? "detail" : displayMode;
6723
+ const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
6692
6724
  const memoryRefs = Array.isArray(messages[0]?.memory_refs) ? messages[0].memory_refs : [];
6693
6725
  return /* @__PURE__ */ jsxs24(
6694
6726
  "div",
@@ -7042,7 +7074,7 @@ function AssistantText({
7042
7074
  },
7043
7075
  [sessionId]
7044
7076
  );
7045
- const cardCtx = useMemo14(
7077
+ const cardCtx = useMemo15(
7046
7078
  () => ({ sessionId, messageId, sendMessage }),
7047
7079
  [sessionId, messageId, sendMessage]
7048
7080
  );
@@ -7331,7 +7363,7 @@ import {
7331
7363
  TerminalSquare,
7332
7364
  WandSparkles
7333
7365
  } from "lucide-react";
7334
- import { useEffect as useEffect15, useMemo as useMemo15, useState as useState18 } from "react";
7366
+ import { useEffect as useEffect15, useMemo as useMemo16, useState as useState18 } from "react";
7335
7367
  import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
7336
7368
  var EMPTY_EVENTS = [];
7337
7369
  function formatElapsedDuration(durationMs) {
@@ -7434,9 +7466,9 @@ function StickyStatusBar({
7434
7466
  onJumpToLatest
7435
7467
  }) {
7436
7468
  const events = useRuntimeStore((state) => state.events[sessionId] ?? EMPTY_EVENTS);
7437
- const startedAt = useMemo15(() => getTurnStartedAt(events), [events]);
7469
+ const startedAt = useMemo16(() => getTurnStartedAt(events), [events]);
7438
7470
  const elapsedDuration = useElapsedDuration(startedAt, isStreaming && isLastTurn);
7439
- const action = useMemo15(() => getCurrentAction(messages), [messages]);
7471
+ const action = useMemo16(() => getCurrentAction(messages), [messages]);
7440
7472
  if (!isStreaming || !isLastTurn) {
7441
7473
  return null;
7442
7474
  }
@@ -7612,8 +7644,8 @@ function MessageList({
7612
7644
  const messages = Array.isArray(rawMessages) ? rawMessages : [];
7613
7645
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId]);
7614
7646
  const askAnswers = useChatStore((state) => state.askAnswers[sessionId]);
7615
- const agentLoopNameSet = useMemo16(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
7616
- const renderBlocks = useMemo16(() => {
7647
+ const agentLoopNameSet = useMemo17(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
7648
+ const renderBlocks = useMemo17(() => {
7617
7649
  const visible = messages.filter((message) => {
7618
7650
  const loopName = message.loop_name ?? "root";
7619
7651
  if (loopName !== "root") return false;
@@ -7678,13 +7710,13 @@ function MessageList({
7678
7710
  flushAssistant();
7679
7711
  return blocks;
7680
7712
  }, [agentLoopNameSet, messages]);
7681
- const hasInterruptedTurn = useMemo16(
7713
+ const hasInterruptedTurn = useMemo17(
7682
7714
  () => renderBlocks.some(
7683
7715
  (block) => block.type === "assistant_turn" && block.messages.some((message) => message.status === "interrupted")
7684
7716
  ),
7685
7717
  [renderBlocks]
7686
7718
  );
7687
- const lastTurnId = useMemo16(() => {
7719
+ const lastTurnId = useMemo17(() => {
7688
7720
  for (let index = renderBlocks.length - 1; index >= 0; index -= 1) {
7689
7721
  const block = renderBlocks[index];
7690
7722
  if (block.type === "assistant_turn") return block.anchorId;
@@ -7692,14 +7724,14 @@ function MessageList({
7692
7724
  }
7693
7725
  return null;
7694
7726
  }, [renderBlocks]);
7695
- const turnNavItems = useMemo16(
7727
+ const turnNavItems = useMemo17(
7696
7728
  () => renderBlocks.filter((block) => block.type === "assistant_turn").map((block) => ({
7697
7729
  id: block.anchorId,
7698
7730
  title: block.railTitle
7699
7731
  })),
7700
7732
  [renderBlocks]
7701
7733
  );
7702
- const stickyTurn = useMemo16(
7734
+ const stickyTurn = useMemo17(
7703
7735
  () => renderBlocks.find(
7704
7736
  (block) => block.type === "assistant_turn" && block.anchorId === lastTurnId && block.isStreaming
7705
7737
  ) ?? null,
@@ -7709,7 +7741,7 @@ function MessageList({
7709
7741
  const scrollContainerRef = useRef11(null);
7710
7742
  const frameRef = useRef11(null);
7711
7743
  const [activeTurnId, setActiveTurnId] = useState19(lastTurnId);
7712
- const layoutSignature = useMemo16(
7744
+ const layoutSignature = useMemo17(
7713
7745
  () => getMessagesMeasureSignature(messages),
7714
7746
  [messages]
7715
7747
  );
@@ -8079,6 +8111,7 @@ export {
8079
8111
  useInputHistory,
8080
8112
  useModelConfig,
8081
8113
  usePreferredModel,
8114
+ useResolvedModel,
8082
8115
  buildVoiceInputUnavailableError,
8083
8116
  useVoiceInput,
8084
8117
  useTiptapVoiceInput,
@@ -8121,4 +8154,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
8121
8154
  * Licensed under the MIT License. See License.txt in the project root for license information.
8122
8155
  *--------------------------------------------------------------------------------------------*)
8123
8156
  */
8124
- //# sourceMappingURL=chunk-QO6CO372.js.map
8157
+ //# sourceMappingURL=chunk-O2BVC7QE.js.map