@copilotkit/web-inspector 1.68.3-canary.1787220377 → 1.69.0

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 (46) hide show
  1. package/README.md +28 -12
  2. package/dist/assets/inspector-logo-kite.cjs +12 -0
  3. package/dist/assets/inspector-logo-kite.cjs.map +1 -0
  4. package/dist/assets/inspector-logo-kite.mjs +6 -0
  5. package/dist/assets/inspector-logo-kite.mjs.map +1 -0
  6. package/dist/index.cjs +3197 -1473
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +122 -30
  9. package/dist/index.d.cts.map +1 -1
  10. package/dist/index.d.mts +122 -30
  11. package/dist/index.d.mts.map +1 -1
  12. package/dist/index.mjs +3198 -1474
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/index.umd.js +3716 -1517
  15. package/dist/index.umd.js.map +1 -1
  16. package/dist/lib/home-briefing.cjs +270 -0
  17. package/dist/lib/home-briefing.cjs.map +1 -0
  18. package/dist/lib/home-briefing.mjs +269 -0
  19. package/dist/lib/home-briefing.mjs.map +1 -0
  20. package/dist/lib/inspector-nav.cjs +58 -0
  21. package/dist/lib/inspector-nav.cjs.map +1 -0
  22. package/dist/lib/inspector-nav.mjs +53 -0
  23. package/dist/lib/inspector-nav.mjs.map +1 -0
  24. package/dist/lib/persistence.cjs +102 -0
  25. package/dist/lib/persistence.cjs.map +1 -1
  26. package/dist/lib/persistence.mjs +98 -1
  27. package/dist/lib/persistence.mjs.map +1 -1
  28. package/dist/lib/telemetry.cjs +47 -33
  29. package/dist/lib/telemetry.cjs.map +1 -1
  30. package/dist/lib/telemetry.d.cts +1 -1
  31. package/dist/lib/telemetry.d.cts.map +1 -1
  32. package/dist/lib/telemetry.d.mts +1 -1
  33. package/dist/lib/telemetry.d.mts.map +1 -1
  34. package/dist/lib/telemetry.mjs +43 -31
  35. package/dist/lib/telemetry.mjs.map +1 -1
  36. package/dist/package.cjs +1 -1
  37. package/dist/package.mjs +1 -1
  38. package/dist/styles/generated.cjs +1 -1
  39. package/dist/styles/generated.cjs.map +1 -1
  40. package/dist/styles/generated.mjs +1 -1
  41. package/dist/styles/generated.mjs.map +1 -1
  42. package/package.json +4 -4
  43. package/dist/assets/inspector-logo-icon.cjs +0 -12
  44. package/dist/assets/inspector-logo-icon.cjs.map +0 -1
  45. package/dist/assets/inspector-logo-icon.mjs +0 -6
  46. package/dist/assets/inspector-logo-icon.mjs.map +0 -1
