@cephalization/phoenix-insight 0.3.0 → 0.4.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.
@@ -1,4 +1,17 @@
1
1
  import { withErrorHandling } from "./client.js";
2
+ /**
3
+ * Debug logger that respects the debug flag or DEBUG environment variable
4
+ */
5
+ function createDebugLogger(debug) {
6
+ const isDebugEnabled = debug ?? !!process.env.DEBUG;
7
+ return {
8
+ log: (message) => {
9
+ if (isDebugEnabled) {
10
+ console.log(`[snapshotSpans] ${message}`);
11
+ }
12
+ },
13
+ };
14
+ }
2
15
  /**
3
16
  * Fetches spans for all projects and writes them to the snapshot
4
17
  *
@@ -7,11 +20,15 @@ import { withErrorHandling } from "./client.js";
7
20
  * @param options - Options for filtering and limiting spans
8
21
  */
9
22
  export async function snapshotSpans(client, mode, options = {}) {
10
- const { startTime, endTime, spansPerProject = 1000 } = options;
23
+ const { startTime, endTime, spansPerProject = 1000, debug } = options;
24
+ const logger = createDebugLogger(debug);
11
25
  // Read projects index to get project names
12
- const projectsIndexContent = await mode.exec("cat /phoenix/projects/index.jsonl");
26
+ // Use relative path so it works with the cwd set by the execution mode
27
+ logger.log("Reading projects index from projects/index.jsonl");
28
+ const projectsIndexContent = await mode.exec("cat projects/index.jsonl");
13
29
  if (!projectsIndexContent.stdout) {
14
30
  // No projects, nothing to do
31
+ logger.log("No projects found in index, skipping span fetch");
15
32
  return;
16
33
  }
17
34
  const projectNames = projectsIndexContent.stdout
@@ -22,9 +39,11 @@ export async function snapshotSpans(client, mode, options = {}) {
22
39
  const project = JSON.parse(line);
23
40
  return project.name;
24
41
  });
42
+ logger.log(`Found ${projectNames.length} project(s): ${projectNames.join(", ")}`);
25
43
  // Fetch spans for each project
26
44
  for (const projectName of projectNames) {
27
45
  await withErrorHandling(async () => {
46
+ logger.log(`Starting span fetch for project: ${projectName}`);
28
47
  const spans = [];
29
48
  let cursor = null;
30
49
  let totalFetched = 0;
@@ -63,10 +82,15 @@ export async function snapshotSpans(client, mode, options = {}) {
63
82
  break;
64
83
  }
65
84
  }
85
+ logger.log(`Completed span fetch for project ${projectName}: ${spans.length} span(s) fetched`);
66
86
  // Write spans to JSONL file
87
+ const spansFilePath = `/phoenix/projects/${projectName}/spans/index.jsonl`;
88
+ logger.log(`Writing spans to ${spansFilePath}`);
67
89
  const jsonlContent = spans.map((span) => JSON.stringify(span)).join("\n");
68
- await mode.writeFile(`/phoenix/projects/${projectName}/spans/index.jsonl`, jsonlContent);
90
+ await mode.writeFile(spansFilePath, jsonlContent);
69
91
  // Write metadata about the spans snapshot
92
+ const metadataFilePath = `/phoenix/projects/${projectName}/spans/metadata.json`;
93
+ logger.log(`Writing metadata to ${metadataFilePath}`);
70
94
  const metadata = {
71
95
  project: projectName,
72
96
  spanCount: spans.length,
@@ -74,7 +98,7 @@ export async function snapshotSpans(client, mode, options = {}) {
74
98
  endTime: endTime || null,
75
99
  snapshotTime: new Date().toISOString(),
76
100
  };
77
- await mode.writeFile(`/phoenix/projects/${projectName}/spans/metadata.json`, JSON.stringify(metadata, null, 2));
101
+ await mode.writeFile(metadataFilePath, JSON.stringify(metadata, null, 2));
78
102
  }, `fetching spans for project ${projectName}`);
79
103
  }
80
104
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cephalization/phoenix-insight",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A CLI for Arize AI Phoenix data analysis with AI agents",
5
5
  "type": "module",
