stratagate-dsh 0.2.35 → 0.2.36

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.36 - 2026-08-28
4
+
5
+ - Make completed conversation turns per Block editable in Advanced Settings, persist it globally, and suggest an optional λ adjustment that preserves decay speed per turn.
6
+
3
7
  ## 0.2.35 - 2026-08-27
4
8
 
5
9
  - Return compact Event, Knowledge Graph, and raw-memory search cards while keeping full details in expand tools.
package/README.md CHANGED
@@ -130,7 +130,7 @@ Open DSH Settings and select **StrataGate-AgentMemory**. The page provides:
130
130
  - source-message expansion from every derived memory;
131
131
  - a Usage Audit chain from a recorded answer turn, through the Evidence Gate verdict and selected memories, back to source messages.
132
132
 
133
- Memory records remain read-only: the UI exposes no edit, delete, approve, or import operation. Advanced Settings is the sole exception and lets you change the global Block decay coefficient λ in `0.05` steps. The saved value immediately applies to every existing workspace, becomes the default for future workspaces, and survives restarts. Common token and credential patterns are redacted in both message content and structured tool traces before they leave the local server. The SQLite database remains the source of truth.
133
+ Memory records remain read-only: the UI exposes no edit, delete, approve, or import operation. Advanced Settings lets you change the completed turns per Block and the global Block decay coefficient λ. When the Block size changes, the UI explains their relationship and suggests a λ that preserves the decay rate per conversation turn; the user decides whether to adopt it. Saved settings immediately apply to every existing workspace, become the defaults for future workspaces, and survive restarts. Existing sealed Blocks are never repartitioned. Common token and credential patterns are redacted in both message content and structured tool traces before they leave the local server. The SQLite database remains the source of truth.
134
134
 
135
135
  ## Configuration
136
136
 
@@ -149,11 +149,11 @@ config:
149
149
  # model: deepseek-chat