@@ -0,0 +1,270 @@
1
+
2
+ //#region src/lib/home-briefing.ts
3
+ const SERVICE_DOCS_URL = {
4
+ threads: "https://docs.copilotkit.ai/threads",
5
+ memory: "https://docs.copilotkit.ai/premium/intelligence-platform",
6
+ a2ui: "https://docs.copilotkit.ai/generative-ui/a2ui",
7
+ "open-gen-ui": "https://docs.copilotkit.ai/generative-ui/open-generative-ui",
8
+ suggestions: "https://docs.copilotkit.ai/agentic-chat-ui",
9
+ audio: "https://docs.copilotkit.ai/voice",
10
+ websocket: "https://docs.copilotkit.ai/premium/intelligence-platform"
11
+ };
12
+ /** Return the Home hero button for a trusted metadata action. */
13
+ function homeHeroActionFromMetadata(action) {
14
+ if (action.kind === "manage_plan") return {
15
+ kind: action.kind,
16
+ url: action.url,
17
+ label: "Manage plan"
18
+ };
19
+ if (action.kind === "renew") return {
20
+ kind: action.kind,
21
+ url: action.url,
22
+ label: "Renew plan"
23
+ };
24
+ return {
25
+ kind: action.kind,
26
+ url: action.url,
27
+ label: "Setup Intelligence"
28
+ };
29
+ }
30
+ /** Return a short preview from markdown, without links or headings. */
31
+ function announcementPreview(markdown, maxLength = 140) {
32
+ const plain = markdown.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[#*_`]/g, "").replace(/\s+/g, " ").trim();
33
+ if (plain.length <= maxLength) return plain;
34
+ return `${plain.slice(0, maxLength).trimEnd()}…`;
35
+ }
36
+ function connectIntelligenceAction(action, connectUrl, licenseState) {
37
+ if (action) return action;
38
+ if (connectUrl && (licenseState === "none" || licenseState === "unknown")) return homeHeroActionFromMetadata({
39
+ kind: "enable_intelligence",
40
+ url: connectUrl
41
+ });
42
+ }
43
+ function heroForState(args) {
44
+ if (!args.connected) {
45
+ const renewing = args.action?.kind === "renew";
46
+ return {
47
+ connection: "disconnected",
48
+ title: renewing ? "Renew Intelligence" : "Intelligence is not setup",
49
+ body: renewing ? "Renew Intelligence to restore persistent Threads and Memory." : "Connect CopilotKit Intelligence to add persistent Threads, Learning and Analytics to your application. Inspect conversations and allow your agents to learn from real use.",
50
+ action: connectIntelligenceAction(args.action, args.connectUrl, args.licenseState)
51
+ };
52
+ }
53
+ return {
54
+ connection: "connected",
55
+ title: "Connected to Intelligence",
56
+ body: "Use Workbench to inspect threads and memory.",
57
+ action: args.action?.kind === "enable_intelligence" ? void 0 : args.action
58
+ };
59
+ }
60
+ function usageFromMetadata(metadata) {
61
+ const usage = metadata.usage;
62
+ if (!usage) return;
63
+ if (usage.limit.kind === "finite") return {
64
+ used: usage.used,
65
+ limitLabel: `${usage.used} / ${usage.limit.value}`,
66
+ ratio: usage.limit.value === 0 ? 1 : usage.used / usage.limit.value
67
+ };
68
+ if (usage.limit.kind === "unlimited") return {
69
+ used: usage.used,
70
+ limitLabel: `${usage.used} / unlimited`
71
+ };
72
+ return {
73
+ used: usage.used,
74
+ limitLabel: `${usage.used} used`
75
+ };
76
+ }
77
+ function newsFromAnnouncement(args) {
78
+ const markdown = args.markdown?.trim();
79
+ if (markdown && args.html) return {
80
+ title: markdown.match(/^#{1,3}\s+(.+)$/m)?.[1]?.trim() || "The latest from CopilotKit",
81
+ previewText: args.previewText?.trim() || announcementPreview(markdown, 160),
82
+ documentHtml: args.html,
83
+ empty: false
84
+ };
85
+ return {
86
+ title: "You're all caught up",
87
+ previewText: "Latest CopilotKit updates will appear here.",
88
+ empty: true
89
+ };
90
+ }
91
+ function runtimeEventSignal(event) {
92
+ if (!event) return {
93
+ label: "No events yet",
94
+ tone: "muted"
95
+ };
96
+ const eventDetails = {
97
+ id: event.id,
98
+ agentId: event.agentId,
99
+ type: event.type,
100
+ timestamp: event.timestamp
101
+ };
102
+ if (event.type === "RUN_ERROR" || event.type === "ERROR") return {
103
+ label: event.type === "RUN_ERROR" ? "Run error" : "Error",
104
+ tone: "error",
105
+ ...eventDetails
106
+ };
107
+ if (event.type === "RUN_FINISHED") return {
108
+ label: "Run completed",
109
+ tone: "success",
110
+ ...eventDetails
111
+ };
112
+ if (event.type.endsWith("_START") || event.type.endsWith("_STARTED") || event.type.endsWith("_CONTENT") || event.type.endsWith("_ARGS") || event.type.endsWith("_DELTA")) return {
113
+ label: "Last event is in progress",
114
+ tone: "active",
115
+ ...eventDetails
116
+ };
117
+ return {
118
+ label: "Last event received",
119
+ tone: "success",
120
+ ...eventDetails
121
+ };
122
+ }
123
+ function runtimeHealthFromInput(input) {
124
+ const lastEvent = runtimeEventSignal(input.lastRuntimeEvent);
125
+ if (input.runtimeConnectionState === "connected") return {
126
+ state: lastEvent.tone === "error" ? "error" : "healthy",
127
+ label: lastEvent.tone === "error" ? "Needs attention" : "Healthy",
128
+ runtime: {
129
+ label: "Available",
130
+ tone: "success"
131
+ },
132
+ liveUpdates: {
133
+ label: "Ready",
134
+ tone: "success"
135
+ },
136
+ lastEvent
137
+ };
138
+ if (input.runtimeConnectionState === "connecting") return {
139
+ state: "checking",
140
+ label: "Checking",
141
+ runtime: {
142
+ label: "Checking",
143
+ tone: "active"
144
+ },
145
+ liveUpdates: {
146
+ label: "Connecting",
147
+ tone: "active"
148
+ },
149
+ lastEvent
150
+ };
151
+ if (input.runtimeConnectionState === "unavailable") return {
152
+ state: "unavailable",
153
+ label: "Unavailable",
154
+ runtime: {
155
+ label: "Unavailable",
156
+ tone: "muted"
157
+ },
158
+ liveUpdates: {
159
+ label: "Not attached",
160
+ tone: "muted"
161
+ },
162
+ lastEvent
163
+ };
164
+ return {
165
+ state: input.runtimeConnectionState === "error" ? "error" : "offline",
166
+ label: input.runtimeConnectionState === "error" ? "Runtime error" : "Offline",
167
+ runtime: {
168
+ label: "Offline",
169
+ tone: "error"
170
+ },
171
+ liveUpdates: {
172
+ label: input.runtimeConnectionState === "error" ? "Error" : "Disconnected",
173
+ tone: "error"
174
+ },
175
+ lastEvent
176
+ };
177
+ }
178
+ /** Build the Home briefing from data the Inspector already has. */
179
+ function buildHomeModel(input) {
180
+ const metadataAction = input.metadata.threadsFooterAction ?? input.metadata.lockedAction;
181
+ const action = metadataAction ? homeHeroActionFromMetadata({
182
+ kind: metadataAction.kind,
183
+ url: metadataAction.url
184
+ }) : void 0;
185
+ const identity = input.metadata.identity;
186
+ const projectLinked = Boolean(identity);
187
+ const intelligenceConnected = input.metadata.licenseState === "valid" || input.metadata.licenseState === "unknown" && input.intelligenceConnected;
188
+ const usage = usageFromMetadata(input.metadata);
189
+ return {
190
+ hero: heroForState({
191
+ connected: intelligenceConnected,
192
+ action,
193
+ connectUrl: input.intelligenceSignupUrl,
194
+ licenseState: input.metadata.licenseState
195
+ }),
196
+ projectLinked,
197
+ project: identity ? {
198
+ organizationName: identity.organizationName,
199
+ projectName: identity.projectName,
200
+ planLabel: input.metadata.plan?.label,
201
+ license: input.metadata.licenseState,
202
+ usage
203
+ } : input.metadata.plan || usage ? {
204
+ organizationName: "Not linked",
205
+ projectName: "This runtime is not linked to a project",
206
+ planLabel: input.metadata.plan?.label,
207
+ license: input.metadata.licenseState,
208
+ usage
209
+ } : void 0,
210
+ runtime: {
211
+ url: input.runtimeUrl,
212
+ health: runtimeHealthFromInput(input)
213
+ },
214
+ services: [
215
+ {
216
+ id: "threads",
217
+ label: "Threads",
218
+ enabled: intelligenceConnected && input.threadsAvailable,
219
+ url: input.runtimeUrl,
220
+ docsUrl: SERVICE_DOCS_URL.threads
221
+ },
222
+ {
223
+ id: "memory",
224
+ label: "Memory",
225
+ enabled: intelligenceConnected && input.memoriesOn,
226
+ docsUrl: SERVICE_DOCS_URL.memory
227
+ },
228
+ {
229
+ id: "a2ui",
230
+ label: "A2UI",
231
+ enabled: input.a2uiOn,
232
+ docsUrl: SERVICE_DOCS_URL.a2ui
233
+ },
234
+ {
235
+ id: "open-gen-ui",
236
+ label: "Open Gen UI",
237
+ enabled: input.openGenUiOn,
238
+ docsUrl: SERVICE_DOCS_URL["open-gen-ui"]
239
+ },
240
+ {
241
+ id: "suggestions",
242
+ label: "Suggestions",
243
+ enabled: input.suggestionsOn,
244
+ docsUrl: SERVICE_DOCS_URL.suggestions
245
+ },
246
+ {
247
+ id: "audio",
248
+ label: "Audio",
249
+ enabled: input.audioOn,
250
+ docsUrl: SERVICE_DOCS_URL.audio
251
+ },
252
+ {
253
+ id: "websocket",
254
+ label: "Websocket",
255
+ enabled: intelligenceConnected && Boolean(input.websocketUrl),
256
+ url: input.websocketUrl,
257
+ docsUrl: SERVICE_DOCS_URL.websocket
258
+ }
259
+ ],
260
+ news: newsFromAnnouncement({
261
+ previewText: input.announcementPreviewText,
262
+ markdown: input.announcementMarkdown,
263
+ html: input.announcementHtml ?? void 0
264
+ })
265
+ };
266
+ }
267
+
268
+ //#endregion
269
+ exports.buildHomeModel = buildHomeModel;
270
+ //# sourceMappingURL=home-briefing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-briefing.cjs","names":[],"sources":["../../src/lib/home-briefing.ts"],"sourcesContent":["import type { InspectorMetadataProjection } from \"./inspector-metadata.js\";\n\nexport type HomeHeroActionKind =\n | \"enable_intelligence\"\n | \"manage_plan\"\n | \"renew\";\n\nexport type HomeHeroAction = {\n kind: HomeHeroActionKind;\n url: string;\n label: string;\n};\n\nexport type HomeConnection = \"connected\" | \"disconnected\";\n\nexport type HomeRuntimeConnectionState =\n | \"connected\"\n | \"connecting\"\n | \"disconnected\"\n | \"error\"\n | \"unavailable\";\n\nexport type HomeRuntimeHealthTone = \"success\" | \"active\" | \"error\" | \"muted\";\n\nexport type HomeServiceId =\n | \"threads\"\n | \"memory\"\n | \"a2ui\"\n | \"open-gen-ui\"\n | \"suggestions\"\n | \"audio\"\n | \"websocket\";\n\nexport type HomeServiceTile = {\n id: HomeServiceId;\n label: string;\n enabled: boolean;\n url?: string;\n docsUrl: string;\n};\n\nexport type HomeModel = {\n hero: {\n connection: HomeConnection;\n title: string;\n body: string;\n action?: HomeHeroAction;\n };\n project?: {\n organizationName: string;\n projectName: string;\n planLabel?: string;\n license: string;\n usage?: {\n used: number;\n limitLabel: string;\n ratio?: number;\n };\n };\n projectLinked: boolean;\n runtime: {\n url?: string;\n health: {\n state: \"healthy\" | \"checking\" | \"offline\" | \"error\" | \"unavailable\";\n label: string;\n runtime: {\n label: string;\n tone: HomeRuntimeHealthTone;\n };\n liveUpdates: {\n label: string;\n tone: HomeRuntimeHealthTone;\n };\n lastEvent: {\n label: string;\n tone: HomeRuntimeHealthTone;\n id?: string;\n agentId?: string;\n type?: string;\n timestamp?: number;\n };\n };\n };\n services: HomeServiceTile[];\n news: {\n title: string;\n previewText: string;\n documentHtml?: string;\n empty: boolean;\n };\n};\n\nexport type HomeBriefingInput = {\n intelligenceConnected: boolean;\n threadsAvailable: boolean;\n metadata: InspectorMetadataProjection;\n runtimeUrl?: string;\n runtimeConnectionState: HomeRuntimeConnectionState;\n lastRuntimeEvent?: {\n id: string;\n agentId: string;\n type: string;\n timestamp: number;\n };\n memoriesOn: boolean;\n a2uiOn: boolean;\n openGenUiOn: boolean;\n suggestionsOn: boolean;\n audioOn: boolean;\n websocketUrl?: string;\n announcementPreviewText?: string;\n announcementMarkdown?: string;\n announcementHtml?: string;\n intelligenceSignupUrl?: string;\n};\n\nconst SERVICE_DOCS_URL: Record<HomeServiceId, string> = {\n threads: \"https://docs.copilotkit.ai/threads\",\n memory: \"https://docs.copilotkit.ai/premium/intelligence-platform\",\n a2ui: \"https://docs.copilotkit.ai/generative-ui/a2ui\",\n \"open-gen-ui\": \"https://docs.copilotkit.ai/generative-ui/open-generative-ui\",\n suggestions: \"https://docs.copilotkit.ai/agentic-chat-ui\",\n audio: \"https://docs.copilotkit.ai/voice\",\n websocket: \"https://docs.copilotkit.ai/premium/intelligence-platform\",\n};\n\n/** Return the Home hero button for a trusted metadata action. */\nexport function homeHeroActionFromMetadata(action: {\n kind: HomeHeroActionKind;\n url: string;\n}): HomeHeroAction {\n if (action.kind === \"manage_plan\") {\n return { kind: action.kind, url: action.url, label: \"Manage plan\" };\n }\n\n if (action.kind === \"renew\") {\n return { kind: action.kind, url: action.url, label: \"Renew plan\" };\n }\n\n return {\n kind: action.kind,\n url: action.url,\n label: \"Setup Intelligence\",\n };\n}\n\n/** Return a short preview from markdown, without links or headings. */\nexport function announcementPreview(markdown: string, maxLength = 140): string {\n const plain = markdown\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/[#*_`]/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n if (plain.length <= maxLength) {\n return plain;\n }\n\n return `${plain.slice(0, maxLength).trimEnd()}…`;\n}\n\nfunction connectIntelligenceAction(\n action: HomeHeroAction | undefined,\n connectUrl?: string,\n licenseState?: InspectorMetadataProjection[\"licenseState\"],\n): HomeHeroAction | undefined {\n if (action) {\n return action;\n }\n\n if (connectUrl && (licenseState === \"none\" || licenseState === \"unknown\")) {\n return homeHeroActionFromMetadata({\n kind: \"enable_intelligence\",\n url: connectUrl,\n });\n }\n\n return undefined;\n}\n\nfunction heroForState(args: {\n connected: boolean;\n action?: HomeHeroAction;\n connectUrl?: string;\n licenseState: InspectorMetadataProjection[\"licenseState\"];\n}): HomeModel[\"hero\"] {\n if (!args.connected) {\n const renewing = args.action?.kind === \"renew\";\n return {\n connection: \"disconnected\",\n title: renewing ? \"Renew Intelligence\" : \"Intelligence is not setup\",\n body: renewing\n ? \"Renew Intelligence to restore persistent Threads and Memory.\"\n : \"Connect CopilotKit Intelligence to add persistent Threads, Learning and Analytics to your application. Inspect conversations and allow your agents to learn from real use.\",\n action: connectIntelligenceAction(\n args.action,\n args.connectUrl,\n args.licenseState,\n ),\n };\n }\n\n return {\n connection: \"connected\",\n title: \"Connected to Intelligence\",\n body: \"Use Workbench to inspect threads and memory.\",\n action:\n args.action?.kind === \"enable_intelligence\" ? undefined : args.action,\n };\n}\n\nfunction usageFromMetadata(metadata: InspectorMetadataProjection):\n | {\n used: number;\n limitLabel: string;\n ratio?: number;\n }\n | undefined {\n const usage = metadata.usage;\n if (!usage) {\n return undefined;\n }\n\n if (usage.limit.kind === \"finite\") {\n return {\n used: usage.used,\n limitLabel: `${usage.used} / ${usage.limit.value}`,\n ratio: usage.limit.value === 0 ? 1 : usage.used / usage.limit.value,\n };\n }\n\n if (usage.limit.kind === \"unlimited\") {\n return {\n used: usage.used,\n limitLabel: `${usage.used} / unlimited`,\n };\n }\n\n return {\n used: usage.used,\n limitLabel: `${usage.used} used`,\n };\n}\n\nfunction newsFromAnnouncement(args: {\n previewText?: string;\n markdown?: string;\n html?: string;\n}): HomeModel[\"news\"] {\n const markdown = args.markdown?.trim();\n if (markdown && args.html) {\n const heading = markdown.match(/^#{1,3}\\s+(.+)$/m)?.[1]?.trim();\n return {\n title: heading || \"The latest from CopilotKit\",\n previewText:\n args.previewText?.trim() || announcementPreview(markdown, 160),\n documentHtml: args.html,\n empty: false,\n };\n }\n\n return {\n title: \"You're all caught up\",\n previewText: \"Latest CopilotKit updates will appear here.\",\n empty: true,\n };\n}\n\nfunction runtimeEventSignal(\n event: HomeBriefingInput[\"lastRuntimeEvent\"],\n): HomeModel[\"runtime\"][\"health\"][\"lastEvent\"] {\n if (!event) {\n return { label: \"No events yet\", tone: \"muted\" };\n }\n\n const eventDetails = {\n id: event.id,\n agentId: event.agentId,\n type: event.type,\n timestamp: event.timestamp,\n };\n\n if (event.type === \"RUN_ERROR\" || event.type === \"ERROR\") {\n return {\n label: event.type === \"RUN_ERROR\" ? \"Run error\" : \"Error\",\n tone: \"error\",\n ...eventDetails,\n };\n }\n\n if (event.type === \"RUN_FINISHED\") {\n return {\n label: \"Run completed\",\n tone: \"success\",\n ...eventDetails,\n };\n }\n\n if (\n event.type.endsWith(\"_START\") ||\n event.type.endsWith(\"_STARTED\") ||\n event.type.endsWith(\"_CONTENT\") ||\n event.type.endsWith(\"_ARGS\") ||\n event.type.endsWith(\"_DELTA\")\n ) {\n return {\n label: \"Last event is in progress\",\n tone: \"active\",\n ...eventDetails,\n };\n }\n\n return {\n label: \"Last event received\",\n tone: \"success\",\n ...eventDetails,\n };\n}\n\nfunction runtimeHealthFromInput(\n input: HomeBriefingInput,\n): HomeModel[\"runtime\"][\"health\"] {\n const lastEvent = runtimeEventSignal(input.lastRuntimeEvent);\n\n if (input.runtimeConnectionState === \"connected\") {\n return {\n state: lastEvent.tone === \"error\" ? \"error\" : \"healthy\",\n label: lastEvent.tone === \"error\" ? \"Needs attention\" : \"Healthy\",\n runtime: { label: \"Available\", tone: \"success\" },\n liveUpdates: { label: \"Ready\", tone: \"success\" },\n lastEvent,\n };\n }\n\n if (input.runtimeConnectionState === \"connecting\") {\n return {\n state: \"checking\",\n label: \"Checking\",\n runtime: { label: \"Checking\", tone: \"active\" },\n liveUpdates: { label: \"Connecting\", tone: \"active\" },\n lastEvent,\n };\n }\n\n if (input.runtimeConnectionState === \"unavailable\") {\n return {\n state: \"unavailable\",\n label: \"Unavailable\",\n runtime: { label: \"Unavailable\", tone: \"muted\" },\n liveUpdates: { label: \"Not attached\", tone: \"muted\" },\n lastEvent,\n };\n }\n\n return {\n state: input.runtimeConnectionState === \"error\" ? \"error\" : \"offline\",\n label:\n input.runtimeConnectionState === \"error\" ? \"Runtime error\" : \"Offline\",\n runtime: { label: \"Offline\", tone: \"error\" },\n liveUpdates: {\n label:\n input.runtimeConnectionState === \"error\" ? \"Error\" : \"Disconnected\",\n tone: \"error\",\n },\n lastEvent,\n };\n}\n\n/** Build the Home briefing from data the Inspector already has. */\nexport function buildHomeModel(input: HomeBriefingInput): HomeModel {\n const metadataAction =\n input.metadata.threadsFooterAction ?? input.metadata.lockedAction;\n const action = metadataAction\n ? homeHeroActionFromMetadata({\n kind: metadataAction.kind,\n url: metadataAction.url,\n })\n : undefined;\n\n const identity = input.metadata.identity;\n const projectLinked = Boolean(identity);\n const intelligenceConnected =\n input.metadata.licenseState === \"valid\" ||\n (input.metadata.licenseState === \"unknown\" && input.intelligenceConnected);\n const usage = usageFromMetadata(input.metadata);\n\n return {\n hero: heroForState({\n connected: intelligenceConnected,\n action,\n connectUrl: input.intelligenceSignupUrl,\n licenseState: input.metadata.licenseState,\n }),\n projectLinked,\n project: identity\n ? {\n organizationName: identity.organizationName,\n projectName: identity.projectName,\n planLabel: input.metadata.plan?.label,\n license: input.metadata.licenseState,\n usage,\n }\n : input.metadata.plan || usage\n ? {\n organizationName: \"Not linked\",\n projectName: \"This runtime is not linked to a project\",\n planLabel: input.metadata.plan?.label,\n license: input.metadata.licenseState,\n usage,\n }\n : undefined,\n runtime: {\n url: input.runtimeUrl,\n health: runtimeHealthFromInput(input),\n },\n services: [\n {\n id: \"threads\",\n label: \"Threads\",\n enabled: intelligenceConnected && input.threadsAvailable,\n url: input.runtimeUrl,\n docsUrl: SERVICE_DOCS_URL.threads,\n },\n {\n id: \"memory\",\n label: \"Memory\",\n enabled: intelligenceConnected && input.memoriesOn,\n docsUrl: SERVICE_DOCS_URL.memory,\n },\n {\n id: \"a2ui\",\n label: \"A2UI\",\n enabled: input.a2uiOn,\n docsUrl: SERVICE_DOCS_URL.a2ui,\n },\n {\n id: \"open-gen-ui\",\n label: \"Open Gen UI\",\n enabled: input.openGenUiOn,\n docsUrl: SERVICE_DOCS_URL[\"open-gen-ui\"],\n },\n {\n id: \"suggestions\",\n label: \"Suggestions\",\n enabled: input.suggestionsOn,\n docsUrl: SERVICE_DOCS_URL.suggestions,\n },\n {\n id: \"audio\",\n label: \"Audio\",\n enabled: input.audioOn,\n docsUrl: SERVICE_DOCS_URL.audio,\n },\n {\n id: \"websocket\",\n label: \"Websocket\",\n enabled: intelligenceConnected && Boolean(input.websocketUrl),\n url: input.websocketUrl,\n docsUrl: SERVICE_DOCS_URL.websocket,\n },\n ],\n news: newsFromAnnouncement({\n previewText: input.announcementPreviewText,\n markdown: input.announcementMarkdown,\n html: input.announcementHtml ?? undefined,\n }),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,269 @@
1
+ //#region src/lib/home-briefing.ts
2
+ const SERVICE_DOCS_URL = {
3
+ threads: "https://docs.copilotkit.ai/threads",
4
+ memory: "https://docs.copilotkit.ai/premium/intelligence-platform",
5
+ a2ui: "https://docs.copilotkit.ai/generative-ui/a2ui",
6
+ "open-gen-ui": "https://docs.copilotkit.ai/generative-ui/open-generative-ui",
7
+ suggestions: "https://docs.copilotkit.ai/agentic-chat-ui",
8
+ audio: "https://docs.copilotkit.ai/voice",
9
+ websocket: "https://docs.copilotkit.ai/premium/intelligence-platform"
10
+ };
11
+ /** Return the Home hero button for a trusted metadata action. */
12
+ function homeHeroActionFromMetadata(action) {
13
+ if (action.kind === "manage_plan") return {
14
+ kind: action.kind,
15
+ url: action.url,
16
+ label: "Manage plan"
17
+ };
18
+ if (action.kind === "renew") return {
19
+ kind: action.kind,
20
+ url: action.url,
21
+ label: "Renew plan"
22
+ };
23
+ return {
24
+ kind: action.kind,
25
+ url: action.url,
26
+ label: "Setup Intelligence"
27
+ };
28
+ }
29
+ /** Return a short preview from markdown, without links or headings. */
30
+ function announcementPreview(markdown, maxLength = 140) {
31
+ const plain = markdown.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[#*_`]/g, "").replace(/\s+/g, " ").trim();
32
+ if (plain.length <= maxLength) return plain;
33
+ return `${plain.slice(0, maxLength).trimEnd()}…`;
34
+ }
35
+ function connectIntelligenceAction(action, connectUrl, licenseState) {
36
+ if (action) return action;
37
+ if (connectUrl && (licenseState === "none" || licenseState === "unknown")) return homeHeroActionFromMetadata({
38
+ kind: "enable_intelligence",
39
+ url: connectUrl
40
+ });
41
+ }
42
+ function heroForState(args) {
43
+ if (!args.connected) {
44
+ const renewing = args.action?.kind === "renew";
45
+ return {
46
+ connection: "disconnected",
47
+ title: renewing ? "Renew Intelligence" : "Intelligence is not setup",
48
+ body: renewing ? "Renew Intelligence to restore persistent Threads and Memory." : "Connect CopilotKit Intelligence to add persistent Threads, Learning and Analytics to your application. Inspect conversations and allow your agents to learn from real use.",
49
+ action: connectIntelligenceAction(args.action, args.connectUrl, args.licenseState)
50
+ };
51
+ }
52
+ return {
53
+ connection: "connected",
54
+ title: "Connected to Intelligence",
55
+ body: "Use Workbench to inspect threads and memory.",
56
+ action: args.action?.kind === "enable_intelligence" ? void 0 : args.action
57
+ };
58
+ }
59
+ function usageFromMetadata(metadata) {
60
+ const usage = metadata.usage;
61
+ if (!usage) return;
62
+ if (usage.limit.kind === "finite") return {
63
+ used: usage.used,
64
+ limitLabel: `${usage.used} / ${usage.limit.value}`,
65
+ ratio: usage.limit.value === 0 ? 1 : usage.used / usage.limit.value
66
+ };
67
+ if (usage.limit.kind === "unlimited") return {
68
+ used: usage.used,
69
+ limitLabel: `${usage.used} / unlimited`
70
+ };
71
+ return {
72
+ used: usage.used,
73
+ limitLabel: `${usage.used} used`
74
+ };
75
+ }
76
+ function newsFromAnnouncement(args) {
77
+ const markdown = args.markdown?.trim();
78
+ if (markdown && args.html) return {
79
+ title: markdown.match(/^#{1,3}\s+(.+)$/m)?.[1]?.trim() || "The latest from CopilotKit",
80
+ previewText: args.previewText?.trim() || announcementPreview(markdown, 160),
81
+ documentHtml: args.html,
82
+ empty: false
83
+ };
84
+ return {
85
+ title: "You're all caught up",
86
+ previewText: "Latest CopilotKit updates will appear here.",
87
+ empty: true
88
+ };
89
+ }
90
+ function runtimeEventSignal(event) {
91
+ if (!event) return {
92
+ label: "No events yet",
93
+ tone: "muted"
94
+ };
95
+ const eventDetails = {
96
+ id: event.id,
97
+ agentId: event.agentId,
98
+ type: event.type,
99
+ timestamp: event.timestamp
100
+ };
101
+ if (event.type === "RUN_ERROR" || event.type === "ERROR") return {
102
+ label: event.type === "RUN_ERROR" ? "Run error" : "Error",
103
+ tone: "error",
104
+ ...eventDetails
105
+ };
106
+ if (event.type === "RUN_FINISHED") return {
107
+ label: "Run completed",
108
+ tone: "success",
109
+ ...eventDetails
110
+ };
111
+ if (event.type.endsWith("_START") || event.type.endsWith("_STARTED") || event.type.endsWith("_CONTENT") || event.type.endsWith("_ARGS") || event.type.endsWith("_DELTA")) return {
112
+ label: "Last event is in progress",
113
+ tone: "active",
114
+ ...eventDetails
115
+ };
116
+ return {
117
+ label: "Last event received",
118
+ tone: "success",
119
+ ...eventDetails
120
+ };
121
+ }
122
+ function runtimeHealthFromInput(input) {
123
+ const lastEvent = runtimeEventSignal(input.lastRuntimeEvent);
124
+ if (input.runtimeConnectionState === "connected") return {
125
+ state: lastEvent.tone === "error" ? "error" : "healthy",
126
+ label: lastEvent.tone === "error" ? "Needs attention" : "Healthy",
127
+ runtime: {
128
+ label: "Available",
129
+ tone: "success"
130
+ },
131
+ liveUpdates: {
132
+ label: "Ready",
133
+ tone: "success"
134
+ },
135
+ lastEvent
136
+ };
137
+ if (input.runtimeConnectionState === "connecting") return {
138
+ state: "checking",
139
+ label: "Checking",
140
+ runtime: {
141
+ label: "Checking",
142
+ tone: "active"
143
+ },
144
+ liveUpdates: {
145
+ label: "Connecting",
146
+ tone: "active"
147
+ },
148
+ lastEvent
149
+ };
150
+ if (input.runtimeConnectionState === "unavailable") return {
151
+ state: "unavailable",
152
+ label: "Unavailable",
153
+ runtime: {
154
+ label: "Unavailable",
155
+ tone: "muted"
156
+ },
157
+ liveUpdates: {
158
+ label: "Not attached",
159
+ tone: "muted"
160
+ },
161
+ lastEvent
162
+ };
163
+ return {
164
+ state: input.runtimeConnectionState === "error" ? "error" : "offline",
165
+ label: input.runtimeConnectionState === "error" ? "Runtime error" : "Offline",
166
+ runtime: {
167
+ label: "Offline",
168
+ tone: "error"
169
+ },
170
+ liveUpdates: {
171
+ label: input.runtimeConnectionState === "error" ? "Error" : "Disconnected",
172
+ tone: "error"
173
+ },
174
+ lastEvent
175
+ };
176
+ }
177
+ /** Build the Home briefing from data the Inspector already has. */
178
+ function buildHomeModel(input) {
179
+ const metadataAction = input.metadata.threadsFooterAction ?? input.metadata.lockedAction;
180
+ const action = metadataAction ? homeHeroActionFromMetadata({
181
+ kind: metadataAction.kind,
182
+ url: metadataAction.url
183
+ }) : void 0;
184
+ const identity = input.metadata.identity;
185
+ const projectLinked = Boolean(identity);
186
+ const intelligenceConnected = input.metadata.licenseState === "valid" || input.metadata.licenseState === "unknown" && input.intelligenceConnected;
187
+ const usage = usageFromMetadata(input.metadata);
188
+ return {
189
+ hero: heroForState({
190
+ connected: intelligenceConnected,
191
+ action,
192
+ connectUrl: input.intelligenceSignupUrl,
193
+ licenseState: input.metadata.licenseState
194
+ }),
195
+ projectLinked,
196
+ project: identity ? {
197
+ organizationName: identity.organizationName,
198
+ projectName: identity.projectName,
199
+ planLabel: input.metadata.plan?.label,
200
+ license: input.metadata.licenseState,
201
+ usage
202
+ } : input.metadata.plan || usage ? {
203
+ organizationName: "Not linked",
204
+ projectName: "This runtime is not linked to a project",
205
+ planLabel: input.metadata.plan?.label,
206
+ license: input.metadata.licenseState,
207
+ usage
208
+ } : void 0,
209
+ runtime: {
210
+ url: input.runtimeUrl,
211
+ health: runtimeHealthFromInput(input)
212
+ },
213
+ services: [
214
+ {
215
+ id: "threads",
216
+ label: "Threads",
217
+ enabled: intelligenceConnected && input.threadsAvailable,
218
+ url: input.runtimeUrl,
219
+ docsUrl: SERVICE_DOCS_URL.threads
220
+ },
221
+ {
222
+ id: "memory",
223
+ label: "Memory",
224
+ enabled: intelligenceConnected && input.memoriesOn,
225
+ docsUrl: SERVICE_DOCS_URL.memory
226
+ },
227
+ {
228
+ id: "a2ui",
229
+ label: "A2UI",
230
+ enabled: input.a2uiOn,
231
+ docsUrl: SERVICE_DOCS_URL.a2ui
232
+ },
233
+ {
234
+ id: "open-gen-ui",
235
+ label: "Open Gen UI",
236
+ enabled: input.openGenUiOn,
237
+ docsUrl: SERVICE_DOCS_URL["open-gen-ui"]
238
+ },
239
+ {
240
+ id: "suggestions",
241
+ label: "Suggestions",
242
+ enabled: input.suggestionsOn,
243
+ docsUrl: SERVICE_DOCS_URL.suggestions
244
+ },
245
+ {
246
+ id: "audio",
247
+ label: "Audio",
248
+ enabled: input.audioOn,
249
+ docsUrl: SERVICE_DOCS_URL.audio
250
+ },
251
+ {
252
+ id: "websocket",
253
+ label: "Websocket",
254
+ enabled: intelligenceConnected && Boolean(input.websocketUrl),
255
+ url: input.websocketUrl,
256
+ docsUrl: SERVICE_DOCS_URL.websocket
257
+ }
258
+ ],
259
+ news: newsFromAnnouncement({
260
+ previewText: input.announcementPreviewText,
261
+ markdown: input.announcementMarkdown,
262
+ html: input.announcementHtml ?? void 0
263
+ })
264
+ };
265
+ }
266
+
267
+ //#endregion
268
+ export { buildHomeModel };
269
+ //# sourceMappingURL=home-briefing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-briefing.mjs","names":[],"sources":["../../src/lib/home-briefing.ts"],"sourcesContent":["import type { InspectorMetadataProjection } from \"./inspector-metadata.js\";\n\nexport type HomeHeroActionKind =\n | \"enable_intelligence\"\n | \"manage_plan\"\n | \"renew\";\n\nexport type HomeHeroAction = {\n kind: HomeHeroActionKind;\n url: string;\n label: string;\n};\n\nexport type HomeConnection = \"connected\" | \"disconnected\";\n\nexport type HomeRuntimeConnectionState =\n | \"connected\"\n | \"connecting\"\n | \"disconnected\"\n | \"error\"\n | \"unavailable\";\n\nexport type HomeRuntimeHealthTone = \"success\" | \"active\" | \"error\" | \"muted\";\n\nexport type HomeServiceId =\n | \"threads\"\n | \"memory\"\n | \"a2ui\"\n | \"open-gen-ui\"\n | \"suggestions\"\n | \"audio\"\n | \"websocket\";\n\nexport type HomeServiceTile = {\n id: HomeServiceId;\n label: string;\n enabled: boolean;\n url?: string;\n docsUrl: string;\n};\n\nexport type HomeModel = {\n hero: {\n connection: HomeConnection;\n title: string;\n body: string;\n action?: HomeHeroAction;\n };\n project?: {\n organizationName: string;\n projectName: string;\n planLabel?: string;\n license: string;\n usage?: {\n used: number;\n limitLabel: string;\n ratio?: number;\n };\n };\n projectLinked: boolean;\n runtime: {\n url?: string;\n health: {\n state: \"healthy\" | \"checking\" | \"offline\" | \"error\" | \"unavailable\";\n label: string;\n runtime: {\n label: string;\n tone: HomeRuntimeHealthTone;\n };\n liveUpdates: {\n label: string;\n tone: HomeRuntimeHealthTone;\n };\n lastEvent: {\n label: string;\n tone: HomeRuntimeHealthTone;\n id?: string;\n agentId?: string;\n type?: string;\n timestamp?: number;\n };\n };\n };\n services: HomeServiceTile[];\n news: {\n title: string;\n previewText: string;\n documentHtml?: string;\n empty: boolean;\n };\n};\n\nexport type HomeBriefingInput = {\n intelligenceConnected: boolean;\n threadsAvailable: boolean;\n metadata: InspectorMetadataProjection;\n runtimeUrl?: string;\n runtimeConnectionState: HomeRuntimeConnectionState;\n lastRuntimeEvent?: {\n id: string;\n agentId: string;\n type: string;\n timestamp: number;\n };\n memoriesOn: boolean;\n a2uiOn: boolean;\n openGenUiOn: boolean;\n suggestionsOn: boolean;\n audioOn: boolean;\n websocketUrl?: string;\n announcementPreviewText?: string;\n announcementMarkdown?: string;\n announcementHtml?: string;\n intelligenceSignupUrl?: string;\n};\n\nconst SERVICE_DOCS_URL: Record<HomeServiceId, string> = {\n threads: \"https://docs.copilotkit.ai/threads\",\n memory: \"https://docs.copilotkit.ai/premium/intelligence-platform\",\n a2ui: \"https://docs.copilotkit.ai/generative-ui/a2ui\",\n \"open-gen-ui\": \"https://docs.copilotkit.ai/generative-ui/open-generative-ui\",\n suggestions: \"https://docs.copilotkit.ai/agentic-chat-ui\",\n audio: \"https://docs.copilotkit.ai/voice\",\n websocket: \"https://docs.copilotkit.ai/premium/intelligence-platform\",\n};\n\n/** Return the Home hero button for a trusted metadata action. */\nexport function homeHeroActionFromMetadata(action: {\n kind: HomeHeroActionKind;\n url: string;\n}): HomeHeroAction {\n if (action.kind === \"manage_plan\") {\n return { kind: action.kind, url: action.url, label: \"Manage plan\" };\n }\n\n if (action.kind === \"renew\") {\n return { kind: action.kind, url: action.url, label: \"Renew plan\" };\n }\n\n return {\n kind: action.kind,\n url: action.url,\n label: \"Setup Intelligence\",\n };\n}\n\n/** Return a short preview from markdown, without links or headings. */\nexport function announcementPreview(markdown: string, maxLength = 140): string {\n const plain = markdown\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/[#*_`]/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n if (plain.length <= maxLength) {\n return plain;\n }\n\n return `${plain.slice(0, maxLength).trimEnd()}…`;\n}\n\nfunction connectIntelligenceAction(\n action: HomeHeroAction | undefined,\n connectUrl?: string,\n licenseState?: InspectorMetadataProjection[\"licenseState\"],\n): HomeHeroAction | undefined {\n if (action) {\n return action;\n }\n\n if (connectUrl && (licenseState === \"none\" || licenseState === \"unknown\")) {\n return homeHeroActionFromMetadata({\n kind: \"enable_intelligence\",\n url: connectUrl,\n });\n }\n\n return undefined;\n}\n\nfunction heroForState(args: {\n connected: boolean;\n action?: HomeHeroAction;\n connectUrl?: string;\n licenseState: InspectorMetadataProjection[\"licenseState\"];\n}): HomeModel[\"hero\"] {\n if (!args.connected) {\n const renewing = args.action?.kind === \"renew\";\n return {\n connection: \"disconnected\",\n title: renewing ? \"Renew Intelligence\" : \"Intelligence is not setup\",\n body: renewing\n ? \"Renew Intelligence to restore persistent Threads and Memory.\"\n : \"Connect CopilotKit Intelligence to add persistent Threads, Learning and Analytics to your application. Inspect conversations and allow your agents to learn from real use.\",\n action: connectIntelligenceAction(\n args.action,\n args.connectUrl,\n args.licenseState,\n ),\n };\n }\n\n return {\n connection: \"connected\",\n title: \"Connected to Intelligence\",\n body: \"Use Workbench to inspect threads and memory.\",\n action:\n args.action?.kind === \"enable_intelligence\" ? undefined : args.action,\n };\n}\n\nfunction usageFromMetadata(metadata: InspectorMetadataProjection):\n | {\n used: number;\n limitLabel: string;\n ratio?: number;\n }\n | undefined {\n const usage = metadata.usage;\n if (!usage) {\n return undefined;\n }\n\n if (usage.limit.kind === \"finite\") {\n return {\n used: usage.used,\n limitLabel: `${usage.used} / ${usage.limit.value}`,\n ratio: usage.limit.value === 0 ? 1 : usage.used / usage.limit.value,\n };\n }\n\n if (usage.limit.kind === \"unlimited\") {\n return {\n used: usage.used,\n limitLabel: `${usage.used} / unlimited`,\n };\n }\n\n return {\n used: usage.used,\n limitLabel: `${usage.used} used`,\n };\n}\n\nfunction newsFromAnnouncement(args: {\n previewText?: string;\n markdown?: string;\n html?: string;\n}): HomeModel[\"news\"] {\n const markdown = args.markdown?.trim();\n if (markdown && args.html) {\n const heading = markdown.match(/^#{1,3}\\s+(.+)$/m)?.[1]?.trim();\n return {\n title: heading || \"The latest from CopilotKit\",\n previewText:\n args.previewText?.trim() || announcementPreview(markdown, 160),\n documentHtml: args.html,\n empty: false,\n };\n }\n\n return {\n title: \"You're all caught up\",\n previewText: \"Latest CopilotKit updates will appear here.\",\n empty: true,\n };\n}\n\nfunction runtimeEventSignal(\n event: HomeBriefingInput[\"lastRuntimeEvent\"],\n): HomeModel[\"runtime\"][\"health\"][\"lastEvent\"] {\n if (!event) {\n return { label: \"No events yet\", tone: \"muted\" };\n }\n\n const eventDetails = {\n id: event.id,\n agentId: event.agentId,\n type: event.type,\n timestamp: event.timestamp,\n };\n\n if (event.type === \"RUN_ERROR\" || event.type === \"ERROR\") {\n return {\n label: event.type === \"RUN_ERROR\" ? \"Run error\" : \"Error\",\n tone: \"error\",\n ...eventDetails,\n };\n }\n\n if (event.type === \"RUN_FINISHED\") {\n return {\n label: \"Run completed\",\n tone: \"success\",\n ...eventDetails,\n };\n }\n\n if (\n event.type.endsWith(\"_START\") ||\n event.type.endsWith(\"_STARTED\") ||\n event.type.endsWith(\"_CONTENT\") ||\n event.type.endsWith(\"_ARGS\") ||\n event.type.endsWith(\"_DELTA\")\n ) {\n return {\n label: \"Last event is in progress\",\n tone: \"active\",\n ...eventDetails,\n };\n }\n\n return {\n label: \"Last event received\",\n tone: \"success\",\n ...eventDetails,\n };\n}\n\nfunction runtimeHealthFromInput(\n input: HomeBriefingInput,\n): HomeModel[\"runtime\"][\"health\"] {\n const lastEvent = runtimeEventSignal(input.lastRuntimeEvent);\n\n if (input.runtimeConnectionState === \"connected\") {\n return {\n state: lastEvent.tone === \"error\" ? \"error\" : \"healthy\",\n label: lastEvent.tone === \"error\" ? \"Needs attention\" : \"Healthy\",\n runtime: { label: \"Available\", tone: \"success\" },\n liveUpdates: { label: \"Ready\", tone: \"success\" },\n lastEvent,\n };\n }\n\n if (input.runtimeConnectionState === \"connecting\") {\n return {\n state: \"checking\",\n label: \"Checking\",\n runtime: { label: \"Checking\", tone: \"active\" },\n liveUpdates: { label: \"Connecting\", tone: \"active\" },\n lastEvent,\n };\n }\n\n if (input.runtimeConnectionState === \"unavailable\") {\n return {\n state: \"unavailable\",\n label: \"Unavailable\",\n runtime: { label: \"Unavailable\", tone: \"muted\" },\n liveUpdates: { label: \"Not attached\", tone: \"muted\" },\n lastEvent,\n };\n }\n\n return {\n state: input.runtimeConnectionState === \"error\" ? \"error\" : \"offline\",\n label:\n input.runtimeConnectionState === \"error\" ? \"Runtime error\" : \"Offline\",\n runtime: { label: \"Offline\", tone: \"error\" },\n liveUpdates: {\n label:\n input.runtimeConnectionState === \"error\" ? \"Error\" : \"Disconnected\",\n tone: \"error\",\n },\n lastEvent,\n };\n}\n\n/** Build the Home briefing from data the Inspector already has. */\nexport function buildHomeModel(input: HomeBriefingInput): HomeModel {\n const metadataAction =\n input.metadata.threadsFooterAction ?? input.metadata.lockedAction;\n const action = metadataAction\n ? homeHeroActionFromMetadata({\n kind: metadataAction.kind,\n url: metadataAction.url,\n })\n : undefined;\n\n const identity = input.metadata.identity;\n const projectLinked = Boolean(identity);\n const intelligenceConnected =\n input.metadata.licenseState === \"valid\" ||\n (input.metadata.licenseState === \"unknown\" && input.intelligenceConnected);\n const usage = usageFromMetadata(input.metadata);\n\n return {\n hero: heroForState({\n connected: intelligenceConnected,\n action,\n connectUrl: input.intelligenceSignupUrl,\n licenseState: input.metadata.licenseState,\n }),\n projectLinked,\n project: identity\n ? {\n organizationName: identity.organizationName,\n projectName: identity.projectName,\n planLabel: input.metadata.plan?.label,\n license: input.metadata.licenseState,\n usage,\n }\n : input.metadata.plan || usage\n ? {\n organizationName: \"Not linked\",\n projectName: \"This runtime is not linked to a project\",\n planLabel: input.metadata.plan?.label,\n license: input.metadata.licenseState,\n usage,\n }\n : undefined,\n runtime: {\n url: input.runtimeUrl,\n health: runtimeHealthFromInput(input),\n },\n services: [\n {\n id: \"threads\",\n label: \"Threads\",\n enabled: intelligenceConnected && input.threadsAvailable,\n url: input.runtimeUrl,\n docsUrl: SERVICE_DOCS_URL.threads,\n },\n {\n id: \"memory\",\n label: \"Memory\",\n enabled: intelligenceConnected && input.memoriesOn,\n docsUrl: SERVICE_DOCS_URL.memory,\n },\n {\n id: \"a2ui\",\n label: \"A2UI\",\n enabled: input.a2uiOn,\n docsUrl: SERVICE_DOCS_URL.a2ui,\n },\n {\n id: \"open-gen-ui\",\n label: \"Open Gen UI\",\n enabled: input.openGenUiOn,\n docsUrl: SERVICE_DOCS_URL[\"open-gen-ui\"],\n },\n {\n id: \"suggestions\",\n label: \"Suggestions\",\n enabled: input.suggestionsOn,\n docsUrl: SERVICE_DOCS_URL.suggestions,\n },\n {\n id: \"audio\",\n label: \"Audio\",\n enabled: input.audioOn,\n docsUrl: SERVICE_DOCS_URL.audio,\n },\n {\n id: \"websocket\",\n label: \"Websocket\",\n enabled: intelligenceConnected && Boolean(input.websocketUrl),\n url: input.websocketUrl,\n docsUrl: SERVICE_DOCS_URL.websocket,\n },\n ],\n news: newsFromAnnouncement({\n previewText: input.announcementPreviewText,\n markdown: input.announcementMarkdown,\n html: input.announcementHtml ?? undefined,\n }),\n };\n}\n"],"mappings":";AAoHA,MAAM,mBAAkD;CACtD,SAAS;CACT,QAAQ;CACR,MAAM;CACN,eAAe;CACf,aAAa;CACb,OAAO;CACP,WAAW;CACZ;;AAGD,SAAgB,2BAA2B,QAGxB;AACjB,KAAI,OAAO,SAAS,cAClB,QAAO;EAAE,MAAM,OAAO;EAAM,KAAK,OAAO;EAAK,OAAO;EAAe;AAGrE,KAAI,OAAO,SAAS,QAClB,QAAO;EAAE,MAAM,OAAO;EAAM,KAAK,OAAO;EAAK,OAAO;EAAc;AAGpE,QAAO;EACL,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,OAAO;EACR;;;AAIH,SAAgB,oBAAoB,UAAkB,YAAY,KAAa;CAC7E,MAAM,QAAQ,SACX,QAAQ,0BAA0B,KAAK,CACvC,QAAQ,WAAW,GAAG,CACtB,QAAQ,QAAQ,IAAI,CACpB,MAAM;AACT,KAAI,MAAM,UAAU,UAClB,QAAO;AAGT,QAAO,GAAG,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC;;AAGhD,SAAS,0BACP,QACA,YACA,cAC4B;AAC5B,KAAI,OACF,QAAO;AAGT,KAAI,eAAe,iBAAiB,UAAU,iBAAiB,WAC7D,QAAO,2BAA2B;EAChC,MAAM;EACN,KAAK;EACN,CAAC;;AAMN,SAAS,aAAa,MAKA;AACpB,KAAI,CAAC,KAAK,WAAW;EACnB,MAAM,WAAW,KAAK,QAAQ,SAAS;AACvC,SAAO;GACL,YAAY;GACZ,OAAO,WAAW,uBAAuB;GACzC,MAAM,WACF,iEACA;GACJ,QAAQ,0BACN,KAAK,QACL,KAAK,YACL,KAAK,aACN;GACF;;AAGH,QAAO;EACL,YAAY;EACZ,OAAO;EACP,MAAM;EACN,QACE,KAAK,QAAQ,SAAS,wBAAwB,SAAY,KAAK;EAClE;;AAGH,SAAS,kBAAkB,UAMb;CACZ,MAAM,QAAQ,SAAS;AACvB,KAAI,CAAC,MACH;AAGF,KAAI,MAAM,MAAM,SAAS,SACvB,QAAO;EACL,MAAM,MAAM;EACZ,YAAY,GAAG,MAAM,KAAK,KAAK,MAAM,MAAM;EAC3C,OAAO,MAAM,MAAM,UAAU,IAAI,IAAI,MAAM,OAAO,MAAM,MAAM;EAC/D;AAGH,KAAI,MAAM,MAAM,SAAS,YACvB,QAAO;EACL,MAAM,MAAM;EACZ,YAAY,GAAG,MAAM,KAAK;EAC3B;AAGH,QAAO;EACL,MAAM,MAAM;EACZ,YAAY,GAAG,MAAM,KAAK;EAC3B;;AAGH,SAAS,qBAAqB,MAIR;CACpB,MAAM,WAAW,KAAK,UAAU,MAAM;AACtC,KAAI,YAAY,KAAK,KAEnB,QAAO;EACL,OAFc,SAAS,MAAM,mBAAmB,GAAG,IAAI,MAAM,IAE3C;EAClB,aACE,KAAK,aAAa,MAAM,IAAI,oBAAoB,UAAU,IAAI;EAChE,cAAc,KAAK;EACnB,OAAO;EACR;AAGH,QAAO;EACL,OAAO;EACP,aAAa;EACb,OAAO;EACR;;AAGH,SAAS,mBACP,OAC6C;AAC7C,KAAI,CAAC,MACH,QAAO;EAAE,OAAO;EAAiB,MAAM;EAAS;CAGlD,MAAM,eAAe;EACnB,IAAI,MAAM;EACV,SAAS,MAAM;EACf,MAAM,MAAM;EACZ,WAAW,MAAM;EAClB;AAED,KAAI,MAAM,SAAS,eAAe,MAAM,SAAS,QAC/C,QAAO;EACL,OAAO,MAAM,SAAS,cAAc,cAAc;EAClD,MAAM;EACN,GAAG;EACJ;AAGH,KAAI,MAAM,SAAS,eACjB,QAAO;EACL,OAAO;EACP,MAAM;EACN,GAAG;EACJ;AAGH,KACE,MAAM,KAAK,SAAS,SAAS,IAC7B,MAAM,KAAK,SAAS,WAAW,IAC/B,MAAM,KAAK,SAAS,WAAW,IAC/B,MAAM,KAAK,SAAS,QAAQ,IAC5B,MAAM,KAAK,SAAS,SAAS,CAE7B,QAAO;EACL,OAAO;EACP,MAAM;EACN,GAAG;EACJ;AAGH,QAAO;EACL,OAAO;EACP,MAAM;EACN,GAAG;EACJ;;AAGH,SAAS,uBACP,OACgC;CAChC,MAAM,YAAY,mBAAmB,MAAM,iBAAiB;AAE5D,KAAI,MAAM,2BAA2B,YACnC,QAAO;EACL,OAAO,UAAU,SAAS,UAAU,UAAU;EAC9C,OAAO,UAAU,SAAS,UAAU,oBAAoB;EACxD,SAAS;GAAE,OAAO;GAAa,MAAM;GAAW;EAChD,aAAa;GAAE,OAAO;GAAS,MAAM;GAAW;EAChD;EACD;AAGH,KAAI,MAAM,2BAA2B,aACnC,QAAO;EACL,OAAO;EACP,OAAO;EACP,SAAS;GAAE,OAAO;GAAY,MAAM;GAAU;EAC9C,aAAa;GAAE,OAAO;GAAc,MAAM;GAAU;EACpD;EACD;AAGH,KAAI,MAAM,2BAA2B,cACnC,QAAO;EACL,OAAO;EACP,OAAO;EACP,SAAS;GAAE,OAAO;GAAe,MAAM;GAAS;EAChD,aAAa;GAAE,OAAO;GAAgB,MAAM;GAAS;EACrD;EACD;AAGH,QAAO;EACL,OAAO,MAAM,2BAA2B,UAAU,UAAU;EAC5D,OACE,MAAM,2BAA2B,UAAU,kBAAkB;EAC/D,SAAS;GAAE,OAAO;GAAW,MAAM;GAAS;EAC5C,aAAa;GACX,OACE,MAAM,2BAA2B,UAAU,UAAU;GACvD,MAAM;GACP;EACD;EACD;;;AAIH,SAAgB,eAAe,OAAqC;CAClE,MAAM,iBACJ,MAAM,SAAS,uBAAuB,MAAM,SAAS;CACvD,MAAM,SAAS,iBACX,2BAA2B;EACzB,MAAM,eAAe;EACrB,KAAK,eAAe;EACrB,CAAC,GACF;CAEJ,MAAM,WAAW,MAAM,SAAS;CAChC,MAAM,gBAAgB,QAAQ,SAAS;CACvC,MAAM,wBACJ,MAAM,SAAS,iBAAiB,WAC/B,MAAM,SAAS,iBAAiB,aAAa,MAAM;CACtD,MAAM,QAAQ,kBAAkB,MAAM,SAAS;AAE/C,QAAO;EACL,MAAM,aAAa;GACjB,WAAW;GACX;GACA,YAAY,MAAM;GAClB,cAAc,MAAM,SAAS;GAC9B,CAAC;EACF;EACA,SAAS,WACL;GACE,kBAAkB,SAAS;GAC3B,aAAa,SAAS;GACtB,WAAW,MAAM,SAAS,MAAM;GAChC,SAAS,MAAM,SAAS;GACxB;GACD,GACD,MAAM,SAAS,QAAQ,QACrB;GACE,kBAAkB;GAClB,aAAa;GACb,WAAW,MAAM,SAAS,MAAM;GAChC,SAAS,MAAM,SAAS;GACxB;GACD,GACD;EACN,SAAS;GACP,KAAK,MAAM;GACX,QAAQ,uBAAuB,MAAM;GACtC;EACD,UAAU;GACR;IACE,IAAI;IACJ,OAAO;IACP,SAAS,yBAAyB,MAAM;IACxC,KAAK,MAAM;IACX,SAAS,iBAAiB;IAC3B;GACD;IACE,IAAI;IACJ,OAAO;IACP,SAAS,yBAAyB,MAAM;IACxC,SAAS,iBAAiB;IAC3B;GACD;IACE,IAAI;IACJ,OAAO;IACP,SAAS,MAAM;IACf,SAAS,iBAAiB;IAC3B;GACD;IACE,IAAI;IACJ,OAAO;IACP,SAAS,MAAM;IACf,SAAS,iBAAiB;IAC3B;GACD;IACE,IAAI;IACJ,OAAO;IACP,SAAS,MAAM;IACf,SAAS,iBAAiB;IAC3B;GACD;IACE,IAAI;IACJ,OAAO;IACP,SAAS,MAAM;IACf,SAAS,iBAAiB;IAC3B;GACD;IACE,IAAI;IACJ,OAAO;IACP,SAAS,yBAAyB,QAAQ,MAAM,aAAa;IAC7D,KAAK,MAAM;IACX,SAAS,iBAAiB;IAC3B;GACF;EACD,MAAM,qBAAqB;GACzB,aAAa,MAAM;GACnB,UAAU,MAAM;GAChB,MAAM,MAAM,oBAAoB;GACjC,CAAC;EACH"}
@@ -0,0 +1,58 @@
1
+
2
+ //#region src/lib/inspector-nav.ts
3
+ const INSPECTOR_GROUPS = {
4
+ home: ["home", "whats-new"],
5
+ workbench: [
6
+ "playground",
7
+ "threads",
8
+ "memories"
9
+ ],
10
+ inspect: [
11
+ "agents",
12
+ "ag-ui-events",
13
+ "frontend-tools",
14
+ "capabilities",
15
+ "agent-context"
16
+ ]
17
+ };
18
+ const INSPECTOR_MENU_KEYS = [
19
+ ...INSPECTOR_GROUPS.home,
20
+ ...INSPECTOR_GROUPS.workbench,
21
+ ...INSPECTOR_GROUPS.inspect
22
+ ];
23
+ const INSPECTOR_NAV_SECTIONS = [
24
+ {
25
+ group: "home",
26
+ label: null
27
+ },
28
+ {
29
+ group: "workbench",
30
+ label: "Workbench"
31
+ },
32
+ {
33
+ group: "inspect",
34
+ label: "Inspect"
35
+ }
36
+ ];
37
+ const ICON_RAIL_MAX_WIDTH_PX = 720;
38
+ /** Return whether persisted state names a known Inspector leaf. */
39
+ function isInspectorMenuKey(value) {
40
+ return typeof value === "string" && INSPECTOR_MENU_KEYS.some((menuKey) => menuKey === value);
41
+ }
42
+ /** Return the sidebar group that owns a leaf. */
43
+ function getGroupForMenu(key) {
44
+ for (const group of Object.keys(INSPECTOR_GROUPS)) if (INSPECTOR_GROUPS[group].some((menuKey) => menuKey === key)) return group;
45
+ return "workbench";
46
+ }
47
+ /** Return whether the sidebar should collapse to an icon rail. */
48
+ function shouldUseIconRail(args) {
49
+ return args.dockedLeft || args.width < ICON_RAIL_MAX_WIDTH_PX;
50
+ }
51
+
52
+ //#endregion
53
+ exports.INSPECTOR_GROUPS = INSPECTOR_GROUPS;
54
+ exports.INSPECTOR_NAV_SECTIONS = INSPECTOR_NAV_SECTIONS;
55
+ exports.getGroupForMenu = getGroupForMenu;
56
+ exports.isInspectorMenuKey = isInspectorMenuKey;
57
+ exports.shouldUseIconRail = shouldUseIconRail;
58
+ //# sourceMappingURL=inspector-nav.cjs.map