comisai 1.0.23 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/node_modules/@comis/agent/dist/executor/pi-executor.js +17 -0
  2. package/node_modules/@comis/agent/dist/index.d.ts +2 -1
  3. package/node_modules/@comis/agent/dist/index.js +1 -1
  4. package/node_modules/@comis/agent/dist/model/auth-storage-adapter.d.ts +21 -0
  5. package/node_modules/@comis/agent/dist/model/auth-storage-adapter.js +15 -1
  6. package/node_modules/@comis/agent/dist/model/model-registry-adapter.d.ts +46 -0
  7. package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +108 -0
  8. package/node_modules/@comis/agent/package.json +1 -1
  9. package/node_modules/@comis/channels/package.json +1 -1
  10. package/node_modules/@comis/cli/package.json +1 -1
  11. package/node_modules/@comis/core/dist/bootstrap.js +5 -0
  12. package/node_modules/@comis/core/dist/config/env-layer.d.ts +31 -0
  13. package/node_modules/@comis/core/dist/config/env-layer.js +41 -0
  14. package/node_modules/@comis/core/dist/config/layered.d.ts +9 -0
  15. package/node_modules/@comis/core/dist/config/layered.js +11 -0
  16. package/node_modules/@comis/core/package.json +1 -1
  17. package/node_modules/@comis/daemon/dist/daemon.js +3 -0
  18. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +15 -3
  19. package/node_modules/@comis/daemon/package.json +1 -1
  20. package/node_modules/@comis/gateway/package.json +1 -1
  21. package/node_modules/@comis/infra/package.json +1 -1
  22. package/node_modules/@comis/memory/package.json +1 -1
  23. package/node_modules/@comis/scheduler/package.json +1 -1
  24. package/node_modules/@comis/shared/package.json +1 -1
  25. package/node_modules/@comis/skills/package.json +1 -1
  26. package/node_modules/@comis/web/dist/assets/{agent-detail-BG9MGWWj.js → agent-detail-ru-AhppM.js} +270 -270
  27. package/node_modules/@comis/web/dist/assets/agent-editor-hjwRuFVp.js +2173 -0
  28. package/node_modules/@comis/web/dist/assets/{agent-list-LHCJ4rw2.js → agent-list-6Uotjatr.js} +170 -170
  29. package/node_modules/@comis/web/dist/assets/{approvals-q9VH_IKr.js → approvals-C-K6hN2U.js} +13 -13
  30. package/node_modules/@comis/web/dist/assets/billing-view-CxysXH0p.js +375 -0
  31. package/node_modules/@comis/web/dist/assets/{channel-detail-CaInesJM.js → channel-detail-BBCKtmne.js} +265 -265
  32. package/node_modules/@comis/web/dist/assets/channel-list-FkfeOLBQ.js +323 -0
  33. package/node_modules/@comis/web/dist/assets/{chat-console-CNmzl0JW.js → chat-console-BumBaIgO.js} +243 -246
  34. package/node_modules/@comis/web/dist/assets/{config-editor-DX4ITw6y.js → config-editor-C9BSwHGy.js} +477 -477
  35. package/node_modules/@comis/web/dist/assets/{context-dag-browser-BwiaF5tf.js → context-dag-browser-BHm00mJD.js} +105 -105
  36. package/node_modules/@comis/web/dist/assets/{context-engine-BZ5Am6hA.js → context-engine-BENY3pWE.js} +136 -136
  37. package/node_modules/@comis/web/dist/assets/decorate-BvWYovGE.js +38 -0
  38. package/node_modules/@comis/web/dist/assets/{delivery-view-OfBZof-m.js → delivery-view-BCnkPsAp.js} +134 -134
  39. package/node_modules/@comis/web/dist/assets/{diagnostics-view-YFwCxgr2.js → diagnostics-view-C_jQFG2H.js} +82 -82
  40. package/node_modules/@comis/web/dist/assets/directive-BOYXJ-K-.js +1 -0
  41. package/node_modules/@comis/web/dist/assets/{extract-variables-BM5qyK-s.js → extract-variables-B7-Doo7l.js} +39 -39
  42. package/node_modules/@comis/web/dist/assets/{ic-array-editor-B7m6x7-S.js → ic-array-editor-BLoEyeLS.js} +29 -29
  43. package/node_modules/@comis/web/dist/assets/{ic-breadcrumb-CUMpp3BL.js → ic-breadcrumb-DqN6G3gc.js} +16 -16
  44. package/node_modules/@comis/web/dist/assets/{ic-budget-segment-bar-BtJ6x5mN.js → ic-budget-segment-bar-zLsMzjDO.js} +20 -20
  45. package/node_modules/@comis/web/dist/assets/ic-chat-message-FdQcZsSQ.js +352 -0
  46. package/node_modules/@comis/web/dist/assets/{ic-confirm-dialog-CCDbB04e.js → ic-confirm-dialog-DGlPbV1T.js} +26 -26
  47. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CnT1b8xr.js → ic-connection-dot-BgYiK2N4.js} +13 -13
  48. package/node_modules/@comis/web/dist/assets/ic-data-table-CKIvr-ag.js +277 -0
  49. package/node_modules/@comis/web/dist/assets/ic-delivery-row-B3YwjjuM.js +67 -0
  50. package/node_modules/@comis/web/dist/assets/{ic-detail-panel-BF83r-if.js → ic-detail-panel-DiCe4hLr.js} +27 -27
  51. package/node_modules/@comis/web/dist/assets/{ic-empty-state-60l2ePhd.js → ic-empty-state-CM3Wbj2f.js} +19 -19
  52. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-ByRjij68.js +359 -0
  53. package/node_modules/@comis/web/dist/assets/ic-icon-BGNCCPpZ.js +33 -0
  54. package/node_modules/@comis/web/dist/assets/{ic-layer-waterfall-COvEYMg5.js → ic-layer-waterfall-WkaFyu-l.js} +18 -18
  55. package/node_modules/@comis/web/dist/assets/ic-relative-time-B3UAnTqg.js +12 -0
  56. package/node_modules/@comis/web/dist/assets/{ic-search-input-CSOxY9g7.js → ic-search-input-B02AGw1i.js} +22 -22
  57. package/node_modules/@comis/web/dist/assets/{ic-select-Ce-Raudx.js → ic-select-BqfZISjw.js} +29 -29
  58. package/node_modules/@comis/web/dist/assets/ic-tabs-yBjkWKJH.js +95 -0
  59. package/node_modules/@comis/web/dist/assets/ic-tag-CvMVQFRR.js +33 -0
  60. package/node_modules/@comis/web/dist/assets/{ic-time-range-picker-CypCT68y.js → ic-time-range-picker-DXbYeBmY.js} +31 -31
  61. package/node_modules/@comis/web/dist/assets/{ic-tool-call-7MaXSsCW.js → ic-tool-call-DMPHsLyx.js} +51 -51
  62. package/node_modules/@comis/web/dist/assets/index-CVEaS9aY.css +2 -0
  63. package/node_modules/@comis/web/dist/assets/index-FLPhHz8p.js +2792 -0
  64. package/node_modules/@comis/web/dist/assets/{mcp-management-BNZPnpDn.js → mcp-management-5jyScQis.js} +209 -209
  65. package/node_modules/@comis/web/dist/assets/{media-config-BBvTYxOX.js → media-config-J9oT9PPs.js} +154 -154
  66. package/node_modules/@comis/web/dist/assets/{media-test-BkK3RCRK.js → media-test-DGTCtM8-.js} +259 -259
  67. package/node_modules/@comis/web/dist/assets/{memory-inspector-1hDGCGat.js → memory-inspector-D5Re9ptG.js} +450 -450
  68. package/node_modules/@comis/web/dist/assets/{message-center-CXefwsUu.js → message-center-cRLK6ZmG.js} +290 -290
  69. package/node_modules/@comis/web/dist/assets/{models-C1qcU_j3.js → models-D5vu07MR.js} +371 -371
  70. package/node_modules/@comis/web/dist/assets/observability-types-D0tkwElU.js +1 -0
  71. package/node_modules/@comis/web/dist/assets/{observe-view-C0VBhX4C.js → observe-view-CalNNEmd.js} +399 -399
  72. package/node_modules/@comis/web/dist/assets/pipeline-builder-DUYDGwZf.js +1495 -0
  73. package/node_modules/@comis/web/dist/assets/{pipeline-history-DkfOQ6SW.js → pipeline-history-BAO8brOe.js} +124 -124
  74. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-hyHgD0ai.js → pipeline-history-detail-DectIoQt.js} +65 -65
  75. package/node_modules/@comis/web/dist/assets/{pipeline-list-BPW8hV-q.js → pipeline-list-BHlaBKww.js} +227 -227
  76. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-Bip16T7e.js → pipeline-monitor-BhtpNEHf.js} +298 -298
  77. package/node_modules/@comis/web/dist/assets/{scheduler-BGgwKd06.js → scheduler-VafN_8xi.js} +486 -486
  78. package/node_modules/@comis/web/dist/assets/{security-D15st4xx.js → security-QQXMRTlo.js} +389 -389
  79. package/node_modules/@comis/web/dist/assets/{session-detail-SGEYNJ0M.js → session-detail-BpZ_8Yih.js} +294 -294
  80. package/node_modules/@comis/web/dist/assets/session-key-parser-Dkqcj2Ss.js +1 -0
  81. package/node_modules/@comis/web/dist/assets/session-list-DfCm8Cec.js +231 -0
  82. package/node_modules/@comis/web/dist/assets/{setup-wizard-nT0tz9QP.js → setup-wizard-C-z477CG.js} +486 -494
  83. package/node_modules/@comis/web/dist/assets/{skills-D8yVfSUy.js → skills-BCOGPf6s.js} +329 -329
  84. package/node_modules/@comis/web/dist/assets/{subagents-HHXMeHYo.js → subagents-l-auUraL.js} +74 -74
  85. package/node_modules/@comis/web/dist/assets/{workspace-manager-BQlr10iH.js → workspace-manager-DlvBixiq.js} +236 -236
  86. package/node_modules/@comis/web/dist/index.html +3 -2
  87. package/node_modules/@comis/web/package.json +1 -1
  88. package/package.json +15 -15
  89. package/node_modules/@comis/web/dist/assets/agent-editor-C26Q_xCs.js +0 -2173
  90. package/node_modules/@comis/web/dist/assets/billing-view-CtYvBqTE.js +0 -375
  91. package/node_modules/@comis/web/dist/assets/channel-list-B8dj3O9a.js +0 -323
  92. package/node_modules/@comis/web/dist/assets/directive-DoeGSK_T.js +0 -1
  93. package/node_modules/@comis/web/dist/assets/ic-chat-message-CFyDJd0z.js +0 -352
  94. package/node_modules/@comis/web/dist/assets/ic-data-table-CKUNTxHw.js +0 -277
  95. package/node_modules/@comis/web/dist/assets/ic-delivery-row-GP5Fkygs.js +0 -67
  96. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-C8FuSMe1.js +0 -359
  97. package/node_modules/@comis/web/dist/assets/ic-icon-xeGTVhVG.js +0 -33
  98. package/node_modules/@comis/web/dist/assets/ic-relative-time-3FqpjeAI.js +0 -12
  99. package/node_modules/@comis/web/dist/assets/ic-tabs-B7QtM_v8.js +0 -95
  100. package/node_modules/@comis/web/dist/assets/ic-tag-CPPUnDLF.js +0 -33
  101. package/node_modules/@comis/web/dist/assets/index-CEcM1R_C.js +0 -2830
  102. package/node_modules/@comis/web/dist/assets/index-CIJFuItj.css +0 -1
  103. package/node_modules/@comis/web/dist/assets/observability-types-D7jUtSde.js +0 -1
  104. package/node_modules/@comis/web/dist/assets/pipeline-builder-DcUUIrm0.js +0 -1496
  105. package/node_modules/@comis/web/dist/assets/session-key-parser-DPORMVyU.js +0 -1
  106. package/node_modules/@comis/web/dist/assets/session-list-6ybUTxbY.js +0 -231
