promptmetrics-sample 1.0.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/.env.example +12 -0
- package/README.md +235 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/tests/logs.test.d.ts +7 -0
- package/dist/tests/logs.test.d.ts.map +1 -0
- package/dist/tests/logs.test.js +163 -0
- package/dist/tests/logs.test.js.map +1 -0
- package/dist/tests/providers.test.d.ts +7 -0
- package/dist/tests/providers.test.d.ts.map +1 -0
- package/dist/tests/providers.test.js +99 -0
- package/dist/tests/providers.test.js.map +1 -0
- package/dist/tests/tags.test.d.ts +7 -0
- package/dist/tests/tags.test.d.ts.map +1 -0
- package/dist/tests/tags.test.js +220 -0
- package/dist/tests/tags.test.js.map +1 -0
- package/dist/tests/template-run-load.test.d.ts +11 -0
- package/dist/tests/template-run-load.test.d.ts.map +1 -0
- package/dist/tests/template-run-load.test.js +245 -0
- package/dist/tests/template-run-load.test.js.map +1 -0
- package/dist/tests/templates.test.d.ts +7 -0
- package/dist/tests/templates.test.d.ts.map +1 -0
- package/dist/tests/templates.test.js +152 -0
- package/dist/tests/templates.test.js.map +1 -0
- package/dist/tests/traceable.test.d.ts +7 -0
- package/dist/tests/traceable.test.d.ts.map +1 -0
- package/dist/tests/traceable.test.js +300 -0
- package/dist/tests/traceable.test.js.map +1 -0
- package/dist/tests/traces.test.d.ts +7 -0
- package/dist/tests/traces.test.d.ts.map +1 -0
- package/dist/tests/traces.test.js +264 -0
- package/dist/tests/traces.test.js.map +1 -0
- package/dist/tests/versions.test.d.ts +7 -0
- package/dist/tests/versions.test.d.ts.map +1 -0
- package/dist/tests/versions.test.js +145 -0
- package/dist/tests/versions.test.js.map +1 -0
- package/dist/utils/logger.d.ts +26 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +79 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +36 -0
- package/sample-project-plan.md +316 -0
- package/src/index.ts +36 -0
- package/src/tests/logs.test.ts +180 -0
- package/src/tests/providers.test.ts +99 -0
- package/src/tests/tags.test.ts +237 -0
- package/src/tests/template-run-load.test.ts +332 -0
- package/src/tests/templates.test.ts +154 -0
- package/src/tests/traceable.test.ts +290 -0
- package/src/tests/traces.test.ts +298 -0
- package/src/tests/versions.test.ts +155 -0
- package/src/utils/logger.ts +91 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Tags Test Suite
|
|
5
|
+
* Tests the pm_tags feature for prompt logs
|
|
6
|
+
*/
|
|
7
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
8
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
10
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
11
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
12
|
+
};
|
|
13
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
14
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
require("dotenv/config");
|
|
18
|
+
const sdk_1 = require("@promptmetrics/sdk");
|
|
19
|
+
const logger_1 = require("../utils/logger");
|
|
20
|
+
const pm = new sdk_1.PromptMetrics({
|
|
21
|
+
apiKey: process.env.PROMPTMETRICS_API_KEY,
|
|
22
|
+
});
|
|
23
|
+
const TEST_VERSION_ID = process.env.TEST_VERSION_ID;
|
|
24
|
+
const tests = [
|
|
25
|
+
{
|
|
26
|
+
name: "Run version with pm_tags array",
|
|
27
|
+
fn: async () => {
|
|
28
|
+
if (!TEST_VERSION_ID) {
|
|
29
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const tags = ["sdk-test", "automated", "tag-feature-test"];
|
|
33
|
+
const result = await pm.versions.run(TEST_VERSION_ID, {
|
|
34
|
+
variables: {
|
|
35
|
+
topic: "Tags Feature Test",
|
|
36
|
+
},
|
|
37
|
+
pm_tags: tags,
|
|
38
|
+
});
|
|
39
|
+
if (!result)
|
|
40
|
+
throw new Error("Run failed");
|
|
41
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
42
|
+
logger_1.logger.data("Status", result.status);
|
|
43
|
+
logger_1.logger.data("Tags Sent", tags);
|
|
44
|
+
logger_1.logger.data("Tags in Response", result.tags || "Not returned");
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "Run version with empty pm_tags (should inherit from template)",
|
|
49
|
+
fn: async () => {
|
|
50
|
+
if (!TEST_VERSION_ID) {
|
|
51
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const result = await pm.versions.run(TEST_VERSION_ID, {
|
|
55
|
+
variables: {
|
|
56
|
+
topic: "No Tags Test",
|
|
57
|
+
},
|
|
58
|
+
// No pm_tags - should inherit from template
|
|
59
|
+
});
|
|
60
|
+
if (!result)
|
|
61
|
+
throw new Error("Run failed");
|
|
62
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
63
|
+
logger_1.logger.data("Status", result.status);
|
|
64
|
+
logger_1.logger.data("Tags (inherited)", result.tags || "None");
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "Run version with single tag",
|
|
69
|
+
fn: async () => {
|
|
70
|
+
if (!TEST_VERSION_ID) {
|
|
71
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const result = await pm.versions.run(TEST_VERSION_ID, {
|
|
75
|
+
variables: {
|
|
76
|
+
topic: "Single Tag Test",
|
|
77
|
+
},
|
|
78
|
+
pm_tags: ["single-tag"],
|
|
79
|
+
});
|
|
80
|
+
if (!result)
|
|
81
|
+
throw new Error("Run failed");
|
|
82
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
83
|
+
logger_1.logger.data("Tags", result.tags || "Not returned");
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "Run version with many tags",
|
|
88
|
+
fn: async () => {
|
|
89
|
+
if (!TEST_VERSION_ID) {
|
|
90
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const manyTags = [
|
|
94
|
+
"tag1",
|
|
95
|
+
"tag2",
|
|
96
|
+
"tag3",
|
|
97
|
+
"tag4",
|
|
98
|
+
"tag5",
|
|
99
|
+
"production",
|
|
100
|
+
"customer-support",
|
|
101
|
+
"high-priority",
|
|
102
|
+
"eu-region",
|
|
103
|
+
"compliance",
|
|
104
|
+
];
|
|
105
|
+
const result = await pm.versions.run(TEST_VERSION_ID, {
|
|
106
|
+
variables: {
|
|
107
|
+
topic: "Many Tags Test",
|
|
108
|
+
},
|
|
109
|
+
pm_tags: manyTags,
|
|
110
|
+
});
|
|
111
|
+
if (!result)
|
|
112
|
+
throw new Error("Run failed");
|
|
113
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
114
|
+
logger_1.logger.data("Tags Count", manyTags.length);
|
|
115
|
+
logger_1.logger.data("Tags in Response", result.tags?.length || 0);
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "Verify tags are stored in prompt log",
|
|
120
|
+
fn: async () => {
|
|
121
|
+
if (!TEST_VERSION_ID) {
|
|
122
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const uniqueTag = `verify-${Date.now()}`;
|
|
126
|
+
// Run with unique tag
|
|
127
|
+
const runResult = await pm.versions.run(TEST_VERSION_ID, {
|
|
128
|
+
variables: {
|
|
129
|
+
topic: "Tag Verification",
|
|
130
|
+
},
|
|
131
|
+
pm_tags: [uniqueTag, "verification-test"],
|
|
132
|
+
});
|
|
133
|
+
logger_1.logger.data("Run Request ID", runResult.request_id);
|
|
134
|
+
// Wait a moment for the log to be created
|
|
135
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
136
|
+
// Fetch recent logs and check for our tag
|
|
137
|
+
const logs = await pm.logs.list({
|
|
138
|
+
template_version_id: TEST_VERSION_ID,
|
|
139
|
+
limit: 5,
|
|
140
|
+
sort_by: "created_at",
|
|
141
|
+
sort_order: "desc",
|
|
142
|
+
});
|
|
143
|
+
if (logs.length === 0) {
|
|
144
|
+
logger_1.logger.info("No logs found to verify");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const latestLog = logs[0];
|
|
148
|
+
logger_1.logger.data("Latest Log ID", latestLog._id);
|
|
149
|
+
logger_1.logger.data("Latest Log Tags", latestLog.tags || "None");
|
|
150
|
+
// Check if our unique tag is in the log
|
|
151
|
+
if (latestLog.tags && latestLog.tags.includes(uniqueTag)) {
|
|
152
|
+
logger_1.logger.success(`Tag '${uniqueTag}' verified in log!`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
logger_1.logger.info("Tag may be stored but not returned in list response");
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: "Tags with special characters",
|
|
161
|
+
fn: async () => {
|
|
162
|
+
if (!TEST_VERSION_ID) {
|
|
163
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const specialTags = [
|
|
167
|
+
"tag-with-dash",
|
|
168
|
+
"tag_with_underscore",
|
|
169
|
+
"tag.with.dots",
|
|
170
|
+
"CamelCaseTag",
|
|
171
|
+
"UPPERCASE",
|
|
172
|
+
"lowercase",
|
|
173
|
+
"tag123",
|
|
174
|
+
];
|
|
175
|
+
const result = await pm.versions.run(TEST_VERSION_ID, {
|
|
176
|
+
variables: {
|
|
177
|
+
topic: "Special Tags Test",
|
|
178
|
+
},
|
|
179
|
+
pm_tags: specialTags,
|
|
180
|
+
});
|
|
181
|
+
if (!result)
|
|
182
|
+
throw new Error("Run failed");
|
|
183
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
184
|
+
logger_1.logger.data("Special Tags Sent", specialTags.length);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: "Tags inside @traceable function",
|
|
189
|
+
fn: async () => {
|
|
190
|
+
if (!TEST_VERSION_ID) {
|
|
191
|
+
logger_1.logger.info("Skipped - TEST_VERSION_ID not set");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Create a traceable function that runs a version with tags
|
|
195
|
+
class TaggedService {
|
|
196
|
+
async runWithTags(topic, tags) {
|
|
197
|
+
return pm.versions.run(TEST_VERSION_ID, {
|
|
198
|
+
variables: { topic },
|
|
199
|
+
pm_tags: tags,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
__decorate([
|
|
204
|
+
pm.traceable({ name: "tagged_llm_call" }),
|
|
205
|
+
__metadata("design:type", Function),
|
|
206
|
+
__metadata("design:paramtypes", [String, Array]),
|
|
207
|
+
__metadata("design:returntype", Promise)
|
|
208
|
+
], TaggedService.prototype, "runWithTags", null);
|
|
209
|
+
const service = new TaggedService();
|
|
210
|
+
const result = await service.runWithTags("Traceable Tags Test", [
|
|
211
|
+
"traceable-test",
|
|
212
|
+
"nested-tags",
|
|
213
|
+
]);
|
|
214
|
+
logger_1.logger.data("Result Status", result.status);
|
|
215
|
+
logger_1.logger.data("Trace ID", pm.getCurrentTraceId() || "N/A");
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
];
|
|
219
|
+
(0, logger_1.runTestSuite)("Tags (pm_tags) Test Suite", tests);
|
|
220
|
+
//# sourceMappingURL=tags.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.test.js","sourceRoot":"","sources":["../../src/tests/tags.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
/**
|
|
3
|
+
* Template Run Load Test
|
|
4
|
+
* Configurable load testing for canary deployments
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npm run test:load -- --requests=1000 --concurrency=50
|
|
8
|
+
* npm run test:load -- --template=my-template --requests=500
|
|
9
|
+
*/
|
|
10
|
+
import "dotenv/config";
|
|
11
|
+
//# sourceMappingURL=template-run-load.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-run-load.test.d.ts","sourceRoot":"","sources":["../../src/tests/template-run-load.test.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,eAAe,CAAC"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Template Run Load Test
|
|
5
|
+
* Configurable load testing for canary deployments
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npm run test:load -- --requests=1000 --concurrency=50
|
|
9
|
+
* npm run test:load -- --template=my-template --requests=500
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("dotenv/config");
|
|
13
|
+
const sdk_1 = require("@promptmetrics/sdk");
|
|
14
|
+
// Parse command line arguments
|
|
15
|
+
function parseArgs() {
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
const config = {};
|
|
18
|
+
args.forEach((arg) => {
|
|
19
|
+
const [key, value] = arg.replace("--", "").split("=");
|
|
20
|
+
switch (key) {
|
|
21
|
+
case "template":
|
|
22
|
+
config.templateIdentifier = value;
|
|
23
|
+
break;
|
|
24
|
+
case "requests":
|
|
25
|
+
config.requestCount = parseInt(value);
|
|
26
|
+
break;
|
|
27
|
+
case "concurrency":
|
|
28
|
+
config.concurrency = parseInt(value);
|
|
29
|
+
break;
|
|
30
|
+
case "error-rate":
|
|
31
|
+
config.errorRate = parseFloat(value);
|
|
32
|
+
break;
|
|
33
|
+
case "delay":
|
|
34
|
+
config.delayMs = parseInt(value);
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return config;
|
|
39
|
+
}
|
|
40
|
+
// Default configuration
|
|
41
|
+
const defaultConfig = {
|
|
42
|
+
templateIdentifier: process.env.TEST_TEMPLATE_NAME || "test-template",
|
|
43
|
+
requestCount: 100,
|
|
44
|
+
concurrency: 10,
|
|
45
|
+
errorRate: 0,
|
|
46
|
+
delayMs: 0,
|
|
47
|
+
variables: {},
|
|
48
|
+
};
|
|
49
|
+
// Merge with CLI args
|
|
50
|
+
const cliConfig = parseArgs();
|
|
51
|
+
const config = { ...defaultConfig, ...cliConfig };
|
|
52
|
+
// Initialize SDK
|
|
53
|
+
const pm = new sdk_1.PromptMetrics({
|
|
54
|
+
apiKey: process.env.PROMPTMETRICS_API_KEY,
|
|
55
|
+
});
|
|
56
|
+
const metrics = {
|
|
57
|
+
totalRequests: 0,
|
|
58
|
+
successfulRequests: 0,
|
|
59
|
+
failedRequests: 0,
|
|
60
|
+
canaryRequests: 0,
|
|
61
|
+
legacyRequests: 0,
|
|
62
|
+
errors: [],
|
|
63
|
+
responseTimes: [],
|
|
64
|
+
startTime: new Date(),
|
|
65
|
+
};
|
|
66
|
+
// Progress bar
|
|
67
|
+
function renderProgressBar(current, total) {
|
|
68
|
+
const percentage = Math.floor((current / total) * 100);
|
|
69
|
+
const barLength = 20;
|
|
70
|
+
const filledLength = Math.floor((current / total) * barLength);
|
|
71
|
+
const bar = "█".repeat(filledLength) + "░".repeat(barLength - filledLength);
|
|
72
|
+
return `[${bar}] ${percentage}% (${current}/${total})`;
|
|
73
|
+
}
|
|
74
|
+
// Single request execution
|
|
75
|
+
async function executeRequest(requestId) {
|
|
76
|
+
const startTime = Date.now();
|
|
77
|
+
try {
|
|
78
|
+
// Simulate error based on error rate
|
|
79
|
+
const shouldFail = Math.random() < config.errorRate;
|
|
80
|
+
if (shouldFail) {
|
|
81
|
+
throw new Error(`Simulated error for request ${requestId}`);
|
|
82
|
+
}
|
|
83
|
+
// Execute template run
|
|
84
|
+
const result = await pm.templates.run(config.templateIdentifier, {
|
|
85
|
+
variables: config.variables,
|
|
86
|
+
});
|
|
87
|
+
const responseTime = Date.now() - startTime;
|
|
88
|
+
// Try to detect if this was a canary request
|
|
89
|
+
// This would need to be exposed by the API or inferred from metadata
|
|
90
|
+
const isCanary = result.metadata?.is_canary;
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
responseTime,
|
|
94
|
+
isCanary,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
const responseTime = Date.now() - startTime;
|
|
99
|
+
metrics.errors.push({
|
|
100
|
+
message: error.message || "Unknown error",
|
|
101
|
+
timestamp: new Date(),
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
success: false,
|
|
105
|
+
responseTime,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Execute batch of requests concurrently
|
|
110
|
+
async function executeBatch(batchSize, startIndex) {
|
|
111
|
+
const promises = [];
|
|
112
|
+
for (let i = 0; i < batchSize; i++) {
|
|
113
|
+
const requestId = startIndex + i;
|
|
114
|
+
promises.push(executeRequest(requestId));
|
|
115
|
+
}
|
|
116
|
+
const results = await Promise.all(promises);
|
|
117
|
+
// Update metrics
|
|
118
|
+
results.forEach((result) => {
|
|
119
|
+
metrics.totalRequests++;
|
|
120
|
+
metrics.responseTimes.push(result.responseTime);
|
|
121
|
+
if (result.success) {
|
|
122
|
+
metrics.successfulRequests++;
|
|
123
|
+
if (result.isCanary === true) {
|
|
124
|
+
metrics.canaryRequests++;
|
|
125
|
+
}
|
|
126
|
+
else if (result.isCanary === false) {
|
|
127
|
+
metrics.legacyRequests++;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
metrics.failedRequests++;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// Main load test execution
|
|
136
|
+
async function runLoadTest() {
|
|
137
|
+
console.log("\n" + "=".repeat(60));
|
|
138
|
+
console.log("🚀 Template Run Load Test");
|
|
139
|
+
console.log("=".repeat(60));
|
|
140
|
+
console.log(`Template: ${config.templateIdentifier}`);
|
|
141
|
+
console.log(`Requests: ${config.requestCount}`);
|
|
142
|
+
console.log(`Concurrency: ${config.concurrency}`);
|
|
143
|
+
console.log(`Error Rate: ${(config.errorRate * 100).toFixed(1)}%`);
|
|
144
|
+
console.log(`Delay: ${config.delayMs}ms`);
|
|
145
|
+
console.log("=".repeat(60) + "\n");
|
|
146
|
+
const batches = Math.ceil(config.requestCount / config.concurrency);
|
|
147
|
+
for (let i = 0; i < batches; i++) {
|
|
148
|
+
const startIndex = i * config.concurrency;
|
|
149
|
+
const remainingRequests = config.requestCount - startIndex;
|
|
150
|
+
const batchSize = Math.min(config.concurrency, remainingRequests);
|
|
151
|
+
// Execute batch
|
|
152
|
+
await executeBatch(batchSize, startIndex);
|
|
153
|
+
// Update progress
|
|
154
|
+
process.stdout.write(`\rProgress: ${renderProgressBar(metrics.totalRequests, config.requestCount)}`);
|
|
155
|
+
// Delay between batches if configured
|
|
156
|
+
if (config.delayMs && i < batches - 1) {
|
|
157
|
+
await new Promise((resolve) => setTimeout(resolve, config.delayMs));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
metrics.endTime = new Date();
|
|
161
|
+
console.log("\n");
|
|
162
|
+
}
|
|
163
|
+
// Calculate and display results
|
|
164
|
+
function displayResults() {
|
|
165
|
+
const duration = (metrics.endTime.getTime() - metrics.startTime.getTime()) / 1000;
|
|
166
|
+
const avgResponseTime = metrics.responseTimes.reduce((a, b) => a + b, 0) /
|
|
167
|
+
metrics.responseTimes.length || 0;
|
|
168
|
+
const minResponseTime = Math.min(...metrics.responseTimes) || 0;
|
|
169
|
+
const maxResponseTime = Math.max(...metrics.responseTimes) || 0;
|
|
170
|
+
const requestsPerSecond = metrics.totalRequests / duration;
|
|
171
|
+
console.log("=".repeat(60));
|
|
172
|
+
console.log("📊 Test Results");
|
|
173
|
+
console.log("=".repeat(60));
|
|
174
|
+
// Request stats
|
|
175
|
+
console.log("\n📈 Request Statistics:");
|
|
176
|
+
console.log(` ✓ Total Requests: ${metrics.totalRequests}`);
|
|
177
|
+
console.log(` ✓ Successful: ${metrics.successfulRequests} (${((metrics.successfulRequests / metrics.totalRequests) *
|
|
178
|
+
100).toFixed(1)}%)`);
|
|
179
|
+
console.log(` ✗ Failed: ${metrics.failedRequests} (${((metrics.failedRequests / metrics.totalRequests) *
|
|
180
|
+
100).toFixed(1)}%)`);
|
|
181
|
+
// Canary distribution (if available)
|
|
182
|
+
if (metrics.canaryRequests > 0 || metrics.legacyRequests > 0) {
|
|
183
|
+
const totalVersioned = metrics.canaryRequests + metrics.legacyRequests;
|
|
184
|
+
console.log("\n🔀 Traffic Distribution:");
|
|
185
|
+
console.log(` 🐤 Canary Requests: ${metrics.canaryRequests} (${((metrics.canaryRequests / totalVersioned) *
|
|
186
|
+
100).toFixed(1)}%)`);
|
|
187
|
+
console.log(` 🏛️ Legacy Requests: ${metrics.legacyRequests} (${((metrics.legacyRequests / totalVersioned) *
|
|
188
|
+
100).toFixed(1)}%)`);
|
|
189
|
+
}
|
|
190
|
+
// Performance stats
|
|
191
|
+
console.log("\n⚡ Performance:");
|
|
192
|
+
console.log(` ⏱️ Duration: ${duration.toFixed(2)}s`);
|
|
193
|
+
console.log(` 📊 Requests/sec: ${requestsPerSecond.toFixed(2)}`);
|
|
194
|
+
console.log(` 📉 Avg Response Time: ${avgResponseTime.toFixed(0)}ms`);
|
|
195
|
+
console.log(` 📊 Min Response Time: ${minResponseTime.toFixed(0)}ms`);
|
|
196
|
+
console.log(` 📊 Max Response Time: ${maxResponseTime.toFixed(0)}ms`);
|
|
197
|
+
// Error details
|
|
198
|
+
if (metrics.errors.length > 0) {
|
|
199
|
+
console.log("\n❌ Errors:");
|
|
200
|
+
const errorCounts = new Map();
|
|
201
|
+
metrics.errors.forEach((error) => {
|
|
202
|
+
const count = errorCounts.get(error.message) || 0;
|
|
203
|
+
errorCounts.set(error.message, count + 1);
|
|
204
|
+
});
|
|
205
|
+
errorCounts.forEach((count, message) => {
|
|
206
|
+
console.log(` • ${message}: ${count} occurrences`);
|
|
207
|
+
});
|
|
208
|
+
// Show last 3 errors with timestamps
|
|
209
|
+
console.log("\n Recent Errors:");
|
|
210
|
+
metrics.errors.slice(-3).forEach((error) => {
|
|
211
|
+
console.log(` ${error.timestamp.toISOString()}: ${error.message}`);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
console.log("\n" + "=".repeat(60));
|
|
215
|
+
// Validation checks
|
|
216
|
+
console.log("\n✅ Validation:");
|
|
217
|
+
// Check counter accuracy (if we can query the backend)
|
|
218
|
+
console.log(` ℹ️ Note: Verify backend counters match these numbers`);
|
|
219
|
+
console.log(` Expected total_requests: ${metrics.totalRequests}`);
|
|
220
|
+
console.log(` Expected canary_requests: ${metrics.canaryRequests}`);
|
|
221
|
+
console.log(` Expected legacy_requests: ${metrics.legacyRequests}`);
|
|
222
|
+
console.log("\n" + "=".repeat(60) + "\n");
|
|
223
|
+
}
|
|
224
|
+
// Main execution
|
|
225
|
+
async function main() {
|
|
226
|
+
try {
|
|
227
|
+
await runLoadTest();
|
|
228
|
+
displayResults();
|
|
229
|
+
// Exit with appropriate code
|
|
230
|
+
if (metrics.failedRequests > 0 && config.errorRate === 0) {
|
|
231
|
+
console.log("⚠️ Test completed with unexpected errors");
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.log("✅ Test completed successfully");
|
|
236
|
+
process.exit(0);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.error("❌ Load test failed:", error.message);
|
|
241
|
+
process.exit(1);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
main();
|
|
245
|
+
//# sourceMappingURL=template-run-load.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-run-load.test.js","sourceRoot":"","sources":["../../src/tests/template-run-load.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.test.d.ts","sourceRoot":"","sources":["../../src/tests/templates.test.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,eAAe,CAAC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Templates Test Suite
|
|
5
|
+
* Tests all template-related SDK operations
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
require("dotenv/config");
|
|
9
|
+
const sdk_1 = require("@promptmetrics/sdk");
|
|
10
|
+
const logger_1 = require("../utils/logger");
|
|
11
|
+
const pm = new sdk_1.PromptMetrics({
|
|
12
|
+
apiKey: process.env.PROMPTMETRICS_API_KEY,
|
|
13
|
+
});
|
|
14
|
+
const TEST_TEMPLATE_NAME = process.env.TEST_TEMPLATE_NAME || "test-template";
|
|
15
|
+
const TEST_TEMPLATE_ID = process.env.TEST_TEMPLATE_ID;
|
|
16
|
+
const tests = [
|
|
17
|
+
{
|
|
18
|
+
name: "Get template by name",
|
|
19
|
+
fn: async () => {
|
|
20
|
+
const template = await pm.templates.get(TEST_TEMPLATE_NAME);
|
|
21
|
+
if (!template)
|
|
22
|
+
throw new Error("Template not found");
|
|
23
|
+
logger_1.logger.data("Template ID", template._id);
|
|
24
|
+
logger_1.logger.data("Template Name", template.name);
|
|
25
|
+
logger_1.logger.data("Versions Count", template.versions?.length || 0);
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "Get template by ID",
|
|
30
|
+
fn: async () => {
|
|
31
|
+
if (!TEST_TEMPLATE_ID) {
|
|
32
|
+
logger_1.logger.info("Skipped - TEST_TEMPLATE_ID not set");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const template = await pm.templates.get(TEST_TEMPLATE_ID);
|
|
36
|
+
if (!template)
|
|
37
|
+
throw new Error("Template not found");
|
|
38
|
+
logger_1.logger.data("Template ID", template._id);
|
|
39
|
+
logger_1.logger.data("Template Name", template.name);
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "Get template with specific version number",
|
|
44
|
+
fn: async () => {
|
|
45
|
+
const template = await pm.templates.get(TEST_TEMPLATE_NAME, {
|
|
46
|
+
version: 1,
|
|
47
|
+
});
|
|
48
|
+
if (!template)
|
|
49
|
+
throw new Error("Template not found");
|
|
50
|
+
logger_1.logger.data("Template Name", template.name);
|
|
51
|
+
logger_1.logger.data("Version", template.versions?.[0]?.version || "N/A");
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "Get template with env_label (production)",
|
|
56
|
+
fn: async () => {
|
|
57
|
+
try {
|
|
58
|
+
const template = await pm.templates.get(TEST_TEMPLATE_NAME, {
|
|
59
|
+
env_label: "production",
|
|
60
|
+
});
|
|
61
|
+
if (!template)
|
|
62
|
+
throw new Error("Template not found");
|
|
63
|
+
logger_1.logger.data("Template Name", template.name);
|
|
64
|
+
logger_1.logger.data("Env Label", template.versions?.[0]?.env_label || "N/A");
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const err = error;
|
|
68
|
+
if (err.message?.includes("not found")) {
|
|
69
|
+
logger_1.logger.info("No production version found - this is OK");
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "List templates with pagination",
|
|
79
|
+
fn: async () => {
|
|
80
|
+
const result = await pm.templates.list({
|
|
81
|
+
page: 1,
|
|
82
|
+
per_page: 10,
|
|
83
|
+
});
|
|
84
|
+
if (!result)
|
|
85
|
+
throw new Error("Failed to list templates");
|
|
86
|
+
logger_1.logger.data("Templates Count", result.prompts?.length || 0);
|
|
87
|
+
logger_1.logger.data("Total", result.total || 0);
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "List templates with search filter",
|
|
92
|
+
fn: async () => {
|
|
93
|
+
const result = await pm.templates.list({
|
|
94
|
+
search: TEST_TEMPLATE_NAME.substring(0, 4), // Search with partial name
|
|
95
|
+
page: 1,
|
|
96
|
+
per_page: 10,
|
|
97
|
+
});
|
|
98
|
+
if (!result)
|
|
99
|
+
throw new Error("Failed to list templates");
|
|
100
|
+
logger_1.logger.data("Search Results", result.prompts?.length || 0);
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "Run template (canary-aware)",
|
|
105
|
+
fn: async () => {
|
|
106
|
+
const result = await pm.templates.run(TEST_TEMPLATE_NAME, {
|
|
107
|
+
variables: {
|
|
108
|
+
topic: "SDK Template Run Test",
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
if (!result)
|
|
112
|
+
throw new Error("Run failed");
|
|
113
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
114
|
+
logger_1.logger.data("Status", result.status);
|
|
115
|
+
logger_1.logger.data("Latency", `${result.latency}s`);
|
|
116
|
+
logger_1.logger.data("Total Tokens", result.llm_total_tokens);
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "Run template with pm_tags",
|
|
121
|
+
fn: async () => {
|
|
122
|
+
const result = await pm.templates.run(TEST_TEMPLATE_NAME, {
|
|
123
|
+
variables: {
|
|
124
|
+
topic: "Template Tags Test",
|
|
125
|
+
},
|
|
126
|
+
pm_tags: ["template-run-test", "sdk-sample"],
|
|
127
|
+
});
|
|
128
|
+
if (!result)
|
|
129
|
+
throw new Error("Run failed");
|
|
130
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
131
|
+
logger_1.logger.data("Status", result.status);
|
|
132
|
+
logger_1.logger.data("Tags", result.tags || "Not returned");
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "Run template with specific version",
|
|
137
|
+
fn: async () => {
|
|
138
|
+
const result = await pm.templates.run(TEST_TEMPLATE_NAME, {
|
|
139
|
+
version: 1,
|
|
140
|
+
variables: {
|
|
141
|
+
topic: "Specific Version Test",
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
if (!result)
|
|
145
|
+
throw new Error("Run failed");
|
|
146
|
+
logger_1.logger.data("Request ID", result.request_id);
|
|
147
|
+
logger_1.logger.data("Status", result.status);
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
(0, logger_1.runTestSuite)("Templates Test Suite", tests);
|
|
152
|
+
//# sourceMappingURL=templates.test.js.map
|