@openchambery/web 1.19.14 → 1.19.15-beta.1

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 (58) hide show
  1. package/dist/assets/{AssistantView-Dncbu_Z2.js → AssistantView-D5rEZ-Ss.js} +2 -2
  2. package/dist/assets/{DiagramView-CovEl1BY.js → DiagramView-DaB9Sb7S.js} +1 -1
  3. package/dist/assets/MarkdownRenderer-emLeoNjI.js +2 -0
  4. package/dist/assets/{MarkdownRendererImpl-CCfHY-86.js → MarkdownRendererImpl-BWCAPlqn.js} +1 -1
  5. package/dist/assets/{MarkstreamRendererImpl-y6QgIUZA.js → MarkstreamRendererImpl-BD_NFKUv.js} +1 -1
  6. package/dist/assets/MobileDetailNavigation-DqXVAIap.js +1 -0
  7. package/dist/assets/{MobileShareBridge-B4S7BaUj.js → MobileShareBridge-Bk2fdkJk.js} +1 -1
  8. package/dist/assets/MobileSurface-C4mpcOCh.js +2 -0
  9. package/dist/assets/{MultiRunWindow-BeHa-CG6.js → MultiRunWindow-rs49_K1E.js} +1 -1
  10. package/dist/assets/{SettingsView-Dn7odtQz.js → SettingsView-b8LUjoad.js} +2 -2
  11. package/dist/assets/{SettingsWindow-C0tWPS5f.js → SettingsWindow-D8JFlPdA.js} +1 -1
  12. package/dist/assets/{TerminalView-BnJgC7Qo.js → TerminalView-DCd-Godi.js} +1 -1
  13. package/dist/assets/{ToolOutputDialog-D9S-X8hM.js → ToolOutputDialog-B50L_nUP.js} +1 -1
  14. package/dist/assets/{appThemeRegistry-DBrvaJnq.js → appThemeRegistry-BWtCaTMe.js} +1 -1
  15. package/dist/assets/{fileMentionTouchSelection-Dc004xOh.js → fileMentionTouchSelection-DKYkoypI.js} +1 -1
  16. package/dist/assets/{gitApi-Cm3JLQqh.js → gitApi-D4PyYgLZ.js} +1 -1
  17. package/dist/assets/{insertionBoundaries-CTWYFsbH.js → insertionBoundaries-Bnnx03Wj.js} +1 -1
  18. package/dist/assets/{main-CSqu3MB4.js → main-BRiQTNFX.js} +4 -4
  19. package/dist/assets/{main-DwMprEyr.js → main-CnY0LWNc.js} +2 -2
  20. package/dist/assets/{miniChat-C8bzY_Ye.js → miniChat-B0pw_mUs.js} +2 -2
  21. package/dist/assets/{mobile-Oy-SRKkr.js → mobile-BKHmxwXz.js} +2 -2
  22. package/dist/assets/{multirun-ClcuaiKU.js → multirun-BQKqVfFT.js} +1 -1
  23. package/dist/assets/{projectMeta-F93wE2Ye.js → projectMeta-BvG8sdtC.js} +1 -1
  24. package/dist/assets/{renderElectronMiniChatApp-rOOhMVlQ.js → renderElectronMiniChatApp-E5a0yy7E.js} +2 -2
  25. package/dist/assets/{renderMobileApp-BP_hGwHP.js → renderMobileApp-DT0L4Ah6.js} +4 -4
  26. package/dist/assets/{runtimeConfig-iJ2mTBVN.js → runtimeConfig-utWzrDwa.js} +1 -1
  27. package/dist/assets/{runtimeEndpointReset-ISnhAS3q.js → runtimeEndpointReset-DE6lwHyg.js} +1 -1
  28. package/dist/assets/sessionChangeSummary-BG7l2heP.js +2 -0
  29. package/dist/assets/{sessionLookup-DQQ9-DuP.js → sessionLookup-12zVOR0J.js} +1 -1
  30. package/dist/assets/src-CFUi4riW.css +2 -0
  31. package/dist/assets/{useAppFontEffects--IcU7jyv.js → useAppFontEffects-BhYuP4L2.js} +5 -5
  32. package/dist/assets/{useDesktopWindowControlsLayout-BqJ5R_T2.js → useDesktopWindowControlsLayout-DPNMRkrI.js} +1 -1
  33. package/dist/assets/{useEffectiveDirectory-ChWXV8xM.js → useEffectiveDirectory-Ji8AKgzY.js} +1 -1
  34. package/dist/assets/{useMobileNavigationStore-DQkgxuzg.js → useMobileNavigationStore-BYdpuwL7.js} +1 -1
  35. package/dist/assets/{useSessionAutoCleanup-DWWAvQQ0.js → useSessionAutoCleanup-CADZCvZL.js} +1 -1
  36. package/dist/assets/{useWorkerHighlightedLines-D2oQszsk.js → useWorkerHighlightedLines-CuG88Lsj.js} +1 -1
  37. package/dist/index.html +3 -3
  38. package/dist/mini-chat.html +3 -3
  39. package/dist/mobile.html +3 -3
  40. package/package.json +1 -1
  41. package/server/lib/assistants/DOCUMENTATION.md +33 -12
  42. package/server/lib/assistants/contact-store.js +25 -1
  43. package/server/lib/assistants/contact-store.test.js +39 -5
  44. package/server/lib/assistants/contact-tools.js +3 -3
  45. package/server/lib/assistants/harness.js +136 -101
  46. package/server/lib/assistants/harness.test.js +235 -8
  47. package/server/lib/assistants/pi-tools.js +2 -0
  48. package/server/lib/assistants/pi-tools.test.js +8 -0
  49. package/server/lib/assistants/service.js +313 -74
  50. package/server/lib/assistants/service.test.js +555 -18
  51. package/server/lib/llm/DOCUMENTATION.md +9 -4
  52. package/server/lib/llm/generate.js +45 -6
  53. package/server/lib/llm/generate.test.js +52 -0
  54. package/dist/assets/MarkdownRenderer-CZqok-Cf.js +0 -2
  55. package/dist/assets/MobileDetailNavigation-Ca-d5eZ9.js +0 -1
  56. package/dist/assets/MobileSurface-xL5Jby4U.js +0 -2
  57. package/dist/assets/sessionChangeSummary-BAzU2J1H.js +0 -2
  58. package/dist/assets/src-DYeppLfP.css +0 -2
@@ -47,9 +47,14 @@ The 1.18.4 client exposes `GET /provider`, `GET /config/providers`, and
47
47
  `attachment`). Non-vision models (for example deepseek-v4-flash) keep the
48
48
  `[image: …]` description and any text-file bytes, and skip image data URLs so
49
49
  generate cannot stall on unsupported vision parts. Non-image text files are
50
- also inlined into the flattened prompt. Wait for idle via `session.status` +
51
- `session.messages`; a deterministic `session.messages` SDK error (for example
52
- HTTP 400) fails generate immediately. Then delete the session and surface
50
+ also inlined into the flattened prompt. Wait for idle via `session.status` +
51
+ `session.messages`; a deterministic `session.messages` SDK error (for example
52
+ HTTP 400) fails generate immediately. The generator deadline is a **stall**
53
+ timer (`GENERATE_TIMEOUT_MS` = 90s), not a wall-clock cap. Busy / retry
54
+ session status, an incomplete assistant message, and throwaway
55
+ `message.part.delta` tokens reset the stall timer — a live model must not
56
+ look like "no response".
57
+ Then delete the session and surface
53
58
  delete SDK errors in diagnostics without erasing a successful text result.
54
59
  Throwaway sessions use `metadata.openchamber.llm.purpose = 'chat-completions'`
55
60
  (and archived immediately) so sidebar visibility, session-index, session-title,
@@ -107,4 +112,4 @@ bubble splitting, and OpenChamber API tools (`assign_session`). Those tools
107
112
  deliver through contact **cards**, not this completions payload. The gateway
108
113
  stays a text generator: OpenCode coding tools stay denied.
109
114
 
110
- Internal completion/generate calls accept an optional AbortSignal from the contact continuation. It is combined with the generator deadline and passed to upstream requests and settle polling. Cancellation still runs throwaway-session cleanup; it must not turn a late model response into a new tool operation.
115
+ Internal completion/generate calls accept an optional AbortSignal from the contact continuation. It is combined with the stall generator deadline and passed to upstream requests and settle polling. Cancellation still runs throwaway-session cleanup; it must not turn a late model response into a new tool operation.
@@ -6,6 +6,10 @@ const SETTLE_POLL_MS = 250;
6
6
  const INCOMPLETE_ASSISTANT_SETTLE_PROBES = 2;
7
7
  const EMPTY_IDLE_PROBES = 5;
8
8
 
