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.
Files changed (55) hide show
  1. package/.env.example +12 -0
  2. package/README.md +235 -0
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +29 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/tests/logs.test.d.ts +7 -0
  8. package/dist/tests/logs.test.d.ts.map +1 -0
  9. package/dist/tests/logs.test.js +163 -0
  10. package/dist/tests/logs.test.js.map +1 -0
  11. package/dist/tests/providers.test.d.ts +7 -0
  12. package/dist/tests/providers.test.d.ts.map +1 -0
  13. package/dist/tests/providers.test.js +99 -0
  14. package/dist/tests/providers.test.js.map +1 -0
  15. package/dist/tests/tags.test.d.ts +7 -0
  16. package/dist/tests/tags.test.d.ts.map +1 -0
  17. package/dist/tests/tags.test.js +220 -0
  18. package/dist/tests/tags.test.js.map +1 -0
  19. package/dist/tests/template-run-load.test.d.ts +11 -0
  20. package/dist/tests/template-run-load.test.d.ts.map +1 -0
  21. package/dist/tests/template-run-load.test.js +245 -0
  22. package/dist/tests/template-run-load.test.js.map +1 -0
  23. package/dist/tests/templates.test.d.ts +7 -0
  24. package/dist/tests/templates.test.d.ts.map +1 -0
  25. package/dist/tests/templates.test.js +152 -0
  26. package/dist/tests/templates.test.js.map +1 -0
  27. package/dist/tests/traceable.test.d.ts +7 -0
  28. package/dist/tests/traceable.test.d.ts.map +1 -0
  29. package/dist/tests/traceable.test.js +300 -0
  30. package/dist/tests/traceable.test.js.map +1 -0
  31. package/dist/tests/traces.test.d.ts +7 -0
  32. package/dist/tests/traces.test.d.ts.map +1 -0
  33. package/dist/tests/traces.test.js +264 -0
  34. package/dist/tests/traces.test.js.map +1 -0
  35. package/dist/tests/versions.test.d.ts +7 -0
  36. package/dist/tests/versions.test.d.ts.map +1 -0
  37. package/dist/tests/versions.test.js +145 -0
  38. package/dist/tests/versions.test.js.map +1 -0
  39. package/dist/utils/logger.d.ts +26 -0
  40. package/dist/utils/logger.d.ts.map +1 -0
  41. package/dist/utils/logger.js +79 -0
  42. package/dist/utils/logger.js.map +1 -0
  43. package/package.json +36 -0
  44. package/sample-project-plan.md +316 -0
  45. package/src/index.ts +36 -0
  46. package/src/tests/logs.test.ts +180 -0
  47. package/src/tests/providers.test.ts +99 -0
  48. package/src/tests/tags.test.ts +237 -0
  49. package/src/tests/template-run-load.test.ts +332 -0
  50. package/src/tests/templates.test.ts +154 -0
  51. package/src/tests/traceable.test.ts +290 -0
  52. package/src/tests/traces.test.ts +298 -0
  53. package/src/tests/versions.test.ts +155 -0
  54. package/src/utils/logger.ts +91 -0
  55. 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":";;AACA;;;;;;;GAOG;;AAEH,yBAAuB;AACvB,4CAAmD;AAanD,+BAA+B;AAC/B,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtD,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,UAAU;gBACb,MAAM,CAAC,kBAAkB,GAAG,KAAK,CAAC;gBAClC,MAAM;YACR,KAAK,UAAU;gBACb,MAAM,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,aAAa;gBAChB,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,YAAY;gBACf,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,OAAO;gBACV,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACjC,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,wBAAwB;AACxB,MAAM,aAAa,GAAmB;IACpC,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,eAAe;IACrE,YAAY,EAAE,GAAG;IACjB,WAAW,EAAE,EAAE;IACf,SAAS,EAAE,CAAC;IACZ,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,sBAAsB;AACtB,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;AAC9B,MAAM,MAAM,GAAmB,EAAE,GAAG,aAAa,EAAE,GAAG,SAAS,EAAE,CAAC;AAElE,iBAAiB;AACjB,MAAM,EAAE,GAAG,IAAI,mBAAa,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAsB;CAC3C,CAAC,CAAC;AAeH,MAAM,OAAO,GAAgB;IAC3B,aAAa,EAAE,CAAC;IAChB,kBAAkB,EAAE,CAAC;IACrB,cAAc,EAAE,CAAC;IACjB,cAAc,EAAE,CAAC;IACjB,cAAc,EAAE,CAAC;IACjB,MAAM,EAAE,EAAE;IACV,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,IAAI,IAAI,EAAE;CACtB,CAAC;AAEF,eAAe;AACf,SAAS,iBAAiB,CAAC,OAAe,EAAE,KAAa;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,YAAY,CAAC,CAAC;IAC5E,OAAO,IAAI,GAAG,KAAK,UAAU,MAAM,OAAO,IAAI,KAAK,GAAG,CAAC;AACzD,CAAC;AAED,2BAA2B;AAC3B,KAAK,UAAU,cAAc,CAC3B,SAAiB;IAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,qCAAqC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;QAEpD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,uBAAuB;QACvB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,EAAE;YAC/D,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAE5C,6CAA6C;QAC7C,qEAAqE;QACrE,MAAM,QAAQ,GAAI,MAAc,CAAC,QAAQ,EAAE,SAAS,CAAC;QAErD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY;YACZ,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;YACzC,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY;SACb,CAAC;IACJ,CAAC;AACH,CAAC;AAED,yCAAyC;AACzC,KAAK,UAAU,YAAY,CACzB,SAAiB,EACjB,UAAkB;IAElB,MAAM,QAAQ,GAAG,EAAE,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,UAAU,GAAG,CAAC,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE5C,iBAAiB;IACjB,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACzB,OAAO,CAAC,aAAa,EAAE,CAAC;QACxB,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEhD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC7B,OAAO,CAAC,cAAc,EAAE,CAAC;YAC3B,CAAC;iBAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACrC,OAAO,CAAC,cAAc,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2BAA2B;AAC3B,KAAK,UAAU,WAAW;IACxB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAEpE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;QAC1C,MAAM,iBAAiB,GAAG,MAAM,CAAC,YAAY,GAAG,UAAU,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAElE,gBAAgB;QAChB,MAAM,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAE1C,kBAAkB;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,eAAe,iBAAiB,CAC9B,OAAO,CAAC,aAAa,EACrB,MAAM,CAAC,YAAY,CACpB,EAAE,CACJ,CAAC;QAEF,sCAAsC;QACtC,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,OAAO,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,gCAAgC;AAChC,SAAS,cAAc;IACrB,MAAM,QAAQ,GACZ,CAAC,OAAO,CAAC,OAAQ,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IACpE,MAAM,eAAe,GACnB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,CAAC;IACtC,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,GAAG,QAAQ,CAAC;IAE3D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CACT,4BAA4B,OAAO,CAAC,kBAAkB,KAAK,CACzD,CAAC,OAAO,CAAC,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;QACpD,GAAG,CACJ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACjB,CAAC;IACF,OAAO,CAAC,GAAG,CACT,4BAA4B,OAAO,CAAC,cAAc,KAAK,CACrD,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;QAChD,GAAG,CACJ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACjB,CAAC;IAEF,qCAAqC;IACrC,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CACT,4BAA4B,OAAO,CAAC,cAAc,KAAK,CACrD,CAAC,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC;YACzC,GAAG,CACJ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACjB,CAAC;QACF,OAAO,CAAC,GAAG,CACT,8BAA8B,OAAO,CAAC,cAAc,KAAK,CACvD,CAAC,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC;YACzC,GAAG,CACJ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACjB,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,6BAA6B,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,4BAA4B,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,4BAA4B,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,4BAA4B,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,4BAA4B,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAExE,gBAAgB;IAChB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC9C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClD,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACrC,OAAO,CAAC,GAAG,CAAC,OAAO,OAAO,KAAK,KAAK,cAAc,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,qCAAqC;QACrC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnC,oBAAoB;IACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAE/B,uDAAuD;IACvD,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,iCAAiC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,kCAAkC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,kCAAkC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAExE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,iBAAiB;AACjB,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,WAAW,EAAE,CAAC;QACpB,cAAc,EAAE,CAAC;QAEjB,6BAA6B;QAC7B,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,IAAI,MAAM,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;YACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ts-node
2
+ /**
3
+ * Templates Test Suite
4
+ * Tests all template-related SDK operations
5
+ */
6
+ import "dotenv/config";
7
+ //# sourceMappingURL=templates.test.d.ts.map
@@ -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