@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.
- package/dist/snapshot/spans.js +28 -4
- package/package.json +3 -1
- package/src/snapshot/spans.ts +33 -12
package/dist/snapshot/spans.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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(
|
|
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
|
+
"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",
|
package/src/snapshot/spans.ts
CHANGED
|
@@ -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
|
-
|
|
51
|
-
|
|
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
|
}
|