@@ -1,364 +1,4 @@
1
- import{a as x,S as $,b as i,g as C,A as v,s as S,f as k,i as R,n as T,r as o,t as A}from"./index-CEcM1R_C.js";import{d as D,a as y}from"./observability-types-D7jUtSde.js";import"./ic-tabs-B7QtM_v8.js";import"./ic-tag-CPPUnDLF.js";import"./ic-relative-time-3FqpjeAI.js";import"./ic-empty-state-60l2ePhd.js";import"./ic-delivery-row-GP5Fkygs.js";import"./ic-icon-xeGTVhVG.js";var I=Object.defineProperty,F=Object.getOwnPropertyDescriptor,l=(e,t,r,n)=>{for(var d=n>1?void 0:n?F(t,r):t,u=e.length-1,p;u>=0;u--)(p=e[u])&&(d=(n?p(t,r,d):p(d))||d);return n&&d&&I(t,r,d),d};const N=3e4,E=[{id:"overview",label:"Overview"},{id:"billing",label:"Billing"},{id:"delivery",label:"Delivery"},{id:"channels",label:"Channels"},{id:"diagnostics",label:"Diagnostics"}];let s=class extends x{constructor(){super(...arguments),this.rpcClient=null,this.eventDispatcher=null,this.initialTab="overview",this._sse=null,this._reloadDebounce=null,this._loadState="loading",this._activeTab="overview",this._error="",this._requestsToday=0,this._tokensToday=0,this._costToday=0,this._errorsToday=0,this._tokenUsage24h=[],this._billingByProvider=[],this._billingByAgent=[],this._billingTotal=null,this._diagnosticsEvents=[],this._deliveryTraces=[],this._deliveryStats=null,this._channelActivity=[],this._agentHealth=[],this._channelHealth=[],this._resetConfirming=!1,this._resetInput="",this._deliveryChannelFilter="all",this._deliveryStatusFilter="all",this._deliveryTimeRange="1h",this._expandedTraceId=null,this._refreshInterval=null,this._rpcStatusUnsub=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.initialTab,this._initSse()}_initSse(){!this.eventDispatcher||this._sse||(this._sse=new $(this,this.eventDispatcher,{"observability:metrics":()=>{this._scheduleReload(500)},"observability:token_usage":()=>{this._scheduleReload()},"observability:reset":()=>{this._scheduleReload()}}))}_scheduleReload(e=300){this._reloadDebounce!==null&&clearTimeout(this._reloadDebounce),this._reloadDebounce=setTimeout(()=>{this._reloadDebounce=null,this._loadData()},e)}disconnectedCallback(){super.disconnectedCallback(),this._reloadDebounce!==null&&(clearTimeout(this._reloadDebounce),this._reloadDebounce=null),this._refreshInterval!==null&&(clearInterval(this._refreshInterval),this._refreshInterval=null),this._rpcStatusUnsub?.(),this._rpcStatusUnsub=null}willUpdate(e){e.has("initialTab")&&(this._activeTab=this.initialTab),e.has("rpcClient")&&(this.rpcClient?this._tryLoad():this._loadState="loaded"),e.has("eventDispatcher")&&this.eventDispatcher&&!this._sse&&this._initSse()}_tryLoad(){if(!this.rpcClient){this._loadState="loaded";return}this._rpcStatusUnsub?.(),this.rpcClient.status==="connected"?this._startLoading():this._rpcStatusUnsub=this.rpcClient.onStatusChange(e=>{e==="connected"&&this._startLoading()})}_startLoading(){this._loadData(),this._refreshInterval===null&&(this._refreshInterval=setInterval(()=>{this._loadData()},N))}async _loadData(){if(!this.rpcClient||this.rpcClient.status!=="connected"){this._loadState="loaded";return}const e=this.rpcClient,[t,r,n,d,u,p,w,b,_]=await Promise.allSettled([e.call("obs.delivery.stats"),e.call("obs.billing.total"),e.call("obs.billing.usage24h"),e.call("obs.billing.byProvider"),e.call("obs.diagnostics"),e.call("obs.delivery.recent"),e.call("obs.channels.all"),e.call("agents.list"),e.call("channels.list")]);let h=!1,m="";if(t.status==="fulfilled"){const a=t.value,c=Number(a.total??a.totalDelivered??0),g=Number(a.failures??a.failed??0);let f=0;a.successRate!==void 0?f=Number(a.successRate):c>0&&(f=Number(a.successes??0)/c*100),this._deliveryStats={successRate:f,avgLatencyMs:Number(a.avgLatencyMs??0),totalDelivered:c,failed:g},this._requestsToday=c,this._errorsToday=g,h=!0}else m=t.reason instanceof Error?t.reason.message:"Failed to load delivery stats";if(r.status==="fulfilled"){const a=r.value,c={totalTokens:Number(a.totalTokens??0),totalCost:Number(a.totalCost??0)};this._billingTotal=c,this._tokensToday=c.totalTokens,this._costToday=c.totalCost,h=!0}else m||(m=r.reason instanceof Error?r.reason.message:"Failed to load billing total");if(n.status==="fulfilled"&&(this._tokenUsage24h=Array.isArray(n.value)?n.value:[],h=!0),d.status==="fulfilled"){const a=d.value;if(Array.isArray(a))this._billingByProvider=a;else{const c=a;this._billingByProvider=Array.isArray(c.providers)?c.providers:[]}h=!0}if(u.status==="fulfilled"){const a=u.value;if(Array.isArray(a))this._diagnosticsEvents=a;else{const c=a;this._diagnosticsEvents=Array.isArray(c.events)?c.events:[]}h=!0}if(p.status==="fulfilled"){const a=p.value;if(Array.isArray(a))this._deliveryTraces=a;else{const c=a;this._deliveryTraces=Array.isArray(c.deliveries)?c.deliveries:[]}h=!0}if(w.status==="fulfilled"){const a=w.value;if(Array.isArray(a))this._channelActivity=a;else{const c=a;this._channelActivity=Array.isArray(c.channels)?c.channels:[]}h=!0}if(b.status==="fulfilled"){const a=Array.isArray(b.value.agents)?b.value.agents:[];if(a.length>0){const c=await Promise.allSettled(a.map(g=>e.call("agents.get",{agentId:g})));this._agentHealth=c.filter(g=>g.status==="fulfilled").map(g=>g.value)}else this._agentHealth=[];h=!0}_.status==="fulfilled"&&(this._channelHealth=Array.isArray(_.value.channels)?_.value.channels:[],h=!0),h?(this._loadState="loaded",this._error=""):(this._loadState="error",this._error=m||"Failed to load observability data")}_onTabChange(e){this._activeTab=e.detail}_formatNumber(e){return new Intl.NumberFormat("en-US").format(e)}_formatTokens(e){if(e>=1e6){const t=e/1e6;return t%1===0?`${t}M`:`${t.toFixed(1)}M`}if(e>=1e3){const t=e/1e3;return t%1===0?`${t}K`:`${t.toFixed(1)}K`}return String(e)}_formatCost(e){return`$${(e??0).toFixed(2)}`}_getErrorRate(){return!this._deliveryStats||this._deliveryStats.totalDelivered===0?0:this._deliveryStats.failed/this._deliveryStats.totalDelivered*100}_getErrorRateColor(){const e=this._getErrorRate();return e>5?"var(--ic-error)":e>1?"var(--ic-warning)":"var(--ic-success)"}_getLatencyColor(){const e=this._deliveryStats?.avgLatencyMs??0;return e>5e3?"var(--ic-error)":e>2e3?"var(--ic-warning)":""}_getAgentModel(e){return typeof e.model=="string"?e.model:"unknown"}_onResetClick(){this._resetConfirming=!0,this._resetInput=""}_onResetCancel(){this._resetConfirming=!1,this._resetInput=""}_onResetInput(e){this._resetInput=e.target.value}async _onResetConfirm(){if(!(this._resetInput!=="RESET"||!this.rpcClient)){try{await this.rpcClient.call("obs.reset")}catch{}this._resetConfirming=!1,this._resetInput="",await this._loadData()}}_renderOverview(){const e=this.rpcClient&&this.rpcClient.status==="connected",t=this._getErrorRate(),r=e?this._deliveryStats&&this._deliveryStats.totalDelivered>0?`${t.toFixed(1)}%`:"0%":"---",n=e?this._deliveryStats?`${this._deliveryStats.avgLatencyMs}ms`:"0ms":"---",d=e?String(this._agentHealth.filter(u=>!u.suspended).length):"---";return i`
2
- <!-- 6 Stat Cards -->
3
- <div class="stats-grid">
4
- <ic-stat-card
5
- label="Requests/min"
6
- .value=${e?this._formatNumber(this._requestsToday):"---"}
7
- ></ic-stat-card>
8
- <ic-stat-card
9
- label="Error Rate"
10
- .value=${r}
11
- ></ic-stat-card>
12
- <ic-stat-card
13
- label="Avg Latency"
14
- .value=${n}
15
- ></ic-stat-card>
16
- <ic-stat-card
17
- label="Active Agents"
18
- .value=${d}
19
- ></ic-stat-card>
20
- <ic-stat-card
21
- label="Tokens (24h)"
22
- .value=${e?this._formatTokens(this._tokensToday):"---"}
23
- ></ic-stat-card>
24
- <ic-stat-card
25
- label="Cost Today"
26
- .value=${e?this._formatCost(this._costToday):"---"}
27
- ></ic-stat-card>
28
- </div>
29
-
30
- <!-- Time-series Charts -->
31
- <div class="section">
32
- <div class="charts-section">
33
- <div>
34
- <div class="chart-title">Token Usage (24h)</div>
35
- <div class="chart-container">
36
- ${this._tokenUsage24h.length>0?i`
37
- <div class="bar-chart" aria-label="Token usage bar chart">
38
- ${this._renderTokenBars()}
39
- </div>
40
- <div class="chart-labels">
41
- <span>00</span>
42
- <span>06</span>
43
- <span>12</span>
44
- <span>18</span>
45
- <span>24</span>
46
- </div>
47
- `:i`<div style="color: var(--ic-text-dim); text-align: center; padding: var(--ic-space-lg);">No usage data</div>`}
48
- </div>
49
- </div>
50
- <div class="sparkline-side">
51
- <div>
52
- <div class="chart-title">Cost Trend (7d)</div>
53
- <div class="chart-container">
54
- <ic-sparkline
55
- .data=${this._costToday>0?[this._costToday]:[]}
56
- .width=${200}
57
- .height=${60}
58
- color="var(--ic-accent)"
59
- ></ic-sparkline>
60
- </div>
61
- </div>
62
- <div>
63
- <div class="chart-title">Error Rate (24h)</div>
64
- <div class="chart-container">
65
- <ic-sparkline
66
- .data=${this._errorsToday>0?[this._errorsToday]:[]}
67
- .width=${200}
68
- .height=${60}
69
- color="var(--ic-error)"
70
- ></ic-sparkline>
71
- </div>
72
- </div>
73
- </div>
74
- </div>
75
- </div>
76
-
77
- <!-- Health Grids -->
78
- <div class="section">
79
- <div class="health-grids">
80
- <div>
81
- <div class="section-title">Agent Health</div>
82
- ${this._renderAgentHealthGrid()}
83
- </div>
84
- <div>
85
- <div class="section-title">Channel Health</div>
86
- ${this._renderChannelHealthGrid()}
87
- </div>
88
- </div>
89
- </div>
90
-
91
- <!-- Reset Section -->
92
- ${this._renderResetSection()}
93
- `}_renderTokenBars(){const e=Math.max(...this._tokenUsage24h.map(t=>t.tokens),1);return this._tokenUsage24h.map(t=>i`<div class="bar" style="height: ${t.tokens/e*100}%" title="${t.hour}:00 - ${this._formatTokens(t.tokens)} tokens"></div>`)}_renderAgentHealthGrid(){return this._agentHealth.length===0?i`<div class="health-empty">No agents configured</div>`:i`
94
- <div class="grid-table health-grid-table" role="table" aria-label="Agent health">
95
- <div class="grid-header" role="row">
96
- <div class="cell" role="columnheader">Agent</div>
97
- <div class="cell" role="columnheader">Model</div>
98
- <div class="cell" role="columnheader">Status</div>
99
- </div>
100
- ${this._agentHealth.map(e=>i`
101
- <div class="grid-row" role="row">
102
- <div class="cell cell-mono" role="cell">${e.agentId}</div>
103
- <div class="cell" role="cell">${this._getAgentModel(e.config)}</div>
104
- <div class="cell" role="cell">
105
- ${e.suspended?i`<ic-tag variant="default">suspended</ic-tag>`:i`<ic-tag variant="success">active</ic-tag>`}
106
- </div>
107
- </div>
108
- `)}
109
- </div>
110
- `}_renderChannelHealthGrid(){return this._channelHealth.length===0?i`<div class="health-empty">No channels configured</div>`:i`
111
- <div class="grid-table health-grid-table" role="table" aria-label="Channel health">
112
- <div class="grid-header" role="row">
113
- <div class="cell" role="columnheader">Channel</div>
114
- <div class="cell" role="columnheader">Type</div>
115
- <div class="cell" role="columnheader">Status</div>
116
- </div>
117
- ${this._channelHealth.map(e=>{const t=C(e.status),r={green:"success",yellow:"warning",red:"error",gray:"default"};return i`
118
- <div class="grid-row" role="row">
119
- <div class="cell" role="cell">${e.channelId??e.channelType}</div>
120
- <div class="cell" role="cell">${e.channelType}</div>
121
- <div class="cell" role="cell">
122
- <ic-tag variant=${r[t.severity]}>
123
- ${t.label}
124
- </ic-tag>
125
- </div>
126
- </div>
127
- `})}
128
- </div>
129
- `}_renderResetSection(){return i`
130
- <div class="reset-section">
131
- <div class="section-title">Reset Observability Data</div>
132
- ${this._resetConfirming?i`
133
- <div class="reset-warning">
134
- This will permanently clear all observability data. Type RESET to confirm.
135
- </div>
136
- <input
137
- class="reset-input"
138
- type="text"
139
- .value=${this._resetInput}
140
- @input=${this._onResetInput}
141
- placeholder="Type RESET"
142
- />
143
- <div class="reset-actions">
144
- <button class="reset-cancel-btn" @click=${this._onResetCancel}>Cancel</button>
145
- <button
146
- class="reset-confirm-btn"
147
- ?disabled=${this._resetInput!=="RESET"}
148
- @click=${this._onResetConfirm}
149
- >Confirm Reset</button>
150
- </div>
151
- `:i`
152
- <button class="reset-btn" @click=${this._onResetClick}>
153
- Reset Observability Data
154
- </button>
155
- `}
156
- </div>
157
- `}_renderBilling(){return this._billingByProvider.length===0&&this._billingByAgent.length===0?i`<ic-empty-state icon="dollar-sign" message="No billing data available"></ic-empty-state>`:i`
158
- ${this._billingByProvider.length>0?i`
159
- <div class="section">
160
- <div class="section-title">By Provider</div>
161
- <div class="grid-table-scroll">
162
- <div class="grid-table provider-table" role="table">
163
- <div class="grid-header" role="row">
164
- <div class="cell" role="columnheader">Provider</div>
165
- <div class="cell cell-right" role="columnheader">Total Tokens</div>
166
- <div class="cell cell-right" role="columnheader">Calls</div>
167
- <div class="cell cell-right" role="columnheader">Cost</div>
168
- </div>
169
- ${this._billingByProvider.map(e=>i`
170
- <div class="grid-row" role="row">
171
- <div class="cell" role="cell">${e.provider}</div>
172
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.totalTokens)}</div>
173
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.callCount)}</div>
174
- <div class="cell cell-mono cell-right" role="cell">${this._formatCost(e.totalCost)}</div>
175
- </div>
176
- `)}
177
- ${this._renderProviderTotal()}
178
- </div>
179
- </div>
180
- </div>
181
- `:v}
182
-
183
- ${this._billingByAgent.length>0?i`
184
- <div class="section">
185
- <div class="section-title">By Agent</div>
186
- <div class="grid-table-scroll">
187
- <div class="grid-table agent-table" role="table">
188
- <div class="grid-header" role="row">
189
- <div class="cell" role="columnheader">Agent</div>
190
- <div class="cell cell-right" role="columnheader">Tokens</div>
191
- <div class="cell cell-right" role="columnheader">% Total</div>
192
- <div class="cell cell-right" role="columnheader">Cost</div>
193
- </div>
194
- ${this._billingByAgent.map(e=>i`
195
- <div class="grid-row" role="row">
196
- <div class="cell" role="cell">${e.agentId}</div>
197
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.totalTokens)}</div>
198
- <div class="cell cell-mono cell-right" role="cell">${e.percentOfTotal.toFixed(1)}%</div>
199
- <div class="cell cell-mono cell-right" role="cell">${this._formatCost(e.cost)}</div>
200
- </div>
201
- `)}
202
- </div>
203
- </div>
204
- </div>
205
- `:v}
206
- `}_renderProviderTotal(){const e=this._billingByProvider.reduce((t,r)=>({totalTokens:t.totalTokens+r.totalTokens,callCount:t.callCount+r.callCount,totalCost:t.totalCost+r.totalCost}),{totalTokens:0,callCount:0,totalCost:0});return i`
207
- <div class="grid-row total-row" role="row">
208
- <div class="cell" role="cell">Total</div>
209
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.totalTokens)}</div>
210
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.callCount)}</div>
211
- <div class="cell cell-mono cell-right" role="cell">${this._formatCost(e.totalCost)}</div>
212
- </div>
213
- `}_renderDiagnostics(){if(this._diagnosticsEvents.length===0)return i`<ic-empty-state icon="activity" message="No diagnostic events"></ic-empty-state>`;const e=[...this._diagnosticsEvents].sort((t,r)=>r.timestamp-t.timestamp);return i`
214
- <div class="grid-table-scroll">
215
- <div class="grid-table diagnostics-table" role="table">
216
- <div class="grid-header" role="row">
217
- <div class="cell" role="columnheader">Time</div>
218
- <div class="cell" role="columnheader">Category</div>
219
- <div class="cell" role="columnheader">Message</div>
220
- <div class="cell" role="columnheader">Level</div>
221
- </div>
222
- ${e.map(t=>i`
223
- <div class="grid-row" role="row">
224
- <div class="cell" role="cell">
225
- <ic-relative-time .timestamp=${t.timestamp}></ic-relative-time>
226
- </div>
227
- <div class="cell" role="cell">
228
- <ic-tag>${t.category}</ic-tag>
229
- </div>
230
- <div class="cell" role="cell">${D(t)}</div>
231
- <div class="cell" role="cell">
232
- <ic-tag variant=${y(t)==="error"?"error":y(t)==="warn"?"warning":"default"}>
233
- ${y(t)}
234
- </ic-tag>
235
- </div>
236
- </div>
237
- `)}
238
- </div>
239
- </div>
240
- `}_getTimeRangeMs(){return{"1h":36e5,"6h":216e5,"24h":864e5,"7d":6048e5}[this._deliveryTimeRange]??36e5}_getFilteredTraces(){const e=Date.now(),t=this._getTimeRangeMs();return this._deliveryTraces.filter(r=>!(this._deliveryChannelFilter!=="all"&&r.channelType!==this._deliveryChannelFilter||this._deliveryStatusFilter!=="all"&&r.status!==this._deliveryStatusFilter||r.timestamp<e-t)).sort((r,n)=>n.timestamp-r.timestamp)}_onDeliveryChannelFilter(e){this._deliveryChannelFilter=e.target.value}_onDeliveryStatusFilter(e){this._deliveryStatusFilter=e.target.value}_onDeliveryTimeRange(e){this._deliveryTimeRange=e.target.value}_onTraceClick(e){const t=e.detail;this._expandedTraceId=this._expandedTraceId===t?null:t}_renderDeliveryStats(){if(!this._deliveryStats)return v;const e=this._deliveryStats,t=e.totalDelivered>0,r=t?e.successRate>=99?"rate-green":e.successRate>=95?"rate-yellow":"rate-red":"";return i`
241
- <div class="stats-summary">
242
- <span>Success <span class="stat-value ${r}">${t?`${e.successRate.toFixed(1)}%`:"N/A"}</span></span>
243
- <span>Avg <span class="stat-value">${t?`${e.avgLatencyMs}ms`:"N/A"}</span></span>
244
- <span>Total <span class="stat-value">${this._formatNumber(e.totalDelivered)}</span></span>
245
- </div>
246
- `}_renderTraceDetail(e){return!e.steps||e.steps.length===0?i`
247
- <div class="trace-detail">
248
- <div class="trace-detail-title">Delivery Steps</div>
249
- <div style="color: var(--ic-text-dim); font-size: var(--ic-text-sm); margin-top: var(--ic-space-sm);">
250
- No step details available
251
- </div>
252
- </div>
253
- `:i`
254
- <div class="trace-detail">
255
- <div class="trace-detail-title">Delivery Steps</div>
256
- <div class="step-list">
257
- ${e.steps.map(t=>i`
258
- <div class="step-item">
259
- <span class="step-dot ${t.status}"></span>
260
- <span>${t.name} &mdash; ${t.durationMs}ms</span>
261
- </div>
262
- ${t.error?i`<div class="step-error">${t.error}</div>`:v}
263
- `)}
264
- </div>
265
- </div>
266
- `}_renderChannelFilterSelect(){const e=[...new Set(this._deliveryTraces.map(t=>t.channelType))];return i`
267
- <select class="filter-select" @change=${this._onDeliveryChannelFilter}>
268
- <option value="all">All Channels</option>
269
- ${e.map(t=>i`<option value=${t}>${t}</option>`)}
270
- </select>
271
- `}_renderStatusFilterSelect(){return i`
272
- <select class="filter-select" @change=${this._onDeliveryStatusFilter}>
273
- <option value="all">All Statuses</option>
274
- <option value="success">Success</option>
275
- <option value="failed">Failed</option>
276
- <option value="timeout">Timeout</option>
277
- </select>
278
- `}_renderTimeRangeSelect(){return i`
279
- <select class="filter-select" @change=${this._onDeliveryTimeRange}>
280
- <option value="1h">1 hour</option>
281
- <option value="6h">6 hours</option>
282
- <option value="24h">24 hours</option>
283
- <option value="7d">7 days</option>
284
- </select>
285
- `}_renderDeliveryRow(e){return i`
286
- <ic-delivery-row
287
- .trace=${e}
288
- @trace-click=${this._onTraceClick}
289
- ></ic-delivery-row>
290
- ${this._expandedTraceId===e.traceId?this._renderTraceDetail(e):v}
291
- `}_renderDeliveryTab(){const e=this._getFilteredTraces();return i`
292
- ${this._renderDeliveryStats()}
293
-
294
- <div class="filter-row">
295
- ${this._renderChannelFilterSelect()}
296
- ${this._renderStatusFilterSelect()}
297
- ${this._renderTimeRangeSelect()}
298
- </div>
299
-
300
- ${e.length===0?i`<ic-empty-state icon="truck" message="No delivery traces match the current filters"></ic-empty-state>`:i`
301
- <div class="grid-table-scroll">
302
- <div class="grid-table delivery-table" role="table" aria-label="Delivery traces">
303
- <div class="grid-header" role="row">
304
- <div class="cell" role="columnheader">Time</div>
305
- <div class="cell" role="columnheader">Channel</div>
306
- <div class="cell" role="columnheader">Message</div>
307
- <div class="cell" role="columnheader">Status</div>
308
- <div class="cell" role="columnheader">Latency</div>
309
- <div class="cell" role="columnheader">Steps</div>
310
- </div>
311
- ${e.map(t=>this._renderDeliveryRow(t))}
312
- </div>
313
- </div>
314
- `}
315
- `}_renderChannelsTab(){if(this._channelActivity.length===0)return i`<ic-empty-state icon="radio" title="No Channel Data" description="Channel activity will appear once channels are connected and processing messages."></ic-empty-state>`;const e=[...this._channelActivity].sort((r,n)=>r.isStale&&!n.isStale?-1:!r.isStale&&n.isStale?1:n.lastActiveAt-r.lastActiveAt),t=e.filter(r=>r.isStale).length;return i`
316
- ${t>0?i`<div class="stale-alert">${t} stale channel(s) detected</div>`:v}
317
-
318
- <div class="grid-table-scroll">
319
- <div class="grid-table channel-table" role="table" aria-label="Channel activity">
320
- <div class="grid-header" role="row">
321
- <div class="cell" role="columnheader">Channel</div>
322
- <div class="cell" role="columnheader">ID</div>
323
- <div class="cell cell-right" role="columnheader">Sent</div>
324
- <div class="cell cell-right" role="columnheader">Received</div>
325
- <div class="cell" role="columnheader">Last Active</div>
326
- <div class="cell" role="columnheader">Status</div>
327
- </div>
328
- ${e.map(r=>i`
329
- <div class="grid-row ${r.isStale?"stale":""}" role="row">
330
- <div class="cell" role="cell"><ic-tag variant=${r.channelType}>${r.channelType}</ic-tag></div>
331
- <div class="cell cell-mono" role="cell">${r.channelId}</div>
332
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(r.messagesSent)}</div>
333
- <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(r.messagesReceived)}</div>
334
- <div class="cell" role="cell"><ic-relative-time .timestamp=${r.lastActiveAt}></ic-relative-time></div>
335
- <div class="cell" role="cell">
336
- ${r.isStale?i`<ic-tag variant="warning">Stale</ic-tag>`:i`<ic-tag variant="success">Active</ic-tag>`}
337
- </div>
338
- </div>
339
- `)}
340
- </div>
341
- </div>
342
- `}_renderTabContent(){switch(this._activeTab){case"overview":return this._renderOverview();case"billing":return this._renderBilling();case"delivery":return this._renderDeliveryTab();case"channels":return this._renderChannelsTab();case"diagnostics":return this._renderDiagnostics();default:return this._renderOverview()}}render(){return this._loadState==="loading"&&this.rpcClient?i`<ic-skeleton-view variant="table"></ic-skeleton-view>`:this._loadState==="error"?i`
343
- <div class="error-container">
344
- <span class="error-message">${this._error}</span>
345
- <button class="retry-btn" @click=${()=>this._tryLoad()}>Retry</button>
346
- </div>
347
- `:i`
348
- <div class="observe-view">
349
- <ic-tabs
350
- .tabs=${E}
351
- .activeTab=${this._activeTab}
352
- @tab-change=${this._onTabChange}
353
- >
354
- <div slot="overview">${this._activeTab==="overview"?this._renderOverview():v}</div>
355
- <div slot="billing">${this._activeTab==="billing"?this._renderBilling():v}</div>
356
- <div slot="delivery">${this._activeTab==="delivery"?this._renderDeliveryTab():v}</div>
357
- <div slot="channels">${this._activeTab==="channels"?this._renderChannelsTab():v}</div>
358
- <div slot="diagnostics">${this._activeTab==="diagnostics"?this._renderDiagnostics():v}</div>
359
- </ic-tabs>
360
- </div>
361
- `}};s.styles=[S,k,R`
1
+ import{c as e,f as t,h as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./decorate-BvWYovGE.js";import{n as u,t as d}from"./observability-types-D0tkwElU.js";import{i as f,t as p}from"./index-FLPhHz8p.js";import"./ic-tag-CvMVQFRR.js";import"./ic-relative-time-B3UAnTqg.js";import"./ic-empty-state-CM3Wbj2f.js";import"./ic-tabs-yBjkWKJH.js";import"./ic-delivery-row-B3YwjjuM.js";var m=3e4,h=[{id:`overview`,label:`Overview`},{id:`billing`,label:`Billing`},{id:`delivery`,label:`Delivery`},{id:`channels`,label:`Channels`},{id:`diagnostics`,label:`Diagnostics`}],g=class extends r{constructor(...e){super(...e),this.rpcClient=null,this.eventDispatcher=null,this.initialTab=`overview`,this._sse=null,this._reloadDebounce=null,this._loadState=`loading`,this._activeTab=`overview`,this._error=``,this._requestsToday=0,this._tokensToday=0,this._costToday=0,this._errorsToday=0,this._tokenUsage24h=[],this._billingByProvider=[],this._billingByAgent=[],this._billingTotal=null,this._diagnosticsEvents=[],this._deliveryTraces=[],this._deliveryStats=null,this._channelActivity=[],this._agentHealth=[],this._channelHealth=[],this._resetConfirming=!1,this._resetInput=``,this._deliveryChannelFilter=`all`,this._deliveryStatusFilter=`all`,this._deliveryTimeRange=`1h`,this._expandedTraceId=null,this._refreshInterval=null,this._rpcStatusUnsub=null}static{this.styles=[o,i,n`
362
2
  :host {
363
3
  display: block;
364
4
  }
@@ -769,46 +409,406 @@ import{a as x,S as $,b as i,g as C,A as v,s as S,f as k,i as R,n as T,r as o,t a
769
409
  outline-offset: 2px;
770
410
  }
771
411
 
772
- .reset-actions {
773
- display: flex;
774
- gap: var(--ic-space-sm);
775
- }
412
+ .reset-actions {
413
+ display: flex;
414
+ gap: var(--ic-space-sm);
415
+ }
416
+
417
+ .reset-cancel-btn {
418
+ padding: 0.5rem 1rem;
419
+ background: var(--ic-surface);
420
+ border: 1px solid var(--ic-border);
421
+ border-radius: var(--ic-radius-md);
422
+ color: var(--ic-text);
423
+ font-size: var(--ic-text-sm);
424
+ cursor: pointer;
425
+ font-family: inherit;
426
+ }
427
+
428
+ .reset-confirm-btn {
429
+ padding: 0.5rem 1rem;
430
+ border: none;
431
+ border-radius: var(--ic-radius-md);
432
+ font-size: var(--ic-text-sm);
433
+ cursor: pointer;
434
+ font-family: inherit;
435
+ font-weight: 500;
436
+ }
437
+
438
+ .reset-confirm-btn[disabled] {
439
+ background: var(--ic-surface);
440
+ color: var(--ic-text-dim);
441
+ cursor: not-allowed;
442
+ }
443
+
444
+ .reset-confirm-btn:not([disabled]) {
445
+ background: var(--ic-error);
446
+ color: #fff;
447
+ }
448
+
449
+ .sparkline-side {
450
+ display: flex;
451
+ flex-direction: column;
452
+ gap: var(--ic-space-lg);
453
+ }
454
+ `]}connectedCallback(){super.connectedCallback(),this._activeTab=this.initialTab,this._initSse()}_initSse(){!this.eventDispatcher||this._sse||(this._sse=new f(this,this.eventDispatcher,{"observability:metrics":()=>{this._scheduleReload(500)},"observability:token_usage":()=>{this._scheduleReload()},"observability:reset":()=>{this._scheduleReload()}}))}_scheduleReload(e=300){this._reloadDebounce!==null&&clearTimeout(this._reloadDebounce),this._reloadDebounce=setTimeout(()=>{this._reloadDebounce=null,this._loadData()},e)}disconnectedCallback(){super.disconnectedCallback(),this._reloadDebounce!==null&&(clearTimeout(this._reloadDebounce),this._reloadDebounce=null),this._refreshInterval!==null&&(clearInterval(this._refreshInterval),this._refreshInterval=null),this._rpcStatusUnsub?.(),this._rpcStatusUnsub=null}willUpdate(e){e.has(`initialTab`)&&(this._activeTab=this.initialTab),e.has(`rpcClient`)&&(this.rpcClient?this._tryLoad():this._loadState=`loaded`),e.has(`eventDispatcher`)&&this.eventDispatcher&&!this._sse&&this._initSse()}_tryLoad(){if(!this.rpcClient){this._loadState=`loaded`;return}this._rpcStatusUnsub?.(),this.rpcClient.status===`connected`?this._startLoading():this._rpcStatusUnsub=this.rpcClient.onStatusChange(e=>{e===`connected`&&this._startLoading()})}_startLoading(){this._loadData(),this._refreshInterval===null&&(this._refreshInterval=setInterval(()=>{this._loadData()},m))}async _loadData(){if(!this.rpcClient||this.rpcClient.status!==`connected`){this._loadState=`loaded`;return}let e=this.rpcClient,[t,n,r,i,a,o,s,c,l]=await Promise.allSettled([e.call(`obs.delivery.stats`),e.call(`obs.billing.total`),e.call(`obs.billing.usage24h`),e.call(`obs.billing.byProvider`),e.call(`obs.diagnostics`),e.call(`obs.delivery.recent`),e.call(`obs.channels.all`),e.call(`agents.list`),e.call(`channels.list`)]),u=!1,d=``;if(t.status===`fulfilled`){let e=t.value,n=Number(e.total??e.totalDelivered??0),r=Number(e.failures??e.failed??0),i=0;e.successRate===void 0?n>0&&(i=Number(e.successes??0)/n*100):i=Number(e.successRate),this._deliveryStats={successRate:i,avgLatencyMs:Number(e.avgLatencyMs??0),totalDelivered:n,failed:r},this._requestsToday=n,this._errorsToday=r,u=!0}else d=t.reason instanceof Error?t.reason.message:`Failed to load delivery stats`;if(n.status===`fulfilled`){let e=n.value,t={totalTokens:Number(e.totalTokens??0),totalCost:Number(e.totalCost??0)};this._billingTotal=t,this._tokensToday=t.totalTokens,this._costToday=t.totalCost,u=!0}else d||=n.reason instanceof Error?n.reason.message:`Failed to load billing total`;if(r.status===`fulfilled`&&(this._tokenUsage24h=Array.isArray(r.value)?r.value:[],u=!0),i.status===`fulfilled`){let e=i.value;if(Array.isArray(e))this._billingByProvider=e;else{let t=e;this._billingByProvider=Array.isArray(t.providers)?t.providers:[]}u=!0}if(a.status===`fulfilled`){let e=a.value;if(Array.isArray(e))this._diagnosticsEvents=e;else{let t=e;this._diagnosticsEvents=Array.isArray(t.events)?t.events:[]}u=!0}if(o.status===`fulfilled`){let e=o.value;if(Array.isArray(e))this._deliveryTraces=e;else{let t=e;this._deliveryTraces=Array.isArray(t.deliveries)?t.deliveries:[]}u=!0}if(s.status===`fulfilled`){let e=s.value;if(Array.isArray(e))this._channelActivity=e;else{let t=e;this._channelActivity=Array.isArray(t.channels)?t.channels:[]}u=!0}if(c.status===`fulfilled`){let t=Array.isArray(c.value.agents)?c.value.agents:[];if(t.length>0){let n=await Promise.allSettled(t.map(t=>e.call(`agents.get`,{agentId:t})));this._agentHealth=n.filter(e=>e.status===`fulfilled`).map(e=>e.value)}else this._agentHealth=[];u=!0}l.status===`fulfilled`&&(this._channelHealth=Array.isArray(l.value.channels)?l.value.channels:[],u=!0),u?(this._loadState=`loaded`,this._error=``):(this._loadState=`error`,this._error=d||`Failed to load observability data`)}_onTabChange(e){this._activeTab=e.detail}_formatNumber(e){return new Intl.NumberFormat(`en-US`).format(e)}_formatTokens(e){if(e>=1e6){let t=e/1e6;return t%1==0?`${t}M`:`${t.toFixed(1)}M`}if(e>=1e3){let t=e/1e3;return t%1==0?`${t}K`:`${t.toFixed(1)}K`}return String(e)}_formatCost(e){return`$${(e??0).toFixed(2)}`}_getErrorRate(){return!this._deliveryStats||this._deliveryStats.totalDelivered===0?0:this._deliveryStats.failed/this._deliveryStats.totalDelivered*100}_getErrorRateColor(){let e=this._getErrorRate();return e>5?`var(--ic-error)`:e>1?`var(--ic-warning)`:`var(--ic-success)`}_getLatencyColor(){let e=this._deliveryStats?.avgLatencyMs??0;return e>5e3?`var(--ic-error)`:e>2e3?`var(--ic-warning)`:``}_getAgentModel(e){return typeof e.model==`string`?e.model:`unknown`}_onResetClick(){this._resetConfirming=!0,this._resetInput=``}_onResetCancel(){this._resetConfirming=!1,this._resetInput=``}_onResetInput(e){this._resetInput=e.target.value}async _onResetConfirm(){if(!(this._resetInput!==`RESET`||!this.rpcClient)){try{await this.rpcClient.call(`obs.reset`)}catch{}this._resetConfirming=!1,this._resetInput=``,await this._loadData()}}_renderOverview(){let e=this.rpcClient&&this.rpcClient.status===`connected`,n=this._getErrorRate(),r=e?this._deliveryStats&&this._deliveryStats.totalDelivered>0?`${n.toFixed(1)}%`:`0%`:`---`,i=e?this._deliveryStats?`${this._deliveryStats.avgLatencyMs}ms`:`0ms`:`---`,a=e?String(this._agentHealth.filter(e=>!e.suspended).length):`---`;return t`
455
+ <!-- 6 Stat Cards -->
456
+ <div class="stats-grid">
457
+ <ic-stat-card
458
+ label="Requests/min"
459
+ .value=${e?this._formatNumber(this._requestsToday):`---`}
460
+ ></ic-stat-card>
461
+ <ic-stat-card
462
+ label="Error Rate"
463
+ .value=${r}
464
+ ></ic-stat-card>
465
+ <ic-stat-card
466
+ label="Avg Latency"
467
+ .value=${i}
468
+ ></ic-stat-card>
469
+ <ic-stat-card
470
+ label="Active Agents"
471
+ .value=${a}
472
+ ></ic-stat-card>
473
+ <ic-stat-card
474
+ label="Tokens (24h)"
475
+ .value=${e?this._formatTokens(this._tokensToday):`---`}
476
+ ></ic-stat-card>
477
+ <ic-stat-card
478
+ label="Cost Today"
479
+ .value=${e?this._formatCost(this._costToday):`---`}
480
+ ></ic-stat-card>
481
+ </div>
482
+
483
+ <!-- Time-series Charts -->
484
+ <div class="section">
485
+ <div class="charts-section">
486
+ <div>
487
+ <div class="chart-title">Token Usage (24h)</div>
488
+ <div class="chart-container">
489
+ ${this._tokenUsage24h.length>0?t`
490
+ <div class="bar-chart" aria-label="Token usage bar chart">
491
+ ${this._renderTokenBars()}
492
+ </div>
493
+ <div class="chart-labels">
494
+ <span>00</span>
495
+ <span>06</span>
496
+ <span>12</span>
497
+ <span>18</span>
498
+ <span>24</span>
499
+ </div>
500
+ `:t`<div style="color: var(--ic-text-dim); text-align: center; padding: var(--ic-space-lg);">No usage data</div>`}
501
+ </div>
502
+ </div>
503
+ <div class="sparkline-side">
504
+ <div>
505
+ <div class="chart-title">Cost Trend (7d)</div>
506
+ <div class="chart-container">
507
+ <ic-sparkline
508
+ .data=${this._costToday>0?[this._costToday]:[]}
509
+ .width=${200}
510
+ .height=${60}
511
+ color="var(--ic-accent)"
512
+ ></ic-sparkline>
513
+ </div>
514
+ </div>
515
+ <div>
516
+ <div class="chart-title">Error Rate (24h)</div>
517
+ <div class="chart-container">
518
+ <ic-sparkline
519
+ .data=${this._errorsToday>0?[this._errorsToday]:[]}
520
+ .width=${200}
521
+ .height=${60}
522
+ color="var(--ic-error)"
523
+ ></ic-sparkline>
524
+ </div>
525
+ </div>
526
+ </div>
527
+ </div>
528
+ </div>
529
+
530
+ <!-- Health Grids -->
531
+ <div class="section">
532
+ <div class="health-grids">
533
+ <div>
534
+ <div class="section-title">Agent Health</div>
535
+ ${this._renderAgentHealthGrid()}
536
+ </div>
537
+ <div>
538
+ <div class="section-title">Channel Health</div>
539
+ ${this._renderChannelHealthGrid()}
540
+ </div>
541
+ </div>
542
+ </div>
776
543
 
777
- .reset-cancel-btn {
778
- padding: 0.5rem 1rem;
779
- background: var(--ic-surface);
780
- border: 1px solid var(--ic-border);
781
- border-radius: var(--ic-radius-md);
782
- color: var(--ic-text);
783
- font-size: var(--ic-text-sm);
784
- cursor: pointer;
785
- font-family: inherit;
786
- }
544
+ <!-- Reset Section -->
545
+ ${this._renderResetSection()}
546
+ `}_renderTokenBars(){let e=Math.max(...this._tokenUsage24h.map(e=>e.tokens),1);return this._tokenUsage24h.map(n=>t`<div class="bar" style="height: ${n.tokens/e*100}%" title="${n.hour}:00 - ${this._formatTokens(n.tokens)} tokens"></div>`)}_renderAgentHealthGrid(){return this._agentHealth.length===0?t`<div class="health-empty">No agents configured</div>`:t`
547
+ <div class="grid-table health-grid-table" role="table" aria-label="Agent health">
548
+ <div class="grid-header" role="row">
549
+ <div class="cell" role="columnheader">Agent</div>
550
+ <div class="cell" role="columnheader">Model</div>
551
+ <div class="cell" role="columnheader">Status</div>
552
+ </div>
553
+ ${this._agentHealth.map(e=>t`
554
+ <div class="grid-row" role="row">
555
+ <div class="cell cell-mono" role="cell">${e.agentId}</div>
556
+ <div class="cell" role="cell">${this._getAgentModel(e.config)}</div>
557
+ <div class="cell" role="cell">
558
+ ${e.suspended?t`<ic-tag variant="default">suspended</ic-tag>`:t`<ic-tag variant="success">active</ic-tag>`}
559
+ </div>
560
+ </div>
561
+ `)}
562
+ </div>
563
+ `}_renderChannelHealthGrid(){return this._channelHealth.length===0?t`<div class="health-empty">No channels configured</div>`:t`
564
+ <div class="grid-table health-grid-table" role="table" aria-label="Channel health">
565
+ <div class="grid-header" role="row">
566
+ <div class="cell" role="columnheader">Channel</div>
567
+ <div class="cell" role="columnheader">Type</div>
568
+ <div class="cell" role="columnheader">Status</div>
569
+ </div>
570
+ ${this._channelHealth.map(e=>{let n=p(e.status);return t`
571
+ <div class="grid-row" role="row">
572
+ <div class="cell" role="cell">${e.channelId??e.channelType}</div>
573
+ <div class="cell" role="cell">${e.channelType}</div>
574
+ <div class="cell" role="cell">
575
+ <ic-tag variant=${{green:`success`,yellow:`warning`,red:`error`,gray:`default`}[n.severity]}>
576
+ ${n.label}
577
+ </ic-tag>
578
+ </div>
579
+ </div>
580
+ `})}
581
+ </div>
582
+ `}_renderResetSection(){return t`
583
+ <div class="reset-section">
584
+ <div class="section-title">Reset Observability Data</div>
585
+ ${this._resetConfirming?t`
586
+ <div class="reset-warning">
587
+ This will permanently clear all observability data. Type RESET to confirm.
588
+ </div>
589
+ <input
590
+ class="reset-input"
591
+ type="text"
592
+ .value=${this._resetInput}
593
+ @input=${this._onResetInput}
594
+ placeholder="Type RESET"
595
+ />
596
+ <div class="reset-actions">
597
+ <button class="reset-cancel-btn" @click=${this._onResetCancel}>Cancel</button>
598
+ <button
599
+ class="reset-confirm-btn"
600
+ ?disabled=${this._resetInput!==`RESET`}
601
+ @click=${this._onResetConfirm}
602
+ >Confirm Reset</button>
603
+ </div>
604
+ `:t`
605
+ <button class="reset-btn" @click=${this._onResetClick}>
606
+ Reset Observability Data
607
+ </button>
608
+ `}
609
+ </div>
610
+ `}_renderBilling(){return this._billingByProvider.length===0&&this._billingByAgent.length===0?t`<ic-empty-state icon="dollar-sign" message="No billing data available"></ic-empty-state>`:t`
611
+ ${this._billingByProvider.length>0?t`
612
+ <div class="section">
613
+ <div class="section-title">By Provider</div>
614
+ <div class="grid-table-scroll">
615
+ <div class="grid-table provider-table" role="table">
616
+ <div class="grid-header" role="row">
617
+ <div class="cell" role="columnheader">Provider</div>
618
+ <div class="cell cell-right" role="columnheader">Total Tokens</div>
619
+ <div class="cell cell-right" role="columnheader">Calls</div>
620
+ <div class="cell cell-right" role="columnheader">Cost</div>
621
+ </div>
622
+ ${this._billingByProvider.map(e=>t`
623
+ <div class="grid-row" role="row">
624
+ <div class="cell" role="cell">${e.provider}</div>
625
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.totalTokens)}</div>
626
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.callCount)}</div>
627
+ <div class="cell cell-mono cell-right" role="cell">${this._formatCost(e.totalCost)}</div>
628
+ </div>
629
+ `)}
630
+ ${this._renderProviderTotal()}
631
+ </div>
632
+ </div>
633
+ </div>
634
+ `:l}
787
635
 