150
150
  ```
151
151
 
152
- `blockDecayLambda` is the initial fallback. Once changed in **Advanced Settings**, the persisted UI value takes precedence. The default is `0.3`; smaller values forget more slowly and consume more tokens, and values above `0.4` are not recommended.
152
+ `blockTurnSize` and `blockDecayLambda` are initial fallbacks. Once changed in **Advanced Settings**, persisted UI values take precedence. λ defaults to `0.3`; smaller values forget more slowly and consume more tokens, and values above `0.4` are not recommended.
153
153
 
154
154
  `project` derives a stable namespace from the normalized session working directory. `session` isolates every DSH session. `global` shares one namespace.
155
155
 
156
- `blockTurnSize` controls how many completed DSH turns are sealed into each Block. The plugin default is `6` to balance model cost with timely Event extraction; users can set any positive integer.
156
+ `blockTurnSize` controls how many completed DSH turns are sealed into each Block; one turn is one user request plus the completed AI response. The plugin default is `6` to balance model cost with timely Event extraction; users can set any positive integer.
157
157
 
158
158
  `blockDecayLambda` controls decay by the distance between a Block's pointer anchor and the latest sealed Block in the same DSH session. It defaults to `0.3`. Smaller values decay more slowly; values above `0.4` are not recommended. Turns in the open tail do not increase Block age.
159
159
 
package/dist/client.js CHANGED
@@ -361,7 +361,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
361
361
  .sg-status{display:inline-flex;align-items:center;gap:5px;padding:2px 7px;border-radius:5px;font-size:12px;font-weight:650}.sg-status:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}.sg-status.organized{color:var(--sg-good);background:var(--sg-good-soft)}.sg-status.processing{color:var(--sg-accent);background:var(--sg-accent-soft)}.sg-status.waiting{color:var(--sg-muted);background:var(--sg-soft)}.sg-status.failed{color:var(--sg-warn);background:var(--sg-warn-soft)}
362
362
  .sg-backbar{display:flex;align-items:center;min-height:35px;margin:-4px 0 13px}.sg-back{display:inline-flex;align-items:center;gap:6px;margin-left:-7px;padding:6px 7px;border-radius:6px;font-weight:650}.sg-detail-header{padding-bottom:16px;border-bottom:1px solid var(--sg-border)}.sg-detail-section{padding:18px 0;border-bottom:1px solid var(--sg-border)}.sg-detail-section:last-child{border-bottom:0}.sg-section-title{margin:0 0 11px;font-size:14px;font-weight:730}.sg-prose{margin:0;white-space:pre-wrap}.sg-facts{margin:0;padding-left:20px}.sg-facts li+li{margin-top:7px}.sg-related-list{display:flex;flex-direction:column}.sg-related{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border:0;border-bottom:1px solid var(--sg-border);background:transparent;text-align:left;cursor:pointer}.sg-related:last-child{border-bottom:0}.sg-related-name{color:var(--sg-accent)}.sg-related-time{flex:0 0 auto;color:var(--sg-muted);font-size:12px}
363
363
  .sg-source-label{display:flex;align-items:center;gap:8px}.sg-source-icon{color:var(--sg-muted)}.sg-tech{margin-top:13px}.sg-tech summary{color:var(--sg-muted);font-size:12px;cursor:pointer}.sg-tech-body{margin-top:10px;padding:11px;border-radius:7px;background:var(--sg-soft);font-size:12px}.sg-tech-row{display:grid;grid-template-columns:88px minmax(0,1fr);gap:9px;padding:3px 0}.sg-code{font:12px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.sg-raw-message{padding-top:10px;margin-top:10px;border-top:1px solid var(--sg-border)}
364
- .sg-result-count{margin:0 0 9px;color:var(--sg-muted);font-size:12px}.sg-result-event{padding:8px 0;border-bottom:1px solid var(--sg-border)}.sg-result-event:last-child{border-bottom:0}.sg-pipeline{display:flex;flex-direction:column}.sg-stage{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;padding:9px 0;border-bottom:1px solid var(--sg-border)}.sg-stage:last-child{border-bottom:0}.sg-stage-value{font-size:12px}.sg-stage-value.done{color:var(--sg-good)}.sg-stage-value.failed{color:var(--sg-danger)}.sg-stage-value.waiting{color:var(--sg-muted)}.sg-lambda-control{display:flex;align-items:center;justify-content:flex-end;gap:7px}.sg-number-input{width:82px;padding:4px 5px;border:1px solid var(--sg-border);border-radius:6px;background:var(--sg-surface);text-align:right}.sg-setting-note{margin:7px 0 11px;color:var(--sg-muted);font-size:12px}.sg-safe-note{padding:11px 12px;margin-bottom:12px;border-radius:7px;background:var(--sg-good-soft);color:var(--sg-good);font-weight:650}.sg-error-note{margin:8px 0 0;color:var(--sg-muted);font-size:12px}
364
+ .sg-result-count{margin:0 0 9px;color:var(--sg-muted);font-size:12px}.sg-result-event{padding:8px 0;border-bottom:1px solid var(--sg-border)}.sg-result-event:last-child{border-bottom:0}.sg-pipeline{display:flex;flex-direction:column}.sg-stage{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;padding:9px 0;border-bottom:1px solid var(--sg-border)}.sg-stage:last-child{border-bottom:0}.sg-stage-value{font-size:12px}.sg-stage-value.done{color:var(--sg-good)}.sg-stage-value.failed{color:var(--sg-danger)}.sg-stage-value.waiting{color:var(--sg-muted)}.sg-lambda-control{display:flex;align-items:center;justify-content:flex-end;gap:7px}.sg-number-input{width:82px;padding:4px 5px;border:1px solid var(--sg-border);border-radius:6px;background:var(--sg-surface);text-align:right}.sg-setting-note{margin:7px 0 11px;color:var(--sg-muted);font-size:12px}.sg-setting-suggestion{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 10px;margin:4px 0 10px;border-radius:7px;background:var(--sg-soft);font-size:12px}.sg-save-button{align-self:flex-end;padding:7px 12px;margin-top:12px;border:0;border-radius:6px;background:var(--sg-accent);color:white;cursor:pointer}.sg-save-button:disabled{opacity:.5;cursor:not-allowed}.sg-safe-note{padding:11px 12px;margin-bottom:12px;border-radius:7px;background:var(--sg-good-soft);color:var(--sg-good);font-weight:650}.sg-error-note{margin:8px 0 0;color:var(--sg-muted);font-size:12px}
365
365
  .sg-menu{display:grid;gap:7px}.sg-menu-row{display:grid;grid-template-columns:38px minmax(0,1fr) auto;align-items:center;gap:11px;width:100%;padding:12px;border:1px solid transparent;border-radius:10px;background:color-mix(in srgb,var(--sg-surface) 48%,transparent);text-align:left;cursor:pointer}.sg-menu-row:hover{border-color:color-mix(in srgb,var(--sg-accent) 22%,var(--sg-border));background:color-mix(in srgb,var(--sg-accent) 6%,var(--sg-surface));transform:translateY(-1px);box-shadow:0 8px 20px color-mix(in srgb,var(--sg-text) 6%,transparent)}.sg-menu-row:hover .sg-menu-title,.sg-menu-row:hover .sg-chevron{color:var(--sg-accent)}.sg-menu-icon{width:32px;height:32px;display:grid;place-items:center;border:1px solid color-mix(in srgb,var(--sg-accent) 14%,var(--sg-border));border-radius:8px;background:var(--sg-soft);color:var(--sg-muted);font-weight:700}.sg-menu-title{font-weight:700}.sg-menu-subtitle{color:var(--sg-muted);font-size:12px}.sg-counts{display:flex;gap:22px;padding:5px 0 18px;border-bottom:1px solid var(--sg-border)}.sg-count-value{font-size:22px;font-weight:760;letter-spacing:-.03em}.sg-count-label{color:var(--sg-muted);font-size:12px}.sg-structured-group{padding-top:17px}.sg-raw-group{padding:12px 0;border-bottom:1px solid var(--sg-border)}.sg-raw-group summary{cursor:pointer;font-weight:680}.sg-raw-json{max-height:360px;padding:11px;margin:10px 0 0;overflow:auto;border-radius:7px;background:var(--sg-soft)}
366
366
  .sg-import-card{padding:15px;border:1px solid color-mix(in srgb,var(--sg-accent) 22%,var(--sg-border));border-radius:11px;background:color-mix(in srgb,var(--sg-surface) 72%,transparent);box-shadow:0 8px 24px color-mix(in srgb,var(--sg-text) 5%,transparent)}.sg-import-card textarea{width:100%;min-height:270px;padding:11px;border:1px solid var(--sg-border);border-radius:8px;background:var(--sg-page);resize:vertical;outline:0;font:12px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace}.sg-import-card textarea:focus{border-color:var(--sg-accent);box-shadow:0 0 0 3px var(--sg-focus)}.sg-import-actions{display:flex;align-items:center;gap:10px;margin-top:11px;flex-wrap:wrap}.sg-import-button{padding:8px 13px;border:1px solid var(--sg-accent);border-radius:7px;background:var(--sg-accent);color:#fff;cursor:pointer;font-weight:680}.sg-import-button:disabled{cursor:wait;opacity:.6}.sg-import-hint{margin:8px 0 0;color:var(--sg-muted);font-size:12px}.sg-import-result{margin-top:12px;padding:10px 11px;border-radius:7px;background:var(--sg-good-soft);color:var(--sg-good);font-size:12px}.sg-import-error{margin-top:12px;padding:10px 11px;border-radius:7px;background:var(--sg-danger-soft);color:var(--sg-danger);font-size:12px}
367
367
  .sg-import-overlay{position:fixed;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:18px;background:rgba(0,0,0,.52);backdrop-filter:blur(2px);animation:sg-view-in var(--sg-medium) var(--sg-ease) both}.sg-import-dialog{width:min(720px,calc(100vw - 28px));max-height:calc(100vh - 36px);overflow:auto;padding:14px;border:1px solid color-mix(in srgb,var(--sg-border) 90%,#fff 10%);border-radius:12px;background:var(--sg-page);box-shadow:0 24px 80px rgba(0,0,0,.42)}.sg-import-dialog-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:13px}.sg-import-dialog-title{margin:0;font-size:18px;font-weight:760}.sg-import-step{padding:12px;margin-top:10px;border-radius:9px;background:color-mix(in srgb,var(--sg-surface) 78%,transparent)}.sg-import-step-head{display:flex;align-items:center;gap:9px;margin-bottom:9px}.sg-import-step-num{display:grid;place-items:center;width:25px;height:25px;border-radius:50%;background:var(--sg-text);color:var(--sg-page);font-weight:760}.sg-import-step-title{font-weight:720}.sg-import-prompt{max-height:185px;padding:10px;overflow:auto;border-radius:7px;background:var(--sg-page);color:var(--sg-muted);font:12px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap}.sg-import-dialog .sg-import-card{padding:0;border:0;box-shadow:none;background:transparent}.sg-import-dialog .sg-import-card textarea{min-height:165px;background:var(--sg-page)}.sg-import-dialog-foot{display:flex;justify-content:flex-end;gap:9px;margin-top:14px}.sg-import-cancel{padding:8px 18px;border:1px solid var(--sg-border);border-radius:7px;background:transparent;cursor:pointer}.sg-import-dialog .sg-import-button{padding:8px 18px}.sg-import-copy{margin-left:auto;padding:6px 11px;border:1px solid var(--sg-border);border-radius:6px;background:var(--sg-page);cursor:pointer;font-size:12px}.sg-import-copy:hover{border-color:var(--sg-accent);color:var(--sg-accent)}.sg-import-loading{color:var(--sg-muted);font-size:12px}
@@ -397,4 +397,4 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
397
397
  `;function api2(path,params,options2){let query=new URLSearchParams(params||{}),url="/api/stratagate/"+path+(query.size?"?"+query:""),attempt=0,request=()=>fetch(url,{cache:"no-store",...options2}).then(res=>res.json().catch(()=>({})).then(data4=>{if(!res.ok)throw new Error(data4&&data4.error||"HTTP "+res.status);return data4})).catch(reason=>{let message=String(reason?.message||reason);if((reason instanceof TypeError||message.includes("Failed to fetch"))&&!options2?.method&&attempt<2)return attempt+=1,new Promise(resolve2=>window.setTimeout(resolve2,attempt*300)).then(request);throw new Error(message+"\uFF08"+path+"\uFF09")});return request()}function projectName(item,workspaceTitles={}){let value=String(item?.namespace||item||"");if(value.includes(":project:")){let key=value.split(":project:").pop();return key&&workspaceTitles[key]?workspaceTitles[key]:item?.workspaceName&&item.workspaceName!=="\u5F53\u524D\u5DE5\u4F5C\u533A"?item.workspaceName:"\u5DE5\u4F5C\u533A\u540D\u79F0\u8BFB\u53D6\u4E2D\u2026"}return item?.workspaceName?item.workspaceName:value.includes(":global:")?value.split(":global:").pop()||"\u5168\u5C40\u8BB0\u5FC6":value.includes(":session:")?"\u5F53\u524D\u5BF9\u8BDD":value||"\u5F53\u524D\u5DE5\u4F5C\u533A"}function workspaceProjectKey(path){let canonical=String(path||"").replaceAll("\\","/").toLowerCase();return!canonical||!globalThis.crypto?.subtle?Promise.resolve(""):globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(canonical)).then(digest=>Array.from(new Uint8Array(digest).slice(0,10),byte=>byte.toString(16).padStart(2,"0")).join(""))}function formatTime(value){if(!value)return"\u65F6\u95F4\u672A\u77E5";let date=new Date(value);if(Number.isNaN(date.getTime()))return String(value);let seconds=Math.round((Date.now()-date.getTime())/1e3);if(seconds>=0&&seconds<60)return"\u521A\u521A";if(seconds>=60&&seconds<3600)return Math.floor(seconds/60)+" \u5206\u949F\u524D";let timeZone="Asia/Shanghai",dayKey=input=>new Intl.DateTimeFormat("en-CA",{timeZone,year:"numeric",month:"2-digit",day:"2-digit"}).format(input),clock=input=>new Intl.DateTimeFormat("zh-CN",{timeZone,hour:"2-digit",minute:"2-digit",hour12:!1}).format(input),now=new Date;if(dayKey(date)===dayKey(now))return"\u4ECA\u5929 "+clock(date);let yesterday=new Date(now.getTime()-1440*60*1e3);return dayKey(date)===dayKey(yesterday)?"\u6628\u5929 "+clock(date):new Intl.DateTimeFormat("zh-CN",{timeZone,month:"numeric",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}).format(date)}function statusText(status){return status==="organized"?"\u5DF2\u6574\u7406":status==="failed"?"\u6574\u7406\u5931\u8D25":status==="waiting"?"\u7B49\u5F85\u6574\u7406":"\u6574\u7406\u4E2D"}function Loading(){return h("div",{className:"sg-loading",role:"status"},h("div",{className:"sg-skeleton"}),h("div",{className:"sg-skeleton"}),h("div",{className:"sg-skeleton"}))}function Empty({title,copy:copy3}){return h("div",{className:"sg-empty"},h("strong",null,title),h("span",null,copy3))}function BackBar({label,onBack}){return h("div",{className:"sg-backbar"},h("button",{className:"sg-back",onClick:onBack,title:"\u8FD4\u56DE"},h("span",{"aria-hidden":"true"},"\u2190"),label))}function FailureAlert({count,onOpen}){return count?h("button",{className:"sg-alert",onClick:onOpen},h("span",{className:"sg-alert-mark","aria-hidden":"true"},"\u26A0"),h("span",null,h("span",{className:"sg-alert-title"},count+" \u6761\u77ED\u671F\u8BB0\u5FC6\u5C1A\u672A\u6574\u7406\u5B8C\u6210"),h("br"),h("span",{className:"sg-alert-copy"},"\u539F\u59CB\u5185\u5BB9\u5DF2\u7ECF\u4FDD\u5B58\uFF0C\u4E0D\u4F1A\u4E22\u5931\u3002")),h("span",{className:"sg-chevron","aria-hidden":"true"},"\u203A")):null}function ProcessingAlert({visible}){return visible?h("div",{className:"sg-processing-alert",role:"status","aria-live":"polite"},h("span",{className:"sg-processing-icon","aria-hidden":"true"},"\u21BB"),h("span",null,h("span",{className:"sg-processing-title"},"\u6B63\u5728\u89E6\u53D1\u8BB0\u5FC6\u6574\u7406"),h("span",{className:"sg-processing-copy"},"Block\u3001Event \u548C\u77E5\u8BC6\u56FE\u8C31\u6B63\u5728\u751F\u6210\uFF0C\u8BF7\u7A0D\u5019\u3002"))):null}function SearchBox({value,onChange}){return h("div",{className:"sg-search"},h("span",{className:"sg-search-mark","aria-hidden":"true"},"\u2315"),h("input",{value,onChange:event3=>onChange(event3.target.value),placeholder:"\u641C\u7D22\u8BB0\u5FC6\u3001\u4EBA\u7269\u3001\u9879\u76EE\u3001\u6982\u5FF5\u2026","aria-label":"\u641C\u7D22\u957F\u671F\u8BB0\u5FC6"}))}let NODE_META={person:["\u4EBA\u7269","#8b6ccf","\u2659"],project:["\u9879\u76EE","#6f55ae","\u25A3"],organization:["\u7EC4\u7EC7","#3978cf","\u2318"],tool:["\u5DE5\u5177","#3b854d","\u25A4"],place:["\u5730\u70B9","#a9632b","\u2302"]},EVENT_TYPE_TEXT={decision:"\u51B3\u7B56",release:"\u53D1\u5E03",task_completed:"\u4EFB\u52A1\u5B8C\u6210",plan:"\u8BA1\u5212",change:"\u53D8\u66F4",cancellation:"\u53D6\u6D88",incident:"\u4E8B\u4EF6",meeting:"\u4F1A\u8BAE",collaboration:"\u534F\u4F5C",migration:"\u8FC1\u79FB",other:"\u5176\u4ED6"},EVENT_STATUS_TEXT={occurred:"\u5DF2\u53D1\u751F",planned:"\u8BA1\u5212\u4E2D",cancelled:"\u5DF2\u53D6\u6D88",ongoing:"\u8FDB\u884C\u4E2D",unknown:"\u672A\u77E5"},EVENT_RELATIONS=[["supersedesEventIds","\u53D6\u4EE3"],["conflictsWithEventIds","\u51B2\u7A81"],["sameEventId","\u540C\u4E00\u4E8B\u4EF6"],["beforeEventIds","\u4E4B\u524D"],["afterEventIds","\u4E4B\u540E"],["relatedEventIds","\u76F8\u5173"]];function exactTime(value){if(!value)return"\u672A\u77E5";let date=new Date(value);return Number.isNaN(date.getTime())?String(value):new Intl.DateTimeFormat("zh-CN",{timeZone:"Asia/Shanghai",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1}).format(date)}function eventOccurrence(event3){let happened=event3.temporal?.happenedStart||event3.temporal?.happenedEnd;return{value:happened||event3.temporal?.mentionedAt||event3.createdAt,known:!!happened}}function NodePill({node,onClick}){let meta3=NODE_META[node.type]||["\u5B9E\u4F53","#64748b","\u2022"];return h("button",{className:"sg-entity-pill",onClick},h("span",{style:{color:meta3[1]}},meta3[2]),node.name)}function NodeSummaryBubble({node,x:x2,y:y2,width:width2,height:height2=560,onViewDetails}){if(!node)return null;let facts=(node.facts||[]).filter(fact=>fact.status==="active").slice(0,5),eventCount=new Set(node.sourceEventIds||[]).size;return h("aside",{className:"sg-node-bubble "+(x2>width2*.62?"flip":""),style:{left:x2/width2*100+"%",top:y2/height2*100+"%"}},h("div",{className:"sg-node-bubble-head"},h("h3",null,node.name),h("span",{className:"sg-status-dot"},"\u25CF "+(node.status==="active"?"\u6D3B\u8DC3":node.status||"\u672A\u77E5"))),(node.tags||[]).length?h("div",{className:"sg-node-tags"},node.tags.slice(0,4).map(tag=>h("span",{key:tag,className:"sg-node-tag"},tag))):null,h("p",{className:"sg-node-bubble-state"},node.currentState||"\u6682\u65E0\u5F53\u524D\u72B6\u6001"),facts.length?h("ul",null,facts.map(fact=>h("li",{key:fact.id},h("strong",null,fact.key+"\uFF1A"),Array.isArray(fact.value)?fact.value.join("\u3001"):fact.value))):h("p",{className:"sg-node-bubble-state"},"\u6682\u65E0\u5173\u952E\u4E8B\u5B9E"),h("div",{className:"sg-node-bubble-foot"},h("span",null,eventCount+" \u6761\u76F8\u5173\u4E8B\u4EF6"),h("button",{type:"button",onClick:onViewDetails},"\u67E5\u770B\u8BE6\u60C5 \u2192")))}let GRAPH_NODE_RADIUS={peripheral:30,normal:38,important:46,core:54},GRAPH_IMPORTANCE_TEXT={peripheral:"\u8FB9\u7F18\u8282\u70B9",normal:"\u666E\u901A\u8282\u70B9",important:"\u91CD\u8981\u8282\u70B9",core:"\u6838\u5FC3\u8282\u70B9"};function graphNameKey(value){return String(value||"").toLocaleLowerCase().replace(/[^\p{L}\p{N}]+/gu,"")}function graphTimestamp(value){let timestamp=Date.parse(String(value||""));return Number.isFinite(timestamp)?timestamp:0}function graphNodeImportance(nodes3,edges3,project){let activeEdges=edges3.filter(edge=>edge.status==="active"),activeSupportingEvents=node=>(node.supportingEvents||[]).filter(event3=>event3.status!=="forgotten"&&event3.status!=="archived"),relationCounts=new Map(nodes3.map(node=>[node.id,0])),neighbors=new Map(nodes3.map(node=>[node.id,new Set]));for(let edge of activeEdges)relationCounts.set(edge.fromNodeId,(relationCounts.get(edge.fromNodeId)||0)+1),relationCounts.set(edge.toNodeId,(relationCounts.get(edge.toNodeId)||0)+1),neighbors.get(edge.fromNodeId)?.add(edge.toNodeId),neighbors.get(edge.toNodeId)?.add(edge.fromNodeId);let projectKey=graphNameKey(project),directWorkspaceNodes=new Set(nodes3.filter(node=>projectKey&&[node.name,...node.aliases||[]].some(name=>{let key=graphNameKey(name);return key===projectKey||key.length>=5&&projectKey.length>=5&&(key.includes(projectKey)||projectKey.includes(key))})).map(node=>node.id)),workspaceAffinity=new Map(nodes3.map(node=>[node.id,directWorkspaceNodes.has(node.id)?1:0]));for(let nodeId of directWorkspaceNodes)for(let neighborId of neighbors.get(nodeId)||[]){workspaceAffinity.set(neighborId,Math.max(workspaceAffinity.get(neighborId)||0,.55));for(let secondHopId of neighbors.get(neighborId)||[])workspaceAffinity.set(secondHopId,Math.max(workspaceAffinity.get(secondHopId)||0,.25))}let supportCounts=new Map(nodes3.map(node=>{let supportingEvents=activeSupportingEvents(node);return[node.id,supportingEvents.length?new Set(supportingEvents.map(event3=>event3.id)).size:new Set(node.sourceEventIds||[]).size]})),maxSupport=Math.max(1,...supportCounts.values()),maxRelations=Math.max(1,...relationCounts.values()),latestActivity=0;for(let node of nodes3){latestActivity=Math.max(latestActivity,graphTimestamp(node.updatedAt));for(let event3 of activeSupportingEvents(node))latestActivity=Math.max(latestActivity,graphTimestamp(event3.updatedAt||event3.createdAt))}for(let edge of activeEdges)latestActivity=Math.max(latestActivity,graphTimestamp(edge.updatedAt));let halfLife=2160*60*60*1e3,recency=timestamp=>timestamp&&latestActivity?Math.exp(-Math.max(0,latestActivity-timestamp)/halfLife):0,scored=nodes3.map(node=>{let sustainedMentions=activeSupportingEvents(node).map(event3=>recency(graphTimestamp(event3.updatedAt||event3.createdAt))).sort((left,right)=>right-left).slice(0,3),recentScore=.25*recency(graphTimestamp(node.updatedAt))+.75*sustainedMentions.reduce((sum,value)=>sum+value,0)/3,supportScore=Math.log1p(supportCounts.get(node.id)||0)/Math.log1p(maxSupport),relationScore=Math.log1p(relationCounts.get(node.id)||0)/Math.log1p(maxRelations),score=.42*supportScore+.28*relationScore+.15*recentScore+.15*(workspaceAffinity.get(node.id)||0);return{id:node.id,score}}),ordered=scored.map(({score})=>score).sort((left,right)=>left-right),quantile=ratio=>ordered[Math.ceil(Math.max(0,ordered.length-1)*ratio)]||0,spread=(ordered[ordered.length-1]||0)-(ordered[0]||0),thresholds={normal:quantile(.25),important:quantile(.6),core:quantile(.85)};return new Map(scored.map(({id:id2,score})=>{let tier;return spread<.02?tier=score>=.65?"core":score>=.38?"important":"normal":score>=thresholds.core?tier="core":score>=thresholds.important?tier="important":score>=thresholds.normal?tier="normal":tier="peripheral",[id2,{score,tier,radius:GRAPH_NODE_RADIUS[tier]}]}))}function GraphCanvas({nodes:nodes3,edges:edges3,clusters,importance,selectedId,onSelect,showSummary=!1,onViewDetails}){let containerRef=React.useRef(null),graphRef=React.useRef(null),selectedIdRef=React.useRef(selectedId);selectedIdRef.current=selectedId;let[selectedPoint,setSelectedPoint]=React.useState(null),[zoomPercent,setZoomPercent]=React.useState(100),displayedNodes=[...nodes3].sort((left,right)=>(importance.get(right.id)?.score||0)-(importance.get(left.id)?.score||0)).slice(0,40),displayedIds=new Set(displayedNodes.map(node=>node.id)),visibleClusters=(clusters||[]).map(cluster=>({...cluster,nodeIds:(cluster.nodeIds||[]).filter(id2=>displayedIds.has(id2))})).filter(cluster=>cluster.nodeIds.length),assignedIds=new Set(visibleClusters.flatMap(cluster=>cluster.nodeIds));for(let node of displayedNodes.filter(item=>!assignedIds.has(item.id)))visibleClusters.push({id:"fallback-"+node.id,label:(node.tags||[])[0]||node.name,nodeIds:[node.id],tags:node.tags||[]});let membership=new Map(visibleClusters.flatMap(cluster=>cluster.nodeIds.map(id2=>[id2,cluster.id]))),activeEdges=edges3.filter(edge=>edge.status==="active"&&displayedIds.has(edge.fromNodeId)&&displayedIds.has(edge.toNodeId)),signature=JSON.stringify({nodes:displayedNodes.map(node=>[node.id,node.name,node.type,node.tags||[],importance.get(node.id)?.tier]),edges:activeEdges.map(edge=>[edge.id,edge.fromNodeId,edge.toNodeId,edge.relation,edge.confidence]),clusters:visibleClusters.map(cluster=>[cluster.id,cluster.label,cluster.nodeIds])});React.useEffect(()=>{let container2=containerRef.current;if(!container2||!cytoscape4||!displayedNodes.length)return;let computed=getComputedStyle(container2),textColor=computed.getPropertyValue("--sg-text").trim()||"#0f1115",mutedColor=computed.getPropertyValue("--sg-muted").trim()||"#64748b",borderColor=computed.getPropertyValue("--sg-border").trim()||"#d5d9df",pageColor=computed.getPropertyValue("--sg-page").trim()||"#ffffff",accentColor=computed.getPropertyValue("--sg-accent").trim()||"#4176e6",reduceMotion=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches===!0,parentIds=new Map(visibleClusters.map(cluster=>[cluster.id,"sg-parent-"+cluster.id])),clusterSizes=new Map(visibleClusters.map(cluster=>[cluster.id,cluster.nodeIds.length])),elements=[...visibleClusters.map(cluster=>({data:{id:parentIds.get(cluster.id),label:cluster.label+" \xB7 "+cluster.nodeIds.length},classes:"sg-community"})),...displayedNodes.map(node=>{let meta3=NODE_META[node.type]||["\u5B9E\u4F53","#64748b","\u2022"],semantic=(node.tags||[])[0]||meta3[0],visualImportance=importance.get(node.id)||{tier:"normal",radius:GRAPH_NODE_RADIUS.normal};return{data:{id:node.id,parent:parentIds.get(membership.get(node.id)),label:node.name+`
398
398
  `+semantic,color:meta3[1],size:visualImportance.radius*2,tier:visualImportance.tier},classes:"sg-memory-node"}}),...activeEdges.map(edge=>{let fromCluster=membership.get(edge.fromNodeId),toCluster=membership.get(edge.toNodeId),sameCluster=fromCluster===toCluster,labeled=sameCluster&&(clusterSizes.get(fromCluster)||0)<=6;return{data:{id:"sg-edge-"+edge.id,source:edge.fromNodeId,target:edge.toNodeId,label:edge.relation},classes:"sg-memory-edge "+(sameCluster?"same-community":"cross-community")+(labeled?" labeled":"")}})],graph=cytoscape4({container:container2,elements,wheelSensitivity:.22,minZoom:.25,maxZoom:2.4,selectionType:"single",boxSelectionEnabled:!1,style:[{selector:"node.sg-community",style:{"background-color":accentColor,"background-opacity":.045,"border-color":accentColor,"border-opacity":.28,"border-width":1,"border-style":"dashed",shape:"round-rectangle",padding:"22px",label:"data(label)",color:mutedColor,"font-size":12,"font-weight":700,"text-valign":"top","text-halign":"center","text-margin-y":-9,"text-background-color":pageColor,"text-background-opacity":.82,"text-background-padding":"3px"}},{selector:"node.sg-memory-node",style:{width:"data(size)",height:"data(size)","background-color":"data(color)","background-opacity":.28,"border-color":"data(color)","border-width":1.5,label:"data(label)",color:textColor,"font-size":11,"font-weight":650,"text-wrap":"wrap","text-max-width":96,"text-valign":"center","text-halign":"center","overlay-opacity":0,"transition-property":"border-width, border-color, underlay-opacity","transition-duration":reduceMotion?"0ms":"180ms"}},{selector:"node.sg-memory-node:selected",style:{"border-width":4,"border-color":accentColor,"underlay-color":accentColor,"underlay-opacity":.16,"underlay-padding":7}},{selector:"edge.sg-memory-edge",style:{width:1.2,"line-color":mutedColor,"target-arrow-color":mutedColor,"target-arrow-shape":"triangle","curve-style":"bezier",opacity:.58,"arrow-scale":.75,label:"","overlay-opacity":0}},{selector:"edge.sg-memory-edge.labeled",style:{label:"data(label)",color:textColor,"font-size":10,"text-background-color":pageColor,"text-background-opacity":.88,"text-background-padding":"2px","text-rotation":"autorotate"}},{selector:"edge.sg-memory-edge.cross-community",style:{opacity:.24,"line-style":"dashed"}},{selector:"edge.sg-memory-edge.selected-relation",style:{opacity:.9,width:2,label:"data(label)",color:textColor,"font-size":10,"text-background-color":pageColor,"text-background-opacity":.9,"text-background-padding":"2px"}}]});graphRef.current=graph;let updatePoint=()=>{let selected=graph.getElementById(selectedIdRef.current);if(!selected.length){setSelectedPoint(null);return}let point=selected.renderedPosition();setSelectedPoint({x:point.x,y:point.y,width:container2.clientWidth||760,height:container2.clientHeight||522})};graph.on("tap","node.sg-memory-node",event3=>onSelect(event3.target.id()));let updateZoom=()=>setZoomPercent(Math.round(graph.zoom()*100));graph.on("pan zoom resize",updatePoint),graph.on("zoom",updateZoom),graph.on("layoutstop",updatePoint),graph.on("layoutstop",updateZoom);let resizeObserver=globalThis.ResizeObserver?new globalThis.ResizeObserver(()=>{graph.resize(),updatePoint()}):null;return resizeObserver?.observe(container2),graph.layout({name:"fcose",quality:"default",randomize:!0,animate:reduceMotion?!1:"end",animationDuration:reduceMotion?0:320,animationEasing:"ease-out-cubic",fit:!0,padding:48,nodeRepulsion:5200,idealEdgeLength:edge=>edge.hasClass("cross-community")?170:78,edgeElasticity:.42,nestingFactor:1.35,gravity:.28,gravityCompound:1,gravityRangeCompound:1.5,tile:!0}).run(),()=>{resizeObserver?.disconnect(),graphRef.current=null,graph.destroy()}},[signature]),React.useEffect(()=>{let graph=graphRef.current;if(!graph)return;graph.nodes(".sg-memory-node").unselect(),graph.edges().removeClass("selected-relation");let selected=graph.getElementById(selectedId);if(!selected.length){setSelectedPoint(null);return}selected.select(),selected.connectedEdges().addClass("selected-relation");let point=selected.renderedPosition(),container2=containerRef.current;setSelectedPoint({x:point.x,y:point.y,width:container2?.clientWidth||760,height:container2?.clientHeight||522})},[selectedId,signature]);let setGraphZoom=nextPercent=>{let graph=graphRef.current,container2=containerRef.current;if(!graph||!container2)return;let percent=Math.min(240,Math.max(25,Number(nextPercent)));graph.zoom({level:percent/100,renderedPosition:{x:container2.clientWidth/2,y:container2.clientHeight/2}})};if(!nodes3.length)return h(Empty,{title:"\u77E5\u8BC6\u56FE\u8C31\u6B63\u5728\u5F62\u6210",copy:"Event \u4F1A\u5728\u540E\u53F0\u5206\u6279\u6295\u5F71\u4E3A\u8282\u70B9\u4E0E\u5173\u7CFB\u3002"});if(!cytoscape4)return h(Empty,{title:"\u56FE\u8C31\u7EC4\u4EF6\u672A\u80FD\u52A0\u8F7D",copy:"\u8BF7\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u540E\u518D\u8BD5\u3002"});let selectedNode=nodes3.find(node=>node.id===selectedId);return h("div",{className:"sg-graph-canvas",role:"img","aria-label":visibleClusters.length+" \u4E2A Leiden \u4E3B\u9898\u7FA4\u7EC4\u7684\u77E5\u8BC6\u56FE\u8C31"},h("div",{ref:containerRef,className:"sg-cytoscape"}),h("div",{className:"sg-graph-zoom",role:"group","aria-label":"\u77E5\u8BC6\u56FE\u8C31\u7F29\u653E"},h("button",{type:"button",onClick:()=>setGraphZoom(zoomPercent-20),disabled:zoomPercent<=25,title:"\u7F29\u5C0F","aria-label":"\u7F29\u5C0F\u77E5\u8BC6\u56FE\u8C31"},"\u2212"),h("input",{type:"range",min:"25",max:"240",step:"5",value:String(zoomPercent),onInput:event3=>setGraphZoom(event3.target.value),title:"\u7F29\u653E\u6BD4\u4F8B "+zoomPercent+"%","aria-label":"\u77E5\u8BC6\u56FE\u8C31\u7F29\u653E\u6BD4\u4F8B","aria-valuetext":zoomPercent+"%"}),h("button",{type:"button",onClick:()=>setGraphZoom(zoomPercent+20),disabled:zoomPercent>=240,title:"\u653E\u5927","aria-label":"\u653E\u5927\u77E5\u8BC6\u56FE\u8C31"},"+")),h("div",{className:"sg-graph-a11y","aria-label":"\u77E5\u8BC6\u56FE\u8C31\u8282\u70B9\u5217\u8868"},displayedNodes.map(node=>h("button",{key:node.id,onClick:()=>onSelect(node.id)},node.name+"\uFF0C"+((node.tags||[])[0]||(NODE_META[node.type]||["\u5B9E\u4F53"])[0])+"\uFF0C"+GRAPH_IMPORTANCE_TEXT[importance.get(node.id)?.tier||"normal"]))),showSummary&&selectedNode&&selectedPoint?h(NodeSummaryBubble,{node:selectedNode,x:selectedPoint.x,y:selectedPoint.y,width:selectedPoint.width,height:selectedPoint.height,onViewDetails}):null,h("div",{className:"sg-graph-legend"},Object.entries(NODE_META).map(([type,meta3])=>h("span",{key:type},h("i",{style:{background:meta3[1]}}),meta3[0]))))}function NodeDetailPanel({node,nodes:nodes3,edges:edges3,events,onEvent}){if(!node)return h("aside",{className:"sg-long-detail sg-placeholder-detail"},"\u9009\u62E9\u8282\u70B9\u67E5\u770B\u5F53\u524D\u72B6\u6001\u4E0E\u8BC1\u636E");let meta3=NODE_META[node.type]||["\u5B9E\u4F53","#64748b","\u2022"],relations=edges3.filter(edge=>edge.status==="active"&&(edge.fromNodeId===node.id||edge.toNodeId===node.id)),eventMap=new Map(events.map(event3=>[event3.id,event3]));return h("aside",{className:"sg-long-detail"},h("div",{className:"sg-node-head"},h("span",{className:"sg-node-avatar",style:{background:meta3[1]}},meta3[2]),h("div",null,h("h2",null,node.name),h("span",{className:"sg-muted"},meta3[0]))),(node.tags||[]).length?h("section",null,h("h3",null,"\u8BED\u4E49\u6807\u7B7E"),h("div",{className:"sg-node-tags"},node.tags.map(tag=>h("span",{key:tag,className:"sg-node-tag"},tag)))):null,h("section",null,h("h3",null,"\u5F53\u524D\u72B6\u6001"),h("span",{className:"sg-status-dot"},"\u25CF "+(node.status==="active"?"\u6D3B\u8DC3":node.status)),node.currentState?h("p",{className:"sg-detail-copy"},node.currentState):null),h("section",null,h("h3",null,"\u5173\u952E\u4E8B\u5B9E"),node.facts?.filter(fact=>fact.status==="active").length?h("ul",null,node.facts.filter(fact=>fact.status==="active").map(fact=>h("li",{key:fact.id},h("strong",null,fact.key+"\uFF1A"),Array.isArray(fact.value)?fact.value.join("\u3001"):fact.value))):h("p",{className:"sg-muted"},"\u6682\u65E0\u5173\u952E\u4E8B\u5B9E")),h("section",null,h("h3",null,"\u76F8\u5173\u5173\u7CFB"),relations.length?relations.map(edge=>{let outgoing=edge.fromNodeId===node.id,other=nodes3.find(item=>item.id===(outgoing?edge.toNodeId:edge.fromNodeId));return h("div",{key:edge.id,className:"sg-relation-row"},h("span",null,outgoing?edge.relation:"\u88AB"+edge.relation),h("strong",null,other?.name||"\u672A\u77E5\u8282\u70B9"),h("small",null,Math.round(edge.confidence*100)+"%"))}):h("p",{className:"sg-muted"},"\u6682\u65E0\u5173\u7CFB")),h("section",null,h("h3",null,"\u652F\u6491\u4E8B\u4EF6"),(node.sourceEventIds||[]).flatMap(id2=>eventMap.get(id2)||[]).slice(0,8).map(event3=>h("button",{key:event3.id,className:"sg-support-event",onClick:()=>onEvent(event3.id)},h("span",null,exactTime(eventOccurrence(event3).value)+" \xB7 "+event3.title),h("b",null,"\u203A")))))}function EventDetailPanel({event:event3,nodes:nodes3,events,onNode,openSource,className="",onMouseEnter,onMouseLeave}){if(!event3)return h("aside",{className:"sg-long-detail sg-placeholder-detail"},"\u9009\u62E9\u4E8B\u4EF6\u67E5\u770B\u5B8C\u6574\u65F6\u95F4\u3001\u5173\u7CFB\u4E0E\u8BC1\u636E");let temporal=event3.temporal||{},eventMap=new Map(events.map(item=>[item.id,item])),nodeMap=new Map(nodes3.map(node=>[node.id,node])),relations=EVENT_RELATIONS.flatMap(([key,label])=>{let value=temporal[key];return(Array.isArray(value)?value:value?[value]:[]).map(id2=>({id:id2,label}))});return h("aside",{className:"sg-long-detail "+className,onMouseEnter,onMouseLeave},h("div",{className:"sg-event-detail-head"},h("h2",null,event3.title),h("span",{className:"sg-event-status "+(temporal.status||"unknown")},EVENT_STATUS_TEXT[temporal.status]||"\u672A\u77E5")),h("span",{className:"sg-type-badge"},EVENT_TYPE_TEXT[temporal.eventType]||temporal.eventType||"\u5176\u4ED6"),h("section",null,h("h3",null,"\u6458\u8981"),h("p",{className:"sg-detail-copy"},event3.summary||"\u6682\u65E0\u6458\u8981")),event3.narrative&&event3.narrative!==event3.summary?h("section",null,h("h3",null,"\u4E8B\u4EF6\u53D9\u8FF0"),h("p",{className:"sg-detail-copy"},event3.narrative)):null,h("section",null,h("h3",null,"\u65F6\u95F4\u4FE1\u606F"),h("dl",{className:"sg-time-grid"},h("dt",null,"\u5B9E\u9645\u53D1\u751F\u65F6\u95F4"),h("dd",null,temporal.happenedStart?exactTime(temporal.happenedStart)+(temporal.happenedEnd&&temporal.happenedEnd!==temporal.happenedStart?" \u2014 "+exactTime(temporal.happenedEnd):""):"\u672A\u77E5"),h("dt",null,"\u63D0\u53CA\u65F6\u95F4"),h("dd",null,exactTime(temporal.mentionedAt||event3.createdAt)),h("dt",null,"\u65F6\u95F4\u7CBE\u5EA6"),h("dd",null,temporal.precision||"unknown"),h("dt",null,"\u539F\u59CB\u8868\u8FBE"),h("dd",null,temporal.originalText||"\u672A\u8BB0\u5F55"))),h("section",null,h("h3",null,"\u53C2\u4E0E\u5B9E\u4F53"),h("div",{className:"sg-tags"},(temporal.participantNodeIds||[]).flatMap(id2=>nodeMap.get(id2)||[]).map(node=>h(NodePill,{key:node.id,node,onClick:()=>onNode(node.id)})),(temporal.participantNodeIds||[]).length?null:(temporal.participants||[]).map(name=>h("span",{key:name,className:"sg-tag"},name)))),relations.length?h("section",null,h("h3",null,"\u4E8B\u4EF6\u5173\u7CFB"),relations.map(relation=>h("div",{key:relation.label+relation.id,className:"sg-relation-row"},h("span",null,relation.label),h("strong",null,eventMap.get(relation.id)?.title||relation.id)))):null,h("section",null,h("h3",null,"\u8BC1\u636E\u6765\u6E90"),h("div",{className:"sg-evidence-row"},h("span",null,"\u6765\u6E90 Block"),h("code",null,event3.sourceBlockId)),h("div",{className:"sg-evidence-row"},h("span",null,"\u7F6E\u4FE1\u5EA6"),h("strong",null,Math.round((event3.confidence||0)*100)+"%"))),h("button",{className:"sg-source-button",onClick:()=>openSource(event3)},"\u67E5\u770B\u6765\u6E90\u539F\u59CB\u6D88\u606F \u2192"))}function TimelineList({events,nodes:nodes3,query,filters,onSelect,selectedId,floating=!1,onNode,openSource}){let[preview,setPreview]=React.useState(null),pinnedId=React.useRef(""),hideTimer=React.useRef(null),cancelHide=()=>{hideTimer.current&&window.clearTimeout(hideTimer.current),hideTimer.current=null},hidePreview=()=>{cancelHide(),setPreview(null),pinnedId.current=""},showPreview=(event3,target,pin=!1)=>{if(!floating||!pin&&pinnedId.current)return;cancelHide();let rect=target.getBoundingClientRect(),width2=Math.min(380,window.innerWidth-24),maxHeight=Math.min(620,window.innerHeight*.72),left=rect.right+12+width2<=window.innerWidth-12?rect.right+12:Math.max(12,rect.left-width2-12),top=Math.min(Math.max(12,rect.top-8),Math.max(12,window.innerHeight-maxHeight-12));setPreview({event:event3,left,top}),pin&&(pinnedId.current=event3.id)},scheduleHide=()=>{pinnedId.current||(cancelHide(),hideTimer.current=window.setTimeout(()=>setPreview(null),140))};React.useEffect(()=>()=>cancelHide(),[]);let normalized=query.trim().toLocaleLowerCase(),now=new Date,weekAgo=now.getTime()-7*864e5,groups={\u4ECA\u5929:[],\u672C\u5468:[],\u66F4\u65E9:[]};events.filter(event3=>event3.status!=="forgotten"&&event3.status!=="archived").filter(event3=>!normalized||JSON.stringify(event3).toLocaleLowerCase().includes(normalized)).filter(event3=>!filters.type||event3.temporal?.eventType===filters.type).filter(event3=>!filters.status||event3.temporal?.status===filters.status).filter(event3=>!filters.node||(event3.temporal?.participantNodeIds||[]).includes(filters.node)).filter(event3=>{let info=eventOccurrence(event3),time2=Date.parse(info.value);return!filters.time||(filters.time==="unknown"?!info.known:filters.time==="today"?Number.isFinite(time2)&&new Date(time2).toDateString()===now.toDateString():filters.time==="week"?time2>=weekAgo:!0)}).sort((a,b)=>String(eventOccurrence(b).value).localeCompare(String(eventOccurrence(a).value))).forEach(event3=>{let info=eventOccurrence(event3),time2=Date.parse(info.value),sameDay=Number.isFinite(time2)&&new Date(time2).toDateString()===now.toDateString();groups[sameDay?"\u4ECA\u5929":time2>=weekAgo?"\u672C\u5468":"\u66F4\u65E9"].push(event3)});let nodeMap=new Map(nodes3.map(node=>[node.id,node]));return h("div",{className:"sg-timeline"},Object.entries(groups).map(([label,items])=>items.length?h("section",{key:label,className:"sg-time-group"},h("h3",null,label),items.map(event3=>{let info=eventOccurrence(event3),temporal=event3.temporal||{};return h("button",{key:event3.id,className:"sg-timeline-card "+(event3.id===selectedId?"selected":""),onMouseEnter:hover=>showPreview(event3,hover.currentTarget),onMouseLeave:scheduleHide,onFocus:focus=>showPreview(event3,focus.currentTarget),onBlur:scheduleHide,onClick:click=>{onSelect(event3.id),showPreview(event3,click.currentTarget,!0)}},h("span",{className:"sg-timeline-dot"}),h("div",{className:"sg-event-clock"},info.known?exactTime(info.value).replace(/^\d{4}\//,""):"\u53D1\u751F\u65F6\u95F4\u672A\u77E5",info.known?null:h("small",null,"\u63D0\u53CA\u4E8E "+exactTime(info.value))),h("div",{className:"sg-event-main"},h("div",{className:"sg-event-title-row"},h("strong",null,event3.title),h("span",{className:"sg-type-badge"},EVENT_TYPE_TEXT[temporal.eventType]||temporal.eventType||"\u5176\u4ED6")),h("p",null,event3.summary||"\u6682\u65E0\u6458\u8981"),h("div",{className:"sg-tags"},(temporal.participantNodeIds||[]).flatMap(id2=>nodeMap.get(id2)||[]).map(node=>h("span",{key:node.id,className:"sg-tag"},node.name)),(temporal.participantNodeIds||[]).length?null:(temporal.participants||[]).map(name=>h("span",{key:name,className:"sg-tag"},name)))),h("span",{className:"sg-event-status "+(temporal.status||"unknown")},EVENT_STATUS_TEXT[temporal.status]||"\u672A\u77E5"))})):null),floating&&preview?h("div",{className:"sg-event-popover",style:{left:preview.left+"px",top:preview.top+"px"},onMouseEnter:cancelHide,onMouseLeave:scheduleHide},h("button",{type:"button",className:"sg-popover-close","aria-label":"\u5173\u95ED\u4E8B\u4EF6\u8BE6\u60C5",onClick:hidePreview},"\xD7"),h(EventDetailPanel,{event:preview.event,nodes:nodes3,events,onNode,openSource})):null)}function LongTermPage({events,graph,project,query,setQuery,openEvent}){let[mode,setMode]=React.useState("graph"),[selectedNodeId,setSelectedNodeId]=React.useState(""),[selectedEventId,setSelectedEventId]=React.useState(""),[eventFilters,setEventFilters]=React.useState({time:"",node:"",type:"",status:""}),[nodeType,setNodeType]=React.useState(""),[nodeTag,setNodeTag]=React.useState(""),[filtersOpen,setFiltersOpen]=React.useState(!1),[fullScreen,setFullScreen]=React.useState(!1),nodes3=graph.nodes||[],edges3=graph.edges||[],clusters=graph.clusters||[],normalized=query.trim().toLocaleLowerCase(),nodeImportance=React.useMemo(()=>graphNodeImportance(nodes3,edges3,project),[nodes3,edges3,project]),nodeTags=[...new Set(nodes3.flatMap(node=>node.tags||[]))].sort((left,right)=>left.localeCompare(right));React.useEffect(()=>{if(!fullScreen)return;let previous=document.body.style.overflow;document.body.style.overflow="hidden";let onKeyDown=event3=>{event3.key==="Escape"&&(setFullScreen(!1),setFiltersOpen(!1))};return window.addEventListener("keydown",onKeyDown),()=>{document.body.style.overflow=previous,window.removeEventListener("keydown",onKeyDown)}},[fullScreen]);let visibleNodes=nodes3.filter(node=>node.status!=="archived").filter(node=>!nodeType||node.type===nodeType).filter(node=>!nodeTag||(node.tags||[]).includes(nodeTag)).filter(node=>!normalized||JSON.stringify(node).toLocaleLowerCase().includes(normalized)),selectEvent=id2=>{setSelectedEventId(id2),setMode("timeline")},selectNode=id2=>{setSelectedNodeId(id2),setMode("graph")},openExplorer=()=>{mode==="graph"&&!selectedNodeId&&visibleNodes[0]&&setSelectedNodeId(visibleNodes[0].id),mode==="timeline"&&!selectedEventId&&events[0]&&setSelectedEventId(events[0].id),setFiltersOpen(!0),setFullScreen(!0)},migration=graph.migration||{projected:events.length,total:events.length,complete:!0},activeFilterCount=mode==="graph"?+!!nodeType+ +!!nodeTag:Object.values(eventFilters).filter(Boolean).length,filterControls=mode==="graph"?h("div",{className:"sg-filterbar"},h("select",{value:nodeType,onChange:event3=>setNodeType(event3.target.value),"aria-label":"\u8282\u70B9\u7C7B\u578B"},h("option",{value:""},"\u5168\u90E8\u8282\u70B9\u7C7B\u578B"),Object.entries(NODE_META).map(([value,meta3])=>h("option",{key:value,value},meta3[0]))),h("select",{value:nodeTag,onChange:event3=>setNodeTag(event3.target.value),"aria-label":"\u8BED\u4E49\u6807\u7B7E"},h("option",{value:""},"\u5168\u90E8\u8BED\u4E49\u6807\u7B7E"),nodeTags.map(tag=>h("option",{key:tag,value:tag},tag)))):h("div",{className:"sg-filterbar"},h("select",{value:eventFilters.time,onChange:event3=>setEventFilters({...eventFilters,time:event3.target.value}),"aria-label":"\u65F6\u95F4\u8303\u56F4"},h("option",{value:""},"\u5168\u90E8\u65F6\u95F4"),h("option",{value:"today"},"\u4ECA\u5929"),h("option",{value:"week"},"\u672C\u5468"),h("option",{value:"unknown"},"\u53D1\u751F\u65F6\u95F4\u672A\u77E5")),h("select",{value:eventFilters.node,onChange:event3=>setEventFilters({...eventFilters,node:event3.target.value}),"aria-label":"\u53C2\u4E0E\u5B9E\u4F53"},h("option",{value:""},"\u5168\u90E8\u5B9E\u4F53"),nodes3.map(node=>h("option",{key:node.id,value:node.id},node.name))),h("select",{value:eventFilters.type,onChange:event3=>setEventFilters({...eventFilters,type:event3.target.value}),"aria-label":"\u4E8B\u4EF6\u7C7B\u578B"},h("option",{value:""},"\u5168\u90E8\u7C7B\u578B"),Object.entries(EVENT_TYPE_TEXT).map(([value,label])=>h("option",{key:value,value},label))),h("select",{value:eventFilters.status,onChange:event3=>setEventFilters({...eventFilters,status:event3.target.value}),"aria-label":"\u4E8B\u4EF6\u72B6\u6001"},h("option",{value:""},"\u5168\u90E8\u72B6\u6001"),Object.entries(EVENT_STATUS_TEXT).map(([value,label])=>h("option",{key:value,value},label))));return h("section",{className:"sg-long-explorer "+(fullScreen?"fullscreen":""),"aria-label":fullScreen?"\u957F\u671F\u8BB0\u5FC6\u5168\u5C4F\u63A2\u7D22":"\u957F\u671F\u8BB0\u5FC6\u6D4F\u89C8"},h("nav",{className:"sg-long-tabs"},h("button",{className:mode==="graph"?"active":"",onClick:()=>setMode("graph")},"\u77E5\u8BC6\u56FE\u8C31"),h("button",{className:mode==="timeline"?"active":"",onClick:()=>setMode("timeline")},"\u4E8B\u4EF6\u65F6\u95F4\u7EBF")),migration.complete?null:h("div",{className:"sg-migration",role:"status"},h("span",{className:"sg-processing-icon"},"\u21BB"),h("span",null,"\u6B63\u5728\u5347\u7EA7\u957F\u671F\u8BB0\u5FC6 \xB7 "+migration.projected+" / "+migration.total+" Events"),h("small",null,migration.failed?migration.failed+" \u6279\u5F85\u91CD\u8BD5":"\u540E\u53F0\u589E\u91CF\u5904\u7406\uFF0C\u4E0D\u5F71\u54CD\u5176\u4ED6\u529F\u80FD")),h("div",{className:"sg-long-toolbar"},h(SearchBox,{value:query,onChange:setQuery}),h("button",{type:"button",className:"sg-toolbar-button","aria-expanded":filtersOpen?"true":"false",onClick:()=>setFiltersOpen(!filtersOpen)},"\u7B5B\u9009 \u25BE",activeFilterCount?h("span",{className:"sg-active-filter-count"},activeFilterCount):null),h("span",{className:"sg-toolbar-count"},mode==="graph"?visibleNodes.length+" \u4E2A\u8282\u70B9 \xB7 "+edges3.filter(edge=>edge.status==="active").length+" \u6761\u5173\u7CFB":events.length+" \u6761\u4E8B\u4EF6 \xB7 "+project),h("button",{type:"button",className:"sg-toolbar-button",onClick:fullScreen?()=>{setFullScreen(!1),setFiltersOpen(!1)}:openExplorer},fullScreen?"\u9000\u51FA\u5168\u5C4F":"\u26F6 \u5168\u5C4F\u67E5\u770B"+(mode==="graph"?"\u56FE\u8C31":"\u65F6\u95F4\u7EBF"))),filtersOpen?filterControls:null,mode==="graph"?h("div",{className:"sg-long-layout "+(fullScreen?"":"sg-summary-layout")},h(GraphCanvas,{nodes:visibleNodes,edges:edges3,clusters,importance:nodeImportance,selectedId:selectedNodeId,onSelect:setSelectedNodeId,showSummary:!fullScreen,onViewDetails:openExplorer}),fullScreen?h(NodeDetailPanel,{node:nodes3.find(node=>node.id===selectedNodeId),nodes:nodes3,edges:edges3,events,onEvent:selectEvent}):null):h("div",{className:"sg-long-layout "+(fullScreen?"sg-timeline-layout":"sg-summary-layout")},h(TimelineList,{events,nodes:nodes3,query,filters:eventFilters,onSelect:setSelectedEventId,selectedId:selectedEventId,floating:!fullScreen,onNode:selectNode,openSource:openEvent}),fullScreen?h(EventDetailPanel,{event:events.find(event3=>event3.id===selectedEventId),nodes:nodes3,events,onNode:selectNode,openSource:openEvent}):null))}function previewText(value){let text=String(value||"").replace(/\s+/g," ").trim()||"\u6682\u65E0\u5185\u5BB9";return text.length>200?text.slice(0,200)+"\u2026":text}function turnRangeText(range){return!Array.isArray(range)||range.length<2||range[1]<range[0]?"\u7B49\u5F85\u65B0\u5BF9\u8BDD":"Turn "+range[0]+"\u2013"+range[1]}function LayerPreview({layer,currentLevel,expanding,menuOpen,allowExpand,onMenuToggle,onExpand}){let itemRef=React.useRef(null),hideTimer=React.useRef(null),popoverRef=React.useRef(null),level=Number(layer.level),actionable=allowExpand&&level>currentLevel,cancelHide=()=>{hideTimer.current&&window.clearTimeout(hideTimer.current),hideTimer.current=null},removePopover=()=>{popoverRef.current?.remove(),popoverRef.current=null},showPopover=()=>{cancelHide();let rect=itemRef.current?.getBoundingClientRect();if(!rect)return;let width2=Math.min(390,Math.max(240,window.innerWidth-24)),maxHeight=Math.min(520,window.innerHeight*.7),right=rect.right+12,left=right+width2<=window.innerWidth-12?right:Math.max(12,rect.left-width2-12),top=Math.min(Math.max(12,rect.top-8),Math.max(12,window.innerHeight-maxHeight-12));if(!popoverRef.current){let popover=document.createElement("aside"),title=document.createElement("strong"),content=document.createElement("p"),theme=window.getComputedStyle(itemRef.current),pageTheme=window.getComputedStyle(itemRef.current.closest(".sg-memory"));popover.className="sg-layer-popover",popover.setAttribute("role","tooltip"),popover.style.background=pageTheme.backgroundColor,popover.style.color=pageTheme.color,popover.style.borderColor=theme.borderColor,title.textContent="L"+level+" \u5B8C\u6574\u5185\u5BB9",content.className="sg-layer-full",content.textContent=String(layer.content||"\u6682\u65E0\u5185\u5BB9"),popover.append(title,content),popover.addEventListener("mouseenter",cancelHide),popover.addEventListener("mouseleave",scheduleHide),document.body.appendChild(popover),popoverRef.current=popover}popoverRef.current.style.left=left+"px",popoverRef.current.style.top=top+"px"},scheduleHide=()=>{cancelHide(),hideTimer.current=window.setTimeout(removePopover,140)};return React.useEffect(()=>()=>{cancelHide(),removePopover()},[]),h("div",{className:"sg-layer-hover"},h("div",{ref:itemRef,className:"sg-layer-item "+(level===currentLevel?"current":""),"data-level":String(level),tabIndex:0,onMouseEnter:showPopover,onMouseLeave:scheduleHide,onFocus:showPopover,onBlur:scheduleHide},h("span",{className:"sg-layer-label"},"L"+level),h("span",{className:"sg-layer-preview"},previewText(layer.content)),actionable?h("button",{className:"sg-layer-more",type:"button","aria-label":"L"+level+" \u64CD\u4F5C","aria-expanded":menuOpen?"true":"false",onClick:event3=>{event3.stopPropagation(),onMenuToggle(level)}},"\xB7\xB7\xB7"):h("span",{className:"sg-layer-more-placeholder","aria-hidden":"true"}),menuOpen?h("div",{className:"sg-layer-menu"},h("button",{type:"button",disabled:expanding,onClick:event3=>{event3.stopPropagation(),onMenuToggle(null),onExpand(level)}},expanding?"\u6B63\u5728\u5C55\u5F00\u2026":"\u5C55\u5F00\u5230\u8FD9\u4E00\u5C42")):null))}function BlockLayerPanel({block,detail,loading,expandingLevel,onExpand}){let[openMenuLevel,setOpenMenuLevel]=React.useState(null);if(React.useEffect(()=>{let closeMenu=event3=>{if(event3.key==="Escape"){setOpenMenuLevel(null);return}event3.target?.closest?.(".sg-layer-more, .sg-layer-menu")||setOpenMenuLevel(null)};return document.addEventListener("pointerdown",closeMenu),document.addEventListener("keydown",closeMenu),()=>{document.removeEventListener("pointerdown",closeMenu),document.removeEventListener("keydown",closeMenu)}},[]),loading)return h("div",{className:"sg-layer-panel"},h(Loading));let layers=Array.isArray(detail?.layers)?detail.layers:[];return h("div",{className:"sg-layer-panel"},h("div",{className:"sg-layer-heading"},h("strong",null,"\u5206\u5C42\u5185\u5BB9\u9884\u89C8"),h("span",null,"\u5F53\u524D\u5C42\u7EA7\uFF1AL"+block.currentLevel+" \xB7 \u60AC\u505C\u53EF\u67E5\u770B\u5B8C\u6574\u5185\u5BB9")),block.virtual?h("div",{className:"sg-virtual-note"},"\u65E7\u4F1A\u8BDD\u5C55\u793A\u7247\u6BB5\u4E3A\u53EA\u8BFB\u5185\u5BB9\uFF0C\u4E0D\u4F1A\u6539\u5199\u539F\u59CB\u6570\u636E\u5E93\u3002"):null,layers.length?h("div",{className:"sg-layer-stack"},layers.slice().sort((a,b)=>a.level-b.level).map(layer=>h(LayerPreview,{key:layer.level,layer,currentLevel:block.currentLevel,expanding:expandingLevel===layer.level,menuOpen:openMenuLevel===layer.level,allowExpand:!block.virtual,onMenuToggle:level=>setOpenMenuLevel(current=>current===level?null:level),onExpand}))):h("div",{className:"sg-muted"},"\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u8BE5 Block \u7684\u5206\u5C42\u5185\u5BB9\u3002"))}function expansionLabel(source){return source==="user"?"\u7528\u6237\u5C55\u5F00":source==="agent"?"Agent \u5C55\u5F00":source==="legacy"?"\u66FE\u5C55\u5F00":""}function ShortTermPage({blocks,openBlock,conversations,activeThreadId,namespace,onConversationChange,refresh}){let visible=[...blocks].sort((a,b)=>Number(a.sequence||0)-Number(b.sequence||0)||String(a.createdAt).localeCompare(String(b.createdAt))),distributionRef=React.useRef(null),[rail,setRail]=React.useState({value:0,max:0}),[expandedId,setExpandedId]=React.useState(""),[details,setDetails]=React.useState({}),[loadingId,setLoadingId]=React.useState(""),[expanding,setExpanding]=React.useState({blockId:"",level:-1}),[inlineError,setInlineError]=React.useState(""),currentOpen=openBlock||{turnRange:null,messages:0,status:"open"};React.useEffect(()=>{let node=distributionRef.current;if(!node)return;let updateRail=()=>{let max5=Math.max(0,node.scrollWidth-node.clientWidth);setRail({value:Math.min(max5,Math.round(node.scrollLeft)),max:max5})};node.scrollLeft=node.scrollWidth,updateRail();let observer=typeof ResizeObserver=="function"?new ResizeObserver(updateRail):null;return observer?.observe(node),()=>observer?.disconnect()},[visible.length,activeThreadId]);let toggleBlock=block=>{if(expandedId===block.id){setExpandedId("");return}setExpandedId(block.id),setInlineError(""),!details[block.id]&&(setLoadingId(block.id),api2("sources",{namespace,blockId:block.id}).then(value=>setDetails(current=>({...current,[block.id]:value}))).catch(reason=>setInlineError(String(reason.message||reason))).finally(()=>setLoadingId("")))},expandTo=(block,level)=>(setInlineError(""),setExpanding({blockId:block.id,level}),api2("blocks/expand",{namespace,blockId:block.id,level:"L"+level},{method:"PATCH"}).then(()=>refresh()).catch(reason=>setInlineError(String(reason.message||reason))).finally(()=>setExpanding({blockId:"",level:-1})));return h(React.Fragment,null,h("section",{className:"sg-decay-overview","aria-labelledby":"sg-decay-title"},h("div",{className:"sg-decay-head"},h("h2",{className:"sg-decay-title",id:"sg-decay-title"},"\u5757\u8870\u51CF\u603B\u89C8"),h("label",{className:"sg-conversation"},h("span",null,"\u5F53\u524D\u5BF9\u8BDD\uFF1A"),h("select",{value:activeThreadId||"",disabled:!conversations.length,onChange:event3=>onConversationChange(event3.target.value),"aria-label":"\u5F53\u524D\u5BF9\u8BDD"},conversations.map(conversation=>h("option",{key:conversation.id,value:conversation.id},conversation.label))))),h("p",{className:"sg-decay-copy"},"L0 \u5C42\u6700\u6D45\u6700\u7B80\u7565\uFF0CL5 \u5C42\u6700\u6DF1\u6700\u8BE6\u7EC6\uFF0C\u79BB\u5F53\u524D\u5BF9\u8BDD\u8D8A\u8FDC\uFF0CBlock \u4F1A\u9010\u6E10\u7B80\u7565\u3002"),h("div",{ref:distributionRef,className:"sg-distribution","aria-label":"Block \u5F53\u524D\u5C42\u7EA7\u5206\u5E03",onScroll:event3=>{let node=event3.currentTarget;setRail({value:Math.round(node.scrollLeft),max:Math.max(0,node.scrollWidth-node.clientWidth)})},onWheel:event3=>{rail.max<=0||(event3.preventDefault(),event3.currentTarget.scrollLeft+=event3.deltaY+event3.deltaX)}},visible.map(block=>h("span",{key:block.id,className:"sg-level-chip","data-level":String(block.currentLevel),title:"Block #"+block.sequence},"L"+block.currentLevel)),h("span",{className:"sg-level-chip sg-open-chip"},"\u5F00\u653E\u5757 \xB7 \u672A\u5C01\u5B58")),h("input",{className:"sg-distribution-rail",type:"range",min:"0",max:String(Math.max(1,rail.max)),step:"1",value:String(Math.min(rail.value,Math.max(1,rail.max))),disabled:rail.max<=0,onChange:event3=>{let value=Number(event3.target.value);distributionRef.current&&(distributionRef.current.scrollLeft=value),setRail(current=>({...current,value}))},"aria-label":"Block \u5206\u5E03\u6ED1\u8F68"}),h("div",{className:"sg-time-direction","aria-hidden":"true"},h("span",null,"\u66F4\u65E7"),h("span",{className:"sg-time-line"}),h("span",null,"\u66F4\u65B0 \u2192")),h("div",{className:"sg-overview-meta"},h("span",null,"\u5DF2\u5C01\u5B58\u5757\uFF1A"+visible.length),h("span",null,"\u5F00\u653E\u5757\uFF1A"+turnRangeText(currentOpen.turnRange)+"\uFF08\u672A\u5C01\u5B58\uFF09"))),h("section",{className:"sg-block-list","aria-label":"Block \u5217\u8868"},h("div",{className:"sg-block-header","aria-hidden":"true"},h("span",null,"\u5F53\u524D\u5C42\u7EA7"),h("span",null,"Block"),h("span",null,"\u8986\u76D6 Turn"),h("span",null,"\u8DDD\u6700\u65B0\u5C01\u5B58\u5757"),h("span")),inlineError?h("div",{className:"sg-inline-error"},"\u64CD\u4F5C\u672A\u5B8C\u6210\uFF1A"+inlineError):null,visible.map(block=>h("div",{key:block.id,className:"sg-block-unit"},h("button",{className:"sg-block-toggle",type:"button",onClick:()=>toggleBlock(block),"aria-expanded":expandedId===block.id?"true":"false"},h("span",{className:"sg-level-cell"},h("span",{className:"sg-level-badge","data-level":String(block.currentLevel)},"L"+block.currentLevel),expansionLabel(block.expansionSource)?h("span",{className:"sg-lifted"},expansionLabel(block.expansionSource)):null),h("span",{className:"sg-block-name"},(block.virtual?"\u65E7 Block #":"Block #")+block.sequence),h("span",{className:"sg-block-turn"},turnRangeText(block.turnRange)),h("span",{className:"sg-block-distance"},block.distanceFromLatest===0?"0\uFF08\u6700\u65B0\uFF09":block.distanceFromLatest+" \u4E2A Block"),h("span",{className:"sg-row-chevron","aria-hidden":"true"},expandedId===block.id?"\u2303":"\u203A")),expandedId===block.id?h("div",{className:"sg-block-expanded"},h(BlockLayerPanel,{block,detail:details[block.id],loading:loadingId===block.id,expandingLevel:expanding.blockId===block.id?expanding.level:-1,onExpand:level=>expandTo(block,level)})):null)),h("div",{className:"sg-block-unit"},h("div",{className:"sg-block-toggle sg-open-row"},h("span",{className:"sg-level-cell"},h("span",{className:"sg-open-badge"},"\u5F00\u653E\u5757")),h("span",{className:"sg-block-name"},"\u672A\u5C01\u5B58"),h("span",{className:"sg-block-turn"},turnRangeText(currentOpen.turnRange)),h("span",{className:"sg-block-distance"},"\u2014"),h("span")))))}function SourceDetails({item,source,kind}){let messages=source?.messages||[];return h("div",{className:"sg-detail-section"},h("h3",{className:"sg-section-title"},"\u6765\u6E90"),h("div",{className:"sg-source-label"},h("span",{className:"sg-source-icon","aria-hidden":"true"},"\u25A3"),h("span",null,"\u5F53\u524D DeepSeek \u5BF9\u8BDD")),h("details",{className:"sg-tech"},h("summary",null,"\u6280\u672F\u8BE6\u60C5"),h("div",{className:"sg-tech-body"},h("div",{className:"sg-tech-row"},h("span",{className:"sg-muted"},kind==="block"?"Block ID":"Event ID"),h("span",{className:"sg-code"},item.id)),kind==="block"&&item.turnRange?h("div",{className:"sg-tech-row"},h("span",{className:"sg-muted"},"Turn"),h("span",null,item.turnRange.join(" - "))):null,messages.length?messages.map(message=>h("div",{key:message.id,className:"sg-raw-message"},h("div",{className:"sg-muted"},String(message.role||"")+" \xB7 "+formatTime(message.createdAt)),h("div",{className:"sg-code"},String(message.content||"")))):h("div",{className:"sg-muted"},"\u5F53\u524D\u6570\u636E\u4E2D\u6CA1\u6709\u53EF\u663E\u793A\u7684\u6765\u6E90\u6D88\u606F\u3002"))))}function EventDetail({event:event3,project,source,onBack,backLabel}){return h(React.Fragment,null,h(BackBar,{label:backLabel,onBack}),h("header",{className:"sg-detail-header"},h("h2",{className:"sg-detail-title"},event3.title||"\u8BB0\u5FC6\u8BE6\u60C5"),event3.summary?h("p",{className:"sg-detail-subtitle"},event3.summary):null,h("div",{className:"sg-meta"},h("span",null,formatTime(event3.updatedAt||event3.createdAt)),h("span",{className:"sg-meta-sep"},project))),event3.narrative?h("div",{className:"sg-detail-section"},h("h3",{className:"sg-section-title"},"AI \u5BF9\u8FD9\u6BB5\u7ECF\u5386\u7684\u7406\u89E3"),h("p",{className:"sg-prose"},event3.narrative)):null,h("div",{className:"sg-detail-section"},h("h3",{className:"sg-section-title"},"\u53C2\u4E0E\u5B9E\u4F53"),(event3.temporal?.participants||[]).length?h("div",{className:"sg-tags"},event3.temporal.participants.map(name=>h("span",{key:name,className:"sg-tag"},name))):h("span",{className:"sg-muted"},"\u672A\u8BB0\u5F55")),h(SourceDetails,{item:event3,source,kind:"event"}))}function ElementDetail({element:element3,events,source,openEvent,onBack,backLabel}){let facts=[];element3.currentState&&facts.push(element3.currentState);for(let fact of element3.facts||[]){let value=Array.isArray(fact.value)?fact.value.join("\u3001"):fact.value;value&&!facts.includes(String(value))&&facts.push(String(value))}let related=events.filter(event3=>(element3.sourceEventIds||[]).includes(event3.id)).sort((a,b)=>String(b.updatedAt).localeCompare(String(a.updatedAt)));return h(React.Fragment,null,h(BackBar,{label:backLabel,onBack}),h("header",{className:"sg-detail-header"},h("h2",{className:"sg-detail-title"},element3.name||"\u76F8\u5173\u4E8B\u7269"),h("p",{className:"sg-detail-subtitle"},"AI \u5173\u4E8E\u5B83\u76EE\u524D\u77E5\u9053\u8FD9\u4E9B"),h("div",{className:"sg-meta"},h("span",null,"\u76F8\u5173\u7ECF\u5386 "+related.length+" \u6761"),h("span",{className:"sg-meta-sep"},"\u6700\u8FD1\u66F4\u65B0 "+formatTime(element3.updatedAt)))),h("div",{className:"sg-detail-section"},facts.length?h("ul",{className:"sg-facts"},facts.map((fact,index)=>h("li",{key:index},fact))):h("div",{className:"sg-muted"},"\u6682\u65F6\u6CA1\u6709\u5F62\u6210\u53EF\u5C55\u793A\u7684\u8BA4\u8BC6\u3002")),h("div",{className:"sg-detail-section"},h("h3",{className:"sg-section-title"},"\u76F8\u5173\u7ECF\u5386"),related.length?h("div",{className:"sg-related-list"},related.map(event3=>h("button",{key:event3.id,className:"sg-related",onClick:()=>openEvent(event3)},h("span",{className:"sg-related-name"},event3.title),h("span",{className:"sg-related-time"},formatTime(event3.updatedAt||event3.createdAt))))):h("div",{className:"sg-muted"},"\u6CA1\u6709\u5173\u8054\u7ECF\u5386\u3002")),h(SourceDetails,{item:element3,source,kind:"element"}))}function ProcessingStatus({overview,blocks,onBack,refresh}){let failures=overview.failedJobDetails||[],failedBlocks=blocks.filter(block=>block.status==="failed"),first2=failures[0];return h(React.Fragment,null,h(BackBar,{label:"\u8FD4\u56DE",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u5904\u7406\u72B6\u6001"),h("p",null,failures.length+" \u4E2A\u4EFB\u52A1\u9700\u8981\u7EE7\u7EED\u5904\u7406")),h("div",{className:"sg-safe-note"},"\u539F\u59CB\u8BB0\u5FC6\u5DF2\u4FDD\u5B58\uFF0C\u4E0D\u4F1A\u4E22\u5931\u3002"),h("div",{className:"sg-detail-section"},h("div",{className:"sg-pipeline"},h("div",{className:"sg-stage"},h("span",null,"\u8BB0\u5FC6\u4FDD\u5B58"),h("span",{className:"sg-stage-value done"},"\u2713 \u5DF2\u5B8C\u6210")),h("div",{className:"sg-stage"},h("span",null,"\u4E8B\u4EF6\u63D0\u53D6"),h("span",{className:"sg-stage-value "+(first2?.kind==="event-extraction"?"failed":"done")},first2?.kind==="event-extraction"?"\xD7 \u5931\u8D25":"\u2713 \u5DF2\u5B8C\u6210")),h("div",{className:"sg-stage"},h("span",null,"\u56FE\u8C31\u6295\u5F71"),h("span",{className:"sg-stage-value "+(first2?.kind==="graph-projection"?"failed":first2?.kind==="event-extraction"?"waiting":"done")},first2?.kind==="graph-projection"?"\xD7 \u5931\u8D25":first2?.kind==="event-extraction"?"\u2014 \u7B49\u5F85":"\u2713 \u5DF2\u5B8C\u6210")))),failedBlocks.length?h("div",{className:"sg-detail-section"},h("h3",{className:"sg-section-title"},"\u53D7\u5F71\u54CD\u7684\u77ED\u671F\u8BB0\u5FC6"),failedBlocks.map(block=>h("div",{key:block.id,className:"sg-result-event"},block.title||block.summary||"\u77ED\u671F\u8BB0\u5FC6"))):null,h("button",{className:"sg-alert",onClick:refresh,style:{marginTop:"16px"}},h("span",{className:"sg-alert-mark"},"\u21BB"),h("span",null,h("span",{className:"sg-alert-title"},"\u91CD\u65B0\u68C0\u67E5\u72B6\u6001"),h("br"),h("span",{className:"sg-alert-copy"},"\u4EFB\u52A1\u4F1A\u6CBF\u7528\u73B0\u6709\u91CD\u8BD5\u673A\u5236\u7EE7\u7EED\u5904\u7406\u3002")),h("span",{className:"sg-chevron"},"\u203A")),h("details",{className:"sg-tech"},h("summary",null,"\u6280\u672F\u9519\u8BEF\u8BE6\u60C5"),h("pre",{className:"sg-tech-body sg-code"},first2?.lastErrorFull||first2?.lastError||"\u6CA1\u6709\u8BB0\u5F55\u6280\u672F\u9519\u8BEF\u3002")))}function ImportPage({namespace,onBack,refresh}){let[text,setText]=React.useState(""),[prompt,setPrompt]=React.useState(""),[promptLoading,setPromptLoading]=React.useState(!0),[copied,setCopied]=React.useState(!1),[busy,setBusy]=React.useState(!1),[result,setResult]=React.useState(null),[error3,setError]=React.useState("");React.useEffect(()=>{let active=!0;api2("import").then(value=>{active&&setPrompt(String(value.prompt||""))}).catch(reason=>{active&&setError(String(reason?.message||reason))}).finally(()=>{active&&setPromptLoading(!1)});let onKeyDown=event3=>{event3.key==="Escape"&&!busy&&onBack()};return window.addEventListener("keydown",onKeyDown),()=>{active=!1,window.removeEventListener("keydown",onKeyDown)}},[]);let copyPrompt=()=>{if(!prompt)return;(navigator.clipboard?.writeText?navigator.clipboard.writeText(prompt):Promise.reject(new Error("\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u81EA\u52A8\u590D\u5236"))).then(()=>{setCopied(!0),window.setTimeout(()=>setCopied(!1),1600)}).catch(reason=>setError(String(reason?.message||reason)))},submit=()=>{if(!(!text.trim()||busy)){try{JSON.parse(text)}catch{setError("\u7C98\u8D34\u5185\u5BB9\u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u8BF7\u8BA9\u5916\u90E8 AI \u53EA\u8F93\u51FA JSON \u540E\u91CD\u8BD5\u3002");return}return setBusy(!0),setError(""),setResult(null),api2("import",{namespace},{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({namespace,text})}).then(next2=>(setResult(next2),refresh().then(()=>window.setTimeout(onBack,900)))).catch(reason=>setError(String(reason?.message||reason))).finally(()=>setBusy(!1))}};return h("div",{className:"sg-import-overlay",role:"presentation",onMouseDown:event3=>{event3.target===event3.currentTarget&&!busy&&onBack()}},h("section",{className:"sg-import-dialog",role:"dialog","aria-modal":"true","aria-labelledby":"sg-import-title"},h("header",{className:"sg-import-dialog-head"},h("h2",{id:"sg-import-title",className:"sg-import-dialog-title"},"\u5C06\u8BB0\u5FC6\u5BFC\u5165 StrataGate"),h("button",{type:"button",className:"sg-icon-button",disabled:busy,onClick:onBack,"aria-label":"\u5173\u95ED"},"\xD7")),h("div",{className:"sg-import-step"},h("div",{className:"sg-import-step-head"},h("span",{className:"sg-import-step-num"},"1"),h("span",{className:"sg-import-step-title"},"\u590D\u5236\u4EE5\u4E0B\u63D0\u793A\u8BCD\u5230\u5176\u4ED6 AI \u5BF9\u8BDD\u4E2D"),h("button",{type:"button",className:"sg-import-copy",disabled:promptLoading||!prompt,onClick:copyPrompt},copied?"\u5DF2\u590D\u5236":"\u590D\u5236")),promptLoading?h("div",{className:"sg-import-loading"},"\u6B63\u5728\u52A0\u8F7D\u63D0\u793A\u8BCD\u2026"):h("div",{className:"sg-import-prompt",tabIndex:"0"},prompt||"\u63D0\u793A\u8BCD\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u3002")),h("div",{className:"sg-import-step"},h("div",{className:"sg-import-step-head"},h("span",{className:"sg-import-step-num"},"2"),h("span",{className:"sg-import-step-title"},"\u5C06\u7ED3\u679C\u7C98\u8D34\u5230\u4E0B\u65B9\uFF0C\u6DFB\u52A0\u5230 StrataGate \u8BB0\u5FC6")),h("div",{className:"sg-import-card"},h("textarea",{value:text,onChange:event3=>setText(event3.target.value),placeholder:"\u5728\u6B64\u7C98\u8D34\u5916\u90E8 AI \u8FD4\u56DE\u7684\u8BB0\u5FC6 JSON","aria-label":"\u5916\u90E8 AI \u8BB0\u5FC6 JSON"}))),error3?h("div",{className:"sg-import-error"},error3):null,result?h("div",{className:"sg-import-result"},"\u5BFC\u5165\u5B8C\u6210\uFF1A\u65B0\u589E "+Number(result.importedCount||0)+" \u6761\u8BB0\u5FC6\u3002"):null,h("footer",{className:"sg-import-dialog-foot"},h("button",{type:"button",className:"sg-import-cancel",disabled:busy,onClick:onBack},"\u53D6\u6D88"),h("button",{type:"button",className:"sg-import-button",disabled:busy||!text.trim(),onClick:submit},busy?"\u6B63\u5728\u6DFB\u52A0\u2026":"\u6DFB\u52A0\u5230\u8BB0\u5FC6"))))}function MoreHome({selected,setView}){let rows=[["import","\u21C4","\u5BFC\u5165\u522B\u7684 AI \u8BB0\u5FC6","\u7C98\u8D34\u5916\u90E8 AI \u603B\u7ED3\u5E76\u5BFC\u5165"],["structure","\u25C7","\u8BB0\u5FC6\u7ED3\u6784","\u6D4F\u89C8 Event \u4E0E\u77E5\u8BC6\u56FE\u8C31"],["system","\u2713","\u7CFB\u7EDF\u72B6\u6001","\u5904\u7406\u4EFB\u52A1\u548C\u6700\u8FD1\u6574\u7406\u65F6\u95F4"],["audit","\u2197","\u4F7F\u7528\u8BB0\u5F55","\u957F\u671F\u8BB0\u5FC6\u4F55\u65F6\u88AB\u4F7F\u7528"],["raw","{}","\u539F\u59CB\u6570\u636E","Block\u3001Event\u3001Graph \u4E0E\u6A21\u578B\u54CD\u5E94"],["settings","\u2699","\u9AD8\u7EA7\u8BBE\u7F6E","Schema\u3001\u63D0\u53D6\u95F4\u9694\u4E0E\u9879\u76EE\u7A7A\u95F4"],["support","?","\u53CD\u9988\u4E0E\u652F\u6301","\u62A5\u544A\u95EE\u9898\u3001\u63D0\u51FA\u5EFA\u8BAE\u6216\u54A8\u8BE2\u4F7F\u7528\u65B9\u6CD5"]];return h(React.Fragment,null,h("div",{className:"sg-intro"},h("h2",null,"\u66F4\u591A"),h("p",null,"\u9AD8\u7EA7\u4FE1\u606F\u4E0E\u5DE5\u7A0B\u89C6\u56FE")),h("div",{className:"sg-menu"},rows.map(([id2,icon,title,subtitle])=>h("button",{key:id2,className:"sg-menu-row",onClick:()=>setView({name:id2})},h("span",{className:"sg-menu-icon","aria-hidden":"true"},icon),h("span",null,h("span",{className:"sg-menu-title"},title),h("br"),h("span",{className:"sg-menu-subtitle"},subtitle)),h("span",{className:"sg-chevron"},"\u203A")))))}function limitedJson(value,limit2=4500){let text=JSON.stringify(value,null,2).replace(/\b(?:sk|gh[opasu]|github_pat)_[A-Za-z0-9_-]{12,}\b/g,"[REDACTED_TOKEN]").replace(/\b(Bearer\s+)[A-Za-z0-9._~+/-]{12,}={0,2}\b/gi,"$1[REDACTED]").replace(/\b(api[_-]?key|token|password|secret)\s*[:=]\s*([^\s,;]+)/gi,"$1=[REDACTED]");return text.length>limit2?text.slice(0,limit2)+`
399
399
  \u2026\uFF08\u5185\u5BB9\u5DF2\u622A\u65AD\uFF09`:text}function safeErrorSummary(value){let firstLine=String(value||"").split(/\r?\n/,1)[0].trim();return firstLine.length>240?firstLine.slice(0,240)+"\u2026":firstLine}function SupportPage({overview,selected,project,data:data4,recentError,onBack}){let[includeLogs,setIncludeLogs]=React.useState(!1),[includeMemory,setIncludeMemory]=React.useState(!1),latestJobError=selected?.failedJobDetails?.[0]?.lastError||"",lines=["## \u81EA\u52A8\u8BCA\u65AD\u4FE1\u606F","","- StrataGate \u7248\u672C\uFF1A"+(overview.pluginVersion||"unknown"),"- Harness \u7248\u672C\uFF1A"+(overview.harnessVersion||"unknown"),"- \u5F53\u524D\u5DE5\u4F5C\u533A\uFF1A"+project,"- blockTurnSize\uFF1A"+(selected?.blockTurnSize??"unknown"),"- \u5DF2\u5C01\u5B58\u5757\uFF1A"+(selected?.blocks??0),"- Event / Graph Node \u6570\u91CF\uFF1A"+(selected?.events??0)+" / "+(selected?.graphNodes??0),"- \u6700\u8FD1\u9519\u8BEF\uFF1A"+(safeErrorSummary(recentError||latestJobError)||"\u65E0"),"","> \u9ED8\u8BA4\u8BCA\u65AD\u4E0D\u5305\u542B\u539F\u59CB\u804A\u5929\u3001L5\u3001Event \u6216 Graph \u5185\u5BB9\u3002"];includeLogs&&lines.push("","<details><summary>\u8BCA\u65AD\u65E5\u5FD7</summary>","","```json",limitedJson({frontendError:recentError||null,failedJobs:selected?.failedJobDetails||[]}),"```","</details>"),includeMemory&&lines.push("","<details><summary>\u7528\u6237\u4E3B\u52A8\u9644\u52A0\u7684\u8BB0\u5FC6\u6570\u636E\uFF08\u53EF\u80FD\u5305\u542B\u5BF9\u8BDD\u5185\u5BB9\uFF09</summary>","","```json",limitedJson({blocks:data4.blocks,events:data4.events,graph:data4.graph}),"```","</details>");let issueParams=new URLSearchParams({title:"[Bug] StrataGate\uFF1A",body:lines.join(`
400
- `)}),featureParams=new URLSearchParams({title:"[Feature] StrataGate\uFF1A",body:"\u8BF7\u63CF\u8FF0\u5E0C\u671B\u589E\u52A0\u7684\u80FD\u529B\u3001\u4F7F\u7528\u573A\u666F\u548C\u9884\u671F\u884C\u4E3A\u3002"});return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u53CD\u9988\u4E0E\u652F\u6301"),h("p",null,"\u9009\u62E9\u6700\u5408\u9002\u7684\u5165\u53E3\uFF0C\u6211\u4EEC\u4F1A\u5E26\u4E0A\u5FC5\u8981\u4E14\u5B89\u5168\u7684\u4E0A\u4E0B\u6587\u3002")),h("div",{className:"sg-privacy-note"},"\u57FA\u7840\u8BCA\u65AD\u4E0D\u4F1A\u9644\u5E26\u539F\u59CB\u804A\u5929\u3001L5\u3001Event \u6216 Graph \u5185\u5BB9\u3002"),h("section",{className:"sg-support-card"},h("h3",null,"\u9047\u5230\u95EE\u9898"),h("p",null,"\u63D2\u4EF6\u4F1A\u6574\u7406\u7248\u672C\u3001\u914D\u7F6E\u3001\u6570\u91CF\u548C\u6700\u8FD1\u9519\u8BEF\uFF0C\u5E2E\u52A9\u5FEB\u901F\u5B9A\u4F4D\u3002"),h("label",{className:"sg-check"},h("input",{type:"checkbox",checked:includeLogs,onChange:event3=>setIncludeLogs(event3.target.checked)}),h("span",null,"\u9644\u52A0\u8BCA\u65AD\u65E5\u5FD7")),h("label",{className:"sg-check"},h("input",{type:"checkbox",checked:includeMemory,onChange:event3=>setIncludeMemory(event3.target.checked)}),h("span",null,"\u9644\u52A0\u8BB0\u5FC6\u6570\u636E\uFF08\u53EF\u80FD\u5305\u542B\u5BF9\u8BDD\u5185\u5BB9\uFF09")),includeMemory?h("div",{className:"sg-error-note"},"\u4F60\u5DF2\u9009\u62E9\u9644\u52A0\u53EF\u80FD\u5305\u542B\u5BF9\u8BDD\u5185\u5BB9\u7684\u8BB0\u5FC6\u6570\u636E\uFF0C\u8BF7\u5728 GitHub \u63D0\u4EA4\u524D\u518D\u6B21\u68C0\u67E5\u3002"):null,h("a",{className:"sg-primary-link",href:ISSUE_URL+"?"+issueParams,target:"_blank",rel:"noopener noreferrer"},"\u5728 GitHub \u63D0\u4EA4 Issue")),h("section",{className:"sg-support-card"},h("h3",null,"\u529F\u80FD\u5EFA\u8BAE"),h("p",null,"\u63CF\u8FF0\u4F7F\u7528\u573A\u666F\u548C\u5E0C\u671B\u5B9E\u73B0\u7684\u884C\u4E3A\u3002"),h("a",{className:"sg-link",href:ISSUE_URL+"?"+featureParams,target:"_blank",rel:"noopener noreferrer"},"\u521B\u5EFA Feature Request \u2192")),h("section",{className:"sg-support-card"},h("h3",null,"\u4F7F\u7528\u7591\u95EE"),h("p",null,"\u5728 GitHub Discussion \u7684 Q&A \u533A\u4EA4\u6D41\u4F7F\u7528\u65B9\u6CD5\u3002"),h("a",{className:"sg-link",href:DISCUSSION_URL,target:"_blank",rel:"noopener noreferrer"},"\u524D\u5F80 Discussion / Q&A \u2192")))}function StructurePage({events,graph,openEvent,onBack}){return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u8BB0\u5FC6\u7ED3\u6784"),h("p",null,"\u5B8C\u6574\u6D4F\u89C8\u73B0\u6709\u7ED3\u6784\u5316\u8BB0\u5FC6")),h("div",{className:"sg-counts"},h("div",null,h("div",{className:"sg-count-value"},events.length),h("div",{className:"sg-count-label"},"\u7ECF\u5386 / Event")),h("div",null,h("div",{className:"sg-count-value"},graph.nodes.length),h("div",{className:"sg-count-label"},"\u77E5\u8BC6\u56FE\u8C31\u8282\u70B9"))),h("div",{className:"sg-structured-group"},h("h3",{className:"sg-section-title"},"\u7ECF\u5386"),events.map(event3=>h("button",{key:event3.id,className:"sg-related",onClick:()=>openEvent(event3)},h("span",null,event3.title),h("span",{className:"sg-related-time"},formatTime(event3.updatedAt))))),h("div",{className:"sg-structured-group"},h("h3",{className:"sg-section-title"},"\u56FE\u8C31\u8282\u70B9"),graph.nodes.map(node=>h("div",{key:node.id,className:"sg-related"},h("span",null,node.name),h("span",{className:"sg-related-time"},(node.sourceEventIds||[]).length+" \u6761\u652F\u6491\u4E8B\u4EF6")))))}function SystemPage({selected,blocks,onBack,refresh}){let processing=blocks.filter(block=>block.status==="processing").length;return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u7CFB\u7EDF\u72B6\u6001"),h("p",null,"\u4EC5\u5728\u8FD9\u91CC\u5C55\u793A\u8BB0\u5FC6\u5904\u7406\u7684\u5DE5\u7A0B\u72B6\u6001")),h("div",{className:"sg-pipeline"},[["Block \u6570\u91CF",selected.blocks],["\u5F85\u5904\u7406\u4EFB\u52A1",processing],["\u5931\u8D25\u4EFB\u52A1",selected.failedJobs],["\u6700\u8FD1\u6574\u7406\u65F6\u95F4",formatTime(selected.lastActivityAt)],["Event \u63D0\u53D6",selected.failedJobDetails?.some(item=>item.kind==="event-extraction")?"\u6709\u5931\u8D25":"\u6B63\u5E38"],["\u56FE\u8C31\u6295\u5F71",selected.failedJobDetails?.some(item=>item.kind==="graph-projection")?"\u6709\u5931\u8D25":"\u6B63\u5E38"]].map(([label,value])=>h("div",{key:label,className:"sg-stage"},h("span",null,label),h("span",{className:"sg-stage-value "+(label==="\u5931\u8D25\u4EFB\u52A1"&&value?"failed":"waiting")},String(value))))),h("button",{className:"sg-quiet-button",onClick:refresh,style:{marginTop:"14px"}},"\u21BB \u91CD\u65B0\u68C0\u67E5"))}function AuditPage({audit,onBack}){return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u4F7F\u7528\u8BB0\u5F55"),h("p",null,"\u957F\u671F\u8BB0\u5FC6\u88AB\u4F7F\u7528\u7684\u65F6\u95F4\u4E0E\u6765\u6E90")),audit.length?audit.map(item=>{let value=item.audit||{};return h("details",{key:item.id,className:"sg-audit"},h("summary",null,h("strong",null,"\u4F7F\u7528\u4E86 "+((item.events||[]).length+(item.elements||[]).length)+" \u6761\u8BB0\u5FC6"),h("span",{className:"sg-muted"}," \xB7 "+formatTime(item.createdAt))),h("div",{className:"sg-audit-body"},h("div",null,(item.events||[]).map(event3=>event3.title).join("\u3001")||(item.elements||[]).map(element3=>element3.name).join("\u3001")||"\u65E7\u7248\u4F7F\u7528\u8BB0\u5F55"),h("div",{className:"sg-tech-row sg-audit-evidence"},h("span",{className:"sg-muted"},"\u6765\u6E90\u4F1A\u8BDD"),h("span",{className:"sg-code"},value.sessionId||"\u672A\u8BB0\u5F55")),value.turn!==void 0?h("div",{className:"sg-tech-row"},h("span",{className:"sg-muted"},"Turn"),h("span",null,value.turn)):null))}):h(Empty,{title:"\u8FD8\u6CA1\u6709\u4F7F\u7528\u8BB0\u5F55",copy:"AI \u5728\u56DE\u7B54\u4E2D\u91C7\u7528\u957F\u671F\u8BB0\u5FC6\u540E\u4F1A\u8BB0\u5F55\u5728\u8FD9\u91CC\u3002"}))}function RawPage({data:data4,selected,onBack}){let groups=[["Block raw",data4.blocks],["Event raw",data4.events],["Graph raw",data4.graph],["Usage raw",data4.audit],["\u6A21\u578B\u54CD\u5E94",selected.successfulModelResponses||[]]];return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u539F\u59CB\u6570\u636E"),h("p",null,"\u4F9B\u6392\u67E5\u95EE\u9898\u4F7F\u7528\u7684\u5185\u90E8\u5B57\u6BB5\u4E0E JSON")),groups.map(([label,value])=>h("details",{key:label,className:"sg-raw-group"},h("summary",null,label+" ("+(Array.isArray(value)?value.length:(value.nodes?.length||0)+(value.edges?.length||0))+")"),h("pre",{className:"sg-raw-json sg-code"},JSON.stringify(value,null,2)))))}function SettingsPage({selected,namespace,onBack,updateLambda,savingLambda}){let[lambda,setLambda]=React.useState(String(selected.blockDecayLambda??.3));React.useEffect(()=>setLambda(String(selected.blockDecayLambda??.3)),[selected.blockDecayLambda]);let changeLambda=event3=>{let raw=event3.target.value;setLambda(raw);let value=Number(raw);raw!==""&&Number.isFinite(value)&&value>=0&&updateLambda(value)},rows=[["Schema \u7248\u672C","v"+selected.schemaVersion],["\u63D0\u53D6\u95F4\u9694","\u6BCF "+selected.blockTurnSize+" \u8F6E\u5F62\u6210\u4E00\u4E2A Block"],["\u6A21\u578B","\u7531 DSH \u5F53\u524D\u6A21\u578B\u914D\u7F6E\u63D0\u4F9B"],["\u5185\u90E8\u7A7A\u95F4 ID",namespace],["\u5DF2\u5904\u7406\u8F6E\u6B21",selected.currentTurn]];return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u9AD8\u7EA7\u8BBE\u7F6E"),h("p",null,"\u4FEE\u6539\u540E\u4F1A\u7ACB\u5373\u5E94\u7528\u5230\u6240\u6709\u5DF2\u6709\u5DE5\u4F5C\u533A\uFF0C\u5E76\u4F5C\u4E3A\u65B0\u5DE5\u4F5C\u533A\u7684\u9ED8\u8BA4\u503C\u3002")),h("div",{className:"sg-pipeline"},h("div",{className:"sg-stage"},h("span",null,"Block \u8870\u51CF\u7CFB\u6570 \u03BB"),h("span",{className:"sg-lambda-control"},h("input",{className:"sg-number-input",type:"number",min:"0",step:"0.05",value:lambda,onChange:changeLambda,"aria-label":"Block \u8870\u51CF\u7CFB\u6570 \u03BB"}),h("span",{className:"sg-stage-value waiting"},savingLambda?"\u4FDD\u5B58\u4E2D\u2026":"\u5DF2\u4FDD\u5B58"))),h("p",{className:"sg-setting-note"},"\u9ED8\u8BA4 0.3\uFF1B\u6570\u5B57\u8D8A\u5C0F\uFF0C\u8BB0\u5FC6\u9057\u5FD8\u8D8A\u6162\uFF0C\u6D88\u8017 token \u8D8A\u591A\uFF0C\u4E0D\u5EFA\u8BAE\u5927\u4E8E 0.4\u3002"),rows.map(([label,value])=>h("div",{key:label,className:"sg-stage"},h("span",null,label),h("span",{className:label==="\u5185\u90E8\u7A7A\u95F4 ID"?"sg-stage-value sg-code":"sg-stage-value"},String(value))))))}function MemoryPage({useWorkspaces,useSessions}){let workspaceItems=useWorkspaces(state=>state.items),sessionById=useSessions(state=>state.byId||{}),[overview,setOverview]=React.useState({namespaces:[]}),[namespace,setNamespace]=React.useState(""),[workspaceTitles,setWorkspaceTitles]=React.useState({}),[workspaceSessionIds,setWorkspaceSessionIds]=React.useState({}),[conversationId,setConversationId]=React.useState(""),[section,setSection]=React.useState("short"),[view,setView]=React.useState({name:"root"}),[data4,setData]=React.useState({events:[],graph:{nodes:[],edges:[],migration:null},blocks:[],openBlock:null,conversations:[],activeThreadId:null,audit:[]}),[query,setQuery]=React.useState(""),[source,setSource]=React.useState(null),[loading,setLoading]=React.useState(!0),[error3,setError]=React.useState(""),[recentError,setRecentError]=React.useState(""),[savingLambda,setSavingLambda]=React.useState(!1),reportError=reason=>{let message=String(reason?.message||reason);setError(message),setRecentError(message)};React.useEffect(()=>{let active=!0;return Promise.all((workspaceItems||[]).map(async workspace=>({key:await workspaceProjectKey(workspace.path),title:String(workspace.title||"").trim(),sessionIds:Array.isArray(workspace.sessionIds)?workspace.sessionIds.map(String):[]}))).then(entries=>{active&&(setWorkspaceTitles(Object.fromEntries(entries.filter(({key,title})=>key&&title).map(({key,title})=>[key,title]))),setWorkspaceSessionIds(Object.fromEntries(entries.filter(({key})=>key).map(({key,sessionIds})=>[key,sessionIds]))))}),()=>{active=!1}},[workspaceItems]);let loadOverview=React.useCallback(()=>(setError(""),api2("overview").then(next2=>(setOverview(next2),setNamespace(current=>next2.namespaces?.some(item=>item.namespace===current)?current:next2.namespaces?.[0]?.namespace||""),next2)).catch(reason=>(reportError(reason),null))),[]),loadMemoryData=React.useCallback((activeNamespace,options2={})=>{let background=options2.background===!0;return activeNamespace?(background||setLoading(!0),Promise.allSettled([api2("memories",{namespace:activeNamespace,kind:"events",limit:"200"}),api2("memories",{namespace:activeNamespace,kind:"graph"}),api2("memories",{namespace:activeNamespace,kind:"blocks",limit:"200",...options2.threadId?{threadId:options2.threadId}:{}}),api2("audit",{namespace:activeNamespace,limit:"100"})]).then(results=>{let[events,graph,blocks,audit]=results;setData(previous=>({events:events.status==="fulfilled"?events.value.items||[]:previous.events,graph:graph.status==="fulfilled"?graph.value:previous.graph,blocks:blocks.status==="fulfilled"?blocks.value.items||[]:previous.blocks,openBlock:blocks.status==="fulfilled"?blocks.value.openBlock||null:previous.openBlock,conversations:blocks.status==="fulfilled"?blocks.value.conversations||[]:previous.conversations,activeThreadId:blocks.status==="fulfilled"?blocks.value.activeThreadId||null:previous.activeThreadId,audit:audit.status==="fulfilled"?audit.value.items||[]:previous.audit})),blocks.status==="fulfilled"&&setConversationId(blocks.value.activeThreadId||"");let failure=results.find(result=>result.status==="rejected");failure&&failure.status==="rejected"?reportError(failure.reason):setError("")}).finally(()=>{background||setLoading(!1)})):(setData({events:[],graph:{nodes:[],edges:[],migration:null},blocks:[],openBlock:null,conversations:[],activeThreadId:null,audit:[]}),background||setLoading(!1),Promise.resolve())},[]);React.useEffect(()=>{setLoading(!0),loadOverview().finally(()=>setLoading(!1))},[]),React.useEffect(()=>{setConversationId(""),setView({name:"root"}),setSource(null),setData({events:[],graph:{nodes:[],edges:[],migration:null},blocks:[],openBlock:null,conversations:[],activeThreadId:null,audit:[]}),loadMemoryData(namespace)},[namespace]),React.useEffect(()=>{if(!namespace)return;let timer=window.setInterval(()=>{Promise.all([loadOverview(),loadMemoryData(namespace,{background:!0,threadId:conversationId})])},2500);return()=>window.clearInterval(timer)},[namespace,conversationId,loadOverview,loadMemoryData]);let selected=(overview.namespaces||[]).find(item=>item.namespace===namespace),project=projectName(selected||namespace,workspaceTitles),activeProjectKey=namespace.includes(":project:")?namespace.split(":project:").pop():"",hostSessionIds=workspaceSessionIds[activeProjectKey]||[],memoryConversations=new Map(data4.conversations.map(conversation=>[conversation.id,conversation])),conversations=[],seenConversations=new Set;for(let id2 of hostSessionIds){let session=sessionById[id2];if(session?.parentId)continue;let memory=memoryConversations.get(id2),dshTitle=String(session?.title||"").trim();conversations.push({...memory||{},id:id2,label:dshTitle||memory?.label||"\u5BF9\u8BDD "+id2.slice(0,8)}),seenConversations.add(id2)}for(let memory of data4.conversations)seenConversations.has(memory.id)||conversations.push(memory);conversations.sort((left,right)=>left.id==="__legacy__"?1:right.id==="__legacy__"?-1:0);let failedCount=Number(selected?.failedJobs||0),processing=!error3&&(Number(selected?.processingJobs||0)>0||data4.blocks.some(block=>block.status==="processing")),goSection=next2=>{setSection(next2),setView({name:"root"}),setSource(null)},sourceParams=(kind,item)=>kind==="event"?{eventId:item.id}:kind==="element"?{elementId:item.id}:{blockId:item.id},loadSource=(kind,item)=>{setSource(null),api2("sources",{namespace,...sourceParams(kind,item)}).then(setSource).catch(reportError)},openWithSource=(kind,item)=>{setView(current=>({name:kind,item,back:current})),loadSource(kind,item)},openEvent=event3=>openWithSource("event",data4.events.find(item=>item.id===event3.id)||event3),goBack=()=>{let previous=view.back||{name:"root"};setView(previous),previous.item&&["event","block"].includes(previous.name)?loadSource(previous.name,previous.item):setSource(null)},backLabel=view.back?.name==="block"?"\u77ED\u671F\u8BB0\u5FC6":view.back?.name==="event"?"\u957F\u671F\u8BB0\u5FC6":view.back?.name==="structure"?"\u8BB0\u5FC6\u7ED3\u6784":section==="short"?"\u77ED\u671F\u8BB0\u5FC6":"\u957F\u671F\u8BB0\u5FC6",refresh=()=>Promise.all([loadOverview(),loadMemoryData(namespace,{threadId:conversationId})]),selectConversation=nextConversationId=>(setConversationId(nextConversationId),setLoading(!0),setError(""),api2("memories",{namespace,kind:"blocks",limit:"200",threadId:nextConversationId}).then(blocks=>{setConversationId(blocks.activeThreadId||""),setData(previous=>({...previous,blocks:blocks.items||[],openBlock:blocks.openBlock||null,conversations:blocks.conversations||[],activeThreadId:blocks.activeThreadId||null}))}).catch(reportError).finally(()=>setLoading(!1))),updateLambda=value=>(setSavingLambda(!0),setError(""),api2("settings",{blockDecayLambda:value},{method:"PATCH"}).then(loadOverview).catch(reportError).finally(()=>setSavingLambda(!1))),moreBack=()=>setView({name:"root"}),content=null;return loading&&!selected?content=h(Loading):selected?view.name==="event"?content=h(EventDetail,{event:view.item,project,source,onBack:goBack,backLabel}):view.name==="status"?content=h(ProcessingStatus,{overview:selected,blocks:data4.blocks,onBack:()=>setView({name:"root"}),refresh}):view.name==="import"?content=h(ImportPage,{namespace,onBack:moreBack,refresh}):view.name==="structure"?content=h(StructurePage,{events:data4.events,graph:data4.graph,openEvent,onBack:moreBack}):view.name==="system"?content=h(SystemPage,{selected,blocks:data4.blocks,onBack:moreBack,refresh}):view.name==="audit"?content=h(AuditPage,{audit:data4.audit,onBack:moreBack}):view.name==="raw"?content=h(RawPage,{data:data4,selected,onBack:moreBack}):view.name==="settings"?content=h(SettingsPage,{selected,namespace,onBack:moreBack,updateLambda,savingLambda}):view.name==="support"?content=h(SupportPage,{overview,selected,project,data:data4,recentError,onBack:moreBack}):content=h(React.Fragment,null,h(FailureAlert,{count:failedCount,onOpen:()=>setView({name:"status"})}),loading?h(Loading):section==="short"?h(ShortTermPage,{key:namespace+":"+conversationId,blocks:data4.blocks,openBlock:data4.openBlock,conversations,activeThreadId:conversationId||data4.activeThreadId||"",namespace,onConversationChange:selectConversation,refresh}):section==="long"?h(LongTermPage,{events:data4.events,graph:data4.graph,project,query,setQuery,openEvent}):h(MoreHome,{setView})):content=h(Empty,{title:"\u8FD8\u6CA1\u6709\u8BB0\u5FC6",copy:"\u5B8C\u6210\u4E00\u4E9B DSH \u5BF9\u8BDD\u540E\uFF0C\u77ED\u671F\u8BB0\u5FC6\u548C\u957F\u671F\u8BB0\u5FC6\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002"}),h("main",{className:"sg-memory","data-testid":"stratagate-memory-ui"},h("style",null,css),h("header",{className:"sg-header"},h("a",{className:"sg-brand",href:STAR_REPOSITORY_URL,target:"_blank",rel:"noopener noreferrer"},h("img",{className:"sg-logo",src:MASCOT_DATA_URL,alt:"StrataGate \u5409\u7965\u7269"}),h("span",{className:"sg-brand-copy"},h("span",{className:"sg-brand-name"},"StrataGate-AgentMemory"),h("span",{className:"sg-brand-kicker"},"\u6709\u6765\u6E90\u3001\u53EF\u8FFD\u6EAF\u7684\u8DE8\u4F1A\u8BDD\u8BB0\u5FC6"))),h("div",{className:"sg-header-usage"},h("span",{className:"sg-usage-count","aria-label":"StrataGate \u5DF2\u5728\u5F53\u524D\u5DE5\u4F5C\u533A\u4E2D\u5E2E\u52A9\u4F7F\u7528\u8BB0\u5FC6 "+Number(selected?.memoryUseCount||0)+" \u6B21\u3002"},h("strong",{className:"sg-usage-number"},Number(selected?.memoryUseCount||0)),h("span",null,"\u6B21\u8BB0\u5FC6\u91C7\u7528")),h("a",{className:"sg-header-star",href:STAR_REPOSITORY_URL,target:"_blank",rel:"noopener noreferrer"},"\u4E3A StrataGate \u70B9 \u{1F31F}\u{1F31F}"))),h("div",{className:"sg-project"},h("span",{className:"sg-project-label"},"\u5F53\u524D\u5DE5\u4F5C\u533A\uFF1A"),h("select",{className:"sg-project-select",value:namespace,onChange:event3=>setNamespace(event3.target.value),"aria-label":"\u5F53\u524D\u5DE5\u4F5C\u533A"},(overview.namespaces||[]).map(item=>h("option",{key:item.namespace,value:item.namespace},projectName(item,workspaceTitles))))),h("nav",{className:"sg-tabs","aria-label":"\u8BB0\u5FC6\u89C6\u56FE"},[["short","\u77ED\u671F\u8BB0\u5FC6"],["long","\u957F\u671F\u8BB0\u5FC6"],["more","\u66F4\u591A"]].map(([id2,label])=>h("button",{key:id2,type:"button",className:"sg-tab "+(section===id2?"active":""),"aria-current":section===id2?"page":void 0,onClick:()=>goSection(id2)},label))),error3?h("div",{className:"sg-error"},h("div",{className:"sg-error-title"},"\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u5B8C\u6574\u8BB0\u5FC6"),h("div",null,"\u5DF2\u663E\u793A\u80FD\u591F\u8BFB\u53D6\u7684\u5185\u5BB9\uFF0C\u8BF7\u7A0D\u540E\u91CD\u65B0\u52A0\u8F7D\u3002"),h("details",null,h("summary",null,"\u6280\u672F\u8BE6\u60C5"),h("div",{className:"sg-code"},error3))):null,h(ProcessingAlert,{visible:processing}),h("section",{key:section+":"+view.name,className:"sg-view","aria-label":"StrataGate \u8BB0\u5FC6\u5185\u5BB9"},content),h("footer",{className:"sg-footer"},"\u53D1\u73B0\u95EE\u9898\uFF1F ",h("button",{type:"button",onClick:()=>{setSection("more"),setView({name:"support"}),setSource(null)}},"\u63D0\u4EA4\u53CD\u9988")))}function apply2(ctx){let slots=ctx.get("slots");slots&&slots.inject("settings.section",()=>slots.register({name:"settings.section",id:"stratagate-memory",order:32,label:()=>"StrataGate-AgentMemory"},props=>h(MemoryPage,props)))}return exports.name="stratagate-dsh",exports.inject=["slots"],exports.apply=apply2,module.exports}});})();
400
+ `)}),featureParams=new URLSearchParams({title:"[Feature] StrataGate\uFF1A",body:"\u8BF7\u63CF\u8FF0\u5E0C\u671B\u589E\u52A0\u7684\u80FD\u529B\u3001\u4F7F\u7528\u573A\u666F\u548C\u9884\u671F\u884C\u4E3A\u3002"});return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u53CD\u9988\u4E0E\u652F\u6301"),h("p",null,"\u9009\u62E9\u6700\u5408\u9002\u7684\u5165\u53E3\uFF0C\u6211\u4EEC\u4F1A\u5E26\u4E0A\u5FC5\u8981\u4E14\u5B89\u5168\u7684\u4E0A\u4E0B\u6587\u3002")),h("div",{className:"sg-privacy-note"},"\u57FA\u7840\u8BCA\u65AD\u4E0D\u4F1A\u9644\u5E26\u539F\u59CB\u804A\u5929\u3001L5\u3001Event \u6216 Graph \u5185\u5BB9\u3002"),h("section",{className:"sg-support-card"},h("h3",null,"\u9047\u5230\u95EE\u9898"),h("p",null,"\u63D2\u4EF6\u4F1A\u6574\u7406\u7248\u672C\u3001\u914D\u7F6E\u3001\u6570\u91CF\u548C\u6700\u8FD1\u9519\u8BEF\uFF0C\u5E2E\u52A9\u5FEB\u901F\u5B9A\u4F4D\u3002"),h("label",{className:"sg-check"},h("input",{type:"checkbox",checked:includeLogs,onChange:event3=>setIncludeLogs(event3.target.checked)}),h("span",null,"\u9644\u52A0\u8BCA\u65AD\u65E5\u5FD7")),h("label",{className:"sg-check"},h("input",{type:"checkbox",checked:includeMemory,onChange:event3=>setIncludeMemory(event3.target.checked)}),h("span",null,"\u9644\u52A0\u8BB0\u5FC6\u6570\u636E\uFF08\u53EF\u80FD\u5305\u542B\u5BF9\u8BDD\u5185\u5BB9\uFF09")),includeMemory?h("div",{className:"sg-error-note"},"\u4F60\u5DF2\u9009\u62E9\u9644\u52A0\u53EF\u80FD\u5305\u542B\u5BF9\u8BDD\u5185\u5BB9\u7684\u8BB0\u5FC6\u6570\u636E\uFF0C\u8BF7\u5728 GitHub \u63D0\u4EA4\u524D\u518D\u6B21\u68C0\u67E5\u3002"):null,h("a",{className:"sg-primary-link",href:ISSUE_URL+"?"+issueParams,target:"_blank",rel:"noopener noreferrer"},"\u5728 GitHub \u63D0\u4EA4 Issue")),h("section",{className:"sg-support-card"},h("h3",null,"\u529F\u80FD\u5EFA\u8BAE"),h("p",null,"\u63CF\u8FF0\u4F7F\u7528\u573A\u666F\u548C\u5E0C\u671B\u5B9E\u73B0\u7684\u884C\u4E3A\u3002"),h("a",{className:"sg-link",href:ISSUE_URL+"?"+featureParams,target:"_blank",rel:"noopener noreferrer"},"\u521B\u5EFA Feature Request \u2192")),h("section",{className:"sg-support-card"},h("h3",null,"\u4F7F\u7528\u7591\u95EE"),h("p",null,"\u5728 GitHub Discussion \u7684 Q&A \u533A\u4EA4\u6D41\u4F7F\u7528\u65B9\u6CD5\u3002"),h("a",{className:"sg-link",href:DISCUSSION_URL,target:"_blank",rel:"noopener noreferrer"},"\u524D\u5F80 Discussion / Q&A \u2192")))}function StructurePage({events,graph,openEvent,onBack}){return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u8BB0\u5FC6\u7ED3\u6784"),h("p",null,"\u5B8C\u6574\u6D4F\u89C8\u73B0\u6709\u7ED3\u6784\u5316\u8BB0\u5FC6")),h("div",{className:"sg-counts"},h("div",null,h("div",{className:"sg-count-value"},events.length),h("div",{className:"sg-count-label"},"\u7ECF\u5386 / Event")),h("div",null,h("div",{className:"sg-count-value"},graph.nodes.length),h("div",{className:"sg-count-label"},"\u77E5\u8BC6\u56FE\u8C31\u8282\u70B9"))),h("div",{className:"sg-structured-group"},h("h3",{className:"sg-section-title"},"\u7ECF\u5386"),events.map(event3=>h("button",{key:event3.id,className:"sg-related",onClick:()=>openEvent(event3)},h("span",null,event3.title),h("span",{className:"sg-related-time"},formatTime(event3.updatedAt))))),h("div",{className:"sg-structured-group"},h("h3",{className:"sg-section-title"},"\u56FE\u8C31\u8282\u70B9"),graph.nodes.map(node=>h("div",{key:node.id,className:"sg-related"},h("span",null,node.name),h("span",{className:"sg-related-time"},(node.sourceEventIds||[]).length+" \u6761\u652F\u6491\u4E8B\u4EF6")))))}function SystemPage({selected,blocks,onBack,refresh}){let processing=blocks.filter(block=>block.status==="processing").length;return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u7CFB\u7EDF\u72B6\u6001"),h("p",null,"\u4EC5\u5728\u8FD9\u91CC\u5C55\u793A\u8BB0\u5FC6\u5904\u7406\u7684\u5DE5\u7A0B\u72B6\u6001")),h("div",{className:"sg-pipeline"},[["Block \u6570\u91CF",selected.blocks],["\u5F85\u5904\u7406\u4EFB\u52A1",processing],["\u5931\u8D25\u4EFB\u52A1",selected.failedJobs],["\u6700\u8FD1\u6574\u7406\u65F6\u95F4",formatTime(selected.lastActivityAt)],["Event \u63D0\u53D6",selected.failedJobDetails?.some(item=>item.kind==="event-extraction")?"\u6709\u5931\u8D25":"\u6B63\u5E38"],["\u56FE\u8C31\u6295\u5F71",selected.failedJobDetails?.some(item=>item.kind==="graph-projection")?"\u6709\u5931\u8D25":"\u6B63\u5E38"]].map(([label,value])=>h("div",{key:label,className:"sg-stage"},h("span",null,label),h("span",{className:"sg-stage-value "+(label==="\u5931\u8D25\u4EFB\u52A1"&&value?"failed":"waiting")},String(value))))),h("button",{className:"sg-quiet-button",onClick:refresh,style:{marginTop:"14px"}},"\u21BB \u91CD\u65B0\u68C0\u67E5"))}function AuditPage({audit,onBack}){return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u4F7F\u7528\u8BB0\u5F55"),h("p",null,"\u957F\u671F\u8BB0\u5FC6\u88AB\u4F7F\u7528\u7684\u65F6\u95F4\u4E0E\u6765\u6E90")),audit.length?audit.map(item=>{let value=item.audit||{};return h("details",{key:item.id,className:"sg-audit"},h("summary",null,h("strong",null,"\u4F7F\u7528\u4E86 "+((item.events||[]).length+(item.elements||[]).length)+" \u6761\u8BB0\u5FC6"),h("span",{className:"sg-muted"}," \xB7 "+formatTime(item.createdAt))),h("div",{className:"sg-audit-body"},h("div",null,(item.events||[]).map(event3=>event3.title).join("\u3001")||(item.elements||[]).map(element3=>element3.name).join("\u3001")||"\u65E7\u7248\u4F7F\u7528\u8BB0\u5F55"),h("div",{className:"sg-tech-row sg-audit-evidence"},h("span",{className:"sg-muted"},"\u6765\u6E90\u4F1A\u8BDD"),h("span",{className:"sg-code"},value.sessionId||"\u672A\u8BB0\u5F55")),value.turn!==void 0?h("div",{className:"sg-tech-row"},h("span",{className:"sg-muted"},"Turn"),h("span",null,value.turn)):null))}):h(Empty,{title:"\u8FD8\u6CA1\u6709\u4F7F\u7528\u8BB0\u5F55",copy:"AI \u5728\u56DE\u7B54\u4E2D\u91C7\u7528\u957F\u671F\u8BB0\u5FC6\u540E\u4F1A\u8BB0\u5F55\u5728\u8FD9\u91CC\u3002"}))}function RawPage({data:data4,selected,onBack}){let groups=[["Block raw",data4.blocks],["Event raw",data4.events],["Graph raw",data4.graph],["Usage raw",data4.audit],["\u6A21\u578B\u54CD\u5E94",selected.successfulModelResponses||[]]];return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u539F\u59CB\u6570\u636E"),h("p",null,"\u4F9B\u6392\u67E5\u95EE\u9898\u4F7F\u7528\u7684\u5185\u90E8\u5B57\u6BB5\u4E0E JSON")),groups.map(([label,value])=>h("details",{key:label,className:"sg-raw-group"},h("summary",null,label+" ("+(Array.isArray(value)?value.length:(value.nodes?.length||0)+(value.edges?.length||0))+")"),h("pre",{className:"sg-raw-json sg-code"},JSON.stringify(value,null,2)))))}function SettingsPage({selected,namespace,onBack,updateSettings,savingSettings}){let[turnSize,setTurnSize]=React.useState(String(selected.blockTurnSize??6)),[lambda,setLambda]=React.useState(String(selected.blockDecayLambda??.3));React.useEffect(()=>{setTurnSize(String(selected.blockTurnSize??6)),setLambda(String(selected.blockDecayLambda??.3))},[selected.blockTurnSize,selected.blockDecayLambda]);let turnSizeValue=Number(turnSize),lambdaValue=Number(lambda),changed=Number.isSafeInteger(turnSizeValue)&&turnSizeValue>=1&&lambda!==""&&Number.isFinite(lambdaValue)&&lambdaValue>=0&&(turnSizeValue!==selected.blockTurnSize||lambdaValue!==selected.blockDecayLambda),suggestedLambda=Math.round((selected.blockDecayLambda??.3)*turnSizeValue/(selected.blockTurnSize||6)/.05)*.05,showSuggestion=Number.isSafeInteger(turnSizeValue)&&turnSizeValue>=1&&turnSizeValue!==selected.blockTurnSize,rows=[["Schema \u7248\u672C","v"+selected.schemaVersion],["\u6A21\u578B","\u7531 DSH \u5F53\u524D\u6A21\u578B\u914D\u7F6E\u63D0\u4F9B"],["\u5185\u90E8\u7A7A\u95F4 ID",namespace],["\u5DF2\u5904\u7406\u8F6E\u6B21",selected.currentTurn]];return h(React.Fragment,null,h(BackBar,{label:"\u66F4\u591A",onBack}),h("div",{className:"sg-intro"},h("h2",null,"\u9AD8\u7EA7\u8BBE\u7F6E"),h("p",null,"\u4FEE\u6539\u540E\u4F1A\u7ACB\u5373\u5E94\u7528\u5230\u6240\u6709\u5DF2\u6709\u5DE5\u4F5C\u533A\uFF0C\u5E76\u4F5C\u4E3A\u65B0\u5DE5\u4F5C\u533A\u7684\u9ED8\u8BA4\u503C\u3002")),h("div",{className:"sg-pipeline"},h("div",{className:"sg-stage"},h("span",null,"\u6BCF\u4E2A Block \u7684\u5BF9\u8BDD\u8F6E\u6570"),h("span",{className:"sg-lambda-control"},h("input",{className:"sg-number-input",type:"number",min:"1",step:"1",value:turnSize,onChange:event3=>setTurnSize(event3.target.value),"aria-label":"\u6BCF\u4E2A Block \u7684\u5BF9\u8BDD\u8F6E\u6570"}),h("span",{className:"sg-stage-value waiting"},"\u8F6E"))),h("p",{className:"sg-setting-note"},"1 \u8F6E\u662F\u4E00\u6B21\u7528\u6237\u63D0\u95EE\u548C AI \u5B8C\u6574\u56DE\u590D\u3002\u8F6E\u6570\u8D8A\u5C0F\uFF0CBlock \u751F\u6210\u8D8A\u9891\u7E41\uFF0C\u4E5F\u4F1A\u8BA9\u76F8\u540C\u957F\u5EA6\u7684\u5BF9\u8BDD\u8870\u51CF\u5F97\u66F4\u5FEB\uFF1B\u5DF2\u6709 Block \u4E0D\u4F1A\u91CD\u65B0\u5207\u5206\uFF0C\u5C1A\u672A\u5C01\u5B58\u7684\u5185\u5BB9\u6309\u65B0\u9608\u503C\u7EE7\u7EED\u5904\u7406\u3002"),h("div",{className:"sg-stage"},h("span",null,"Block \u8870\u51CF\u7CFB\u6570 \u03BB"),h("span",{className:"sg-lambda-control"},h("input",{className:"sg-number-input",type:"number",min:"0",step:"0.05",value:lambda,onChange:event3=>setLambda(event3.target.value),"aria-label":"Block \u8870\u51CF\u7CFB\u6570 \u03BB"}))),h("p",{className:"sg-setting-note"},"\u9ED8\u8BA4 0.3\uFF1B\u6570\u5B57\u8D8A\u5C0F\uFF0C\u8BB0\u5FC6\u9057\u5FD8\u8D8A\u6162\uFF0C\u6D88\u8017 token \u8D8A\u591A\uFF0C\u4E0D\u5EFA\u8BAE\u5927\u4E8E 0.4\u3002"),showSuggestion?h("div",{className:"sg-setting-suggestion"},h("span",null,"\u4E3A\u4FDD\u6301\u6309\u5BF9\u8BDD\u8F6E\u6570\u8BA1\u7B97\u7684\u9057\u5FD8\u901F\u5EA6\uFF0C\u5EFA\u8BAE \u03BB \u8C03\u6574\u4E3A "+suggestedLambda.toFixed(2)+"\u3002"),h("button",{type:"button",className:"sg-quiet-button",onClick:()=>setLambda(String(Number(suggestedLambda.toFixed(2))))},"\u91C7\u7528\u5EFA\u8BAE\u503C")):null,rows.map(([label,value])=>h("div",{key:label,className:"sg-stage"},h("span",null,label),h("span",{className:label==="\u5185\u90E8\u7A7A\u95F4 ID"?"sg-stage-value sg-code":"sg-stage-value"},String(value)))),h("button",{type:"button",className:"sg-save-button",disabled:!changed||savingSettings,onClick:()=>{updateSettings({blockTurnSize:turnSizeValue,blockDecayLambda:lambdaValue})}},savingSettings?"\u4FDD\u5B58\u4E2D\u2026":changed?"\u4FDD\u5B58\u8BBE\u7F6E":"\u5DF2\u4FDD\u5B58")))}function MemoryPage({useWorkspaces,useSessions}){let workspaceItems=useWorkspaces(state=>state.items),sessionById=useSessions(state=>state.byId||{}),[overview,setOverview]=React.useState({namespaces:[]}),[namespace,setNamespace]=React.useState(""),[workspaceTitles,setWorkspaceTitles]=React.useState({}),[workspaceSessionIds,setWorkspaceSessionIds]=React.useState({}),[conversationId,setConversationId]=React.useState(""),[section,setSection]=React.useState("short"),[view,setView]=React.useState({name:"root"}),[data4,setData]=React.useState({events:[],graph:{nodes:[],edges:[],migration:null},blocks:[],openBlock:null,conversations:[],activeThreadId:null,audit:[]}),[query,setQuery]=React.useState(""),[source,setSource]=React.useState(null),[loading,setLoading]=React.useState(!0),[error3,setError]=React.useState(""),[recentError,setRecentError]=React.useState(""),[savingSettings,setSavingSettings]=React.useState(!1),reportError=reason=>{let message=String(reason?.message||reason);setError(message),setRecentError(message)};React.useEffect(()=>{let active=!0;return Promise.all((workspaceItems||[]).map(async workspace=>({key:await workspaceProjectKey(workspace.path),title:String(workspace.title||"").trim(),sessionIds:Array.isArray(workspace.sessionIds)?workspace.sessionIds.map(String):[]}))).then(entries=>{active&&(setWorkspaceTitles(Object.fromEntries(entries.filter(({key,title})=>key&&title).map(({key,title})=>[key,title]))),setWorkspaceSessionIds(Object.fromEntries(entries.filter(({key})=>key).map(({key,sessionIds})=>[key,sessionIds]))))}),()=>{active=!1}},[workspaceItems]);let loadOverview=React.useCallback(()=>(setError(""),api2("overview").then(next2=>(setOverview(next2),setNamespace(current=>next2.namespaces?.some(item=>item.namespace===current)?current:next2.namespaces?.[0]?.namespace||""),next2)).catch(reason=>(reportError(reason),null))),[]),loadMemoryData=React.useCallback((activeNamespace,options2={})=>{let background=options2.background===!0;return activeNamespace?(background||setLoading(!0),Promise.allSettled([api2("memories",{namespace:activeNamespace,kind:"events",limit:"200"}),api2("memories",{namespace:activeNamespace,kind:"graph"}),api2("memories",{namespace:activeNamespace,kind:"blocks",limit:"200",...options2.threadId?{threadId:options2.threadId}:{}}),api2("audit",{namespace:activeNamespace,limit:"100"})]).then(results=>{let[events,graph,blocks,audit]=results;setData(previous=>({events:events.status==="fulfilled"?events.value.items||[]:previous.events,graph:graph.status==="fulfilled"?graph.value:previous.graph,blocks:blocks.status==="fulfilled"?blocks.value.items||[]:previous.blocks,openBlock:blocks.status==="fulfilled"?blocks.value.openBlock||null:previous.openBlock,conversations:blocks.status==="fulfilled"?blocks.value.conversations||[]:previous.conversations,activeThreadId:blocks.status==="fulfilled"?blocks.value.activeThreadId||null:previous.activeThreadId,audit:audit.status==="fulfilled"?audit.value.items||[]:previous.audit})),blocks.status==="fulfilled"&&setConversationId(blocks.value.activeThreadId||"");let failure=results.find(result=>result.status==="rejected");failure&&failure.status==="rejected"?reportError(failure.reason):setError("")}).finally(()=>{background||setLoading(!1)})):(setData({events:[],graph:{nodes:[],edges:[],migration:null},blocks:[],openBlock:null,conversations:[],activeThreadId:null,audit:[]}),background||setLoading(!1),Promise.resolve())},[]);React.useEffect(()=>{setLoading(!0),loadOverview().finally(()=>setLoading(!1))},[]),React.useEffect(()=>{setConversationId(""),setView({name:"root"}),setSource(null),setData({events:[],graph:{nodes:[],edges:[],migration:null},blocks:[],openBlock:null,conversations:[],activeThreadId:null,audit:[]}),loadMemoryData(namespace)},[namespace]),React.useEffect(()=>{if(!namespace)return;let timer=window.setInterval(()=>{Promise.all([loadOverview(),loadMemoryData(namespace,{background:!0,threadId:conversationId})])},2500);return()=>window.clearInterval(timer)},[namespace,conversationId,loadOverview,loadMemoryData]);let selected=(overview.namespaces||[]).find(item=>item.namespace===namespace),project=projectName(selected||namespace,workspaceTitles),activeProjectKey=namespace.includes(":project:")?namespace.split(":project:").pop():"",hostSessionIds=workspaceSessionIds[activeProjectKey]||[],memoryConversations=new Map(data4.conversations.map(conversation=>[conversation.id,conversation])),conversations=[],seenConversations=new Set;for(let id2 of hostSessionIds){let session=sessionById[id2];if(session?.parentId)continue;let memory=memoryConversations.get(id2),dshTitle=String(session?.title||"").trim();conversations.push({...memory||{},id:id2,label:dshTitle||memory?.label||"\u5BF9\u8BDD "+id2.slice(0,8)}),seenConversations.add(id2)}for(let memory of data4.conversations)seenConversations.has(memory.id)||conversations.push(memory);conversations.sort((left,right)=>left.id==="__legacy__"?1:right.id==="__legacy__"?-1:0);let failedCount=Number(selected?.failedJobs||0),processing=!error3&&(Number(selected?.processingJobs||0)>0||data4.blocks.some(block=>block.status==="processing")),goSection=next2=>{setSection(next2),setView({name:"root"}),setSource(null)},sourceParams=(kind,item)=>kind==="event"?{eventId:item.id}:kind==="element"?{elementId:item.id}:{blockId:item.id},loadSource=(kind,item)=>{setSource(null),api2("sources",{namespace,...sourceParams(kind,item)}).then(setSource).catch(reportError)},openWithSource=(kind,item)=>{setView(current=>({name:kind,item,back:current})),loadSource(kind,item)},openEvent=event3=>openWithSource("event",data4.events.find(item=>item.id===event3.id)||event3),goBack=()=>{let previous=view.back||{name:"root"};setView(previous),previous.item&&["event","block"].includes(previous.name)?loadSource(previous.name,previous.item):setSource(null)},backLabel=view.back?.name==="block"?"\u77ED\u671F\u8BB0\u5FC6":view.back?.name==="event"?"\u957F\u671F\u8BB0\u5FC6":view.back?.name==="structure"?"\u8BB0\u5FC6\u7ED3\u6784":section==="short"?"\u77ED\u671F\u8BB0\u5FC6":"\u957F\u671F\u8BB0\u5FC6",refresh=()=>Promise.all([loadOverview(),loadMemoryData(namespace,{threadId:conversationId})]),selectConversation=nextConversationId=>(setConversationId(nextConversationId),setLoading(!0),setError(""),api2("memories",{namespace,kind:"blocks",limit:"200",threadId:nextConversationId}).then(blocks=>{setConversationId(blocks.activeThreadId||""),setData(previous=>({...previous,blocks:blocks.items||[],openBlock:blocks.openBlock||null,conversations:blocks.conversations||[],activeThreadId:blocks.activeThreadId||null}))}).catch(reportError).finally(()=>setLoading(!1))),updateSettings=values=>(setSavingSettings(!0),setError(""),api2("settings",values,{method:"PATCH"}).then(loadOverview).catch(reportError).finally(()=>setSavingSettings(!1))),moreBack=()=>setView({name:"root"}),content=null;return loading&&!selected?content=h(Loading):selected?view.name==="event"?content=h(EventDetail,{event:view.item,project,source,onBack:goBack,backLabel}):view.name==="status"?content=h(ProcessingStatus,{overview:selected,blocks:data4.blocks,onBack:()=>setView({name:"root"}),refresh}):view.name==="import"?content=h(ImportPage,{namespace,onBack:moreBack,refresh}):view.name==="structure"?content=h(StructurePage,{events:data4.events,graph:data4.graph,openEvent,onBack:moreBack}):view.name==="system"?content=h(SystemPage,{selected,blocks:data4.blocks,onBack:moreBack,refresh}):view.name==="audit"?content=h(AuditPage,{audit:data4.audit,onBack:moreBack}):view.name==="raw"?content=h(RawPage,{data:data4,selected,onBack:moreBack}):view.name==="settings"?content=h(SettingsPage,{selected,namespace,onBack:moreBack,updateSettings,savingSettings}):view.name==="support"?content=h(SupportPage,{overview,selected,project,data:data4,recentError,onBack:moreBack}):content=h(React.Fragment,null,h(FailureAlert,{count:failedCount,onOpen:()=>setView({name:"status"})}),loading?h(Loading):section==="short"?h(ShortTermPage,{key:namespace+":"+conversationId,blocks:data4.blocks,openBlock:data4.openBlock,conversations,activeThreadId:conversationId||data4.activeThreadId||"",namespace,onConversationChange:selectConversation,refresh}):section==="long"?h(LongTermPage,{events:data4.events,graph:data4.graph,project,query,setQuery,openEvent}):h(MoreHome,{setView})):content=h(Empty,{title:"\u8FD8\u6CA1\u6709\u8BB0\u5FC6",copy:"\u5B8C\u6210\u4E00\u4E9B DSH \u5BF9\u8BDD\u540E\uFF0C\u77ED\u671F\u8BB0\u5FC6\u548C\u957F\u671F\u8BB0\u5FC6\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002"}),h("main",{className:"sg-memory","data-testid":"stratagate-memory-ui"},h("style",null,css),h("header",{className:"sg-header"},h("a",{className:"sg-brand",href:STAR_REPOSITORY_URL,target:"_blank",rel:"noopener noreferrer"},h("img",{className:"sg-logo",src:MASCOT_DATA_URL,alt:"StrataGate \u5409\u7965\u7269"}),h("span",{className:"sg-brand-copy"},h("span",{className:"sg-brand-name"},"StrataGate-AgentMemory"),h("span",{className:"sg-brand-kicker"},"\u6709\u6765\u6E90\u3001\u53EF\u8FFD\u6EAF\u7684\u8DE8\u4F1A\u8BDD\u8BB0\u5FC6"))),h("div",{className:"sg-header-usage"},h("span",{className:"sg-usage-count","aria-label":"StrataGate \u5DF2\u5728\u5F53\u524D\u5DE5\u4F5C\u533A\u4E2D\u5E2E\u52A9\u4F7F\u7528\u8BB0\u5FC6 "+Number(selected?.memoryUseCount||0)+" \u6B21\u3002"},h("strong",{className:"sg-usage-number"},Number(selected?.memoryUseCount||0)),h("span",null,"\u6B21\u8BB0\u5FC6\u91C7\u7528")),h("a",{className:"sg-header-star",href:STAR_REPOSITORY_URL,target:"_blank",rel:"noopener noreferrer"},"\u4E3A StrataGate \u70B9 \u{1F31F}\u{1F31F}"))),h("div",{className:"sg-project"},h("span",{className:"sg-project-label"},"\u5F53\u524D\u5DE5\u4F5C\u533A\uFF1A"),h("select",{className:"sg-project-select",value:namespace,onChange:event3=>setNamespace(event3.target.value),"aria-label":"\u5F53\u524D\u5DE5\u4F5C\u533A"},(overview.namespaces||[]).map(item=>h("option",{key:item.namespace,value:item.namespace},projectName(item,workspaceTitles))))),h("nav",{className:"sg-tabs","aria-label":"\u8BB0\u5FC6\u89C6\u56FE"},[["short","\u77ED\u671F\u8BB0\u5FC6"],["long","\u957F\u671F\u8BB0\u5FC6"],["more","\u66F4\u591A"]].map(([id2,label])=>h("button",{key:id2,type:"button",className:"sg-tab "+(section===id2?"active":""),"aria-current":section===id2?"page":void 0,onClick:()=>goSection(id2)},label))),error3?h("div",{className:"sg-error"},h("div",{className:"sg-error-title"},"\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u5B8C\u6574\u8BB0\u5FC6"),h("div",null,"\u5DF2\u663E\u793A\u80FD\u591F\u8BFB\u53D6\u7684\u5185\u5BB9\uFF0C\u8BF7\u7A0D\u540E\u91CD\u65B0\u52A0\u8F7D\u3002"),h("details",null,h("summary",null,"\u6280\u672F\u8BE6\u60C5"),h("div",{className:"sg-code"},error3))):null,h(ProcessingAlert,{visible:processing}),h("section",{key:section+":"+view.name,className:"sg-view","aria-label":"StrataGate \u8BB0\u5FC6\u5185\u5BB9"},content),h("footer",{className:"sg-footer"},"\u53D1\u73B0\u95EE\u9898\uFF1F ",h("button",{type:"button",onClick:()=>{setSection("more"),setView({name:"support"}),setSource(null)}},"\u63D0\u4EA4\u53CD\u9988")))}function apply2(ctx){let slots=ctx.get("slots");slots&&slots.inject("settings.section",()=>slots.register({name:"settings.section",id:"stratagate-memory",order:32,label:()=>"StrataGate-AgentMemory"},props=>h(MemoryPage,props)))}return exports.name="stratagate-dsh",exports.inject=["slots"],exports.apply=apply2,module.exports}});})();
package/dist/index.js CHANGED
@@ -2554,7 +2554,7 @@ function errorMessage(error) {
2554
2554
  }
2555
2555
  var STRATAGATE_CONSTRUCTOR_TOKEN = /* @__PURE__ */ Symbol("StrataGate constructor");
2556
2556
  var StrataGate = class _StrataGate {
2557
- blockTurnSize;
2557
+ blockTurnSizeValue;
2558
2558
  blockDecayLambdaValue;
2559
2559
  summarizer;
2560
2560
  extractor;
@@ -2586,7 +2586,7 @@ var StrataGate = class _StrataGate {
2586
2586
  if (token !== STRATAGATE_CONSTRUCTOR_TOKEN) {
2587
2587
  throw new TypeError("Use StrataGate.open() for SQLite or StrataGate.inMemory() for explicit ephemeral storage");
2588
2588
  }
2589
- this.blockTurnSize = Math.max(1, Math.floor(options.blockTurnSize ?? DEFAULT_BLOCK_TURN_SIZE));
2589
+ this.blockTurnSizeValue = Math.max(1, Math.floor(options.blockTurnSize ?? DEFAULT_BLOCK_TURN_SIZE));
2590
2590
  const blockDecayLambda = options.blockDecayLambda ?? BLOCK_DECAY_LAMBDA;
2591
2591
  if (!Number.isFinite(blockDecayLambda) || blockDecayLambda < 0) {
2592
2592
  throw new TypeError("blockDecayLambda must be a non-negative finite number");
@@ -2734,6 +2734,18 @@ var StrataGate = class _StrataGate {
2734
2734
  get storageRevision() {
2735
2735
  return this.revision;
2736
2736
  }
2737
+ get blockTurnSize() {
2738
+ return this.blockTurnSizeValue;
2739
+ }
2740
+ async setBlockTurnSize(value) {
2741
+ if (!Number.isSafeInteger(value) || value < 1) {
2742
+ throw new TypeError("blockTurnSize must be a positive integer");
2743
+ }
2744
+ if (value === this.blockTurnSizeValue) return;
2745
+ await this.commitMutation(() => {
2746
+ this.blockTurnSizeValue = value;
2747
+ });
2748
+ }
2737
2749
  get blockDecayLambda() {
2738
2750
  return this.blockDecayLambdaValue;
2739
2751
  }
@@ -4643,6 +4655,17 @@ var DshMetadataStore = class {
4643
4655
  this.database = new DatabaseSync2(filename);
4644
4656
  this.database.exec(METADATA_SCHEMA);
4645
4657
  }
4658
+ blockTurnSize() {
4659
+ const row = this.database.prepare("SELECT value FROM stratagate_dsh_settings WHERE key = 'blockTurnSize'").get();
4660
+ const value = Number(row?.value);
4661
+ return Number.isSafeInteger(value) && value >= 1 ? value : null;
4662
+ }
4663
+ setBlockTurnSize(value) {
4664
+ if (!Number.isSafeInteger(value) || value < 1) {
4665
+ throw new TypeError("blockTurnSize must be a positive integer");
4666
+ }
4667
+ this.setSetting("blockTurnSize", value);
4668
+ }
4646
4669
  blockDecayLambda() {
4647
4670
  const row = this.database.prepare("SELECT value FROM stratagate_dsh_settings WHERE key = 'blockDecayLambda'").get();
4648
4671
  const value = Number(row?.value);
@@ -4652,11 +4675,14 @@ var DshMetadataStore = class {
4652
4675
  if (!Number.isFinite(value) || value < 0) {
4653
4676
  throw new TypeError("blockDecayLambda must be a non-negative finite number");
4654
4677
  }
4678
+ this.setSetting("blockDecayLambda", value);
4679
+ }
4680
+ setSetting(key, value) {
4655
4681
  this.database.prepare(`
4656
4682
  INSERT INTO stratagate_dsh_settings (key, value, updated_at)
4657
- VALUES ('blockDecayLambda', ?, ?)
4683
+ VALUES (?, ?, ?)
4658
4684
  ON CONFLICT (key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
4659
- `).run(String(value), (/* @__PURE__ */ new Date()).toISOString());
4685
+ `).run(key, String(value), (/* @__PURE__ */ new Date()).toISOString());
4660
4686
  }
4661
4687
  workspaceName(namespace) {
4662
4688
  const row = this.database.prepare("SELECT display_name FROM stratagate_dsh_workspaces WHERE namespace = ?").get(namespace);
@@ -4697,6 +4723,7 @@ var StrataGateRuntime = class {
4697
4723
  this.models = models;
4698
4724
  this.onIngestError = onIngestError;
4699
4725
  this.flushNativeSession = flushNativeSession;
4726
+ this.blockTurnSize = config.blockTurnSize;
4700
4727
  this.blockDecayLambda = config.blockDecayLambda;
4701
4728
  }
4702
4729
  config;
@@ -4714,6 +4741,7 @@ var StrataGateRuntime = class {
4714
4741
  batchSequence = 0;
4715
4742
  closed = false;
4716
4743
  ingestError;
4744
+ blockTurnSize;
4717
4745
  blockDecayLambda;
4718
4746
  acceptEvent(session, event) {
4719
4747
  if (this.closed) return;
@@ -5075,6 +5103,7 @@ var StrataGateRuntime = class {
5075
5103
  if (this.config.database === ":memory:" || !existsSync(this.config.database)) return;
5076
5104
  const metadata = new DshMetadataStore(this.config.database);
5077
5105
  try {
5106
+ this.blockTurnSize = metadata.blockTurnSize() ?? this.config.blockTurnSize;
5078
5107
  this.blockDecayLambda = metadata.blockDecayLambda() ?? this.config.blockDecayLambda;
5079
5108
  } finally {
5080
5109
  metadata.close();
@@ -5083,10 +5112,10 @@ var StrataGateRuntime = class {
5083
5112
  try {
5084
5113
  for (const namespace of storage.listNamespaces()) {
5085
5114
  const loaded = await storage.load(namespace);
5086
- if (!loaded || loaded.snapshot.blockTurnSize === this.config.blockTurnSize && loaded.snapshot.blockDecayLambda === this.blockDecayLambda) continue;
5115
+ if (!loaded || loaded.snapshot.blockTurnSize === this.blockTurnSize && loaded.snapshot.blockDecayLambda === this.blockDecayLambda) continue;
5087
5116
  await storage.save(namespace, {
5088
5117
  ...loaded.snapshot,
5089
- blockTurnSize: this.config.blockTurnSize,
5118
+ blockTurnSize: this.blockTurnSize,
5090
5119
  blockDecayLambda: this.blockDecayLambda
5091
5120
  }, loaded.revision);
5092
5121
  }
@@ -5122,7 +5151,7 @@ var StrataGateRuntime = class {
5122
5151
  memory = await StrataGate.open({
5123
5152
  database: this.config.database,
5124
5153
  namespace: key,
5125
- blockTurnSize: this.config.blockTurnSize,
5154
+ blockTurnSize: this.blockTurnSize,
5126
5155
  blockDecayLambda: this.blockDecayLambda,
5127
5156
  graphProjector: this.models.graphProjector,
5128
5157
  disableElementProjection: true
@@ -5167,6 +5196,18 @@ var StrataGateRuntime = class {
5167
5196
  await update;
5168
5197
  return value;
5169
5198
  }
5199
+ async adminSetBlockTurnSize(value) {
5200
+ if (!Number.isSafeInteger(value) || value < 1) {
5201
+ throw new TypeError("blockTurnSize must be a positive integer");
5202
+ }
5203
+ const update = this.settingsTail.catch(() => {
5204
+ }).then(() => this.applyBlockTurnSize(value));
5205
+ this.settingsTail = update.then(() => {
5206
+ }, () => {
5207
+ });
5208
+ await update;
5209
+ return value;
5210
+ }
5170
5211
  async adminExpandBlock(namespace, id, target) {
5171
5212
  const key = namespace.trim();
5172
5213
  if (!key) throw new TypeError("StrataGate admin namespace must not be empty");
@@ -5181,7 +5222,7 @@ var StrataGateRuntime = class {
5181
5222
  const memory = await StrataGate.open({
5182
5223
  database: this.config.database,
5183
5224
  namespace: key,
5184
- blockTurnSize: this.config.blockTurnSize,
5225
+ blockTurnSize: this.blockTurnSize,
5185
5226
  blockDecayLambda: this.blockDecayLambda,
5186
5227
  summarizer: this.models.summarizer,
5187
5228
  extractor: this.models.extractor,
@@ -5230,6 +5271,37 @@ var StrataGateRuntime = class {
5230
5271
  }
5231
5272
  }
5232
5273
  }
5274
+ async applyBlockTurnSize(value) {
5275
+ await this.flush();
5276
+ this.blockTurnSize = value;
5277
+ if (this.config.database !== ":memory:") {
5278
+ const metadata = new DshMetadataStore(this.config.database);
5279
+ try {
5280
+ metadata.setBlockTurnSize(value);
5281
+ } finally {
5282
+ metadata.close();
5283
+ }
5284
+ }
5285
+ const openNamespaces = /* @__PURE__ */ new Set();
5286
+ for (const [namespace, opening] of this.spaces) {
5287
+ const memory = await opening;
5288
+ await memory.setBlockTurnSize(value);
5289
+ openNamespaces.add(namespace);
5290
+ }
5291
+ if (this.config.database !== ":memory:" && existsSync(this.config.database)) {
5292
+ const storage = new SqliteStorage({ filename: this.config.database });
5293
+ try {
5294
+ for (const namespace of storage.listNamespaces()) {
5295
+ if (openNamespaces.has(namespace)) continue;
5296
+ const loaded = await storage.load(namespace);
5297
+ if (!loaded || loaded.snapshot.blockTurnSize === value) continue;
5298
+ await storage.save(namespace, { ...loaded.snapshot, blockTurnSize: value }, loaded.revision);
5299
+ }
5300
+ } finally {
5301
+ await storage.close();
5302
+ }
5303
+ }
5304
+ }
5233
5305
  space(session) {
5234
5306
  const namespace = this.namespaceFor(session);
5235
5307
  this.rememberWorkspace(namespace, session.header.cwd);
@@ -5238,7 +5310,7 @@ var StrataGateRuntime = class {
5238
5310
  opening = StrataGate.open({
5239
5311
  database: this.config.database,
5240
5312
  namespace,
5241
- blockTurnSize: this.config.blockTurnSize,
5313
+ blockTurnSize: this.blockTurnSize,
5242
5314
  blockDecayLambda: this.blockDecayLambda,
5243
5315
  summarizer: this.models.summarizer,
5244
5316
  extractor: this.models.extractor,
@@ -5936,7 +6008,7 @@ function clusterKnowledgeGraph(rawNodes, rawEdges) {
5936
6008
  }
5937
6009
 
5938
6010
  // src/web.ts
5939
- var STRATAGATE_DSH_VERSION = "0.2.32";
6011
+ var STRATAGATE_DSH_VERSION = "0.2.36";
5940
6012
  var LEGACY_THREAD_ID = "__legacy__";
5941
6013
  var nodeRequire = createRequire(import.meta.url);
5942
6014
  function installedPackageVersion(names) {
@@ -6125,12 +6197,31 @@ async function overview(runtime) {
6125
6197
  };
6126
6198
  }
6127
6199
  async function updateSettings(runtime, url) {
6128
- const raw = url.searchParams.get("blockDecayLambda")?.trim() ?? "";
6129
- const value = Number(raw);
6130
- if (!raw || !Number.isFinite(value) || value < 0) {
6131
- throw new AdminHttpError(400, "blockDecayLambda must be a non-negative finite number");
6132
- }
6133
- return { blockDecayLambda: await runtime.adminSetBlockDecayLambda(value) };
6200
+ const rawTurnSize = url.searchParams.get("blockTurnSize")?.trim();
6201
+ const rawLambda = url.searchParams.get("blockDecayLambda")?.trim();
6202
+ if (rawTurnSize === void 0 && rawLambda === void 0) {
6203
+ throw new AdminHttpError(400, "blockTurnSize or blockDecayLambda is required");
6204
+ }
6205
+ let turnSize;
6206
+ let lambda;
6207
+ if (rawTurnSize !== void 0) {
6208
+ const value = Number(rawTurnSize);
6209
+ if (!rawTurnSize || !Number.isSafeInteger(value) || value < 1) {
6210
+ throw new AdminHttpError(400, "blockTurnSize must be a positive integer");
6211
+ }
6212
+ turnSize = value;
6213
+ }
6214
+ if (rawLambda !== void 0) {
6215
+ const value = Number(rawLambda);
6216
+ if (!rawLambda || !Number.isFinite(value) || value < 0) {
6217
+ throw new AdminHttpError(400, "blockDecayLambda must be a non-negative finite number");
6218
+ }
6219
+ lambda = value;
6220
+ }
6221
+ const result = {};
6222
+ if (turnSize !== void 0) result.blockTurnSize = await runtime.adminSetBlockTurnSize(turnSize);
6223
+ if (lambda !== void 0) result.blockDecayLambda = await runtime.adminSetBlockDecayLambda(lambda);
6224
+ return result;
6134
6225
  }
6135
6226
  async function importExternalMemory(runtime, req) {
6136
6227
  let suppliedBody = req.body;