6
6
  "exports": {
@@ -53,7 +53,9 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@changesets/cli": "^2.29.8",
56
+ "@faker-js/faker": "^10.2.0",
56
57
  "@types/node": "^18.19.0",
58
+ "msw": "^2.12.7",
57
59
  "rimraf": "^5.0.10",
58
60
  "tsc-alias": "^1.8.11",
59
61
  "tsx": "^4.21.0",
@@ -9,6 +9,22 @@ export interface SnapshotSpansOptions {
9
9
  endTime?: Date | string | null;
10
10
  /** Maximum number of spans to fetch per project (default: 1000) */
11
11
  spansPerProject?: number;
12
+ /** Enable debug logging (default: uses DEBUG env var) */
13
+ debug?: boolean;
14
+ }
15
+
16
+ /**
17
+ * Debug logger that respects the debug flag or DEBUG environment variable
18
+ */
19
+ function createDebugLogger(debug?: boolean) {
20
+ const isDebugEnabled = debug ?? !!process.env.DEBUG;
21
+ return {
22
+ log: (message: string) => {
23
+ if (isDebugEnabled) {
24
+ console.log(`[snapshotSpans] ${message}`);
25
+ }
26
+ },
27
+ };
12
28
  }
13
29
 
14
30
  interface SpanData {
@@ -44,14 +60,16 @@ export async function snapshotSpans(
44
60
  mode: ExecutionMode,
45
61
  options: SnapshotSpansOptions = {}
46
62
  ): Promise<void> {
47
- const { startTime, endTime, spansPerProject = 1000 } = options;
63
+ const { startTime, endTime, spansPerProject = 1000, debug } = options;
64
+ const logger = createDebugLogger(debug);
48
65
 
49
66
  // Read projects index to get project names
50
- const projectsIndexContent = await mode.exec(
51
- "cat /phoenix/projects/index.jsonl"
52
- );
67
+ // Use relative path so it works with the cwd set by the execution mode
68
+ logger.log("Reading projects index from projects/index.jsonl");
69
+ const projectsIndexContent = await mode.exec("cat projects/index.jsonl");
53
70
  if (!projectsIndexContent.stdout) {
54
71
  // No projects, nothing to do
72
+ logger.log("No projects found in index, skipping span fetch");
55
73
  return;
56
74
  }
57
75
 
@@ -64,9 +82,12 @@ export async function snapshotSpans(
64
82
  return project.name;
65
83
  });
66
84
 
85
+ logger.log(`Found ${projectNames.length} project(s): ${projectNames.join(", ")}`);
86
+
67
87
  // Fetch spans for each project
68
88
  for (const projectName of projectNames) {
69
89
  await withErrorHandling(async () => {
90
+ logger.log(`Starting span fetch for project: ${projectName}`);
70
91
  const spans: SpanData[] = [];
71
92
  let cursor: string | null = null;
72
93
  let totalFetched = 0;
@@ -117,14 +138,17 @@ export async function snapshotSpans(
117
138
  }
118
139
  }
119
140
 
141
+ logger.log(`Completed span fetch for project ${projectName}: ${spans.length} span(s) fetched`);
142
+
120
143
  // Write spans to JSONL file
144
+ const spansFilePath = `/phoenix/projects/${projectName}/spans/index.jsonl`;
145
+ logger.log(`Writing spans to ${spansFilePath}`);
121
146
  const jsonlContent = spans.map((span) => JSON.stringify(span)).join("\n");
122
- await mode.writeFile(
123
- `/phoenix/projects/${projectName}/spans/index.jsonl`,
124
- jsonlContent
125
- );
147
+ await mode.writeFile(spansFilePath, jsonlContent);
126
148
 
127
149
  // Write metadata about the spans snapshot
150
+ const metadataFilePath = `/phoenix/projects/${projectName}/spans/metadata.json`;
151
+ logger.log(`Writing metadata to ${metadataFilePath}`);
128
152
  const metadata = {
129
153
  project: projectName,
130
154
  spanCount: spans.length,
@@ -133,10 +157,7 @@ export async function snapshotSpans(
133
157
  snapshotTime: new Date().toISOString(),
134
158
  };
135
159
 
136
- await mode.writeFile(
137
- `/phoenix/projects/${projectName}/spans/metadata.json`,
138
- JSON.stringify(metadata, null, 2)
139
- );
160
+ await mode.writeFile(metadataFilePath, JSON.stringify(metadata, null, 2));
140
161
  }, `fetching spans for project ${projectName}`);
141
162
  }
142
163
  }