788
- .reset-confirm-btn {
789
- padding: 0.5rem 1rem;
790
- border: none;
791
- border-radius: var(--ic-radius-md);
792
- font-size: var(--ic-text-sm);
793
- cursor: pointer;
794
- font-family: inherit;
795
- font-weight: 500;
796
- }
636
+ ${this._billingByAgent.length>0?t`
637
+ <div class="section">
638
+ <div class="section-title">By Agent</div>
639
+ <div class="grid-table-scroll">
640
+ <div class="grid-table agent-table" role="table">
641
+ <div class="grid-header" role="row">
642
+ <div class="cell" role="columnheader">Agent</div>
643
+ <div class="cell cell-right" role="columnheader">Tokens</div>
644
+ <div class="cell cell-right" role="columnheader">% Total</div>
645
+ <div class="cell cell-right" role="columnheader">Cost</div>
646
+ </div>
647
+ ${this._billingByAgent.map(e=>t`
648
+ <div class="grid-row" role="row">
649
+ <div class="cell" role="cell">${e.agentId}</div>
650
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.totalTokens)}</div>
651
+ <div class="cell cell-mono cell-right" role="cell">${e.percentOfTotal.toFixed(1)}%</div>
652
+ <div class="cell cell-mono cell-right" role="cell">${this._formatCost(e.cost)}</div>
653
+ </div>
654
+ `)}
655
+ </div>
656
+ </div>
657
+ </div>
658
+ `:l}
659
+ `}_renderProviderTotal(){let e=this._billingByProvider.reduce((e,t)=>({totalTokens:e.totalTokens+t.totalTokens,callCount:e.callCount+t.callCount,totalCost:e.totalCost+t.totalCost}),{totalTokens:0,callCount:0,totalCost:0});return t`
660
+ <div class="grid-row total-row" role="row">
661
+ <div class="cell" role="cell">Total</div>
662
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.totalTokens)}</div>
663
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.callCount)}</div>
664
+ <div class="cell cell-mono cell-right" role="cell">${this._formatCost(e.totalCost)}</div>
665
+ </div>
666
+ `}_renderDiagnostics(){return this._diagnosticsEvents.length===0?t`<ic-empty-state icon="activity" message="No diagnostic events"></ic-empty-state>`:t`
667
+ <div class="grid-table-scroll">
668
+ <div class="grid-table diagnostics-table" role="table">
669
+ <div class="grid-header" role="row">
670
+ <div class="cell" role="columnheader">Time</div>
671
+ <div class="cell" role="columnheader">Category</div>
672
+ <div class="cell" role="columnheader">Message</div>
673
+ <div class="cell" role="columnheader">Level</div>
674
+ </div>
675
+ ${[...this._diagnosticsEvents].sort((e,t)=>t.timestamp-e.timestamp).map(e=>t`
676
+ <div class="grid-row" role="row">
677
+ <div class="cell" role="cell">
678
+ <ic-relative-time .timestamp=${e.timestamp}></ic-relative-time>
679
+ </div>
680
+ <div class="cell" role="cell">
681
+ <ic-tag>${e.category}</ic-tag>
682
+ </div>
683
+ <div class="cell" role="cell">${u(e)}</div>
684
+ <div class="cell" role="cell">
685
+ <ic-tag variant=${d(e)===`error`?`error`:d(e)===`warn`?`warning`:`default`}>
686
+ ${d(e)}
687
+ </ic-tag>
688
+ </div>
689
+ </div>
690
+ `)}
691
+ </div>
692
+ </div>
693
+ `}_getTimeRangeMs(){return{"1h":36e5,"6h":216e5,"24h":864e5,"7d":6048e5}[this._deliveryTimeRange]??36e5}_getFilteredTraces(){let e=Date.now(),t=this._getTimeRangeMs();return this._deliveryTraces.filter(n=>!(this._deliveryChannelFilter!==`all`&&n.channelType!==this._deliveryChannelFilter||this._deliveryStatusFilter!==`all`&&n.status!==this._deliveryStatusFilter||n.timestamp<e-t)).sort((e,t)=>t.timestamp-e.timestamp)}_onDeliveryChannelFilter(e){this._deliveryChannelFilter=e.target.value}_onDeliveryStatusFilter(e){this._deliveryStatusFilter=e.target.value}_onDeliveryTimeRange(e){this._deliveryTimeRange=e.target.value}_onTraceClick(e){let t=e.detail;this._expandedTraceId=this._expandedTraceId===t?null:t}_renderDeliveryStats(){if(!this._deliveryStats)return l;let e=this._deliveryStats,n=e.totalDelivered>0;return t`
694
+ <div class="stats-summary">
695
+ <span>Success <span class="stat-value ${n?e.successRate>=99?`rate-green`:e.successRate>=95?`rate-yellow`:`rate-red`:``}">${n?`${e.successRate.toFixed(1)}%`:`N/A`}</span></span>
696
+ <span>Avg <span class="stat-value">${n?`${e.avgLatencyMs}ms`:`N/A`}</span></span>
697
+ <span>Total <span class="stat-value">${this._formatNumber(e.totalDelivered)}</span></span>
698
+ </div>
699
+ `}_renderTraceDetail(e){return!e.steps||e.steps.length===0?t`
700
+ <div class="trace-detail">
701
+ <div class="trace-detail-title">Delivery Steps</div>
702
+ <div style="color: var(--ic-text-dim); font-size: var(--ic-text-sm); margin-top: var(--ic-space-sm);">
703
+ No step details available
704
+ </div>
705
+ </div>
706
+ `:t`
707
+ <div class="trace-detail">
708
+ <div class="trace-detail-title">Delivery Steps</div>
709
+ <div class="step-list">
710
+ ${e.steps.map(e=>t`
711
+ <div class="step-item">
712
+ <span class="step-dot ${e.status}"></span>
713
+ <span>${e.name} &mdash; ${e.durationMs}ms</span>
714
+ </div>
715
+ ${e.error?t`<div class="step-error">${e.error}</div>`:l}
716
+ `)}
717
+ </div>
718
+ </div>
719
+ `}_renderChannelFilterSelect(){let e=[...new Set(this._deliveryTraces.map(e=>e.channelType))];return t`
720
+ <select class="filter-select" @change=${this._onDeliveryChannelFilter}>
721
+ <option value="all">All Channels</option>
722
+ ${e.map(e=>t`<option value=${e}>${e}</option>`)}
723
+ </select>
724
+ `}_renderStatusFilterSelect(){return t`
725
+ <select class="filter-select" @change=${this._onDeliveryStatusFilter}>
726
+ <option value="all">All Statuses</option>
727
+ <option value="success">Success</option>
728
+ <option value="failed">Failed</option>
729
+ <option value="timeout">Timeout</option>
730
+ </select>
731
+ `}_renderTimeRangeSelect(){return t`
732
+ <select class="filter-select" @change=${this._onDeliveryTimeRange}>
733
+ <option value="1h">1 hour</option>
734
+ <option value="6h">6 hours</option>
735
+ <option value="24h">24 hours</option>
736
+ <option value="7d">7 days</option>
737
+ </select>
738
+ `}_renderDeliveryRow(e){return t`
739
+ <ic-delivery-row
740
+ .trace=${e}
741
+ @trace-click=${this._onTraceClick}
742
+ ></ic-delivery-row>
743
+ ${this._expandedTraceId===e.traceId?this._renderTraceDetail(e):l}
744
+ `}_renderDeliveryTab(){let e=this._getFilteredTraces();return t`
745
+ ${this._renderDeliveryStats()}
797
746
 
