@cephalization/phoenix-insight 0.4.0 → 1.0.2

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 (76) hide show
  1. package/README.md +195 -1
  2. package/dist/chunk-KEQDYZIE.js +237 -0
  3. package/dist/chunk-KEQDYZIE.js.map +1 -0
  4. package/dist/cli.d.ts +1 -0
  5. package/dist/cli.js +3950 -642
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +108 -0
  8. package/dist/index.js +13 -1
  9. package/dist/index.js.map +1 -0
  10. package/dist/ui/assets/code-block-F6WJLWQG-BTdTzfvl.js +154 -0
  11. package/dist/ui/assets/code-block-F6WJLWQG-BTdTzfvl.js.map +1 -0
  12. package/dist/ui/assets/index-CX8aDatf.css +1 -0
  13. package/dist/ui/assets/index-DjZuAW6Y.js +63 -0
  14. package/dist/ui/assets/index-DjZuAW6Y.js.map +1 -0
  15. package/dist/ui/assets/vendor-data-r1ZEkUds.js +40 -0
  16. package/dist/ui/assets/vendor-data-r1ZEkUds.js.map +1 -0
  17. package/dist/ui/assets/vendor-react-Cgg2GOmP.js +2 -0
  18. package/dist/ui/assets/vendor-react-Cgg2GOmP.js.map +1 -0
  19. package/dist/ui/assets/vendor-render-DoMl5bum.js +381 -0
  20. package/dist/ui/assets/vendor-render-DoMl5bum.js.map +1 -0
  21. package/dist/ui/assets/vendor-ui-Cg-YC4hK.js +46 -0
  22. package/dist/ui/assets/vendor-ui-Cg-YC4hK.js.map +1 -0
  23. package/dist/ui/index.html +18 -0
  24. package/dist/ui/vite.svg +1 -0
  25. package/package.json +14 -15
  26. package/dist/agent/index.js +0 -230
  27. package/dist/commands/index.js +0 -2
  28. package/dist/commands/px-fetch-more-spans.js +0 -98
  29. package/dist/commands/px-fetch-more-trace.js +0 -110
  30. package/dist/config/index.js +0 -165
  31. package/dist/config/loader.js +0 -141
  32. package/dist/config/schema.js +0 -53
  33. package/dist/modes/index.js +0 -17
  34. package/dist/modes/local.js +0 -134
  35. package/dist/modes/sandbox.js +0 -121
  36. package/dist/modes/types.js +0 -1
  37. package/dist/observability/index.js +0 -65
  38. package/dist/progress.js +0 -209
  39. package/dist/prompts/index.js +0 -1
  40. package/dist/prompts/system.js +0 -30
  41. package/dist/snapshot/client.js +0 -74
  42. package/dist/snapshot/context.js +0 -441
  43. package/dist/snapshot/datasets.js +0 -68
  44. package/dist/snapshot/experiments.js +0 -135
  45. package/dist/snapshot/index.js +0 -262
  46. package/dist/snapshot/projects.js +0 -44
  47. package/dist/snapshot/prompts.js +0 -199
  48. package/dist/snapshot/spans.js +0 -104
  49. package/dist/snapshot/utils.js +0 -112
  50. package/dist/tsconfig.esm.tsbuildinfo +0 -1
  51. package/src/agent/index.ts +0 -323
  52. package/src/cli.ts +0 -854
  53. package/src/commands/index.ts +0 -8
  54. package/src/commands/px-fetch-more-spans.ts +0 -174
  55. package/src/commands/px-fetch-more-trace.ts +0 -183
  56. package/src/config/index.ts +0 -225
  57. package/src/config/loader.ts +0 -173
  58. package/src/config/schema.ts +0 -66
  59. package/src/index.ts +0 -1
  60. package/src/modes/index.ts +0 -21
  61. package/src/modes/local.ts +0 -163
  62. package/src/modes/sandbox.ts +0 -144
  63. package/src/modes/types.ts +0 -31
  64. package/src/observability/index.ts +0 -90
  65. package/src/progress.ts +0 -239
  66. package/src/prompts/index.ts +0 -1
  67. package/src/prompts/system.ts +0 -31
  68. package/src/snapshot/client.ts +0 -129
  69. package/src/snapshot/context.ts +0 -587
  70. package/src/snapshot/datasets.ts +0 -132
  71. package/src/snapshot/experiments.ts +0 -246
  72. package/src/snapshot/index.ts +0 -403
  73. package/src/snapshot/projects.ts +0 -58
  74. package/src/snapshot/prompts.ts +0 -267
  75. package/src/snapshot/spans.ts +0 -163
  76. package/src/snapshot/utils.ts +0 -140
