@copilotkit/web-inspector 1.61.2 → 1.62.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # @copilotkit/web-inspector
2
+
3
+ ## Standalone Thread Inspector QA
4
+
5
+ Run the shared inspector without an app shell:
6
+
7
+ ```bash
8
+ pnpm nx run @copilotkit/web-inspector:dev:standalone
9
+ ```
10
+
11
+ Open [http://127.0.0.1:5177/](http://127.0.0.1:5177/).
12
+
13
+ Validation steps:
14
+
15
+ 1. Confirm the initial `AG-UI events` scenario opens on the Timeline tab and renders run, message, and tool rows.
16
+ 2. Click `Messages only` and confirm the first-visible Timeline renders persisted message content instead of an empty Timeline.
17
+ 3. Click `Raw event only` and confirm the Timeline renders a `THREAD_STATE_WRITTEN` row with a source-event link.
18
+ 4. Use a Timeline source-event link and confirm it opens the Raw AG-UI Events tab on the corresponding event.
19
+ 5. Open the State tab and confirm the demo state is visible.
20
+
21
+ This harness uses demo provider data only. Manual product validation for Intelligence-backed threads still needs a real Intelligence backend.
@@ -0,0 +1,31 @@
1
+ // @vitest-environment node
2
+
3
+ import { describe, expect, it } from "vitest";
4
+
5
+ import viteConfig from "./vite.config.js";
6
+
7
+ describe("web-inspector dev vite config", () => {
8
+ it("throws when the generated stylesheet import is missing from src/index.ts", () => {
9
+ const plugin = Array.isArray(viteConfig.plugins)
10
+ ? viteConfig.plugins.find(
11
+ (candidate) =>
12
+ candidate != null &&
13
+ typeof candidate === "object" &&
14
+ "name" in candidate &&
15
+ candidate.name === "web-inspector-css-raw-import",
16
+ )
17
+ : undefined;
18
+
19
+ if (!plugin || !("transform" in plugin) || !plugin.transform) {
20
+ throw new Error("web-inspector-css-raw-import plugin not found");
21
+ }
22
+
23
+ expect(() =>
24
+ plugin.transform.call(
25
+ {} as never,
26
+ 'import tailwindStyles from "./styles/other.css";',
27
+ "/repo/packages/web-inspector/src/index.ts",
28
+ ),
29
+ ).toThrow("generated.css import");
30
+ });
31
+ });
package/dev/index.html ADDED
@@ -0,0 +1,115 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>CopilotKit Web Inspector Standalone</title>
7
+ <script type="module" src="/main.ts"></script>
8
+ <style>
9
+ :root {
10
+ color-scheme: light;
11
+ font-family:
12
+ Inter,
13
+ ui-sans-serif,
14
+ system-ui,
15
+ -apple-system,
16
+ BlinkMacSystemFont,
17
+ "Segoe UI",
18
+ sans-serif;
19
+ background: #f7f7f9;
20
+ color: #010507;
21
+ }
22
+
23
+ * {
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ body {
28
+ margin: 0;
29
+ min-height: 100vh;
30
+ }
31
+
32
+ main {
33
+ display: grid;
34
+ grid-template-rows: auto 1fr;
35
+ min-height: 100vh;
36
+ }
37
+
38
+ header {
39
+ display: flex;
40
+ align-items: center;
41
+ justify-content: space-between;
42
+ gap: 16px;
43
+ padding: 14px 18px;
44
+ border-bottom: 1px solid #dbdbe5;
45
+ background: #ffffff;
46
+ }
47
+
48
+ h1 {
49
+ margin: 0;
50
+ font-size: 15px;
51
+ font-weight: 650;
52
+ }
53
+
54
+ p {
55
+ margin: 4px 0 0;
56
+ color: #57575b;
57
+ font-size: 12px;
58
+ }
59
+
60
+ .controls {
61
+ display: flex;
62
+ gap: 8px;
63
+ }
64
+
65
+ button {
66
+ border: 1px solid #dbdbe5;
67
+ border-radius: 6px;
68
+ background: #ffffff;
69
+ color: #010507;
70
+ cursor: pointer;
71
+ font: inherit;
72
+ font-size: 12px;
73
+ padding: 7px 10px;
74
+ }
75
+
76
+ button:hover {
77
+ border-color: #bec2ff;
78
+ }
79
+
80
+ #inspector-host {
81
+ min-height: 0;
82
+ padding: 16px;
83
+ }
84
+
85
+ cpk-thread-inspector {
86
+ display: block;
87
+ height: calc(100vh - 98px);
88
+ min-height: 520px;
89
+ border: 1px solid #dbdbe5;
90
+ border-radius: 8px;
91
+ overflow: hidden;
92
+ background: #ffffff;
93
+ }
94
+ </style>
95
+ </head>
96
+ <body>
97
+ <main>
98
+ <header>
99
+ <div>
100
+ <h1>Web Inspector Standalone Thread Detail</h1>
101
+ <p>
102
+ Demo provider data only. Product validation still needs a real
103
+ Intelligence backend.
104
+ </p>
105
+ </div>
106
+ <div class="controls" aria-label="Demo scenarios">
107
+ <button type="button" data-scenario="events">AG-UI events</button>
108
+ <button type="button" data-scenario="messages">Messages only</button>
109
+ <button type="button" data-scenario="raw">Raw event only</button>
110
+ </div>
111
+ </header>
112
+ <section id="inspector-host"></section>
113
+ </main>
114
+ </body>
115
+ </html>
package/dev/main.ts ADDED
@@ -0,0 +1,165 @@
1
+ import "../src/index.ts";
2
+ import type {
3
+ CpkThreadInspector,
4
+ ThreadDebuggerProvider,
5
+ } from "../src/index.ts";
6
+
7
+ type Scenario = "events" | "messages" | "raw";
8
+
9
+ const host = document.querySelector<HTMLElement>("#inspector-host");
10
+
11
+ if (!host) {
12
+ throw new Error("Missing standalone inspector host element.");
13
+ }
14
+
15
+ const inspector = document.createElement(
16
+ "cpk-thread-inspector",
17
+ ) as CpkThreadInspector;
18
+
19
+ host.appendChild(inspector);
20
+
21
+ const scenarios: Record<
22
+ Scenario,
23
+ {
24
+ label: string;
25
+ threadId: string;
26
+ provider: ThreadDebuggerProvider;
27
+ }
28
+ > = {
29
+ events: {
30
+ label: "AG-UI events",
31
+ threadId: "demo-events-thread",
32
+ provider: {
33
+ getThreadMetadata: async () => ({
34
+ id: "demo-events-thread",
35
+ name: "AG-UI event-backed thread",
36
+ agentId: "demo-agent",
37
+ endUserId: "demo-user",
38
+ status: "completed",
39
+ createdAt: "2026-06-25T10:00:00.000Z",
40
+ updatedAt: "2026-06-25T10:00:04.000Z",
41
+ }),
42
+ getEvents: async () => [
43
+ {
44
+ type: "RUN_STARTED",
45
+ timestamp: "2026-06-25T10:00:00.000Z",
46
+ payload: { runId: "run-1" },
47
+ },
48
+ {
49
+ type: "TEXT_MESSAGE_START",
50
+ timestamp: "2026-06-25T10:00:01.000Z",
51
+ payload: { messageId: "m1", role: "assistant" },
52
+ },
53
+ {
54
+ type: "TEXT_MESSAGE_CONTENT",
55
+ timestamp: "2026-06-25T10:00:02.000Z",
56
+ payload: {
57
+ messageId: "m1",
58
+ delta: "Here is the event-derived timeline row.",
59
+ },
60
+ },
61
+ {
62
+ type: "TOOL_CALL_START",
63
+ timestamp: "2026-06-25T10:00:03.000Z",
64
+ payload: { toolCallId: "tc1", toolCallName: "lookup_docs" },
65
+ },
66
+ {
67
+ type: "TOOL_CALL_ARGS",
68
+ timestamp: "2026-06-25T10:00:03.250Z",
69
+ payload: { toolCallId: "tc1", args: { query: "threads" } },
70
+ },
71
+ {
72
+ type: "RUN_FINISHED",
73
+ timestamp: "2026-06-25T10:00:04.000Z",
74
+ payload: { runId: "run-1" },
75
+ },
76
+ ],
77
+ getState: async () => ({ phase: "complete", selectedScenario: "events" }),
78
+ },
79
+ },
80
+ messages: {
81
+ label: "Messages only",
82
+ threadId: "demo-messages-thread",
83
+ provider: {
84
+ getThreadMetadata: async () => ({
85
+ id: "demo-messages-thread",
86
+ name: "Message-backed thread",
87
+ agentId: "demo-agent",
88
+ endUserId: "demo-user",
89
+ status: "completed",
90
+ }),
91
+ getEvents: async () => [],
92
+ getMessages: async () => [
93
+ {
94
+ id: "u1",
95
+ role: "user",
96
+ content: "Show me the thread timeline.",
97
+ },
98
+ {
99
+ id: "a1",
100
+ role: "assistant",
101
+ content: "This fallback is rendered from persisted messages.",
102
+ },
103
+ ],
104
+ getState: async () => ({ selectedScenario: "messages" }),
105
+ },
106
+ },
107
+ raw: {
108
+ label: "Raw event only",
109
+ threadId: "demo-raw-thread",
110
+ provider: {
111
+ getThreadMetadata: async () => ({
112
+ id: "demo-raw-thread",
113
+ name: "Raw event-backed thread",
114
+ agentId: "demo-agent",
115
+ endUserId: "demo-user",
116
+ status: "active",
117
+ }),
118
+ getEvents: async () => [
119
+ {
120
+ type: "THREAD_STATE_WRITTEN",
121
+ timestamp: "2026-06-25T10:00:00.000Z",
122
+ payload: {
123
+ checkpointId: "checkpoint-1",
124
+ note: "Unsupported event types still render as raw timeline rows.",
125
+ },
126
+ },
127
+ ],
128
+ getState: async () => ({ selectedScenario: "raw" }),
129
+ },
130
+ },
131
+ };
132
+
133
+ function selectScenario(scenario: Scenario): void {
134
+ const selected = scenarios[scenario];
135
+ inspector.provider = selected.provider;
136
+ inspector.threadId = selected.threadId;
137
+ inspector.thread = null;
138
+
139
+ for (const button of document.querySelectorAll<HTMLButtonElement>(
140
+ "[data-scenario]",
141
+ )) {
142
+ const active = button.dataset.scenario === scenario;
143
+ button.setAttribute("aria-pressed", String(active));
144
+ button.style.background = active ? "#eee6fe" : "#ffffff";
145
+ }
146
+
147
+ document.title = `CopilotKit Web Inspector Standalone - ${selected.label}`;
148
+ }
149
+
150
+ for (const button of document.querySelectorAll<HTMLButtonElement>(
151
+ "[data-scenario]",
152
+ )) {
153
+ button.addEventListener("click", () => {
154
+ const scenario = button.dataset.scenario;
155
+ if (
156
+ scenario === "events" ||
157
+ scenario === "messages" ||
158
+ scenario === "raw"
159
+ ) {
160
+ selectScenario(scenario);
161
+ }
162
+ });
163
+ }
164
+
165
+ selectScenario("events");
@@ -0,0 +1,30 @@
1
+ import { defineConfig } from "vite";
2
+
3
+ /**
4
+ * Mirrors the package bundler's CSS-as-string behavior for the standalone
5
+ * harness. The inspector injects generated.css into Shadow DOM via unsafeCSS,
6
+ * so the dev server rewrites that package-local import to Vite's raw string
7
+ * loader without changing production source.
8
+ */
9
+ export default defineConfig({
10
+ plugins: [
11
+ {
12
+ name: "web-inspector-css-raw-import",
13
+ enforce: "pre",
14
+ transform(code, id) {
15
+ if (!id.endsWith("/src/index.ts")) return null;
16
+ const cssImport =
17
+ 'import tailwindStyles from "./styles/generated.css";';
18
+ if (!code.includes(cssImport)) {
19
+ throw new Error(
20
+ "web-inspector dev CSS transform expected src/index.ts to include the generated.css import",
21
+ );
22
+ }
23
+ return code.replace(
24
+ cssImport,
25
+ 'import tailwindStyles from "./styles/generated.css?raw";',
26
+ );
27
+ },
28
+ },
29
+ ],
30
+ });