798
- .reset-confirm-btn[disabled] {
799
- background: var(--ic-surface);
800
- color: var(--ic-text-dim);
801
- cursor: not-allowed;
802
- }
747
+ <div class="filter-row">
748
+ ${this._renderChannelFilterSelect()}
749
+ ${this._renderStatusFilterSelect()}
750
+ ${this._renderTimeRangeSelect()}
751
+ </div>
803
752
 
804
- .reset-confirm-btn:not([disabled]) {
805
- background: var(--ic-error);
806
- color: #fff;
807
- }
753
+ ${e.length===0?t`<ic-empty-state icon="truck" message="No delivery traces match the current filters"></ic-empty-state>`:t`
754
+ <div class="grid-table-scroll">
755
+ <div class="grid-table delivery-table" role="table" aria-label="Delivery traces">
756
+ <div class="grid-header" role="row">
757
+ <div class="cell" role="columnheader">Time</div>
758
+ <div class="cell" role="columnheader">Channel</div>
759
+ <div class="cell" role="columnheader">Message</div>
760
+ <div class="cell" role="columnheader">Status</div>
761
+ <div class="cell" role="columnheader">Latency</div>
762
+ <div class="cell" role="columnheader">Steps</div>
763
+ </div>
764
+ ${e.map(e=>this._renderDeliveryRow(e))}
765
+ </div>
766
+ </div>
767
+ `}
768
+ `}_renderChannelsTab(){if(this._channelActivity.length===0)return t`<ic-empty-state icon="radio" title="No Channel Data" description="Channel activity will appear once channels are connected and processing messages."></ic-empty-state>`;let e=[...this._channelActivity].sort((e,t)=>e.isStale&&!t.isStale?-1:!e.isStale&&t.isStale?1:t.lastActiveAt-e.lastActiveAt),n=e.filter(e=>e.isStale).length;return t`
769
+ ${n>0?t`<div class="stale-alert">${n} stale channel(s) detected</div>`:l}
808
770
 
