pikiloom 0.4.53 → 0.4.54

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 +1 @@
1
- import{j as s}from"./react-vendor-C7Sl8SE7.js";import{O as t,m as i,S as a}from"./index-dR0w8M7K.js";function o({primary:e,secondary:l,tertiary:n}){return s.jsxs("div",{className:"flex flex-col gap-2 pt-1 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e&&s.jsxs(i,{tone:"primary",onClick:e.onClick,disabled:e.disabled,children:[e.loading&&s.jsx(a,{}),e.label]}),l&&s.jsx(i,{tone:"secondary",onClick:l.onClick,disabled:l.disabled,children:l.label})]}),n&&s.jsx("div",{className:"text-xs leading-relaxed text-fg-4",children:n})]})}function c({children:e,className:l}){return s.jsx(t,{padding:"md",elevation:"flat",className:l,children:e})}export{o as A,c as S};
1
+ import{j as s}from"./react-vendor-C7Sl8SE7.js";import{O as t,m as i,S as a}from"./index-89WIHUvA.js";function o({primary:e,secondary:l,tertiary:n}){return s.jsxs("div",{className:"flex flex-col gap-2 pt-1 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e&&s.jsxs(i,{tone:"primary",onClick:e.onClick,disabled:e.disabled,children:[e.loading&&s.jsx(a,{}),e.label]}),l&&s.jsx(i,{tone:"secondary",onClick:l.onClick,disabled:l.disabled,children:l.label})]}),n&&s.jsx("div",{className:"text-xs leading-relaxed text-fg-4",children:n})]})}function c({children:e,className:l}){return s.jsx(t,{padding:"md",elevation:"flat",className:l,children:e})}export{o as A,c as S};
@@ -6,7 +6,7 @@
6
6
  <link rel="icon" type="image/png" href="/logo.png">
7
7
  <title>Pikiloom</title>
8
8
  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
9
- <script type="module" crossorigin src="/assets/index-dR0w8M7K.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-89WIHUvA.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/react-vendor-C7Sl8SE7.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/router-DHISdpPk.js">
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-BQ_R1F_G.css">
@@ -2005,6 +2005,13 @@ async function fetchClaudeUsageFromOAuth(tokenOverride) {
2005
2005
  // one request. `force` is for explicit user-clicked refreshes only: it bypasses both the TTL and
2006
2006
  // the failure backoff (human-paced clicks cannot stampede the endpoint), with a short floor to
2007
2007
  // absorb double-clicks.
2008
+ //
2009
+ // The 429 budget is PER ACCOUNT and shared with every other Claude Code process on the machine,
2010
+ // so the endpoint can stay rate-limited for long stretches through no fault of our cadence. When
2011
+ // it fails and there is no last-good to serve, degrade to the inference-header probe (the same
2012
+ // channel setup-token accounts use): coarser — 5h/7d only, no Extra spend or per-model weekly —
2013
+ // but reliably available, so the native row never goes blank. A later successful oauth read
2014
+ // replaces it with the full-fidelity snapshot.
2008
2015
  const NATIVE_USAGE_FRESH_TTL_MS = 15_000;
2009
2016
  const NATIVE_USAGE_RETRY_TTL_MS = 60_000;
2010
2017
  const NATIVE_USAGE_FORCE_FLOOR_MS = 3_000;
@@ -2022,20 +2029,31 @@ export function claudeNativeUsage(opts) {
2022
2029
  }
2023
2030
  if (claudeNativeUsageLive.inflight)
2024
2031
  return claudeNativeUsageLive.inflight;
2025
- const p = fetchClaudeUsageFromOAuth()
2026
- .then(fresh => {
2027
- if (fresh) {
2028
- claudeUsageCache.lastGood = fresh;
2032
+ const p = (async () => {
2033
+ let result = await fetchClaudeUsageFromOAuth();
2034
+ const oauthOk = !!result;
2035
+ // Degrade to the header probe when oauth fails and there is no full-fidelity snapshot to
2036
+ // serve — including when last-good is itself a header-probe result (keep it refreshing
2037
+ // through a long 429 stretch instead of freezing on the first degraded read).
2038
+ if (!result && (!claudeUsageCache.lastGood || claudeUsageCache.lastGood.source === 'ratelimit-headers')) {
2039
+ const token = getClaudeOAuthToken();
2040
+ if (token)
2041
+ result = await claudeUsageForToken(token, opts);
2042
+ agentLog(`[usage] native oauth usage read failed; header-probe fallback -> ${result ? result.source : 'null'}`);
2043
+ }
2044
+ if (result) {
2045
+ claudeUsageCache.lastGood = result;
2029
2046
  claudeUsageCache.lastAttemptAt = Date.now();
2030
2047
  claudeNativeUsageLive.at = Date.now();
2031
- claudeNativeUsageLive.failedAt = 0;
2048
+ // A header-probe fallback is a degraded read: keep failedAt so the oauth endpoint is
2049
+ // retried on the normal backoff cadence instead of idling out the full ok-TTL.
2050
+ claudeNativeUsageLive.failedAt = oauthOk ? 0 : Date.now();
2032
2051
  }
2033
2052
  else {
2034
2053
  claudeNativeUsageLive.failedAt = Date.now();
2035
2054
  }
2036
- return fresh ?? claudeUsageCache.lastGood;
2037
- })
2038
- .finally(() => { claudeNativeUsageLive.inflight = null; });
2055
+ return result ?? claudeUsageCache.lastGood;
2056
+ })().finally(() => { claudeNativeUsageLive.inflight = null; });
2039
2057
  claudeNativeUsageLive.inflight = p;
2040
2058
  return p;
2041
2059
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pikiloom",
3
- "version": "0.4.53",
3
+ "version": "0.4.54",
4
4
  "description": "Put the world's smartest AI agents in your pocket. Command local Claude & Gemini via IM. | 让最好用的 IM 变成你电脑上的顶级 Agent 控制台",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- import{r as t,j as s}from"./react-vendor-C7Sl8SE7.js";import{c as _t,I as $t,S as Ue,m as Fe,a as R,u as rt,d as Kt,g as zt,l as Wt,e as Yt,j as Xt,f as Gt,s as Vt,Y as Jt}from"./index-dR0w8M7K.js";import{s as Zt,l as er,n as St,m as tr,a as rr,o as nr,d as sr,b as lr,p as or,c as Ce,e as ar,f as bt,g as qe,T as ur,R as cr,U as vt,h as ir,i as It,j as dr,L as fr,I as mr}from"./index-C-9wwAiw.js";import{M as Tt,a as Rt}from"./Modal-BeyxM41U.js";import"./router-DHISdpPk.js";import"./Select-DxYPQ-41.js";import"./DirBrowser-Dk-TadnX.js";import"./markdown-DxQYQFeH.js";import"./ExtensionsTab-wiaVcnfS.js";function gr({snapshot:o}){const[r,f]=t.useState(o.currentIndex??0),[L,I]=t.useState(""),[x,g]=t.useState(!1),[E,k]=t.useState(null);t.useEffect(()=>{f(o.currentIndex??0),I(""),k(null)},[o.promptId,o.currentIndex]);const O=o.questions||[],y=O[r]||null,z=O.length,C=!!(y?.options&&y.options.length),M=C?!!y?.allowFreeform:!0,oe=u=>{u&&(f(c=>c+1),I(""))},ve=async u=>{if(!x){g(!0),k(null);try{const c=await R.interactionSelectOption(o.promptId,u);if(!c.ok){k(c.error||"Failed to submit selection.");return}oe(c.advanced)}catch(c){k(c?.message||"Network error.")}finally{g(!1)}}},ae=async()=>{if(x)return;const u=L.trim();if(!u&&!y?.allowEmpty){k("Please enter a response.");return}g(!0),k(null);try{const c=await R.interactionSubmitText(o.promptId,u);if(!c.ok){k(c.error||"Failed to submit answer.");return}oe(c.advanced)}catch(c){k(c?.message||"Network error.")}finally{g(!1)}},p=async()=>{if(!x){g(!0),k(null);try{const u=await R.interactionSkip(o.promptId);if(!u.ok){k(u.error||"Failed to skip.");return}oe(u.advanced)}catch(u){k(u?.message||"Network error.")}finally{g(!1)}}},ue=async()=>{if(!x){g(!0);try{await R.interactionCancel(o.promptId)}catch{}}},Ie=t.useMemo(()=>{const u=[];return o.hint&&u.push(o.hint),z>1&&u.push(`Question ${r+1} of ${z}`),u.join(" · ")||void 0},[o.hint,r,z]);return s.jsxs(Tt,{open:!0,onClose:ue,wide:C&&(y?.options?.length||0)>3,children:[s.jsx(Rt,{title:o.title||"Pikiloom needs your input",description:Ie,onClose:ue}),y?s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("div",{className:"text-xs font-medium uppercase tracking-wide text-fg-5",children:y.header||"Question"}),s.jsx("div",{className:"mt-1 whitespace-pre-wrap text-sm leading-relaxed text-fg",children:y.prompt})]}),C&&s.jsx("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:(y.options||[]).map(u=>s.jsxs("button",{type:"button",disabled:x,onClick:()=>ve(u.value||u.label),className:_t("group rounded-lg border border-edge bg-panel-alt px-3 py-2 text-left text-sm transition","hover:border-control-border-h hover:bg-control-h hover:shadow-sm","focus:outline-none focus:ring-2 focus:ring-[var(--th-glow-a)]","disabled:cursor-not-allowed disabled:opacity-50"),children:[s.jsx("div",{className:"font-medium text-fg group-hover:text-fg",children:u.label}),u.description&&s.jsx("div",{className:"mt-0.5 text-xs leading-snug text-fg-4",children:u.description})]},u.value||u.label))}),M&&s.jsx("div",{children:s.jsx($t,{value:L,onChange:u=>I(u.target.value),onKeyDown:u=>{u.key==="Enter"&&!u.shiftKey&&!x&&(u.preventDefault(),ae())},placeholder:C?"Or type a custom answer…":"Type your answer…",disabled:x,autoFocus:!C})}),E&&s.jsx("div",{className:"rounded-md border border-red-300/40 bg-red-500/10 px-3 py-2 text-xs text-red-600",children:E}),s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsx("div",{className:"text-xs text-fg-5",children:x?s.jsxs("span",{className:"inline-flex items-center gap-2",children:[s.jsx(Ue,{})," Submitting…"]}):s.jsxs("span",{children:["Press ",s.jsx("kbd",{className:"rounded border border-edge bg-panel-alt px-1.5 py-0.5 text-[10px] uppercase",children:"Enter"})," to send"]})}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(Fe,{variant:"ghost",size:"sm",onClick:p,disabled:x,children:"Skip"}),M&&s.jsx(Fe,{variant:"primary",size:"sm",onClick:ae,disabled:x||!L.trim()&&!y.allowEmpty,children:"Submit"})]})]})]}):s.jsxs("div",{className:"py-6 text-center text-sm text-fg-5",children:[s.jsx(Ue,{className:"mr-2 inline-block"})," Waiting for the agent…"]})]})}function pr(o){return o.isNull?o.localStreamPending||o.holdsActiveState?"reject-null":"apply":(typeof o.updatedAt=="number"?o.updatedAt:0)<o.lastAppliedUpdatedAt?"reject-stale":"apply"}function hr(o,r){return typeof r!="number"?o:r>o?r:o}function xr(o,r){return!o||!o.length?[]:r.size?o.filter(f=>!r.has(f)):o.slice()}function kr(o,r,f,L){if(!o.size)return o;const I=new Set(r);let x=!1;const g=new Map;for(const[E,k]of o){if(f-k>L||!I.has(E)){x=!0;continue}g.set(E,k)}return x?g:o}const nt=12,yt=160,Sr=96,br=[],vr=[],Ir=[],yr=20,Tr=6e4,le=new Map;function Rr(o,r){return`${o}:${r}`}function jr(o,r){for(le.delete(o),le.set(o,r);le.size>yr;)le.delete(le.keys().next().value)}const qr=t.memo(function({session:r,workdir:f,active:L=!0,onSessionChange:I,initialPendingPrompt:x,initialPendingImageUrls:g,onPendingPromptConsumed:E}){const k=rt(e=>e.locale),O=rt(e=>e.agentStatus?.agents?.find(n=>n.agent===r.agent)??null),y=O?.selectedEffort??null,z=O?.selectedModel??null,C=rt(e=>e.modelLayer),M=r.profileId?C?.profiles.find(e=>e.id===r.profileId)??null:null,oe=M?C?.providers.find(e=>e.id===M.providerId)??null:null,ve=r.profileId===void 0?O?.byokProviderName??null:oe?.name??null,ae=r.profileId===void 0?O?.byokProfileName??null:M&&M.name.trim().toLowerCase()!==M.modelId.trim().toLowerCase()?M.name:null,p=t.useMemo(()=>Kt(k),[k]),ue=zt(r.agent||""),Ie=Wt(r),u=!!x||!!(g&&g.length),[c,He]=t.useState(null),[Be,ce]=t.useState(!u),[ie,st]=t.useState(!1),[i,U]=t.useState(null),[de,fe]=t.useState(!1),[W,De]=t.useState(null),[jt,lt]=t.useState(0),[wt,Qe]=t.useState(null),[Y,ye]=t.useState([]),[Nt,Te]=t.useState([]),[me,_e]=t.useState([]),[S,X]=t.useState(x||null),[P,G]=t.useState(g||[]),[At,V]=t.useState(null),F=t.useRef(null);F.current=At;const ot=t.useRef(S);ot.current=S;const[at,q]=t.useState([]),Re=t.useRef([]);Re.current=at;const ge=t.useRef(null),[Lt,ut]=t.useState(null),[je,pe]=t.useState(null),[he,$e]=t.useState(""),[H,Ke]=t.useState(!1),Ot=!!O?.capabilities?.fork,ze=t.useRef(null),A=t.useRef(g||[]),B=t.useRef(i),We=t.useRef(de);B.current=i,We.current=de;const Ye=t.useRef(Y);Ye.current=Y;const ct=t.useRef(W);ct.current=W;const D=t.useRef(null),we=t.useRef(null),J=t.useRef(!0),Z=t.useRef(!1),Ne=t.useRef(null),Xe=t.useRef(!1),Q=t.useRef(u),xe=t.useRef(!1),ee=t.useRef(!1),Ge=t.useRef(!1),Ve=t.useRef(!1),_=t.useRef(null),Ae=t.useRef(0),ke=t.useRef(new Map),it=t.useRef({model:null,effort:null}),Mt=t.useCallback(e=>{it.current=e},[]);t.useEffect(()=>{Ge.current||!u||(Ge.current=!0,x&&!S&&X(x),g&&g.length&&!P.length&&(G(g),A.current=g),ce(!1),lt(e=>e+1),E?.())},[u,E]);const j=t.useCallback(()=>{X(null),G(e=>{for(const n of e)URL.revokeObjectURL(n);return[]}),A.current=[],V(null)},[]),te=t.useCallback(()=>{q(e=>{if(!e.length)return e;for(const n of e)for(const l of n.imageUrls)URL.revokeObjectURL(l);return[]}),ge.current=null},[]),dt=t.useCallback((e,n)=>{const l=Zt({streaming:We.current,liveStreamPhase:B.current?.phase??null,streamPhase:ct.current,queuedTaskCount:Ye.current.length,pendingQueuedCount:Re.current.length}),a=n||[];if(l){const d=`local-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;ge.current=d,q(h=>[...h,{localId:d,taskId:null,prompt:e||"",imageUrls:a}]);return}B.current?.phase==="done"&&U(null);for(const d of A.current)URL.revokeObjectURL(d);ge.current=null,X(e||null),G(a),A.current=a,V(null)},[]),Pt=t.useCallback(e=>{const n=ge.current;if(n){ge.current=null,q(l=>{const a=l.findIndex(h=>h.localId===n);if(a<0)return l;const d=l.slice();return d[a]={...d[a],taskId:e},d});return}V(e)},[]),Et=t.useCallback(async()=>{if(!je)return;const e=he.trim();if(e){Ke(!0);try{const n=await R.forkSession(f,r.agent||"",r.sessionId,je.atTurn,e,{});if(!n.ok||!n.sessionKey){Ke(!1);return}const[l,a]=n.sessionKey.split(":");pe(null),$e(""),I?.({agent:l,sessionId:a,workdir:f})}finally{Ke(!1)}}},[je,he,f,r.agent,r.sessionId,I]);ze.current=Et;const Le=t.useCallback(async(e,n={})=>{try{const l=await er({workdir:f,agent:r.agent||"",sessionId:r.sessionId,rich:!0,turnOffset:e.turnOffset,turnLimit:e.turnLimit,lastNTurns:e.lastNTurns},{force:n.force});return l.ok?St(l):null}catch{return null}},[f,r.agent,r.sessionId]),w=t.useCallback(async({keepOlder:e,force:n=!1,scrollToBottom:l=!1})=>{const a=r.sessionId;if(Ne.current===a)return!1;Ne.current=a;try{const d=await Le({turnOffset:0,turnLimit:nt},{force:n});if(!d||r.sessionId!==a)return!1;if(l&&(Z.current=!0),He(h=>!h||!e?d:tr(h,d)),ce(!1),xe.current&&(xe.current=!1,j()),ee.current){const h=ee.current;ee.current=!1;const ne=h!==!0?h.taskId:null;B.current&&(h===!0||B.current.taskId===ne)&&U(null)}return!0}finally{Ne.current===a&&(Ne.current=null)}},[Le,j,r.sessionId]),Oe=t.useCallback(async()=>{if(!c?.hasOlder||Xe.current)return;const e=D.current;e&&(we.current={scrollHeight:e.scrollHeight,scrollTop:e.scrollTop}),Xe.current=!0,st(!0);try{const n=await Le({turnOffset:Math.max(0,c.totalTurns-c.startTurn),turnLimit:nt});n?He(l=>l?rr(l,n):n):we.current=null}finally{Xe.current=!1,st(!1)}},[Le,c]),Me=t.useRef(null),re=t.useCallback((e,n="ws")=>{if(pr({updatedAt:e?.updatedAt,isNull:!e,lastAppliedUpdatedAt:Ae.current,localStreamPending:Q.current,holdsActiveState:We.current||Ye.current.length>0})!=="apply")return;if(e&&(Ae.current=hr(Ae.current,e.updatedAt)),e?.sessionId&&e.sessionId!==r.sessionId&&(Ve.current=!0,Se.current=`${r.agent}:${e.sessionId}`,I?.({agent:r.agent||"",sessionId:e.sessionId,workdir:f})),!e){const m=Me.current;fe(!1),m==="streaming"?(xe.current=!0,ee.current=!0,w({keepOlder:!0,force:!0,scrollToBottom:J.current})):U(null),Q.current&&m!=="streaming"?w({keepOlder:!0,force:!0}):(m==="done"&&(j(),te()),m!==null&&(Q.current=!1)),Qe(null),De(null),ye([]),Te([]),_e([]),Me.current=null;return}De(e.phase),Qe(e.taskId||null);const a=[];e.taskId&&a.push(e.taskId),Array.isArray(e.queuedTaskIds)&&a.push(...e.queuedTaskIds),ke.current=kr(ke.current,a,Date.now(),Tr);const d=ke.current,h=xr(e.queuedTaskIds,d),ne=(Array.isArray(e.queuedTasks)?e.queuedTasks:[]).filter(m=>!d.has(m.taskId));if(ye(h.length?h:br),Te(ne.length?ne:vr),_e(Array.isArray(e.interactions)&&e.interactions.length?e.interactions:Ir),nr({pendingTaskId:F.current,streamTaskId:e.taskId||null,queuedTaskIds:e.queuedTaskIds})){const m=F.current,T=ot.current||"",v=A.current;q(b=>b.some(se=>se.taskId===m)?b:[...b,{localId:`demote-${m}`,taskId:m,prompt:T,imageUrls:v}]),X(null),G([]),A.current=[],V(null),F.current=null}if(e.phase==="streaming"){if(U({taskId:e.taskId||null,phase:"streaming",text:e.text||"",thinking:e.thinking||"",activity:e.activity,plan:e.plan??null,model:e.model??null,effort:e.effort??null,previewMeta:e.previewMeta??null,subAgents:e.previewMeta?.subAgents??null,generatingImages:e.previewMeta?.generatingImages??0,artifacts:e.artifacts??null,startedAt:typeof e.startedAt=="number"?e.startedAt:null,error:null,question:e.question??null,questionBlocks:e.questionBlocks??null}),fe(!0),e.taskId&&e.taskId!==F.current){const m=Re.current,T=m.findIndex(v=>v.taskId===e.taskId);if(T>=0){const v=m[T];for(const b of A.current)URL.revokeObjectURL(b);X(v.prompt||null),G(v.imageUrls),A.current=v.imageUrls,V(e.taskId),q(b=>b.filter((se,K)=>K!==T))}}J.current&&(Z.current=!0)}else if(e.phase==="queued")U(null),fe(!1);else if(e.phase==="done"){const m=sr(B.current?.taskId??null,e.taskId||null),T=h.length>0;if(m){fe(!1),U(K=>K?{...K,phase:"done",error:e.error??null}:e.error?{taskId:e.taskId||null,phase:"done",text:"",thinking:"",activity:"",plan:null,model:e.model??null,effort:e.effort??null,previewMeta:e.previewMeta??null,subAgents:e.previewMeta?.subAgents??null,generatingImages:e.previewMeta?.generatingImages??0,artifacts:e.artifacts??null,error:e.error,question:e.question??null,questionBlocks:e.questionBlocks??null}:K);const v=B.current,b=!!v&&lr(v),se=!!e.incomplete&&b&&!T;if(Me.current!=="done"){T||(xe.current=!0),ee.current=se?!1:{taskId:e.taskId||null},w({keepOlder:!0,force:!0,scrollToBottom:J.current});const K=r.agent||"",Bt=r.sessionId,Dt=Se.current;_.current&&clearTimeout(_.current),_.current=setTimeout(()=>{_.current=null,R.getSessionStreamState(K,Bt).then(Qt=>{Se.current===Dt&&Je.current(Qt.state,"seed")}).catch(()=>{})},900)}}T||(Q.current=!1)}const $=new Set;if(e.taskId&&$.add(e.taskId),Array.isArray(e.queuedTaskIds))for(const m of e.queuedTaskIds)$.add(m);q(m=>{let T=!1;const v=[];for(const b of m)if(!b.taskId||$.has(b.taskId))v.push(b);else{for(const se of b.imageUrls)URL.revokeObjectURL(se);T=!0}return T?v:m}),Me.current=e.phase},[j,te,w,r.sessionId,r.agent,I,f]),Je=t.useRef(re);Je.current=re;const ft=t.useCallback(()=>{Q.current=!0,lt(e=>e+1)},[]);t.useEffect(()=>()=>{_.current&&(clearTimeout(_.current),_.current=null)},[]);const Ct=t.useCallback(async e=>{try{ke.current.set(e,Date.now()),await R.recallSessionMessage(e),F.current===e&&j(),q(n=>{let l=!1;const a=[];for(const d of n)if(d.taskId===e){for(const h of d.imageUrls)URL.revokeObjectURL(h);l=!0}else a.push(d);return l?a:n}),ye(n=>n.filter(l=>l!==e)),Te(n=>n.filter(l=>l.taskId!==e)),Qe(n=>n===e?null:n)}catch{}},[j]),qt=t.useCallback(async e=>{const n=Re.current.find(l=>l.taskId===e)||null;if(n&&n.imageUrls.length>0){for(const l of A.current)URL.revokeObjectURL(l);X(n.prompt||null),G(n.imageUrls),A.current=n.imageUrls,V(e),F.current=e,q(l=>l.filter(a=>a.taskId!==e))}try{await R.steerSession(e)}catch{}},[]),Ut=t.useCallback(async()=>{try{await R.stopSession(r.agent||"",r.sessionId)}catch{}},[r.agent,r.sessionId]),Pe=Rr(r.agent||"",r.sessionId);t.useEffect(()=>{if(Ve.current){Ve.current=!1;let d=!1;return w({keepOlder:!0,force:!0}).finally(()=>{d||ce(!1)}),()=>{d=!0}}let e=!1;const n=or({workdir:f,agent:r.agent||"",sessionId:r.sessionId,rich:!0,turnOffset:0,turnLimit:nt},{allowStale:!0}),l=u&&!Ge.current,a=n?.ok?St(n):le.get(Pe)||null;return ce(l?!1:!a),He(a),U(null),fe(!1),De(null),ye([]),Te([]),_e([]),Ae.current=0,ke.current=new Map,l||(j(),te(),Q.current=!1,xe.current=!1,ee.current=!1),J.current=!0,Z.current=!0,l||w({keepOlder:!1,force:!0}).finally(()=>{e||ce(!1)}),()=>{e=!0}},[w,r.agent,r.sessionId,f,Pe,j,te]),t.useEffect(()=>{c&&c.turns.length>0&&jr(Pe,c)},[Pe,c]),t.useEffect(()=>{L&&w({keepOlder:!0,force:!0})},[L,w]);const Se=t.useRef(`${r.agent}:${r.sessionId}`);Se.current=`${r.agent}:${r.sessionId}`,Yt("stream-update",t.useCallback(e=>{e.key===Se.current&&re(e.snapshot??null)},[re])),t.useEffect(()=>{let e=!0;return R.getSessionStreamState(r.agent||"",r.sessionId).then(n=>{e&&Je.current(n.state,"seed")}).catch(()=>{}),()=>{e=!1}},[r.agent,r.sessionId,jt]),Xt(t.useCallback(()=>{R.getSessionStreamState(r.agent||"",r.sessionId).then(e=>{re(e.state,"seed")}).catch(()=>{}),w({keepOlder:!0,force:!0})},[re,r.agent,r.sessionId,w])),t.useEffect(()=>{!Q.current&&Ie!=="running"&&!de&&!i&&!W&&Y.length===0&&(j(),te())},[Ie,de,i,W,Y.length,j,te]),t.useLayoutEffect(()=>{const e=we.current,n=D.current;!e||!n||(we.current=null,n.scrollTop=e.scrollTop+(n.scrollHeight-e.scrollHeight))},[c?.turns.length]),t.useLayoutEffect(()=>{if(!Z.current)return;const e=D.current;e&&(Z.current=!1,e.scrollTop=e.scrollHeight,requestAnimationFrame(()=>{J.current&&(e.scrollTop=e.scrollHeight)}))},[c,i]),t.useLayoutEffect(()=>{if(!S)return;const e=D.current;e&&(e.scrollTop=e.scrollHeight)},[S]),t.useEffect(()=>{if(!c?.hasOlder||Be||ie)return;const e=D.current;e&&e.scrollHeight<=e.clientHeight+yt&&Oe()},[c?.hasOlder,c?.turns.length,Oe,Be,ie]);const Ft=t.useCallback(()=>{const e=D.current;if(!e)return;const n=e.scrollHeight-e.scrollTop-e.clientHeight;J.current=n<=Sr,e.scrollTop<=yt&&Oe()},[Oe]),be=i?.model||r.model||z||null,Ze=Gt(r.agent||"",i?.effort||r.thinkingEffort||y||null,r.workflowEnabled??O?.workflowEnabled)||null,mt=ae&&(!be||be===z)?ae:be?Vt(be):null,et=Jt(r,{streaming:de,hasLiveStream:!!i,streamPhase:W,queuedTaskCount:Y.length}),N=c?.turns||[],tt=t.useMemo(()=>{if(!P.length||!N.length)return!1;const e=N[N.length-1];return!e.user||!Ce(e.user.text,S)?!1:e.user.blocks.filter(l=>l.type==="image").length<P.length},[N,S,P.length]),gt=t.useMemo(()=>P.length?P.map(e=>({type:"image",content:e})):!S||!i?.questionBlocks?.length?[]:Ce(S,i.question)?i.questionBlocks:[],[P,S,i]),pt=i?.question||null,Ee=ar(S,pt),ht=bt(pt,S),xt=N.length>0?N[N.length-1]?.user?.text:null,Ht=!!Ee&&N.length>0&&qe(xt,Ee),kt=t.useMemo(()=>{let e=N;if(tt){const $=e[e.length-1];e=[...e.slice(0,-1),{...$,user:null}]}if(!i||!e.length)return e;const n=e[e.length-1],l=Ee;if(!n.assistant)return!!n.user&&!!l&&!Ce(n.user.text,l)&&(qe(n.user.text,l)||bt(l,n.user.text))?[...e.slice(0,-1),{...n,user:{...n.user,text:l}}]:e;const a=(i.text||"").trim(),d=n.assistant.text?.trim()||"";if(!(l!=null?qe(n.user?.text,l):!!d&&!!a&&(a.startsWith(d)||d.startsWith(a))))return e;const ne=n.user&&l&&!Ce(n.user.text,l)?{...n.user,text:l}:n.user;return[...e.slice(0,-1),{...n,user:ne,assistant:null}]},[N,i,Ee,tt]);return s.jsxs("div",{className:"flex flex-col h-full overflow-hidden",children:[s.jsx("div",{ref:D,onScroll:Ft,className:"flex-1 overflow-y-auto overscroll-contain",children:Be&&!S&&!P.length&&!i?s.jsx("div",{className:"flex items-center justify-center py-20",children:s.jsx(Ue,{className:"h-5 w-5 text-fg-4"})}):kt.length===0&&!S&&!P.length&&!i&&!et?s.jsx("div",{className:"py-20 text-center text-[13px] text-fg-5",children:p("hub.noMessages")}):s.jsxs("div",{className:"max-w-[900px] mx-auto px-6 py-6 space-y-0",children:[(c?.hasOlder||ie)&&s.jsxs("div",{className:"mb-4 flex items-center justify-center gap-2 text-[11px] text-fg-5",children:[ie?s.jsx(Ue,{className:"h-3 w-3 text-fg-5"}):s.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-fg-5/35"}),s.jsx("span",{children:p(ie?"hub.loadingOlderTurns":"hub.loadOlderTurnsHint")})]}),r.migratedFrom?.kind==="fork"&&r.migratedFrom.sessionId&&s.jsxs("button",{type:"button",onClick:()=>I?.({agent:r.migratedFrom.agent||r.agent||"",sessionId:r.migratedFrom.sessionId,workdir:f}),className:"mb-4 inline-flex items-center gap-1.5 rounded-md border border-edge bg-panel-alt px-2.5 py-1 text-[11px] text-fg-5 transition hover:border-edge-h hover:text-fg-2",title:`#${r.migratedFrom.sessionId.slice(0,8)}`,children:[s.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[s.jsx("circle",{cx:"6",cy:"6",r:"2"}),s.jsx("circle",{cx:"18",cy:"6",r:"2"}),s.jsx("circle",{cx:"12",cy:"20",r:"2"}),s.jsx("path",{d:"M6 8v3a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V8"}),s.jsx("path",{d:"M12 14v4"})]}),s.jsx("span",{children:p("hub.forkBadge")}),s.jsxs("span",{className:"font-mono",children:["#",r.migratedFrom.sessionId.slice(0,8)]}),typeof r.migratedFrom.forkedAtTurn=="number"&&s.jsxs("span",{className:"text-fg-5/70",children:["· ",p("hub.forkBadgeAt").replace("{turn}",String(r.migratedFrom.forkedAtTurn+1))]})]}),kt.map((e,n)=>{const l=(c?.startTurn||0)+n;return s.jsx(ur,{turn:e,turnIndex:l,agent:r.agent||"",meta:ue,model:mt,effort:Ze,providerName:ve,t:p,workdir:f,onResend:a=>{Z.current=!0,dt(a);const d=it.current;R.sendSessionMessage(f,r.agent||"",r.sessionId,a,{model:d.model||be||void 0,effort:d.effort||Ze||void 0}).then(h=>{h.ok&&ft()}).catch(()=>{j()})},onEdit:a=>ut(a),onFork:Ot?a=>{$e(""),pe({atTurn:a})}:void 0},`${c?.startTurn||0}:${n}`)}),et&&s.jsx("div",{className:"mb-5 animate-in",children:s.jsx(cr,{detail:et,t:p})}),(S||gt.length>0)&&!ht&&(tt||!Ht)&&s.jsxs("div",{className:"session-turn",children:[s.jsx(vt,{text:S||"",blocks:gt,t:p}),!i&&s.jsx("div",{className:"mt-3 mb-5 animate-in",children:s.jsx(ir,{className:"text-fg-5"})})]}),i&&It(i)&&i.question&&(!S||ht)&&!(N.length>0&&qe(xt,i.question))&&s.jsx("div",{className:"session-turn",children:s.jsx(vt,{text:i.question,blocks:i.questionBlocks||void 0,t:p})}),i&&It(i)&&s.jsxs("div",{className:"mb-6",children:[s.jsx(dr,{agent:r.agent||"",meta:ue,model:mt,effort:Ze,providerName:ve,previewMeta:i.previewMeta,hideContextUsage:!0}),s.jsx(fr,{stream:i,t:p,workdir:f})]}),s.jsx("div",{className:"h-4"})]})}),s.jsx(mr,{session:r,workdir:f,onStreamQueued:ft,onSendStart:dt,onSendTaskAssigned:Pt,onSessionChange:I,t:p,streamPhase:W,streamTaskId:wt,queuedTaskIds:Y,queuedTasks:Nt,pendingQueuedSends:at,onRecall:Ct,onSteer:qt,onStopAll:Ut,editDraft:Lt,onEditDraftConsumed:()=>ut(null),onSelectionChange:Mt}),je&&s.jsxs(Tt,{open:!0,onClose:()=>{H||pe(null)},children:[s.jsx(Rt,{title:p("hub.forkPromptTitle"),description:p("hub.forkPromptHint"),onClose:()=>{H||pe(null)}}),s.jsx("textarea",{autoFocus:!0,value:he,disabled:H,onChange:e=>$e(e.target.value),onKeyDown:e=>{e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&he.trim()&&!H&&(e.preventDefault(),ze.current?.())},placeholder:p("hub.forkPromptPlaceholder"),className:"w-full min-h-[120px] resize-y rounded-md border border-edge bg-panel-alt px-3 py-2 text-[13px] leading-relaxed text-fg outline-none focus:border-edge-h"}),s.jsxs("div",{className:"mt-4 flex items-center justify-end gap-2",children:[s.jsx(Fe,{variant:"ghost",disabled:H,onClick:()=>pe(null),children:p("modal.cancel")}),s.jsx(Fe,{variant:"primary",disabled:H||!he.trim(),onClick:()=>{ze.current?.()},children:p(H?"hub.forkSubmitting":"hub.forkSubmit")})]})]}),L&&me.length>0&&s.jsx(gr,{snapshot:me[me.length-1]},me[me.length-1].promptId)]})});export{qr as SessionPanel};