@@ -1,112 +0,0 @@
1
- /**
2
- * Snapshot discovery utilities
3
- *
4
- * Functions for listing and finding snapshots in the local filesystem.
5
- */
6
- import * as fs from "node:fs/promises";
7
- import * as path from "node:path";
8
- import * as os from "node:os";
9
- /**
10
- * Get the base snapshots directory path
11
- */
12
- export function getSnapshotsDir() {
13
- return path.join(os.homedir(), ".phoenix-insight", "snapshots");
14
- }
15
- /**
16
- * Parse a snapshot directory name to extract timestamp
17
- *
18
- * Directory names are in format: `<timestamp>-<random>` where timestamp is Date.now()
19
- * Example: "1704067200000-abc123" -> Date(2024-01-01T00:00:00.000Z)
20
- *
21
- * @param dirName - The directory name to parse
22
- * @returns The parsed timestamp as Date, or null if invalid
23
- */
24
- function parseSnapshotDirName(dirName) {
25
- // Format: <timestamp>-<random>
26
- const match = dirName.match(/^(\d+)-[\w]+$/);
27
- if (!match || !match[1]) {
28
- return null;
29
- }
30
- const timestamp = parseInt(match[1], 10);
31
- if (isNaN(timestamp) || timestamp <= 0) {
32
- return null;
33
- }
34
- const date = new Date(timestamp);
35
- // Validate the date is reasonable (between year 2000 and year 3000)
36
- // Use UTC year to avoid timezone issues
37
- const year = date.getUTCFullYear();
38
- if (year < 2000 || year > 3000) {
39
- return null;
40
- }
41
- return date;
42
- }
43
- /**
44
- * List all available snapshots
45
- *
46
- * Scans the snapshots directory and returns information about each valid snapshot.
47
- * Results are sorted by timestamp descending (most recent first).
48
- *
49
- * @returns Array of snapshot info objects, sorted by timestamp descending
50
- */
51
- export async function listSnapshots() {
52
- const snapshotsDir = getSnapshotsDir();
53
- // Check if snapshots directory exists
54
- try {
55
- await fs.access(snapshotsDir);
56
- }
57
- catch {
58
- // Directory doesn't exist - return empty array
59
- return [];
60
- }
61
- // Read directory contents
62
- let entries;
63
- try {
64
- entries = await fs.readdir(snapshotsDir);
65
- }
66
- catch {
67
- // Cannot read directory - return empty array
68
- return [];
69
- }
70
- // Filter and parse valid snapshot directories
71
- const snapshots = [];
72
- for (const entry of entries) {
73
- const timestamp = parseSnapshotDirName(entry);
74
- if (!timestamp) {
75
- // Invalid directory name format - skip
76
- continue;
77
- }
78
- const snapshotPath = path.join(snapshotsDir, entry, "phoenix");
79
- // Verify the phoenix subdirectory exists
80
- try {
81
- const stat = await fs.stat(snapshotPath);
82
- if (!stat.isDirectory()) {
83
- continue;
84
- }
85
- }
86
- catch {
87
- // Phoenix subdirectory doesn't exist or can't be accessed - skip
88
- continue;
89
- }
90
- snapshots.push({
91
- path: snapshotPath,
92
- timestamp,
93
- id: entry,
94
- });
95
- }
96
- // Sort by timestamp descending (most recent first)
97
- snapshots.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
98
- return snapshots;
99
- }
100
- /**
101
- * Get the latest (most recent) snapshot
102
- *
103
- * @returns The most recent snapshot info, or null if no snapshots exist
104
- */
105
- export async function getLatestSnapshot() {
106
- const snapshots = await listSnapshots();
107
- if (snapshots.length === 0) {
108
- return null;
109
- }
110
- // First element is the most recent due to descending sort
111
- return snapshots[0] ?? null;
112
- }
@@ -1 +0,0 @@
1
- {"root":["../src/cli.ts","../src/index.ts","../src/progress.ts","../src/agent/index.ts","../src/commands/index.ts","../src/commands/px-fetch-more-spans.ts","../src/commands/px-fetch-more-trace.ts","../src/config/index.ts","../src/config/loader.ts","../src/config/schema.ts","../src/modes/index.ts","../src/modes/local.ts","../src/modes/sandbox.ts","../src/modes/types.ts","../src/observability/index.ts","../src/prompts/index.ts","../src/prompts/system.ts","../src/snapshot/client.ts","../src/snapshot/context.ts","../src/snapshot/datasets.ts","../src/snapshot/experiments.ts","../src/snapshot/index.ts","../src/snapshot/projects.ts","../src/snapshot/prompts.ts","../src/snapshot/spans.ts","../src/snapshot/utils.ts"],"version":"5.9.3"}
@@ -1,323 +0,0 @@
1
- /**
2
- * Phoenix Insight AI agent setup using Vercel AI SDK
3
- */
4
-
5
- import {
6
- generateText,
7
- streamText,
8
- tool,
9
- stepCountIs,
10
- type GenerateTextResult,
11
- type StreamTextResult,
12
- } from "ai";
13
- import { anthropic } from "@ai-sdk/anthropic";
14
- import { z } from "zod";
15
- import type { ExecutionMode } from "../modes/types.js";
16
- import { INSIGHT_SYSTEM_PROMPT } from "../prompts/system.js";
17
- import {
18
- fetchMoreSpans,
19
- fetchMoreTrace,
20
- type FetchMoreSpansOptions,
21
- type FetchMoreTraceOptions,
22
- } from "../commands/index.js";
23
- import type { PhoenixClient } from "@arizeai/phoenix-client";
24
- import { PhoenixClientError } from "../snapshot/client.js";
25
-
26
- /**
27
- * Configuration for the Phoenix Insight agent
28
- */
29
- export interface PhoenixInsightAgentConfig {
30
- /** The execution mode (sandbox or local) */
31
- mode: ExecutionMode;
32
- /** Phoenix client instance */
33
- client: PhoenixClient;
34
- /** Maximum number of agent steps before stopping (default: 25) */
35
- maxSteps?: number;
36
- }
37
-
38
- /**
39
- * Phoenix Insight Agent
40
- */
41
- export class PhoenixInsightAgent {
42
- private mode: ExecutionMode;
43
- private client: PhoenixClient;
44
- private maxSteps: number;
45
- private tools: Record<string, any> | null = null;
46
- private model = anthropic("claude-sonnet-4-5");
47
-
48
- constructor(config: PhoenixInsightAgentConfig) {
49
- this.mode = config.mode;
50
- this.client = config.client;
51
- this.maxSteps = config.maxSteps || 25;
52
- }
53
-
54
- /**
55
- * Initialize the agent tools
56
- */
57
- private async initializeTools(): Promise<Record<string, any>> {
58
- if (this.tools) return this.tools;
59
-
60
- // Get the bash tool from the execution mode
61
- const bashTool = await this.mode.getBashTool();
62
-
63
- // Store references in closure for the custom tools
64
- const client = this.client;
65
- const mode = this.mode;
66
-
67
- // Create custom px-fetch-more-spans tool using AI SDK's tool function
68
- const pxFetchMoreSpans = tool({
69
- description:
70
- "Fetch additional spans from Phoenix. Use when you need more span data than what's in the snapshot. You must provide both project name and optionally a limit.",
71
- inputSchema: z.object({
72
- project: z.string().describe("The project name"),
73
- limit: z
74
- .number()
75
- .optional()
76
- .describe("Number of spans to fetch (default: 500)"),
77
- startTime: z
78
- .string()
79
- .optional()
80
- .describe("Start time filter in ISO format"),
81
- endTime: z
82
- .string()
83
- .optional()
84
- .describe("End time filter in ISO format"),
85
- }),
86
- execute: async (params) => {
87
- try {
88
- const options: FetchMoreSpansOptions = {
89
- project: params.project,
90
- limit: params.limit || 500,
91
- startTime: params.startTime,
92
- endTime: params.endTime,
93
- };
94
-
95
- await fetchMoreSpans(client, mode, options);
96
-
97
- return {
98
- success: true,
99
- message: `Fetched additional spans for project ${params.project}. Data saved to /phoenix/projects/${params.project}/spans/`,
100
- };
101
- } catch (error) {
102
- return {
103
- success: false,
104
- error: error instanceof Error ? error.message : String(error),
105
- };
106
- }
107
- },
108
- });
109
-
110
- // Create custom px-fetch-more-trace tool using AI SDK's tool function
111
- const pxFetchMoreTrace = tool({
112
- description:
113
- "Fetch a specific trace by ID from Phoenix. Use when you need to examine a particular trace in detail. You must provide both the trace ID and the project name.",
114
- inputSchema: z.object({
115
- traceId: z.string().describe("The trace ID to fetch"),
116
- project: z.string().describe("The project name to search in"),
117
- }),
118
- execute: async (params) => {
119
- try {
120
- const options: FetchMoreTraceOptions = {
121
- traceId: params.traceId,
122
- project: params.project,
123
- };
124
-
125
- await fetchMoreTrace(client, mode, options);
126
-
127
- return {
128
- success: true,
129
- message: `Fetched trace ${params.traceId}. Data saved to /phoenix/traces/${params.traceId}/`,
130
- };
131
- } catch (error) {
132
- return {
133
- success: false,
134
- error: error instanceof Error ? error.message : String(error),
135
- };
136
- }
137
- },
138
- });
139
-
140
- this.tools = {
141
- bash: bashTool,
142
- px_fetch_more_spans: pxFetchMoreSpans,
143
- px_fetch_more_trace: pxFetchMoreTrace,
144
- };
145
-
146
- return this.tools;
147
- }
148
-
149
- /**
150
- * Generate a response for a user query
151
- */
152
- async generate(
153
- userQuery: string,
154
- options?: {
155
- onStepFinish?: (step: any) => void;
156
- }
157
- ): Promise<GenerateTextResult<any, any>> {
158
- let tools;
159
- try {
160
- tools = await this.initializeTools();
161
- } catch (error) {
162
- throw new Error(
163
- `Failed to initialize agent tools: ${error instanceof Error ? error.message : String(error)}`
164
- );
165
- }
166
-
167
- try {
168
- const result = await generateText({
169
- model: this.model,
170
- system: INSIGHT_SYSTEM_PROMPT,
171
- prompt: userQuery,
172
- tools,
173
- stopWhen: stepCountIs(this.maxSteps),
174
- onStepFinish: options?.onStepFinish,
175
- experimental_telemetry: {
176
- isEnabled: true,
177
- },
178
- });
179
-
180
- return result;
181
- } catch (error) {
182
- // Check for specific AI SDK errors
183
- if (error instanceof Error) {
184
- if (error.message.includes("rate limit")) {
185
- throw new Error(
186
- "AI model rate limit exceeded. Please wait and try again."
187
- );
188
- }
189
- if (error.message.includes("timeout")) {
190
- throw new Error("AI model request timed out. Please try again.");
191
- }
192
- if (
193
- error.message.includes("authentication") ||
194
- error.message.includes("API key")
195
- ) {
196
- throw new Error(
197
- "AI model authentication failed. Check your API key configuration."
198
- );
199
- }
200
- }
201
-
202
- throw new Error(
203
- `AI generation failed: ${error instanceof Error ? error.message : String(error)}`
204
- );
205
- }
206
- }
207
-
208
- /**
209
- * Stream a response for a user query
210
- */
211
- async stream(
212
- userQuery: string,
213
- options?: {
214
- onStepFinish?: (step: any) => void;
215
- }
216
- ): Promise<StreamTextResult<any, any>> {
217
- let tools;
218
- try {
219
- tools = await this.initializeTools();
220
- } catch (error) {
221
- throw new Error(
222
- `Failed to initialize agent tools: ${error instanceof Error ? error.message : String(error)}`
223
- );
224
- }
225
-
226
- try {
227
- const result = streamText({
228
- model: this.model,
229
- system: INSIGHT_SYSTEM_PROMPT,
230
- prompt: userQuery,
231
- tools,
232
- stopWhen: stepCountIs(this.maxSteps),
233
- onStepFinish: options?.onStepFinish,
234
- experimental_telemetry: {
235
- isEnabled: true,
236
- },
237
- });
238
-
239
- return result;
240
- } catch (error) {
241
- // Check for specific AI SDK errors
242
- if (error instanceof Error) {
243
- if (error.message.includes("rate limit")) {
244
- throw new Error(
245
- "AI model rate limit exceeded. Please wait and try again."
246
- );
247
- }
248
- if (error.message.includes("timeout")) {
249
- throw new Error("AI model request timed out. Please try again.");
250
- }
251
- if (
252
- error.message.includes("authentication") ||
253
- error.message.includes("API key")
254
- ) {
255
- throw new Error(
256
- "AI model authentication failed. Check your API key configuration."
257
- );
258
- }
259
- }
260
-
261
- throw new Error(
262
- `AI streaming failed: ${error instanceof Error ? error.message : String(error)}`
263
- );
264
- }
265
- }
266
-
267
- /**
268
- * Clean up resources
269
- */
270
- async cleanup(): Promise<void> {
271
- await this.mode.cleanup();
272
- }
273
- }
274
-
275
- /**
276
- * Creates a Phoenix Insight agent
277
- */
278
- export async function createInsightAgent(
279
- config: PhoenixInsightAgentConfig
280
- ): Promise<PhoenixInsightAgent> {
281
- return new PhoenixInsightAgent(config);
282
- }
283
-
284
- /**
285
- * Run a query with the Phoenix Insight agent
286
- */
287
- export async function runQuery(
288
- agent: PhoenixInsightAgent,
289
- userQuery: string,
290
- options?: {
291
- onStepFinish?: (step: any) => void;
292
- stream?: boolean;
293
- }
294
- ): Promise<GenerateTextResult<any, any> | StreamTextResult<any, any>> {
295
- const { stream = false, ...callbacks } = options || {};
296
-
297
- if (stream) {
298
- return await agent.stream(userQuery, callbacks);
299
- } else {
300
- return await agent.generate(userQuery, callbacks);
301
- }
302
- }
303
-
304
- /**
305
- * Create and run a one-shot query
306
- */
307
- export async function runOneShotQuery(
308
- config: PhoenixInsightAgentConfig,
309
- userQuery: string,
310
- options?: {
311
- onStepFinish?: (step: any) => void;
312
- stream?: boolean;
313
- }
314
- ): Promise<GenerateTextResult<any, any> | StreamTextResult<any, any>> {
315
- const agent = await createInsightAgent(config);
316
-
317
- try {
318
- const result = await runQuery(agent, userQuery, options);
319
- return result;
320
- } finally {
321
- await agent.cleanup();
322
- }
323
- }