809
- .sparkline-side {
810
- display: flex;
811
- flex-direction: column;
812
- gap: var(--ic-space-lg);
813
- }
814
- `];l([T({attribute:!1})],s.prototype,"rpcClient",2);l([T({attribute:!1})],s.prototype,"eventDispatcher",2);l([T()],s.prototype,"initialTab",2);l([o()],s.prototype,"_loadState",2);l([o()],s.prototype,"_activeTab",2);l([o()],s.prototype,"_error",2);l([o()],s.prototype,"_requestsToday",2);l([o()],s.prototype,"_tokensToday",2);l([o()],s.prototype,"_costToday",2);l([o()],s.prototype,"_errorsToday",2);l([o()],s.prototype,"_tokenUsage24h",2);l([o()],s.prototype,"_billingByProvider",2);l([o()],s.prototype,"_billingByAgent",2);l([o()],s.prototype,"_billingTotal",2);l([o()],s.prototype,"_diagnosticsEvents",2);l([o()],s.prototype,"_deliveryTraces",2);l([o()],s.prototype,"_deliveryStats",2);l([o()],s.prototype,"_channelActivity",2);l([o()],s.prototype,"_agentHealth",2);l([o()],s.prototype,"_channelHealth",2);l([o()],s.prototype,"_resetConfirming",2);l([o()],s.prototype,"_resetInput",2);l([o()],s.prototype,"_deliveryChannelFilter",2);l([o()],s.prototype,"_deliveryStatusFilter",2);l([o()],s.prototype,"_deliveryTimeRange",2);l([o()],s.prototype,"_expandedTraceId",2);s=l([A("ic-observe-view")],s);export{s as IcObserveView};
771
+ <div class="grid-table-scroll">
772
+ <div class="grid-table channel-table" role="table" aria-label="Channel activity">
773
+ <div class="grid-header" role="row">
774
+ <div class="cell" role="columnheader">Channel</div>
775
+ <div class="cell" role="columnheader">ID</div>
776
+ <div class="cell cell-right" role="columnheader">Sent</div>
777
+ <div class="cell cell-right" role="columnheader">Received</div>
778
+ <div class="cell" role="columnheader">Last Active</div>
779
+ <div class="cell" role="columnheader">Status</div>
780
+ </div>
781
+ ${e.map(e=>t`
782
+ <div class="grid-row ${e.isStale?`stale`:``}" role="row">
783
+ <div class="cell" role="cell"><ic-tag variant=${e.channelType}>${e.channelType}</ic-tag></div>
784
+ <div class="cell cell-mono" role="cell">${e.channelId}</div>
785
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.messagesSent)}</div>
786
+ <div class="cell cell-mono cell-right" role="cell">${this._formatNumber(e.messagesReceived)}</div>
787
+ <div class="cell" role="cell"><ic-relative-time .timestamp=${e.lastActiveAt}></ic-relative-time></div>
788
+ <div class="cell" role="cell">
789
+ ${e.isStale?t`<ic-tag variant="warning">Stale</ic-tag>`:t`<ic-tag variant="success">Active</ic-tag>`}
790
+ </div>
791
+ </div>
792
+ `)}
793
+ </div>
794
+ </div>
795
+ `}_renderTabContent(){switch(this._activeTab){case`overview`:return this._renderOverview();case`billing`:return this._renderBilling();case`delivery`:return this._renderDeliveryTab();case`channels`:return this._renderChannelsTab();case`diagnostics`:return this._renderDiagnostics();default:return this._renderOverview()}}render(){return this._loadState===`loading`&&this.rpcClient?t`<ic-skeleton-view variant="table"></ic-skeleton-view>`:this._loadState===`error`?t`
796
+ <div class="error-container">
797
+ <span class="error-message">${this._error}</span>
798
+ <button class="retry-btn" @click=${()=>this._tryLoad()}>Retry</button>
799
+ </div>
800
+ `:t`
801
+ <div class="observe-view">
802
+ <ic-tabs
803
+ .tabs=${h}
804
+ .activeTab=${this._activeTab}
805
+ @tab-change=${this._onTabChange}
806
+ >
807
+ <div slot="overview">${this._activeTab===`overview`?this._renderOverview():l}</div>
808
+ <div slot="billing">${this._activeTab===`billing`?this._renderBilling():l}</div>
809
+ <div slot="delivery">${this._activeTab===`delivery`?this._renderDeliveryTab():l}</div>
810
+ <div slot="channels">${this._activeTab===`channels`?this._renderChannelsTab():l}</div>
811
+ <div slot="diagnostics">${this._activeTab===`diagnostics`?this._renderDiagnostics():l}</div>
812
+ </ic-tabs>
813
+ </div>
814
+ `}};c([s({attribute:!1})],g.prototype,`rpcClient`,void 0),c([s({attribute:!1})],g.prototype,`eventDispatcher`,void 0),c([s()],g.prototype,`initialTab`,void 0),c([a()],g.prototype,`_loadState`,void 0),c([a()],g.prototype,`_activeTab`,void 0),c([a()],g.prototype,`_error`,void 0),c([a()],g.prototype,`_requestsToday`,void 0),c([a()],g.prototype,`_tokensToday`,void 0),c([a()],g.prototype,`_costToday`,void 0),c([a()],g.prototype,`_errorsToday`,void 0),c([a()],g.prototype,`_tokenUsage24h`,void 0),c([a()],g.prototype,`_billingByProvider`,void 0),c([a()],g.prototype,`_billingByAgent`,void 0),c([a()],g.prototype,`_billingTotal`,void 0),c([a()],g.prototype,`_diagnosticsEvents`,void 0),c([a()],g.prototype,`_deliveryTraces`,void 0),c([a()],g.prototype,`_deliveryStats`,void 0),c([a()],g.prototype,`_channelActivity`,void 0),c([a()],g.prototype,`_agentHealth`,void 0),c([a()],g.prototype,`_channelHealth`,void 0),c([a()],g.prototype,`_resetConfirming`,void 0),c([a()],g.prototype,`_resetInput`,void 0),c([a()],g.prototype,`_deliveryChannelFilter`,void 0),c([a()],g.prototype,`_deliveryStatusFilter`,void 0),c([a()],g.prototype,`_deliveryTimeRange`,void 0),c([a()],g.prototype,`_expandedTraceId`,void 0),g=c([e(`ic-observe-view`)],g);export{g as IcObserveView};