9
+ const positiveMs = (value, fallback) => (
10
+ Number.isFinite(value) && value > 0 ? Math.trunc(value) : fallback
11
+ );
12
+
9
13
  /**
10
14
  * Session-level deny-all. OpenCode 1.18 session.create serializes this
11
15
  * PermissionRuleset shape (permission/pattern/action). Confirmed on local
@@ -138,9 +142,17 @@ const deniedTools = (ids) => {
138
142
  return tools;
139
143
  };
140
144
 
141
- const waitForIdleAssistant = async ({ client, sessionID, directory, signal }) => {
145
+ const waitForIdleAssistant = async ({
146
+ client,
147
+ sessionID,
148
+ directory,
149
+ signal,
150
+ onProgress = null,
151
+ settlePollMs = SETTLE_POLL_MS,
152
+ }) => {
142
153
  let incompleteAssistantProbes = 0;
143
154
  let emptyIdleProbes = 0;
155
+ const pollMs = positiveMs(settlePollMs, SETTLE_POLL_MS);
144
156
 
145
157
  for (;;) {
146
158
  signal?.throwIfAborted?.();
@@ -160,7 +172,8 @@ const waitForIdleAssistant = async ({ client, sessionID, directory, signal }) =>
160
172
  if (sessionBusy) {
161
173
  incompleteAssistantProbes = 0;
162
174
  emptyIdleProbes = 0;
163
- await sleep(SETTLE_POLL_MS, signal);
175
+ onProgress?.();
176
+ await sleep(pollMs, signal);
164
177
  continue;
165
178
  }
166
179
 
@@ -186,6 +199,7 @@ const waitForIdleAssistant = async ({ client, sessionID, directory, signal }) =>
186
199
  return messagesResult.data;
187
200
  }
188
201
  incompleteAssistantProbes += 1;
202
+ onProgress?.();
189
203
  if (incompleteAssistantProbes >= INCOMPLETE_ASSISTANT_SETTLE_PROBES) {
190
204
  return messagesResult.data;
191
205
  }
@@ -202,7 +216,7 @@ const waitForIdleAssistant = async ({ client, sessionID, directory, signal }) =>
202
216
  if (error?.code === 'upstream_error') throw error;
203
217
  }
204
218
 
205
- await sleep(SETTLE_POLL_MS, signal);
219
+ await sleep(pollMs, signal);
206
220
  }
207
221
  };
208
222
 
@@ -445,6 +459,8 @@ export async function generateOpenCodeText({
445
459
  onTextDelta = null,
446
460
  globalEventHub = null,
447
461
  signal: parentSignal = null,
462
+ timeoutMs = GENERATE_TIMEOUT_MS,
463
+ settlePollMs = SETTLE_POLL_MS,
448
464
  }) {
449
465
  parentSignal?.throwIfAborted();
450
466
  if (!providerID || !modelID) {
@@ -466,7 +482,23 @@ export async function generateOpenCodeText({
466
482
  parentSignal?.throwIfAborted();
467
483
  const controller = new AbortController();
468
484
  const requestSignal = parentSignal ? AbortSignal.any([parentSignal, controller.signal]) : controller.signal;
469
- const timeout = setTimeout(() => controller.abort(new Error(`OpenCode LLM generate timed out after ${GENERATE_TIMEOUT_MS}ms`)), GENERATE_TIMEOUT_MS);
485
+ const stallMs = positiveMs(timeoutMs, GENERATE_TIMEOUT_MS);
486
+ const abortGenerate = (message) => {
487
+ if (controller.signal.aborted) return;
488
+ controller.abort(new Error(message));
489
+ };
490
+ // Idle deadline only: live busy/delta/incomplete assistant progress
491
+ // must not look like "the model hung". There is no wall-clock cap.
492
+ let stallTimer = setTimeout(() => {
493
+ abortGenerate(`OpenCode LLM generate timed out after ${stallMs}ms without progress`);
494
+ }, stallMs);
495
+ const bumpTimeout = () => {
496
+ if (controller.signal.aborted) return;
497
+ clearTimeout(stallTimer);
498
+ stallTimer = setTimeout(() => {
499
+ abortGenerate(`OpenCode LLM generate timed out after ${stallMs}ms without progress`);
500
+ }, stallMs);
501
+ };
470
502
 
471
503
  try {
472
504
  if (probe.available && probe.mode === 'http' && probe.url) {
@@ -542,7 +574,10 @@ export async function generateOpenCodeText({
542
574
  unsubscribeDeltas = subscribeThrowawayTextDeltas({
543
575
  globalEventHub,
544
576
  sessionID,
545
- onTextDelta,
577
+ onTextDelta: (text) => {
578
+ bumpTimeout();
579
+ if (typeof onTextDelta === 'function') onTextDelta(text);
580
+ },
546
581
  });
547
582
 
548
583
  // promptAsync still forwards model/parts/tools. v2 session.prompt does not.
@@ -561,6 +596,7 @@ export async function generateOpenCodeText({
561
596
  if (!promptAdmitted(prompted)) {
562
597
  failGenerate(`OpenCode LLM promptAsync failed: ${sdkErrorMessage(prompted, 'promptAsync failed')}`);
563
598
  }
599
+ bumpTimeout();
564
600
 
565
601
  let text = assistantTextFromPrompt(prompted?.data ?? prompted);
566
602
  if (!text.trim()) {
@@ -569,6 +605,8 @@ export async function generateOpenCodeText({
569
605
  sessionID,
570
606
  directory: workingDirectory,
571
607
  signal: requestSignal,
608
+ onProgress: bumpTimeout,
609
+ settlePollMs,
572
610
  });
573
611
  text = assistantTextFromMessages(settled);
574
612
  }
@@ -596,7 +634,7 @@ export async function generateOpenCodeText({
596
634
  }
597
635
  }
598
636
  } finally {
599
- clearTimeout(timeout);
637
+ clearTimeout(stallTimer);
600
638
  }
601
639
  }
602
640
 
@@ -613,4 +651,5 @@ export const _test = {
613
651
  LLM_AGENT_NAME,
614
652
  AGENT_MARKDOWN,
615
653
  LLM_SESSION_DENY_PERMISSION,
654
+ GENERATE_TIMEOUT_MS,
616
655
  };
@@ -10,6 +10,30 @@ const completedAssistant = (text) => ({
10
10
  })
11
11
 
12
12
 
13
+ const throwawayGenerate = (client, extra = {}) => generateOpenCodeText({
14
+ providerID: 'p',
15
+ modelID: 'm',
16
+ messages: [{ role: 'user', content: 'work' }],
17
+ buildOpenCodeUrl: () => 'http://localhost:1',
18
+ getOpenCodeAuthHeaders: () => ({}),
19
+ detect: async () => ({ available: false, mode: 'throwaway-session' }),
20
+ clientFactory: () => client,
21
+ ensureTempDirectory: async () => '/tmp/timeout-fixture',
22
+ ...extra,
23
+ })
24
+
25
+ const throwawayClient = ({ status, messages, id = 'ses_tmp', remove = vi.fn(async () => ({ data: true })) }) => ({
26
+ tool: { ids: async () => ({ data: [] }) },
27
+ session: {
28
+ create: async () => ({ data: { id } }),
29
+ update: async () => ({ data: { id } }),
30
+ promptAsync: async () => ({ response: { status: 204 } }),
31
+ status,
32
+ messages,
33
+ delete: remove,
34
+ },
35
+ })
36
+
13
37
  describe('generate cancellation', () => {
14
38
  it('cancels throwaway polling and still deletes only its temporary session', async () => {
15
39
  const controller = new AbortController()
@@ -586,6 +610,34 @@ describe('generateOpenCodeText', () => {
586
610
  })
587
611
  })
588
612
 
613
+ describe('generate stall timeout', () => {
614
+ it('keeps waiting while the throwaway session stays busy past the stall deadline', async () => {
615
+ let polls = 0
616
+ const result = await throwawayGenerate(throwawayClient({
617
+ status: async () => {
618
+ polls += 1
619
+ return { data: { ses_tmp: { type: polls < 12 ? 'busy' : 'idle' } } }
620
+ },
621
+ messages: async () => ({ data: [completedAssistant('late reply')] }),
622
+ }), {
623
+ timeoutMs: 50,
624
+ settlePollMs: 10,
625
+ })
626
+ expect(polls).toBeGreaterThan(5)
627
+ expect(result).toEqual({ text: 'late reply', source: 'throwaway-session' })
628
+ })
629
+
630
+ it('times out when throwaway settle makes no progress', async () => {
631
+ await expect(throwawayGenerate(throwawayClient({
632
+ status: async () => ({ data: {} }),
633
+ messages: async () => ({ data: [] }),
634
+ }), {
635
+ timeoutMs: 40,
636
+ settlePollMs: 10,
637
+ })).rejects.toThrow(/timed out after 40ms without progress/)
638
+ })
639
+ })
640
+
589
641
  describe('subscribeThrowawayTextDeltas', () => {
590
642
  it('returns null without a callback or hub', () => {
591
643
  expect(_test.subscribeThrowawayTextDeltas({
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/MarkstreamRendererImpl-y6QgIUZA.js","assets/rolldown-runtime-C0FnF6B9.js","assets/vendor-base-ui-CnHfUmDN.js","assets/vendor-react-DLPElpoQ.js","assets/vendor-markstream-react-DX55XLGO.js","assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js","assets/vendor-markstream-core-Cm34iPLL.js","assets/vendor-floating-ui-dom-BHhLtF5l.js","assets/vendor-floating-ui-core-Co1I1lFV.js","assets/vendor-reactuses-core-BnW6GxJt.js","assets/vendor-lodash-es-DfLbG5Af.js","assets/vendor-js-cookie-hSOiFTtX.js","assets/useMobileNavigationStore-DQkgxuzg.js","assets/runtime-auth-D66yq6ie.js","assets/runtime-switch-LvWDU-SL.js","assets/runtime-fetch-zIalUnbb.js","assets/persistence-DwRBC4zl.js","assets/vendor-zustand-B4dlGEM2.js","assets/useUIStore-CxOoCv7B.js","assets/vendor-pathe-vBmvQE8f.js","assets/vendor-tanstack-query-core-BWz0ose6.js","assets/platform-DQ5_LNKO.js","assets/vendor-opencode-sdk-C07HQypa.js","assets/vendor-tanstack-react-query-D7pys_c9.js","assets/vendor-sonner-DVzioF3d.js","assets/clipboard-GUUNlWIv.js","assets/store-ClnJdJSj.js","assets/useAssistantUIStore-CLPCNoj_.js","assets/vendor-fuse.js-DB5wDJbI.js","assets/utils-2ZK8yboQ.js","assets/vendor-class-variance-authority-BLUaYARZ.js","assets/vendor-tailwind-merge-BicNWLTg.js","assets/useThemeSystem-DMzWVJaW.js","assets/useRuntimeAPIs-DSLXJybW.js","assets/url-CMQwHq4k.js","assets/useEffectiveDirectory-ChWXV8xM.js","assets/markdownHeightCache-BL8CUQ0M.js","assets/dualLimitLru-D8Sphgua.js","assets/MarkdownRendererImpl-CCfHY-86.js","assets/vendor-katex--B5dHUyk.js","assets/markdownTheme-DOfGg-A7.js","assets/vendor-pierre-diffs-DX7XTPG3.js","assets/vendor-hast-util-to-html-B0p1k5Xa.js","assets/vendor-character-entities-legacy-Wut6vMuj.js","assets/vendor-character-entities-html4-DlN_yAFd.js","assets/vendor-ccount-CyGsA0u7.js","assets/vendor-comma-separated-tokens-B9ouxNNS.js","assets/vendor-oniguruma-to-es-CrHzjjSU.js","assets/vendor-oniguruma-parser-D2DIvhSP.js","assets/vendor-diff-Dq7CZNim.js","assets/vendor-lru_map-DpDied8H.js","assets/markdown-worker-CptoICmq.js","assets/FadeInOnReveal-UGwClbL_.js","assets/imageSource-BlAJJUEI.js","assets/relay-image-stream-DM7atqJs.js","assets/vendor-morphdom-BbKiNDAu.js","assets/vendor-beautiful-mermaid-DykqIK5D.js","assets/vendor-dompurify-CeJNOzik.js","assets/vendor-marked-WVekxjAN.js","assets/vendor-remend-C3cXc-tf.js","assets/MarkstreamRendererImpl-DKhVy3nF.css"])))=>i.map(i=>d[i]);
2
- import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{a as t}from"./vendor-zustand-B4dlGEM2.js";import{nt as n,rt as r}from"./vendor-base-ui-CnHfUmDN.js";import{o as i}from"./vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js";import{n as a}from"./vendor-react-DLPElpoQ.js";import{t as o}from"./utils-2ZK8yboQ.js";import{i as s,n as c,t as l}from"./markdownHeightCache-BL8CUQ0M.js";var u=a(),d=e(r(),1),f=`openchamber:chunk-import-reload`,p=250,m=3e4,h=[/Importing a module script failed/i,/Failed to fetch dynamically imported module/i,/error loading dynamically imported module/i,/Loading chunk \S+ failed/i,/ChunkLoadError/i];function g(e){if(e instanceof Error)return`${e.name}\n${e.message}\n${e.stack??``}`;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function _(e){let t=g(e);return h.some(e=>e.test(t))}function v(e){return`1.19.14:${g(e).slice(0,500)}`}function y(e){if(typeof window>`u`)return;let t=Date.now(),n=v(e),r=null;try{let e=window.sessionStorage.getItem(f);if(e)try{r=JSON.parse(e)}catch{r=null}}catch{return}let i=typeof r?.timestamp==`number`?r.timestamp:0;if(!(r?.signature===n&&t-i<m)){try{window.sessionStorage.setItem(f,JSON.stringify({signature:n,timestamp:t}))}catch{return}console.error(`[refresh-debug] chunk-import-reload`,{error:g(e).slice(0,1e3)}),window.setTimeout(()=>{window.location.reload()},0)}}async function b(e,t={}){let n=t.retries??1,r;for(let t=0;t<=n;t+=1)try{return await e()}catch(e){if(r=e,!_(e)||t>=n)break;await new Promise(e=>setTimeout(e,p*(t+1)))}throw _(r)&&y(r),r}var x=e=>(0,d.lazy)(()=>b(e)),S=(e,t)=>{try{let n=t??(typeof localStorage>`u`?null:localStorage);return n?n.getItem(e)===`1`:!1}catch{return!1}},C=(e,t)=>{try{let n=t??(typeof localStorage>`u`?null:localStorage);return!n||n.getItem(e)!==`0`}catch{return!0}},w=(e,t)=>{try{typeof localStorage<`u`&&localStorage.setItem(e,t?`1`:`0`)}catch{}},T=`oc:legend-timeline`,E=e=>S(T,e),D=`oc:markstream-react`,O=e=>C(D,e),k=t(e=>({legendTimelineEnabled:E(),setLegendTimelineEnabled:t=>{w(T,t),e({legendTimelineEnabled:t})},markstreamReactEnabled:O(),setMarkstreamReactEnabled:t=>{w(D,t),e({markstreamReactEnabled:t})}})),A=null,j=()=>(A??=i(()=>import(`./MarkstreamRendererImpl-y6QgIUZA.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60])).catch(e=>{throw A=null,e}),A),M=()=>{j().catch(()=>void 0)},N=null,P=()=>(N??=i(()=>import(`./MarkdownRendererImpl-CCfHY-86.js`).then(e=>e.n),__vite__mapDeps([38,1,14,13,15,16,17,2,18,19,3,20,21,22,5,39,9,10,11,25,26,12,23,24,27,28,29,30,31,32,40,41,42,43,44,45,46,47,48,49,50,33,34,51,37,35,52,53,54,36,55,56,57,58,59])).catch(e=>{throw N=null,e}),N),F=()=>{P().catch(()=>void 0),O()&&M()},I=class extends d.Component{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e){console.warn(`[markstream-react] falling back to the current Markdown renderer`,e)}render(){return this.state.hasError?this.props.fallback:this.props.children}},L=d.createContext(!0),R=()=>d.useContext(L),z=n(),B=x(()=>P().then(e=>({default:e.MarkdownRenderer}))),V=x(()=>j().then(e=>({default:e.MarkstreamRenderer}))),H=x(()=>P().then(e=>({default:e.SimpleMarkdownRenderer}))),U=e=>e===`tool`?`markdown-content markdown-tool`:e===`reasoning`?`markdown-content markdown-reasoning`:`markdown-content leading-relaxed`,W=e=>{let t=(0,u.c)(15),n=k(q),r=typeof e.content==`string`?e.content:``,i=typeof e.variant==`string`?e.variant:`assistant`,a;t[0]!==r||t[1]!==n||t[2]!==e.reserveMeasuredHeight||t[3]!==i?(a=e.reserveMeasuredHeight?c(l(r,n?`markstream:${i}`:i)):void 0,t[0]=r,t[1]=n,t[2]=e.reserveMeasuredHeight,t[3]=i,t[4]=a):a=t[4];let d=a,f;t[5]!==e.className||t[6]!==e.variant?(f=o(`relative break-words w-full min-w-0`,U(e.variant),typeof e.className==`string`?e.className:void 0),t[5]=e.className,t[6]=e.variant,t[7]=f):f=t[7];let p;t[8]!==r||t[9]!==e.animated||t[10]!==d?(p=(0,z.jsx)(s,{animated:e.animated,content:r,reservedHeight:d}),t[8]=r,t[9]=e.animated,t[10]=d,t[11]=p):p=t[11];let m;return t[12]!==f||t[13]!==p?(m=(0,z.jsx)(`div`,{className:f,"aria-busy":`true`,"data-markdown-hydration":`deferred`,"data-markdown-ready":`false`,children:p}),t[12]=f,t[13]=p,t[14]=m):m=t[14],m},G=e=>{let t=(0,u.c)(9),n=R(),r=k(J);if(!n&&e.isStreaming!==!0){let n;return t[0]===e?n=t[1]:(n=(0,z.jsx)(W,{...e,animated:!1,reserveMeasuredHeight:!0}),t[0]=e,t[1]=n),n}let i;t[2]===e?i=t[3]:(i=(0,z.jsx)(d.Suspense,{fallback:(0,z.jsx)(W,{...e,reserveMeasuredHeight:!0}),children:(0,z.jsx)(B,{...e})}),t[2]=e,t[3]=i);let a=i;if(!r)return a;let o;t[4]===e?o=t[5]:(o=(0,z.jsx)(d.Suspense,{fallback:(0,z.jsx)(W,{...e,reserveMeasuredHeight:!0}),children:(0,z.jsx)(V,{...e})}),t[4]=e,t[5]=o);let s;return t[6]!==a||t[7]!==o?(s=(0,z.jsx)(I,{fallback:a,children:o}),t[6]=a,t[7]=o,t[8]=s):s=t[8],s},K=e=>{let t=(0,u.c)(4);if(!R()){let n;return t[0]===e?n=t[1]:(n=(0,z.jsx)(W,{...e,animated:!1}),t[0]=e,t[1]=n),n}let n;return t[2]===e?n=t[3]:(n=(0,z.jsx)(d.Suspense,{fallback:(0,z.jsx)(W,{...e}),children:(0,z.jsx)(H,{...e})}),t[2]=e,t[3]=n),n};function q(e){return e.markstreamReactEnabled}function J(e){return e.markstreamReactEnabled}export{k as a,F as i,K as n,x as o,L as r,G as t};
@@ -1 +0,0 @@
1
- import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{i as t,n}from"./runtime-switch-LvWDU-SL.js";import{n as r}from"./runtime-fetch-zIalUnbb.js";import{u as i}from"./persistence-DwRBC4zl.js";import{nt as a,rt as o}from"./vendor-base-ui-CnHfUmDN.js";import{n as s}from"./vendor-react-DLPElpoQ.js";import{s as c}from"./vendor-tanstack-react-query-D7pys_c9.js";import{i as l}from"./store-ClnJdJSj.js";import{Oo as u,ko as d}from"./useMobileNavigationStore-DQkgxuzg.js";import{t as f}from"./utils-2ZK8yboQ.js";import{n as p}from"./Icon-D1BcR8Tz.js";import{t as m}from"./button-9R-WgVMl.js";var h=e(o(),1),g=s(),_=class extends Error{code;status;resource;constructor(e,t,n,r){super(typeof r==`string`&&r.trim()?r.trim():e),this.code=e,this.status=t,this.resource=n}},v=e=>{if(!e||typeof e!=`object`)return!1;let t=`name`in e?String(e.name):``;return t===`AbortError`||t===`TimeoutError`},y=class extends _{operation;constructor(e,t,n){super(e,t,`share_operation`),this.operation=n}},b=(e,t=200)=>{throw new _(`invalid_${e}_response`,t,e)},x=(e,t)=>e&&typeof e==`object`&&!Array.isArray(e)?e:b(t),S=(e,t)=>typeof e==`string`?e:b(t),C=(e,t)=>e===null||typeof e==`string`?e:b(t),w=(e,t)=>typeof e==`number`&&Number.isFinite(e)?e:b(t),T=(e,t)=>e===null?null:w(e,t),E=(e,t)=>typeof e==`boolean`?e:b(t),D=(e,t,n)=>t.includes(e)?e:b(n),O=e=>{let t=x(e,`capability`);return{supported:E(t.supported,`capability`),enabled:E(t.enabled,`capability`),revision:w(t.revision,`capability`),serverInstanceID:C(t.serverInstanceID,`capability`)}},k=e=>{if(e==null)return null;let t=x(e,`assistant`);return{turnID:S(t.turnID,`assistant`),messageID:S(t.messageID,`assistant`),status:D(t.status,[`queued`,`running`],`assistant`),admittedAt:w(t.admittedAt,`assistant`)}},A=e=>{if(e==null)return null;let t=x(e,`assistant_preview`),n=w(t.ordinal,`assistant_preview`);return!Number.isSafeInteger(n)||n<0?b(`assistant_preview`):{...t.createdAt===void 0?{}:{createdAt:w(t.createdAt,`assistant_preview`)},messageID:S(t.messageID,`assistant_preview`),ordinal:n,role:D(t.role,[`user`,`assistant`],`assistant_preview`),text:S(t.text,`assistant_preview`),fallbackKind:t.fallbackKind===null?null:D(t.fallbackKind,[`image`,`file`,`session`,`assistant`,`schedule`],`assistant_preview`)}},j=e=>{let t=w(e,`assistant_read`);return Number.isSafeInteger(t)&&t>=0?t:b(`assistant_read`)},M=e=>{let t=x(e,`assistant_read`);return{generation:j(t.generation),ordinal:j(t.ordinal),messageID:S(t.messageID,`assistant_read`)}},N=e=>({unreadCount:e.unreadCount===void 0?0:j(e.unreadCount),readWatermark:e.readWatermark==null?null:M(e.readWatermark),readTip:e.readTip==null?null:M(e.readTip)}),P=e=>{let t=x(e,`assistant_read`);return{assistantID:S(t.assistantID,`assistant_read`),changed:E(t.changed,`assistant_read`),unreadCount:j(t.unreadCount),readWatermark:M(t.readWatermark),readTip:M(t.readTip),revision:j(t.revision)}},F=e=>{let t=x(e,`assistant`),n=Array.isArray(t.historySessionIDs)?t.historySessionIDs.map(e=>S(e,`assistant`)):[],r=t.historySessionCount===void 0?n.length:w(t.historySessionCount,`assistant`);if(!Number.isSafeInteger(r)||r<n.length)return b(`assistant`);let i=Array.isArray(t.assignedSessionIDs)?t.assignedSessionIDs.map(e=>S(e,`assistant`)):[],a=t.activeContactTurn===void 0?null:k(t.activeContactTurn),o=t.working===void 0?a!=null:E(t.working,`assistant`);return{...N(t),latestMessagePreview:A(t.latestMessagePreview),id:S(t.id,`assistant`),revision:w(t.revision,`assistant`),enabled:E(t.enabled,`assistant`),name:S(t.name,`assistant`),defaultPrompt:S(t.defaultPrompt,`assistant`),workspacePath:C(t.workspacePath,`assistant`),effectiveWorkspacePath:S(t.effectiveWorkspacePath,`assistant`),managedWorkspacePath:C(t.managedWorkspacePath??null,`assistant`),providerID:S(t.providerID,`assistant`),modelID:S(t.modelID,`assistant`),agent:C(t.agent,`assistant`),variant:C(t.variant??null,`assistant`),mode:D(t.mode,[`continuous`,`stateless`],`assistant`),sessionID:C(t.sessionID,`assistant`),sessionGeneration:w(t.sessionGeneration,`assistant`),historySessionIDs:n,historySessionCount:r,assignedSessionIDs:i,working:o,activeContactTurn:a,createdAt:T(t.createdAt,`assistant`),updatedAt:w(t.updatedAt,`assistant`),tombstoneAt:T(t.tombstoneAt,`assistant`)}},I=e=>{let t=x(e,`snapshot`);return{revision:w(t.revision,`snapshot`),enabled:E(t.enabled,`snapshot`),assistants:Array.isArray(t.assistants)?t.assistants.map(F):b(`snapshot`)}},L=e=>{let t=x(e,`binding`);return{sessionID:C(t.sessionID,`binding`),directory:S(t.directory,`binding`),sessionGeneration:w(t.sessionGeneration,`binding`)}},ee=e=>{let t=x(e,`message_admission`);if(t.admitted!==!0)return b(`message_admission`);let n=t.revision===void 0||t.revision===null?null:w(t.revision,`message_admission`);return{binding:L(t.binding),messageID:S(t.messageID,`message_admission`),admitted:!0,revision:n,...t.replayed===!0?{replayed:!0}:{}}},te=e=>{let t=x(e,`share_operation`);return{operationID:S(t.operationID,`share_operation`),assistantID:S(t.assistantID,`share_operation`),sessionID:C(t.sessionID,`share_operation`),messageID:C(t.messageID,`share_operation`),state:D(t.state,[`submitting`,`running`,`completed`,`failed`,`unresolved`],`share_operation`),phase:S(t.phase,`share_operation`),attempt:w(t.attempt,`share_operation`),leaseExpiresAt:T(t.leaseExpiresAt,`share_operation`),errorCode:C(t.errorCode,`share_operation`)}},ne=e=>{let t=x(e,`assistant_contact_part`);if(t.type===`text`)return{type:`text`,text:S(t.text,`assistant_contact_part`)};if(t.type===`file`){let e=t.filename===void 0||t.filename===null?void 0:S(t.filename,`assistant_contact_part`),n=S(t.mime,`assistant_contact_part`),r=t.url!==void 0&&t.url!==null,i=t.attachmentID!==void 0&&t.attachmentID!==null;if(r&&i)return b(`assistant_contact_part`);if(i){let r=w(t.size,`assistant_contact_part`);return!Number.isSafeInteger(r)||r<0?b(`assistant_contact_part`):{type:`file`,mime:n,attachmentID:S(t.attachmentID,`assistant_contact_part`),sha256:S(t.sha256,`assistant_contact_part`),size:r,...e?{filename:e}:{}}}return r?{type:`file`,mime:n,url:S(t.url,`assistant_contact_part`),...e?{filename:e}:{}}:b(`assistant_contact_part`)}if(t.type===`card`){let e=D(t.cardType,[`session`,`assistant`,`schedule`],`assistant_contact_part`);return e===`session`?{type:`card`,cardType:`session`,sessionID:S(t.sessionID,`assistant_contact_part`),directory:S(t.directory,`assistant_contact_part`),title:C(t.title??null,`assistant_contact_part`),status:C(t.status??null,`assistant_contact_part`),branch:C(t.branch??null,`assistant_contact_part`)}:e===`assistant`?{type:`card`,cardType:`assistant`,assistantID:S(t.assistantID,`assistant_contact_part`),name:S(t.name,`assistant_contact_part`),providerID:S(t.providerID,`assistant_contact_part`),modelID:S(t.modelID,`assistant_contact_part`),mode:D(t.mode??`continuous`,[`continuous`,`stateless`],`assistant_contact_part`)}:{type:`card`,cardType:`schedule`,taskID:S(t.taskID,`assistant_contact_part`),projectID:S(t.projectID,`assistant_contact_part`),name:S(t.name,`assistant_contact_part`),kind:C(t.kind??null,`assistant_contact_part`),time:C(t.time??null,`assistant_contact_part`),timezone:C(t.timezone??null,`assistant_contact_part`),prompt:C(t.prompt??null,`assistant_contact_part`)}}return b(`assistant_contact_part`)},re=e=>{let t=x(e,`assistant_contact`),n=C(t.nextCursor,`assistant_contact`),r=E(t.complete,`assistant_contact`);if(!r&&!n||r&&n||!Array.isArray(t.messages))return b(`assistant_contact`);let i=w(t.generation,`assistant_contact`),a=w(t.revision,`assistant_contact`);return!Number.isSafeInteger(i)||i<0||!Number.isSafeInteger(a)||a<0?b(`assistant_contact`):{messages:t.messages.map(e=>{let t=x(e,`assistant_contact_message`);if(!Array.isArray(t.parts))return b(`assistant_contact_message`);let n=t.parts.map(ne);return{messageID:S(t.messageID,`assistant_contact_message`),assistantID:S(t.assistantID,`assistant_contact_message`),role:D(t.role,[`user`,`assistant`,`peer`],`assistant_contact_message`),turnID:S(t.turnID,`assistant_contact_message`),bubbleIndex:w(t.bubbleIndex,`assistant_contact_message`),createdAt:w(t.createdAt,`assistant_contact_message`),ordinal:w(t.ordinal,`assistant_contact_message`),status:S(t.status,`assistant_contact_message`),fromAssistantID:C(t.fromAssistantID??null,`assistant_contact_message`),fromAssistantName:C(t.fromAssistantName??null,`assistant_contact_message`),parts:n,text:typeof t.text==`string`?t.text:n.filter(e=>e.type===`text`).map(e=>e.text).join(``),cards:n.filter(e=>e.type===`card`)}}),nextCursor:n,complete:r,generation:i,revision:a}},ie=e=>{let t=x(e,`assistant_scheduled_tasks`);return Array.isArray(t.tasks)?{tasks:t.tasks.map(e=>{let t=x(e,`assistant_scheduled_task`),n=t.task===null||t.task===void 0?null:x(t.task,`assistant_scheduled_task_live`);return{assistantID:S(t.assistantID,`assistant_scheduled_task`),projectID:S(t.projectID,`assistant_scheduled_task`),taskID:S(t.taskID,`assistant_scheduled_task`),createdAt:w(t.createdAt,`assistant_scheduled_task`),projectPath:C(t.projectPath??null,`assistant_scheduled_task`),projectLabel:C(t.projectLabel??null,`assistant_scheduled_task`),task:n}})}:b(`assistant_scheduled_tasks`)},R=async(e,t)=>{try{let t=await e.json();if(t&&typeof t.error==`string`&&t.error.trim().length>0)return t.error}catch{return t}return t},z=e=>{let t=typeof e==`string`?e.trim():``;if(!t)throw Error(`projectId is required`);return t},B=e=>e===null||typeof e==`string`,ae=e=>e===null||typeof e==`number`&&Number.isFinite(e),oe=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0&&e<=864e13,se=e=>e===null||oe(e),ce=e=>{if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.projectId==`string`&&t.projectId.length>0&&typeof t.taskId==`string`&&t.taskId.length>0&&typeof t.taskName==`string`&&(t.trigger===`scheduled`||t.trigger===`manual`)&&(t.status===`running`||t.status===`success`||t.status===`error`)&&B(t.sessionId)&&B(t.directory)&&B(t.error)&&oe(t.startedAt)&&se(t.finishedAt)&&ae(t.durationMs)&&(t.durationMs===null||t.durationMs>=0)},le=e=>{if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Malformed scheduled task runs response`);let t=e;if(!Array.isArray(t.runs)||!t.runs.every(ce)||!B(t.nextCursor)||typeof t.complete!=`boolean`||t.complete!==(t.nextCursor===null)||t.nextCursor!==null&&t.nextCursor.length===0)throw Error(`Malformed scheduled task runs response`);return{runs:t.runs,nextCursor:t.nextCursor,complete:t.complete}},ue=async(e,t)=>{let n=new URLSearchParams;e.before&&n.set(`before`,e.before);let i=e.limit??20;if(!Number.isInteger(i)||i<1)throw Error(`limit must be a positive integer`);n.set(`limit`,String(i)),e.projectId&&n.set(`projectId`,e.projectId),e.taskId&&n.set(`taskId`,e.taskId);let a=await r(`/api/openchamber/scheduled-task-runs?${n.toString()}`,{signal:t});if(!a.ok)throw Error(await R(a,`Failed to load scheduled task history`));return le(await a.json().catch(()=>null))},de=async()=>{let e=await r(`/api/openchamber/scheduled-tasks`);if(!e.ok)throw Error(await R(e,`Failed to load schedules`));let t=await e.json().catch(()=>null);return{tasks:Array.isArray(t?.tasks)?t.tasks:[],failedProjectIds:Array.isArray(t?.failedProjectIds)?t.failedProjectIds.filter(e=>typeof e==`string`):[]}},fe=async(e,t)=>{let n=z(e),i=await r(`/api/projects/${encodeURIComponent(n)}/scheduled-tasks`,{method:`PUT`,headers:{"content-type":`application/json`,accept:`application/json`},body:JSON.stringify({task:t})});if(!i.ok)throw Error(await R(i,`Failed to save schedule`));let a=await i.json().catch(()=>null);return!a||!Array.isArray(a.tasks)?[]:a.tasks},pe=async(e,t)=>{let n=z(e),i=z(t),a=await r(`/api/projects/${encodeURIComponent(n)}/scheduled-tasks/${encodeURIComponent(i)}`,{method:`DELETE`,headers:{accept:`application/json`}});if(!a.ok)throw Error(await R(a,`Failed to delete schedule`));let o=await a.json().catch(()=>null);return!o||!Array.isArray(o.tasks)?[]:o.tasks},me=async(e,t)=>{let n=z(e),i=z(t),a=await r(`/api/projects/${encodeURIComponent(n)}/scheduled-tasks/${encodeURIComponent(i)}/run`,{method:`POST`,headers:{accept:`application/json`}});if(!a.ok)throw Error(await R(a,`Failed to run schedule`));let o=await a.json().catch(()=>null);return{sessionId:typeof o?.sessionId==`string`&&o.sessionId.length>0?o.sessionId:void 0}},he=(e,t)=>e.ordinal===t.ordinal?e.messageID<t.messageID?-1:+(e.messageID>t.messageID):e.ordinal-t.ordinal,ge=e=>{if(e.type===`file`||e.type===`card`)return!0;if(e.type!==`text`)return!1;let t=typeof e.text==`string`?e.text.trim():``;return!!t&&!t.startsWith(`oc.settle.`)},_e=(e,t)=>{if(!t||!e.readTip||!((e.unreadCount??0)>0))return null;let n=e.readTip;if(t.generation!==n.generation)return null;let r;for(let n=t.messages.length-1;n>=0;--n){let i=t.messages[n];if(i.assistantID===e.id&&(i.status===`complete`||i.status===`error`)&&i.parts.some(ge)){r=i;break}}if(!r)return null;let i=e.readWatermark;return i&&(i.generation>t.generation||i.generation===t.generation&&he({ordinal:i.ordinal,messageID:i.messageID},{ordinal:r.ordinal,messageID:r.messageID})>=0)?null:{generation:t.generation,ordinal:r.ordinal,messageID:r.messageID}},ve=()=>({messages:[],generation:-1,revision:0,olderCursor:null,olderComplete:!0,hasMessageGap:!1,gapCursor:null,gapRequestIDs:null,gapTargetIDs:null,liveWindowIDs:[]}),V=e=>!!(e&&e.generation>=0),ye=(e,t)=>he({ordinal:e.ordinal,messageID:e.messageID},{ordinal:t.ordinal,messageID:t.messageID}),H=(e,t,n=`incoming`)=>{let r=new Map;for(let t of e)r.set(t.messageID,t);for(let e of t)(n===`incoming`||!r.has(e.messageID))&&r.set(e.messageID,e);return[...r.values()].sort(ye)},be=e=>{let t=1/0;for(let n of e)n.ordinal<t&&(t=n.ordinal);return Number.isFinite(t)?t:null},xe=e=>e.map(e=>e.messageID),Se=(e,t)=>{for(let n of e)if(t.has(n))return!0;return!1},Ce=e=>new Set(e),we=(e,t)=>!e||!t||e.length!==t.length?!1:e.every((e,n)=>e===t[n]),Te=e=>({...e,hasMessageGap:!1,gapCursor:null,gapRequestIDs:null,gapTargetIDs:null}),Ee=(e,t)=>{let n=e??ve(),r=V(n),i=[...t.messages].sort(ye),a=xe(i);if(r&&t.generation<n.generation)return n;if(r&&t.generation>n.generation)return{messages:i,generation:t.generation,revision:t.revision,olderCursor:t.nextCursor,olderComplete:t.complete,hasMessageGap:!1,gapCursor:null,gapRequestIDs:null,gapTargetIDs:null,liveWindowIDs:a};if(!r)return{messages:i,generation:t.generation,revision:t.revision,olderCursor:t.complete?null:t.nextCursor,olderComplete:t.complete,hasMessageGap:!1,gapCursor:null,gapRequestIDs:null,gapTargetIDs:null,liveWindowIDs:a};if(i.length===0)return{...n,generation:t.generation,revision:Math.max(n.revision,t.revision),olderCursor:n.olderCursor??t.nextCursor,olderComplete:n.olderComplete&&t.complete,liveWindowIDs:[],hasMessageGap:n.hasMessageGap,gapCursor:n.hasMessageGap?t.nextCursor??n.gapCursor:null,gapRequestIDs:n.hasMessageGap?n.gapRequestIDs:null,gapTargetIDs:n.hasMessageGap?n.gapTargetIDs:null};let o=be(i),s=H(n.messages.filter(e=>e.ordinal<o),H(n.messages.filter(e=>e.ordinal>=o),i,t.revision>=n.revision?`incoming`:`existing`),`incoming`),c=n.liveWindowIDs,l=Ce(a),u=c.length>0&&Se(c,l),d=n.hasMessageGap,f=n.gapCursor,p=n.gapRequestIDs,m=n.gapTargetIDs;if(!u&&c.length>0&&t.nextCursor){d=!0,f=t.nextCursor;let e=c.filter(e=>!l.has(e));p=e.length>0?e:[...c],m=n.hasMessageGap&&n.gapTargetIDs&&n.gapTargetIDs.length>0?n.gapTargetIDs:p}else n.hasMessageGap?(d=!0,f=n.gapCursor,p=n.gapRequestIDs,m=n.gapTargetIDs):(d=!1,f=null,p=null,m=null);return{messages:s,generation:t.generation,revision:Math.max(n.revision,t.revision),olderCursor:n.liveWindowIDs.length===0&&n.messages.length===0?t.complete?null:t.nextCursor:n.olderCursor,olderComplete:!r||n.liveWindowIDs.length===0&&n.messages.length===0?t.complete:n.olderComplete,hasMessageGap:d,gapCursor:d?f:null,gapRequestIDs:d?p:null,gapTargetIDs:d?m:null,liveWindowIDs:a}},De=(e,t)=>{if(!V(e)||t.generation!==e.generation)return e;let n=t.revision>=e.revision?`incoming`:`existing`,r=H(e.messages,t.messages,n);return{...e,messages:r,revision:Math.max(e.revision,t.revision),olderCursor:t.complete?null:t.nextCursor,olderComplete:t.complete}},Oe=(e,t,n)=>{if(!V(e)||t.generation!==e.generation)return e;let r=t.revision>=e.revision?`incoming`:`existing`,i=H(e.messages,t.messages,r),a=Math.max(e.revision,t.revision),o=n?.requestIDs??e.gapRequestIDs;if(!(e.hasMessageGap&&o&&e.gapRequestIDs&&we(o,e.gapRequestIDs)))return{...e,messages:i,revision:a};let s=xe(t.messages),c=e.gapTargetIDs??[],l=Ce(c);return c.length>0&&Se(s,l)||t.complete||!t.nextCursor?Te({...e,messages:i,revision:a}):{...e,messages:i,revision:a,hasMessageGap:!0,gapCursor:t.nextCursor??e.gapCursor,gapRequestIDs:e.gapRequestIDs,gapTargetIDs:e.gapTargetIDs}},U={snapshot:(e=t())=>[e,`assistants`,`snapshot`],capability:(e=t())=>[e,`assistants`,`capability`],history:(e,r,i,a=t(),o=n())=>[a,o,`assistants`,`history`,e,r,i],contact:(e,r=t(),i=n())=>[r,i,`assistants`,`contact`,e],scheduledTasks:(e,r=t(),i=n())=>[r,i,`assistants`,`scheduled-tasks`,e],globalScheduledTasks:(e=t())=>[e,`scheduled-tasks`]},W=async(e,t={})=>{let n=await r(e,t),i=await n.json().catch(()=>null);if(!n.ok){let e=i&&typeof i==`object`&&`error`in i&&typeof i.error==`string`?i.error:`request_failed`,t=i&&typeof i==`object`&&`message`in i&&typeof i.message==`string`?i.message:void 0;throw new _(e,n.status,void 0,t)}return i},G=(e,t)=>({method:e,headers:{"Content-Type":`application/json`},body:t===void 0?void 0:JSON.stringify(t)}),K=(e,r)=>{if(t()!==e||n()!==r)throw new _(`runtime_stale`,409)},ke=(e,t,r)=>{i.setQueryData(U.snapshot(r),n=>n&&{...n,assistants:n.assistants.map(n=>n.id!==e||n.sessionGeneration>t.sessionGeneration?n:{...n,sessionID:t.sessionID,sessionGeneration:t.sessionGeneration,effectiveWorkspacePath:t.directory})}),i.invalidateQueries({queryKey:U.snapshot(r)}),i.invalidateQueries({queryKey:[r,n(),`assistants`,`history`,e]})},Ae=(e,t)=>{i.setQueryData(U.snapshot(t),t=>t&&{...t,assistants:t.assistants.some(t=>t.id===e.id)?t.assistants.map(t=>t.id===e.id?e:t):[...t.assistants,e]}),i.invalidateQueries({queryKey:U.snapshot(t)})},je=2500,Me=15e3,Ne=e=>!!e?.assistants.some(e=>e.working||e.activeContactTurn),Pe=(e,t={})=>{if(t.assistantID){let n=e?.assistants.find(e=>e.id===t.assistantID);return n?.working||n?.activeContactTurn?je:Me}return Ne(e)?je:Me},q=(e=t())=>({queryKey:U.snapshot(e),queryFn:async({signal:e})=>I(await W(`/api/openchamber/assistants/snapshot`,{signal:e})),retry:2,refetchInterval:e=>Pe(e.state.data),refetchIntervalInBackground:!1,refetchOnWindowFocus:!0,refetchOnReconnect:!0}),J=new Map,Fe=e=>{let n=J.get(e);if(n)n.count+=1;else{let n=d(n=>{if(t()!==e)return;let r=i.getQueryData(U.snapshot(e));(n.type===`event-stream-ready`||n.type===`contact-turn-start`||n.type===`contact-turn-end`||n.type===`assistants-changed`&&(!r||n.revision>r.revision))&&i.invalidateQueries({queryKey:U.snapshot(e),exact:!0})});J.set(e,{count:1,dispose:n})}return()=>{let t=J.get(e);t&&--t.count===0&&(t.dispose(),J.delete(e))}},Ie=()=>{let e=(0,g.c)(5),n,r,i;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=t(),n=c,r=q(i),e[0]=n,e[1]=r,e[2]=i):(n=e[0],r=e[1],i=e[2]);let a=n(r),o,s;return e[3]===Symbol.for(`react.memo_cache_sentinel`)?(o=()=>Fe(i),s=[i],e[3]=o,e[4]=s):(o=e[3],s=e[4]),h.useEffect(o,s),a},Le=e=>e.enabled?e.assistants.reduce((e,t)=>e+(t.unreadCount??0),0):0,Re=()=>{let e=(0,g.c)(5),n,r,i;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=t(),n=c,r={...q(i),select:Le},e[0]=n,e[1]=r,e[2]=i):(n=e[0],r=e[1],i=e[2]);let a=n(r),o,s;return e[3]===Symbol.for(`react.memo_cache_sentinel`)?(o=()=>Fe(i),s=[i],e[3]=o,e[4]=s):(o=e[3],s=e[4]),h.useEffect(o,s),a.data??0},ze=(e,t={})=>{let n=new URLSearchParams;return n.set(`limit`,String(t.limit??20)),t.before&&n.set(`before`,t.before),t.messageID&&n.set(`messageID`,t.messageID),`/api/openchamber/assistants/${encodeURIComponent(e)}/contact/messages?${n}`},Y=async(e,t,n)=>re(await W(ze(e,t),n?{signal:n}:{})),Be=(e,t)=>e.generation===t.generation&&e.revision===t.revision&&e.olderCursor===t.olderCursor&&e.olderComplete===t.olderComplete&&e.hasMessageGap===t.hasMessageGap&&e.gapCursor===t.gapCursor&&e.messages===t.messages&&e.liveWindowIDs===t.liveWindowIDs&&e.gapRequestIDs===t.gapRequestIDs&&e.gapTargetIDs===t.gapTargetIDs,X=new Map,Z=new Map,Q=e=>e.join(``),Ve=async(e,t,n,r,a)=>{let o=Q(t),s=Z.get(o);if(s)return s;let c=(async()=>{let o=i.getQueryData(t)??n,s=0,c=!1,l=!1,u=o.gapRequestIDs?[...o.gapRequestIDs]:null,d=o.gapCursor;for(;o.hasMessageGap&&o.gapCursor&&s<5&&!a?.aborted;){K(r.transport,r.runtimeGeneration),s+=1;let n=o.gapCursor;try{let s=await Y(e,{limit:20,before:n},a);K(r.transport,r.runtimeGeneration);let l=i.getQueryData(t)??o;if(s.generation!==l.generation){o=l;break}let f=!u||!!(l.hasMessageGap&&l.gapRequestIDs&&l.gapRequestIDs.length===u.length&&l.gapRequestIDs.every((e,t)=>e===u[t]));if(o=Oe(l,s,u?{requestIDs:u,cursor:d}:void 0),i.setQueryData(t,o),!f)break;if(!o.hasMessageGap){c=!0;break}if(o.gapCursor&&o.gapCursor!==n)c=!0;else break}catch(e){if(a?.aborted||v(e))break;l=!0,o=i.getQueryData(t)??o;break}}return{view:i.getQueryData(t)??o,failed:l,progressed:c}})();Z.set(o,c);try{return await c}finally{Z.get(o)===c&&Z.delete(o)}},He=(e,r=t(),a=n(),o={})=>({queryKey:U.contact(e,r,a),queryFn:async({signal:t})=>{K(r,a),await u(),K(r,a);let n=U.contact(e,r,a),o=i.getQueryData(n),s=await Y(e,{limit:20},t);K(r,a);let c=Ee(i.getQueryData(n)??o??null,s);i.setQueryData(n,c);let l=Q(n);if(c.hasMessageGap&&c.gapCursor){X.delete(l);let i=await Ve(e,n,c,{transport:r,runtimeGeneration:a},t);c=i.view,(i.failed||i.view.hasMessageGap&&!i.progressed)&&i.view.gapCursor&&X.set(l,i.view.gapCursor)}else X.delete(l);K(r,a);let d=i.getQueryData(n)??c;return o&&Be(o,d)?o:d},retry:2,refetchInterval:()=>o.reconcileInForeground?Pe(i.getQueryData(U.snapshot(r)),{assistantID:e}):!1,refetchIntervalInBackground:!1,refetchOnWindowFocus:!0,refetchOnReconnect:!0,structuralSharing:!0}),Ue=(e,r=!0)=>{let a=t(),o=n(),[s,l]=h.useState(!1),[u,f]=h.useState(null),[p,m]=h.useState(!1),g=h.useRef(null),_=h.useRef(null),y=h.useRef(null),b=h.useRef(null),x=h.useRef({assistantID:e,transport:a,runtimeGeneration:o,enabled:r});x.current={assistantID:e,transport:a,runtimeGeneration:o,enabled:r};let S=c({...He(e,a,o,{reconcileInForeground:!0}),enabled:r&&!!e});h.useEffect(()=>d(n=>{t()===a&&(n.type===`assistants-changed`||n.type===`event-stream-ready`||n.type===`contact-turn-end`)&&(n.type===`contact-turn-end`&&`assistantID`in n&&n.assistantID!==e||i.invalidateQueries({queryKey:U.contact(e,a,o),exact:!0}))}),[e,o,a]),h.useEffect(()=>{let t=Q(U.contact(e,a,o));return()=>{y.current?.abort(),b.current?.abort(),y.current=null,b.current=null,g.current=null,_.current=null,X.delete(t)}},[e,a,o,r]);let C=S.data,w=U.contact(e,a,o),T=async()=>{if(!e||!r)return;if(g.current)return g.current;let t=i.getQueryData(w)??C;if(!t||t.olderComplete||!t.olderCursor)return;f(null),l(!0);let n=new AbortController;b.current?.abort(),b.current=n;let s={transport:a,runtimeGeneration:o,assistantID:e,cursor:t.olderCursor},c=(async()=>{try{K(s.transport,s.runtimeGeneration);let e=await Y(s.assistantID,{limit:20,before:s.cursor},n.signal);if(n.signal.aborted||(K(s.transport,s.runtimeGeneration),x.current.assistantID!==s.assistantID||x.current.transport!==s.transport||x.current.runtimeGeneration!==s.runtimeGeneration))return;let r=i.getQueryData(w)??t;if(e.generation!==r.generation)return;i.setQueryData(w,De(r,e))}catch(e){if(n.signal.aborted||v(e))return;let t=e instanceof Error?e:Error(String(e));throw f(t),t}finally{b.current===n&&(b.current=null),l(!1),g.current=null}})();return g.current=c,c},E=async(t=`explicit`)=>{if(!e||!r)return;if(_.current)return _.current;let n=i.getQueryData(w)??C;if(!n?.hasMessageGap||!n.gapCursor)return;let s=Q(w);if(t===`auto`&&X.get(s)===n.gapCursor)return;t===`explicit`&&X.delete(s),m(!0);let c=new AbortController;y.current?.abort(),y.current=c;let l={transport:a,runtimeGeneration:o,assistantID:e,cursor:n.gapCursor},u=(async()=>{try{K(l.transport,l.runtimeGeneration);let e=await Ve(l.assistantID,w,n,{transport:l.transport,runtimeGeneration:l.runtimeGeneration},c.signal);if(c.signal.aborted)return;if(K(l.transport,l.runtimeGeneration),e.failed||!e.progressed){e.view.gapCursor&&X.set(s,e.view.gapCursor);return}e.view.hasMessageGap||X.delete(s)}catch(e){if(c.signal.aborted||v(e))return;throw X.set(s,l.cursor),e}finally{y.current===c&&(y.current=null),m(!1),_.current=null}})();return _.current=u,u};return h.useEffect(()=>{if(!r||!e||!C?.hasMessageGap||!C.gapCursor||S.isFetching||p)return;let t=Q(w);X.get(t)!==C.gapCursor&&E(`auto`).catch(()=>void 0)},[r,e,C?.hasMessageGap,C?.gapCursor,S.isFetching,p,w]),{data:C?{messages:C.messages,generation:C.generation,revision:C.revision,nextCursor:C.olderCursor,complete:C.olderComplete}:void 0,status:S.status,fetchStatus:S.fetchStatus,isError:S.isError,isPending:S.isPending,isFetching:S.isFetching,isSuccess:S.isSuccess,error:S.error instanceof Error?S.error:S.error?Error(String(S.error)):null,refetch:()=>S.refetch(),fetchPreviousPage:T,hasPreviousPage:!!(C&&!C.olderComplete&&C.olderCursor),isFetchingPreviousPage:s,previousPageError:u,hasMessageGap:!!C?.hasMessageGap,isFillingMessageGap:p,retryMessageGap:()=>E(`explicit`)}},We=async(e,r)=>{let a=t(),o=n();await u(),K(a,o);let s=await Y(e,{messageID:r,limit:1});if(K(a,o),!s.messages.some(e=>e.messageID===r&&e.role===`user`))return null;i.invalidateQueries({queryKey:U.contact(e,a,o),exact:!0}),i.invalidateQueries({queryKey:U.snapshot(a),exact:!0});let c=i.getQueryData(U.snapshot(a));return{admitted:!0,messageID:r,revision:s.revision??c?.revision??null}},Ge=(e,r=t(),i=n())=>({queryKey:U.scheduledTasks(e,r,i),queryFn:async({signal:t})=>{K(r,i);let n=ie(await W(`/api/openchamber/assistants/${encodeURIComponent(e)}/scheduled-tasks`,{signal:t}));return K(r,i),n},refetchOnMount:`always`,retry:(e,t)=>!(t instanceof _&&t.status===404)&&e<2}),Ke=(e,r)=>{let i=(0,g.c)(6),a=r===void 0||r,o,s;if(i[0]!==e){let r=t(),a=n();s=c,o=Ge(e,r,a),i[0]=e,i[1]=o,i[2]=s}else o=i[1],s=i[2];let l=a&&!!e,u;return i[3]!==o||i[4]!==l?(u={...o,enabled:l},i[3]=o,i[4]=l,i[5]=u):u=i[5],s(u)},qe=(e=t())=>({queryKey:U.globalScheduledTasks(e),queryFn:de,refetchOnMount:`always`}),Je=e=>{let t=(0,g.c)(3),n=e===void 0||e,r;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=qe(),t[0]=r):r=t[0];let i;return t[1]===n?i=t[2]:(i={...r,enabled:n},t[1]=n,t[2]=i),c(i)},Ye=(e,r=t())=>{i.invalidateQueries({queryKey:[r,n(),`assistants`,`contact`,e]})},Xe=(e=t())=>({queryKey:U.capability(e),queryFn:()=>ft(),retry:!1}),Ze=()=>{let e=(0,g.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=Xe(),e[0]=t):t=e[0],c(t)},Qe=(e=i,n=t())=>e.getQueryData(U.snapshot(n)),$e=(e=i,n=t())=>e.fetchQuery(q(n)),et=async(e=i)=>{let r=t(),a=n();await e.invalidateQueries({queryKey:U.snapshot(r),exact:!0}),K(r,a);let o=await e.fetchQuery(q(r));return K(r,a),o},tt=async(e,r)=>{let a=t(),o=n();await W(`/api/openchamber/assistants/${encodeURIComponent(e)}/session/abort`,G(`POST`,{sessionID:r.sessionID,sessionGeneration:r.sessionGeneration})),K(a,o),i.invalidateQueries({queryKey:U.snapshot(a),exact:!0})},nt=15e3,rt=e=>{throw e instanceof _?e:v(e)?new _(`admission_timeout`,408):e},it=async(e,r,i)=>{let a=t(),o=n(),s=typeof i==`string`?[{type:`text`,text:i}]:Array.isArray(i.parts)&&i.parts.length>0?i.parts:[{type:`text`,text:i.text??``}],c=AbortSignal.timeout(nt);try{let t=ee(await W(`/api/openchamber/assistants/${encodeURIComponent(e)}/messages`,{...G(`POST`,{messageID:r,parts:s,language:l.getState().locale}),signal:c}));return K(a,o),ke(e,t.binding,a),Ye(e,a),t}catch(e){return rt(e)}},at=async(e,r,i,a,o)=>{let s=t(),c=n(),l=te(await W(`/api/openchamber/assistants/${encodeURIComponent(e)}/share`,G(`POST`,{operationID:r,payload:{messageID:i,parts:a,source:o}})));return K(s,c),l},ot=async(e,r=t(),i=n())=>{K(r,i);let a=te(await W(`/api/openchamber/assistants/share-operations/${encodeURIComponent(e)}`));return K(r,i),a},st=async(e,r=t(),i=n())=>{let a=e;for(let e=0;e<60&&(a.state===`running`||a.state===`submitting`);e+=1)K(r,i),await new Promise(e=>setTimeout(e,750)),a=await ot(a.operationID,r,i);if(K(r,i),a.state===`completed`)return a;throw a.state===`failed`?new y(a.errorCode??`share_failed`,400,a):new y(`share_unresolved`,408,a)},ct=async(e,n)=>{await W(`/api/openchamber/assistants/settings`,G(`PUT`,{enabled:e,expectedRevision:n}));let r=t();await Promise.all([i.invalidateQueries({queryKey:U.snapshot(r),exact:!0}),i.invalidateQueries({queryKey:U.capability(r),exact:!0})])},lt=async e=>{let n=t(),r=F(await W(`/api/openchamber/assistants`,G(`POST`,e)));return Ae(r,n),r},ut=async(e,r)=>{let i=t(),a=n(),o=F(await W(`/api/openchamber/assistants/${encodeURIComponent(e.id)}`,G(`PATCH`,{...r,expectedRevision:e.revision})));return K(i,a),Ae(o,i),o},dt=async e=>{await W(`/api/openchamber/assistants/${encodeURIComponent(e.id)}`,G(`DELETE`,{expectedRevision:e.revision})),await i.invalidateQueries({queryKey:U.snapshot(t())})},ft=async()=>O(await W(`/api/openchamber/assistants/capability`)),pt=async(e,r)=>{let a=t(),o=n(),s=M(r);try{let t=P(await W(`/api/openchamber/assistants/${encodeURIComponent(e)}/contact/read`,{...G(`POST`,s),signal:AbortSignal.timeout(15e3)}));if(K(a,o),t.assistantID!==e)throw new _(`invalid_assistant_read_response`,200);return t}finally{t()===a&&n()===o&&i.invalidateQueries({queryKey:U.snapshot(a),exact:!0})}},mt=async e=>{let r=e.assistants.filter(e=>(e.unreadCount??0)>0&&e.readTip).map(e=>({id:e.id,position:{...e.readTip}})),i=t(),a=n(),o=[];for(let e=0;e<r.length;e+=4)o.push(...await Promise.allSettled(r.slice(e,e+4).map(async e=>(K(i,a),pt(e.id,e.position)))));return{failed:o.filter(e=>e.status===`rejected`).length}},$=a();function ht(e){let t=(0,g.c)(32),{title:n,subtitle:r,backAriaLabel:i,onBack:a,backDisabled:o,actions:s,trailing:c,sticky:l,overlay:u,elevated:d}=e,h=o!==void 0&&o,_;t[0]===s?_=t[1]:(_=s===void 0?[]:s,t[0]=s,t[1]=_);let v=_,y=l!==void 0&&l,b=u!==void 0&&u,x=d!==void 0&&d,S=!!c||v.length>0,C=x||v.some(_t),w=y&&`oc-mobile-detail-navigation-sticky`,T=b&&`absolute inset-x-0 top-0`,E=C?`z-[60]`:b?`z-30`:void 0,D;t[2]!==w||t[3]!==T||t[4]!==E?(D=f(`oc-mobile-detail-navigation relative shrink-0 pt-[max(0.25rem,var(--oc-safe-area-top,0px))]`,w,T,E),t[2]=w,t[3]=T,t[4]=E,t[5]=D):D=t[5];let O=S&&v.length+ +!!c>1?`grid-cols-[2.75rem_minmax(0,1fr)_auto]`:`grid-cols-[2.75rem_minmax(0,1fr)_2.75rem]`,k;t[6]===O?k=t[7]:(k=f(`oc-mobile-detail-navigation-content grid items-center gap-1 px-4`,O),t[6]=O,t[7]=k);let A;t[8]!==i||t[9]!==h||t[10]!==a?(A=a?(0,$.jsx)(m,{type:`button`,variant:`mobileGlass`,size:`mobileIcon`,className:`justify-self-start`,onClick:a,disabled:h,"aria-label":i,children:(0,$.jsx)(p,{name:`arrow-left-s`,className:`size-5`})}):(0,$.jsx)(`span`,{"aria-hidden":`true`}),t[8]=i,t[9]=h,t[10]=a,t[11]=A):A=t[11];let j;t[12]===n?j=t[13]:(j=(0,$.jsx)(`div`,{className:`oc-mobile-detail-title w-full truncate typography-ui-label font-medium text-foreground`,children:n}),t[12]=n,t[13]=j);let M;t[14]===r?M=t[15]:(M=r?(0,$.jsx)(`div`,{className:`oc-mobile-detail-subtitle w-full truncate text-muted-foreground`,"aria-live":`polite`,children:r}):null,t[14]=r,t[15]=M);let N;t[16]!==j||t[17]!==M?(N=(0,$.jsxs)(`div`,{className:`flex w-full max-w-72 min-w-0 flex-col items-center justify-center justify-self-center px-1`,children:[j,M]}),t[16]=j,t[17]=M,t[18]=N):N=t[18];let P;t[19]===v?P=t[20]:(P=v.map(gt),t[19]=v,t[20]=P);let F;t[21]!==P||t[22]!==c?(F=(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center justify-end gap-2`,children:[c,P]}),t[21]=P,t[22]=c,t[23]=F):F=t[23];let I;t[24]!==k||t[25]!==A||t[26]!==N||t[27]!==F?(I=(0,$.jsxs)(`div`,{className:k,children:[A,N,F]}),t[24]=k,t[25]=A,t[26]=N,t[27]=F,t[28]=I):I=t[28];let L;return t[29]!==D||t[30]!==I?(L=(0,$.jsx)(`header`,{className:D,children:I}),t[29]=D,t[30]=I,t[31]=L):L=t[31],L}function gt(e,t){return(0,$.jsx)(m,{type:`button`,variant:`mobileGlass`,size:`mobileIcon`,className:f(e.elevated&&`relative z-[60]`),onClick:e.onClick,disabled:e.disabled,"aria-label":e.ariaLabel,"aria-expanded":e.pressed,title:e.title,children:(0,$.jsx)(p,{name:e.icon,className:`size-5`})},`${e.icon}:${t}`)}function _t(e){return e.elevated}export{y as A,_e as C,me as D,ue as E,fe as O,st as S,de as T,Ue as _,dt as a,Re as b,et as c,Qe as d,it as f,Ze as g,ut as h,lt as i,v as j,_ as k,mt as l,ct as m,tt as n,$e as o,at as p,We as r,ft as s,ht as t,pt as u,Ke as v,pe as w,Je as x,Ie as y};