langwatch 0.5.1 → 0.7.1
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/README.md +19 -0
- package/dist/{add-4WXEWG5H.js → add-5QV3TEWC.js} +28 -32
- package/dist/add-5QV3TEWC.js.map +1 -0
- package/dist/{add-D2WVVKIP.mjs → add-HWFRMAQX.mjs} +14 -18
- package/dist/add-HWFRMAQX.mjs.map +1 -0
- package/dist/{chunk-CAZONSXV.js → chunk-36XAYVMC.js} +186 -76
- package/dist/chunk-36XAYVMC.js.map +1 -0
- package/dist/{chunk-QCYYSMCU.js → chunk-5HAVK64Q.js} +2 -2
- package/dist/chunk-5HAVK64Q.js.map +1 -0
- package/dist/{chunk-ZIULPOMQ.mjs → chunk-7MG7DGPP.mjs} +4 -4
- package/dist/{chunk-YKFTFYKK.mjs → chunk-7VHZNB2S.mjs} +2 -2
- package/dist/chunk-7VHZNB2S.mjs.map +1 -0
- package/dist/{chunk-DLJO7AK5.mjs → chunk-AD7QRYIJ.mjs} +2 -2
- package/dist/{chunk-DISMHYXC.js → chunk-CKIZDPIJ.js} +24 -22
- package/dist/chunk-CKIZDPIJ.js.map +1 -0
- package/dist/{chunk-SVXNUWZI.js → chunk-D7UAKYVI.js} +345 -154
- package/dist/chunk-D7UAKYVI.js.map +1 -0
- package/dist/{chunk-7OZKH5K2.js → chunk-DZH6SY3Z.js} +10 -10
- package/dist/{chunk-7OZKH5K2.js.map → chunk-DZH6SY3Z.js.map} +1 -1
- package/dist/{chunk-H5PON53W.mjs → chunk-EPGKOTSN.mjs} +334 -143
- package/dist/chunk-EPGKOTSN.mjs.map +1 -0
- package/dist/{chunk-N2V6J3U2.mjs → chunk-FEL5FLHA.mjs} +2 -2
- package/dist/{chunk-YNQ44U6D.mjs → chunk-I2SOBPAF.mjs} +23 -21
- package/dist/chunk-I2SOBPAF.mjs.map +1 -0
- package/dist/{chunk-P4SQTYGN.js → chunk-J55AV2YW.js} +32 -32
- package/dist/{chunk-P4SQTYGN.js.map → chunk-J55AV2YW.js.map} +1 -1
- package/dist/{chunk-OXBO24RB.js → chunk-OHM7JUMR.js} +15 -2
- package/dist/chunk-OHM7JUMR.js.map +1 -0
- package/dist/chunk-PYVDTUA6.mjs +352 -0
- package/dist/chunk-PYVDTUA6.mjs.map +1 -0
- package/dist/{chunk-YH5TIVK2.js → chunk-SNDTNU3T.js} +2 -2
- package/dist/{chunk-YH5TIVK2.js.map → chunk-SNDTNU3T.js.map} +1 -1
- package/dist/{chunk-QZGTM76F.mjs → chunk-UNMZPS55.mjs} +7 -3
- package/dist/chunk-UNMZPS55.mjs.map +1 -0
- package/dist/{chunk-CU3443HD.mjs → chunk-URTD2WOC.mjs} +14 -1
- package/dist/{chunk-ECOC36EA.js → chunk-VMZUN4EF.js} +16 -12
- package/dist/chunk-VMZUN4EF.js.map +1 -0
- package/dist/cli/index.js +8 -8
- package/dist/cli/index.mjs +8 -8
- package/dist/{create-OQEMO4MU.mjs → create-LXQB4EFB.mjs} +4 -5
- package/dist/{create-OQEMO4MU.mjs.map → create-LXQB4EFB.mjs.map} +1 -1
- package/dist/{create-4LG4N2A4.js → create-S5RDGF3H.js} +9 -10
- package/dist/create-S5RDGF3H.js.map +1 -0
- package/dist/{implementation-BIlL6-SW.d.ts → implementation-DsHp9FYU.d.ts} +1 -1
- package/dist/{implementation-fAgqv8OM.d.mts → implementation-nE9dgTwc.d.mts} +1 -1
- package/dist/{index-DTEZr0Jn.d.mts → index-D7rKIGrO.d.mts} +12 -12
- package/dist/{index-DTEZr0Jn.d.ts → index-D7rKIGrO.d.ts} +12 -12
- package/dist/index.d.mts +256 -11
- package/dist/index.d.ts +256 -11
- package/dist/index.js +135 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +133 -10
- package/dist/index.mjs.map +1 -1
- package/dist/{init-MQXXHCNT.mjs → init-T4YDPHBA.mjs} +4 -5
- package/dist/{init-MQXXHCNT.mjs.map → init-T4YDPHBA.mjs.map} +1 -1
- package/dist/init-UADBKUJU.js +15 -0
- package/dist/init-UADBKUJU.js.map +1 -0
- package/dist/{list-PFWV7IU6.mjs → list-BQXECLEM.mjs} +13 -14
- package/dist/list-BQXECLEM.mjs.map +1 -0
- package/dist/{list-GIAXAAH5.js → list-HSCIBC4Z.js} +14 -15
- package/dist/list-HSCIBC4Z.js.map +1 -0
- package/dist/{login-BYLXS23I.mjs → login-3IM3PYSJ.mjs} +3 -3
- package/dist/{login-3STX2FAO.js → login-EUDCIJRM.js} +4 -4
- package/dist/{login-3STX2FAO.js.map → login-EUDCIJRM.js.map} +1 -1
- package/dist/observability-sdk/index.d.mts +4 -3
- package/dist/observability-sdk/index.d.ts +4 -3
- package/dist/observability-sdk/index.js +7 -7
- package/dist/observability-sdk/index.mjs +6 -6
- package/dist/observability-sdk/instrumentation/langchain/index.d.mts +2 -1
- package/dist/observability-sdk/instrumentation/langchain/index.d.ts +2 -1
- package/dist/observability-sdk/instrumentation/langchain/index.js +19 -19
- package/dist/observability-sdk/instrumentation/langchain/index.mjs +3 -3
- package/dist/observability-sdk/setup/node/index.d.mts +1 -1
- package/dist/observability-sdk/setup/node/index.d.ts +1 -1
- package/dist/observability-sdk/setup/node/index.js +15 -15
- package/dist/observability-sdk/setup/node/index.mjs +4 -4
- package/dist/{remove-FTF3EBYV.mjs → remove-IVFQAHNT.mjs} +9 -10
- package/dist/{remove-FTF3EBYV.mjs.map → remove-IVFQAHNT.mjs.map} +1 -1
- package/dist/{remove-U3PILQDV.js → remove-VDQ4M6JF.js} +17 -18
- package/dist/remove-VDQ4M6JF.js.map +1 -0
- package/dist/{sync-FOW7DHAH.mjs → sync-2MVHHWCX.mjs} +16 -20
- package/dist/sync-2MVHHWCX.mjs.map +1 -0
- package/dist/{sync-T3T22GVZ.js → sync-KUMBMGJS.js} +31 -35
- package/dist/sync-KUMBMGJS.js.map +1 -0
- package/dist/{types-DyUmlaDx.d.ts → types-B9772cUR.d.ts} +98 -29
- package/dist/{types-jrEEZt9d.d.mts → types-DbPAi4US.d.mts} +98 -29
- package/package.json +16 -11
- package/dist/add-4WXEWG5H.js.map +0 -1
- package/dist/add-D2WVVKIP.mjs.map +0 -1
- package/dist/chunk-CAZONSXV.js.map +0 -1
- package/dist/chunk-CKVDNVFL.mjs +0 -242
- package/dist/chunk-CKVDNVFL.mjs.map +0 -1
- package/dist/chunk-DISMHYXC.js.map +0 -1
- package/dist/chunk-DSIQSULK.js +0 -152
- package/dist/chunk-DSIQSULK.js.map +0 -1
- package/dist/chunk-ECOC36EA.js.map +0 -1
- package/dist/chunk-H5PON53W.mjs.map +0 -1
- package/dist/chunk-OXBO24RB.js.map +0 -1
- package/dist/chunk-QCYYSMCU.js.map +0 -1
- package/dist/chunk-QZGTM76F.mjs.map +0 -1
- package/dist/chunk-R6FBJN7K.js +0 -115
- package/dist/chunk-R6FBJN7K.js.map +0 -1
- package/dist/chunk-SVXNUWZI.js.map +0 -1
- package/dist/chunk-V5M3HUBV.mjs +0 -115
- package/dist/chunk-V5M3HUBV.mjs.map +0 -1
- package/dist/chunk-YEGQXDTE.mjs +0 -152
- package/dist/chunk-YEGQXDTE.mjs.map +0 -1
- package/dist/chunk-YKFTFYKK.mjs.map +0 -1
- package/dist/chunk-YNQ44U6D.mjs.map +0 -1
- package/dist/create-4LG4N2A4.js.map +0 -1
- package/dist/init-EKNL2SQE.js +0 -16
- package/dist/init-EKNL2SQE.js.map +0 -1
- package/dist/list-GIAXAAH5.js.map +0 -1
- package/dist/list-PFWV7IU6.mjs.map +0 -1
- package/dist/remove-U3PILQDV.js.map +0 -1
- package/dist/sync-FOW7DHAH.mjs.map +0 -1
- package/dist/sync-T3T22GVZ.js.map +0 -1
- /package/dist/{chunk-ZIULPOMQ.mjs.map → chunk-7MG7DGPP.mjs.map} +0 -0
- /package/dist/{chunk-DLJO7AK5.mjs.map → chunk-AD7QRYIJ.mjs.map} +0 -0
- /package/dist/{chunk-N2V6J3U2.mjs.map → chunk-FEL5FLHA.mjs.map} +0 -0
- /package/dist/{chunk-CU3443HD.mjs.map → chunk-URTD2WOC.mjs.map} +0 -0
- /package/dist/{login-BYLXS23I.mjs.map → login-3IM3PYSJ.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -257,6 +257,25 @@ span.setAttributes({
|
|
|
257
257
|
});
|
|
258
258
|
```
|
|
259
259
|
|
|
260
|
+
## Testing
|
|
261
|
+
|
|
262
|
+
## Unit and Integration Testing
|
|
263
|
+
|
|
264
|
+
This will run the unit and integration tests. You will need to make sure the values in the `.env` file are set correctly, but you can omit the `E2E_` prefixed variables for these tests.
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
pnpm test
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## E2E Testing
|
|
271
|
+
|
|
272
|
+
For E2E tests, you will need to set the `E2E_` prefixed variables in the `.env` file. You will also need to have run build before.
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
pnpm build
|
|
276
|
+
pnpm test:e2e
|
|
277
|
+
```
|
|
278
|
+
|
|
260
279
|
---
|
|
261
280
|
|
|
262
281
|
## Community & Support
|
|
@@ -3,26 +3,22 @@
|
|
|
3
3
|
var _chunkF6E4XQQUjs = require('./chunk-F6E4XQQU.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var _chunkDSIQSULKjs = require('./chunk-DSIQSULK.js');
|
|
7
6
|
|
|
7
|
+
var _chunkD7UAKYVIjs = require('./chunk-D7UAKYVI.js');
|
|
8
|
+
require('./chunk-SNDTNU3T.js');
|
|
9
|
+
require('./chunk-VMZUN4EF.js');
|
|
10
|
+
require('./chunk-J55AV2YW.js');
|
|
11
|
+
require('./chunk-5HAVK64Q.js');
|
|
12
|
+
require('./chunk-CKIZDPIJ.js');
|
|
8
13
|
|
|
9
|
-
var _chunkSVXNUWZIjs = require('./chunk-SVXNUWZI.js');
|
|
10
|
-
require('./chunk-YH5TIVK2.js');
|
|
11
|
-
require('./chunk-ECOC36EA.js');
|
|
12
|
-
require('./chunk-P4SQTYGN.js');
|
|
13
|
-
require('./chunk-QCYYSMCU.js');
|
|
14
|
-
require('./chunk-DISMHYXC.js');
|
|
15
14
|
|
|
15
|
+
var _chunkDZH6SY3Zjs = require('./chunk-DZH6SY3Z.js');
|
|
16
16
|
|
|
17
|
-
var _chunk7OZKH5K2js = require('./chunk-7OZKH5K2.js');
|
|
18
17
|
|
|
19
18
|
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var _chunkR6FBJN7Kjs = require('./chunk-R6FBJN7K.js');
|
|
19
|
+
var _chunk36XAYVMCjs = require('./chunk-36XAYVMC.js');
|
|
24
20
|
require('./chunk-AZHZ4NB4.js');
|
|
25
|
-
require('./chunk-
|
|
21
|
+
require('./chunk-OHM7JUMR.js');
|
|
26
22
|
|
|
27
23
|
// src/cli/commands/add.ts
|
|
28
24
|
var _fs = require('fs'); var fs = _interopRequireWildcard(_fs);
|
|
@@ -41,12 +37,12 @@ var addLocalFile = async (name, localFilePath) => {
|
|
|
41
37
|
process.exit(1);
|
|
42
38
|
}
|
|
43
39
|
try {
|
|
44
|
-
|
|
45
|
-
await
|
|
46
|
-
const promptsConfig =
|
|
40
|
+
_chunk36XAYVMCjs.FileManager.loadLocalPrompt(localFilePath);
|
|
41
|
+
await _chunkDZH6SY3Zjs.ensureProjectInitialized.call(void 0, );
|
|
42
|
+
const promptsConfig = _chunk36XAYVMCjs.FileManager.loadPromptsConfig();
|
|
47
43
|
promptsConfig.prompts[name] = `file:${localFilePath}`;
|
|
48
|
-
|
|
49
|
-
const lock =
|
|
44
|
+
_chunk36XAYVMCjs.FileManager.savePromptsConfig(promptsConfig);
|
|
45
|
+
const lock = _chunk36XAYVMCjs.FileManager.loadPromptsLock();
|
|
50
46
|
lock.prompts[name] = {
|
|
51
47
|
version: 0,
|
|
52
48
|
// Local files start at version 0
|
|
@@ -54,7 +50,7 @@ var addLocalFile = async (name, localFilePath) => {
|
|
|
54
50
|
materialized: localFilePath
|
|
55
51
|
// Store the original file path
|
|
56
52
|
};
|
|
57
|
-
|
|
53
|
+
_chunk36XAYVMCjs.FileManager.savePromptsLock(lock);
|
|
58
54
|
console.log(
|
|
59
55
|
_chalk2.default.green(
|
|
60
56
|
`\u2713 Added local prompt: ${_chalk2.default.cyan(name)} \u2192 ${_chalk2.default.gray(
|
|
@@ -82,33 +78,33 @@ var addCommand = async (name, options) => {
|
|
|
82
78
|
return;
|
|
83
79
|
}
|
|
84
80
|
_chunkF6E4XQQUjs.checkApiKey.call(void 0, );
|
|
85
|
-
const
|
|
81
|
+
const promptsApiService = new (0, _chunkD7UAKYVIjs.PromptsApiService)();
|
|
86
82
|
const version = (_a = options.version) != null ? _a : "latest";
|
|
87
83
|
const spinner = _ora2.default.call(void 0,
|
|
88
84
|
`Adding ${_chalk2.default.cyan(`${name}@${version}`)}...`
|
|
89
85
|
).start();
|
|
90
86
|
try {
|
|
91
|
-
const prompt = await
|
|
87
|
+
const prompt = await promptsApiService.get(name);
|
|
92
88
|
if (!prompt) {
|
|
93
89
|
spinner.fail();
|
|
94
90
|
console.error(_chalk2.default.red(`Error: Prompt "${name}" not found`));
|
|
95
91
|
process.exit(1);
|
|
96
92
|
}
|
|
97
93
|
spinner.stop();
|
|
98
|
-
await
|
|
94
|
+
await _chunkDZH6SY3Zjs.ensureProjectInitialized.call(void 0, );
|
|
99
95
|
spinner.start(`Adding ${_chalk2.default.cyan(`${name}@${version}`)}...`);
|
|
100
|
-
const materializedPrompt =
|
|
101
|
-
const savedPath =
|
|
96
|
+
const materializedPrompt = _chunk36XAYVMCjs.PromptConverter.fromApiToMaterialized(prompt);
|
|
97
|
+
const savedPath = _chunk36XAYVMCjs.FileManager.saveMaterializedPrompt(
|
|
102
98
|
name,
|
|
103
99
|
materializedPrompt
|
|
104
100
|
);
|
|
105
101
|
const relativePath = path.relative(process.cwd(), savedPath);
|
|
106
|
-
const config =
|
|
107
|
-
const lock =
|
|
102
|
+
const config = _chunk36XAYVMCjs.FileManager.loadPromptsConfig();
|
|
103
|
+
const lock = _chunk36XAYVMCjs.FileManager.loadPromptsLock();
|
|
108
104
|
config.prompts[name] = version;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
_chunk36XAYVMCjs.FileManager.updateLockEntry(lock, name, materializedPrompt, savedPath);
|
|
106
|
+
_chunk36XAYVMCjs.FileManager.savePromptsConfig(config);
|
|
107
|
+
_chunk36XAYVMCjs.FileManager.savePromptsLock(lock);
|
|
112
108
|
spinner.succeed();
|
|
113
109
|
const displayPath = relativePath.startsWith("./") ? relativePath : `./${relativePath}`;
|
|
114
110
|
console.log(
|
|
@@ -120,7 +116,7 @@ var addCommand = async (name, options) => {
|
|
|
120
116
|
);
|
|
121
117
|
} catch (error) {
|
|
122
118
|
spinner.fail();
|
|
123
|
-
if (error instanceof
|
|
119
|
+
if (error instanceof _chunkD7UAKYVIjs.PromptsError) {
|
|
124
120
|
console.error(_chalk2.default.red(`Error: ${error.message}`));
|
|
125
121
|
} else {
|
|
126
122
|
console.error(
|
|
@@ -132,7 +128,7 @@ var addCommand = async (name, options) => {
|
|
|
132
128
|
process.exit(1);
|
|
133
129
|
}
|
|
134
130
|
} catch (error) {
|
|
135
|
-
if (error instanceof
|
|
131
|
+
if (error instanceof _chunkD7UAKYVIjs.PromptsError) {
|
|
136
132
|
console.error(_chalk2.default.red(`Error: ${error.message}`));
|
|
137
133
|
} else {
|
|
138
134
|
console.error(
|
|
@@ -147,4 +143,4 @@ var addCommand = async (name, options) => {
|
|
|
147
143
|
|
|
148
144
|
|
|
149
145
|
exports.addCommand = addCommand;
|
|
150
|
-
//# sourceMappingURL=add-
|
|
146
|
+
//# sourceMappingURL=add-5QV3TEWC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/langwatch/langwatch/typescript-sdk/dist/add-5QV3TEWC.js","../src/cli/commands/add.ts"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACA;ACtBA,+DAAoB;AACpB,uEAAsB;AACtB,4EAAkB;AAClB,oEAAgB;AAahB,IAAM,aAAA,EAAe,MAAA,CACnB,IAAA,EACA,aAAA,EAAA,GACkB;AAElB,EAAA,GAAA,CAAI,CAAI,EAAA,CAAA,UAAA,CAAW,aAAa,CAAA,EAAG;AACjC,IAAA,OAAA,CAAQ,KAAA,CAAM,eAAA,CAAM,GAAA,CAAI,CAAA,6BAAA,EAAgC,aAAa,CAAA,CAAA;AACvD,IAAA;AAChB,EAAA;AAE6C,EAAA;AACnC,IAAA;AACwD,MAAA;AAChE,IAAA;AACc,IAAA;AAChB,EAAA;AAGI,EAAA;AACuC,IAAA;AAGV,IAAA;AAGqB,IAAA;AACD,IAAA;AACR,IAAA;AAGF,IAAA;AACpB,IAAA;AACV,MAAA;AAAA;AACE,MAAA;AACG,MAAA;AAAA;AAChB,IAAA;AACgC,IAAA;AAExB,IAAA;AACA,MAAA;AACiD,QAAA;AACnD,UAAA;AACD,QAAA;AACH,MAAA;AACF,IAAA;AACc,EAAA;AAC6C,IAAA;AACnD,IAAA;AAC0D,MAAA;AAClE,IAAA;AACc,IAAA;AAChB,EAAA;AACF;AAKoB;AAzEpB,EAAA;AA0EM,EAAA;AAE+B,IAAA;AAC8B,MAAA;AAC/C,MAAA;AAChB,IAAA;AAGuB,IAAA;AACqB,MAAA;AAC1C,MAAA;AACF,IAAA;AAGY,IAAA;AAEoC,IAAA;AACb,IAAA;AAGnB,IAAA;AAC4B,MAAA;AACpC,IAAA;AAEJ,IAAA;AAE6C,MAAA;AAElC,MAAA;AACE,QAAA;AAC+C,QAAA;AAC9C,QAAA;AAChB,MAAA;AAGa,MAAA;AAGkB,MAAA;AAG8B,MAAA;AAGI,MAAA;AACnC,MAAA;AAC5B,QAAA;AACA,QAAA;AACF,MAAA;AAC2D,MAAA;AAGd,MAAA;AACJ,MAAA;AAElB,MAAA;AACqC,MAAA;AAGxB,MAAA;AACJ,MAAA;AAEhB,MAAA;AAKZ,MAAA;AACI,MAAA;AACA,QAAA;AACkD,UAAA;AAC1B,YAAA;AACE,UAAA;AAChC,QAAA;AACF,MAAA;AACc,IAAA;AACD,MAAA;AACsB,MAAA;AACiB,QAAA;AAC7C,MAAA;AACG,QAAA;AACA,UAAA;AAE6B,YAAA;AAEnC,UAAA;AACF,QAAA;AACF,MAAA;AACc,MAAA;AAChB,IAAA;AACc,EAAA;AACqB,IAAA;AACiB,MAAA;AAC7C,IAAA;AACG,MAAA;AACA,QAAA;AAEuC,UAAA;AAE7C,QAAA;AACF,MAAA;AACF,IAAA;AACc,IAAA;AAChB,EAAA;AACF;ADpC0E;AACA;AACA","file":"/home/runner/work/langwatch/langwatch/typescript-sdk/dist/add-5QV3TEWC.js","sourcesContent":[null,"import * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { FileManager } from \"../utils/fileManager\";\nimport { PromptsApiService, PromptsError } from \"@/client-sdk/services/prompts\";\nimport { PromptConverter } from \"../utils/promptConverter\";\nimport { ensureProjectInitialized } from \"../utils/init\";\nimport { checkApiKey } from \"../utils/apiKey\";\nimport { LangWatch } from \"@/client-sdk\";\n\ninterface AddOptions {\n version?: string;\n localFile?: string;\n}\n\nconst addLocalFile = async (\n name: string,\n localFilePath: string,\n): Promise<void> => {\n // Validate that the file exists and has the right extension\n if (!fs.existsSync(localFilePath)) {\n console.error(chalk.red(`Error: Local file not found: ${localFilePath}`));\n process.exit(1);\n }\n\n if (!localFilePath.endsWith(\".prompt.yaml\")) {\n console.error(\n chalk.red(`Error: Local file must have .prompt.yaml extension`),\n );\n process.exit(1);\n }\n\n // Load and validate the YAML file\n try {\n FileManager.loadLocalPrompt(localFilePath);\n\n // Ensure project is initialized\n await ensureProjectInitialized();\n\n // Add to prompts.json as a file: dependency\n const promptsConfig = FileManager.loadPromptsConfig();\n promptsConfig.prompts[name] = `file:${localFilePath}`;\n FileManager.savePromptsConfig(promptsConfig);\n\n // Update lock file\n const lock = FileManager.loadPromptsLock();\n lock.prompts[name] = {\n version: 0, // Local files start at version 0\n versionId: \"local\",\n materialized: localFilePath, // Store the original file path\n };\n FileManager.savePromptsLock(lock);\n\n console.log(\n chalk.green(\n `✓ Added local prompt: ${chalk.cyan(name)} → ${chalk.gray(\n localFilePath,\n )}`,\n ),\n );\n } catch (error) {\n console.error(chalk.red(\"Error loading local prompt file:\"));\n console.error(\n chalk.red(error instanceof Error ? error.message : String(error)),\n );\n process.exit(1);\n }\n};\n\nexport const addCommand = async (\n name: string,\n options: AddOptions,\n): Promise<void> => {\n try {\n // Validate prompt name\n if (!name || name.trim() === \"\") {\n console.error(chalk.red(\"Error: Prompt name cannot be empty\"));\n process.exit(1);\n }\n\n // Handle local file addition\n if (options.localFile) {\n await addLocalFile(name, options.localFile);\n return;\n }\n\n // Check API key before doing anything else\n checkApiKey();\n\n const promptsApiService = new PromptsApiService();\n const version = options.version ?? \"latest\";\n\n // Fetch and materialize the prompt (like sync does for individual prompts)\n const spinner = ora(\n `Adding ${chalk.cyan(`${name}@${version}`)}...`,\n ).start();\n\n try {\n // Fetch the prompt from the API\n const prompt = await promptsApiService.get(name);\n\n if (!prompt) {\n spinner.fail();\n console.error(chalk.red(`Error: Prompt \"${name}\" not found`));\n process.exit(1);\n }\n\n // Stop spinner before any user input prompts\n spinner.stop();\n\n // Ensure project is initialized (prompts.json, lock file, directories)\n await ensureProjectInitialized();\n\n // Restart spinner for the actual work\n spinner.start(`Adding ${chalk.cyan(`${name}@${version}`)}...`);\n\n // Convert to MaterializedPrompt format and save\n const materializedPrompt = PromptConverter.fromApiToMaterialized(prompt);\n const savedPath = FileManager.saveMaterializedPrompt(\n name,\n materializedPrompt,\n );\n const relativePath = path.relative(process.cwd(), savedPath);\n\n // Load existing config and lock, add the new dependency\n const config = FileManager.loadPromptsConfig();\n const lock = FileManager.loadPromptsLock();\n\n config.prompts[name] = version;\n FileManager.updateLockEntry(lock, name, materializedPrompt, savedPath);\n\n // Save the updated config and lock\n FileManager.savePromptsConfig(config);\n FileManager.savePromptsLock(lock);\n\n spinner.succeed();\n\n // Show what was done (add ./ prefix for consistency)\n const displayPath = relativePath.startsWith(\"./\")\n ? relativePath\n : `./${relativePath}`;\n console.log(\n chalk.green(\n `✓ Pulled ${chalk.cyan(`${name}@${version}`)} ${chalk.gray(\n `(version ${prompt.version})`,\n )} → ${chalk.gray(displayPath)}`,\n ),\n );\n } catch (error) {\n spinner.fail();\n if (error instanceof PromptsError) {\n console.error(chalk.red(`Error: ${error.message}`));\n } else {\n console.error(\n chalk.red(\n `Error adding prompt: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n ),\n );\n }\n process.exit(1);\n }\n } catch (error) {\n if (error instanceof PromptsError) {\n console.error(chalk.red(`Error: ${error.message}`));\n } else {\n console.error(\n chalk.red(\n `Unexpected error: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n ),\n );\n }\n process.exit(1);\n }\n};\n"]}
|
|
@@ -2,27 +2,23 @@ import {
|
|
|
2
2
|
checkApiKey
|
|
3
3
|
} from "./chunk-DHJKJVY7.mjs";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
} from "./chunk-YEGQXDTE.mjs";
|
|
7
|
-
import {
|
|
5
|
+
PromptsApiService,
|
|
8
6
|
PromptsError
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-EPGKOTSN.mjs";
|
|
8
|
+
import "./chunk-FEL5FLHA.mjs";
|
|
9
|
+
import "./chunk-UNMZPS55.mjs";
|
|
10
|
+
import "./chunk-7MG7DGPP.mjs";
|
|
11
|
+
import "./chunk-7VHZNB2S.mjs";
|
|
12
|
+
import "./chunk-I2SOBPAF.mjs";
|
|
15
13
|
import {
|
|
16
14
|
ensureProjectInitialized
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import {
|
|
19
|
-
FileManager
|
|
20
|
-
} from "./chunk-CKVDNVFL.mjs";
|
|
15
|
+
} from "./chunk-AD7QRYIJ.mjs";
|
|
21
16
|
import {
|
|
17
|
+
FileManager,
|
|
22
18
|
PromptConverter
|
|
23
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-PYVDTUA6.mjs";
|
|
24
20
|
import "./chunk-BTBSMJTY.mjs";
|
|
25
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-URTD2WOC.mjs";
|
|
26
22
|
|
|
27
23
|
// src/cli/commands/add.ts
|
|
28
24
|
import * as fs from "fs";
|
|
@@ -82,13 +78,13 @@ var addCommand = async (name, options) => {
|
|
|
82
78
|
return;
|
|
83
79
|
}
|
|
84
80
|
checkApiKey();
|
|
85
|
-
const
|
|
81
|
+
const promptsApiService = new PromptsApiService();
|
|
86
82
|
const version = (_a = options.version) != null ? _a : "latest";
|
|
87
83
|
const spinner = ora(
|
|
88
84
|
`Adding ${chalk.cyan(`${name}@${version}`)}...`
|
|
89
85
|
).start();
|
|
90
86
|
try {
|
|
91
|
-
const prompt = await
|
|
87
|
+
const prompt = await promptsApiService.get(name);
|
|
92
88
|
if (!prompt) {
|
|
93
89
|
spinner.fail();
|
|
94
90
|
console.error(chalk.red(`Error: Prompt "${name}" not found`));
|
|
@@ -147,4 +143,4 @@ var addCommand = async (name, options) => {
|
|
|
147
143
|
export {
|
|
148
144
|
addCommand
|
|
149
145
|
};
|
|
150
|
-
//# sourceMappingURL=add-
|
|
146
|
+
//# sourceMappingURL=add-HWFRMAQX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/add.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { FileManager } from \"../utils/fileManager\";\nimport { PromptsApiService, PromptsError } from \"@/client-sdk/services/prompts\";\nimport { PromptConverter } from \"../utils/promptConverter\";\nimport { ensureProjectInitialized } from \"../utils/init\";\nimport { checkApiKey } from \"../utils/apiKey\";\nimport { LangWatch } from \"@/client-sdk\";\n\ninterface AddOptions {\n version?: string;\n localFile?: string;\n}\n\nconst addLocalFile = async (\n name: string,\n localFilePath: string,\n): Promise<void> => {\n // Validate that the file exists and has the right extension\n if (!fs.existsSync(localFilePath)) {\n console.error(chalk.red(`Error: Local file not found: ${localFilePath}`));\n process.exit(1);\n }\n\n if (!localFilePath.endsWith(\".prompt.yaml\")) {\n console.error(\n chalk.red(`Error: Local file must have .prompt.yaml extension`),\n );\n process.exit(1);\n }\n\n // Load and validate the YAML file\n try {\n FileManager.loadLocalPrompt(localFilePath);\n\n // Ensure project is initialized\n await ensureProjectInitialized();\n\n // Add to prompts.json as a file: dependency\n const promptsConfig = FileManager.loadPromptsConfig();\n promptsConfig.prompts[name] = `file:${localFilePath}`;\n FileManager.savePromptsConfig(promptsConfig);\n\n // Update lock file\n const lock = FileManager.loadPromptsLock();\n lock.prompts[name] = {\n version: 0, // Local files start at version 0\n versionId: \"local\",\n materialized: localFilePath, // Store the original file path\n };\n FileManager.savePromptsLock(lock);\n\n console.log(\n chalk.green(\n `✓ Added local prompt: ${chalk.cyan(name)} → ${chalk.gray(\n localFilePath,\n )}`,\n ),\n );\n } catch (error) {\n console.error(chalk.red(\"Error loading local prompt file:\"));\n console.error(\n chalk.red(error instanceof Error ? error.message : String(error)),\n );\n process.exit(1);\n }\n};\n\nexport const addCommand = async (\n name: string,\n options: AddOptions,\n): Promise<void> => {\n try {\n // Validate prompt name\n if (!name || name.trim() === \"\") {\n console.error(chalk.red(\"Error: Prompt name cannot be empty\"));\n process.exit(1);\n }\n\n // Handle local file addition\n if (options.localFile) {\n await addLocalFile(name, options.localFile);\n return;\n }\n\n // Check API key before doing anything else\n checkApiKey();\n\n const promptsApiService = new PromptsApiService();\n const version = options.version ?? \"latest\";\n\n // Fetch and materialize the prompt (like sync does for individual prompts)\n const spinner = ora(\n `Adding ${chalk.cyan(`${name}@${version}`)}...`,\n ).start();\n\n try {\n // Fetch the prompt from the API\n const prompt = await promptsApiService.get(name);\n\n if (!prompt) {\n spinner.fail();\n console.error(chalk.red(`Error: Prompt \"${name}\" not found`));\n process.exit(1);\n }\n\n // Stop spinner before any user input prompts\n spinner.stop();\n\n // Ensure project is initialized (prompts.json, lock file, directories)\n await ensureProjectInitialized();\n\n // Restart spinner for the actual work\n spinner.start(`Adding ${chalk.cyan(`${name}@${version}`)}...`);\n\n // Convert to MaterializedPrompt format and save\n const materializedPrompt = PromptConverter.fromApiToMaterialized(prompt);\n const savedPath = FileManager.saveMaterializedPrompt(\n name,\n materializedPrompt,\n );\n const relativePath = path.relative(process.cwd(), savedPath);\n\n // Load existing config and lock, add the new dependency\n const config = FileManager.loadPromptsConfig();\n const lock = FileManager.loadPromptsLock();\n\n config.prompts[name] = version;\n FileManager.updateLockEntry(lock, name, materializedPrompt, savedPath);\n\n // Save the updated config and lock\n FileManager.savePromptsConfig(config);\n FileManager.savePromptsLock(lock);\n\n spinner.succeed();\n\n // Show what was done (add ./ prefix for consistency)\n const displayPath = relativePath.startsWith(\"./\")\n ? relativePath\n : `./${relativePath}`;\n console.log(\n chalk.green(\n `✓ Pulled ${chalk.cyan(`${name}@${version}`)} ${chalk.gray(\n `(version ${prompt.version})`,\n )} → ${chalk.gray(displayPath)}`,\n ),\n );\n } catch (error) {\n spinner.fail();\n if (error instanceof PromptsError) {\n console.error(chalk.red(`Error: ${error.message}`));\n } else {\n console.error(\n chalk.red(\n `Error adding prompt: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n ),\n );\n }\n process.exit(1);\n }\n } catch (error) {\n if (error instanceof PromptsError) {\n console.error(chalk.red(`Error: ${error.message}`));\n } else {\n console.error(\n chalk.red(\n `Unexpected error: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n ),\n );\n }\n process.exit(1);\n }\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,16 +1,124 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
2
2
|
|
|
3
|
-
var _chunkR6FBJN7Kjs = require('./chunk-R6FBJN7K.js');
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
var _chunkAZHZ4NB4js = require('./chunk-AZHZ4NB4.js');
|
|
7
4
|
|
|
5
|
+
// src/cli/utils/promptConverter.ts
|
|
6
|
+
var PromptConverter = class {
|
|
7
|
+
/**
|
|
8
|
+
* Converts a Prompt instance from the API service to the MaterializedPrompt format
|
|
9
|
+
* used for saving to the .materialized directory.
|
|
10
|
+
*/
|
|
11
|
+
static fromApiToMaterialized(prompt) {
|
|
12
|
+
return {
|
|
13
|
+
id: prompt.id,
|
|
14
|
+
name: prompt.name,
|
|
15
|
+
version: prompt.version,
|
|
16
|
+
versionId: prompt.versionId,
|
|
17
|
+
model: prompt.model,
|
|
18
|
+
messages: prompt.messages,
|
|
19
|
+
prompt: prompt.prompt,
|
|
20
|
+
temperature: prompt.temperature,
|
|
21
|
+
maxTokens: prompt.maxTokens,
|
|
22
|
+
inputs: prompt.inputs,
|
|
23
|
+
outputs: prompt.outputs,
|
|
24
|
+
updatedAt: prompt.updatedAt
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Converts a MaterializedPrompt to the YAML content structure
|
|
29
|
+
* for saving to .prompt.yaml files.
|
|
30
|
+
*/
|
|
31
|
+
static fromMaterializedToYaml(prompt) {
|
|
32
|
+
const result = {
|
|
33
|
+
model: prompt.model,
|
|
34
|
+
messages: prompt.messages
|
|
35
|
+
};
|
|
36
|
+
if (prompt.temperature !== void 0 || prompt.maxTokens !== void 0) {
|
|
37
|
+
result.modelParameters = {};
|
|
38
|
+
if (prompt.temperature !== void 0) {
|
|
39
|
+
result.modelParameters.temperature = prompt.temperature;
|
|
40
|
+
}
|
|
41
|
+
if (prompt.maxTokens !== void 0) {
|
|
42
|
+
result.modelParameters.maxTokens = prompt.maxTokens;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Converts a LocalPromptConfig (loaded from YAML) to the format
|
|
49
|
+
* expected by the API service for upserting.
|
|
50
|
+
*/
|
|
51
|
+
static fromLocalToApiFormat(config) {
|
|
52
|
+
return {
|
|
53
|
+
model: config.model,
|
|
54
|
+
modelParameters: config.modelParameters,
|
|
55
|
+
messages: config.messages
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extracts the system prompt from messages array.
|
|
60
|
+
* Used when converting to API format that separates system prompt from messages.
|
|
61
|
+
*/
|
|
62
|
+
static extractSystemPrompt(messages) {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
return (_b = (_a = messages.find((m) => m.role === "system")) == null ? void 0 : _a.content) != null ? _b : "";
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Filters out system messages from the messages array.
|
|
68
|
+
* Used when converting to API format that handles system prompt separately.
|
|
69
|
+
*/
|
|
70
|
+
static filterNonSystemMessages(messages) {
|
|
71
|
+
return messages.filter((m) => m.role !== "system");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Converts version specification strings to actual version constraints.
|
|
75
|
+
* Handles npm-style version specs like "latest", "5", "^5", etc.
|
|
76
|
+
*/
|
|
77
|
+
static parseVersionSpec(versionSpec) {
|
|
78
|
+
if (versionSpec === "latest") {
|
|
79
|
+
return { type: "latest", value: "latest" };
|
|
80
|
+
}
|
|
81
|
+
if (/^\d+$/.test(versionSpec)) {
|
|
82
|
+
return { type: "exact", value: versionSpec };
|
|
83
|
+
}
|
|
84
|
+
return { type: "tag", value: versionSpec };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validates that a YAML config can be safely converted to API format.
|
|
88
|
+
* Returns validation errors if any, or null if valid.
|
|
89
|
+
*/
|
|
90
|
+
static validateForApiConversion(config) {
|
|
91
|
+
var _a;
|
|
92
|
+
const errors = [];
|
|
93
|
+
if (!((_a = config.model) == null ? void 0 : _a.trim())) {
|
|
94
|
+
errors.push("Model is required and cannot be empty");
|
|
95
|
+
}
|
|
96
|
+
if (!config.messages || config.messages.length === 0) {
|
|
97
|
+
errors.push("At least one message is required");
|
|
98
|
+
}
|
|
99
|
+
if (config.messages) {
|
|
100
|
+
config.messages.forEach((message, index) => {
|
|
101
|
+
var _a2;
|
|
102
|
+
if (!["system", "user", "assistant"].includes(message.role)) {
|
|
103
|
+
errors.push(
|
|
104
|
+
`Message ${index}: role must be 'system', 'user', or 'assistant'`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (!((_a2 = message.content) == null ? void 0 : _a2.trim())) {
|
|
108
|
+
errors.push(`Message ${index}: content cannot be empty`);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return errors;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
8
116
|
// src/cli/utils/fileManager.ts
|
|
9
117
|
var _fs = require('fs'); var fs = _interopRequireWildcard(_fs);
|
|
10
118
|
var _path = require('path'); var path = _interopRequireWildcard(_path);
|
|
11
119
|
var _jsyaml = require('js-yaml'); var yaml = _interopRequireWildcard(_jsyaml);
|
|
12
120
|
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
13
|
-
var
|
|
121
|
+
var _FileManager = class _FileManager {
|
|
14
122
|
static getPromptsConfigPath() {
|
|
15
123
|
return path.join(process.cwd(), this.PROMPTS_CONFIG_FILE);
|
|
16
124
|
}
|
|
@@ -59,21 +167,6 @@ var FileManager = class {
|
|
|
59
167
|
}
|
|
60
168
|
return { created: false, path: configPath };
|
|
61
169
|
}
|
|
62
|
-
static loadPromptsLock() {
|
|
63
|
-
const lockPath = this.getPromptsLockPath();
|
|
64
|
-
if (!fs.existsSync(lockPath)) {
|
|
65
|
-
return {
|
|
66
|
-
lockfileVersion: 1,
|
|
67
|
-
prompts: {}
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
const content = fs.readFileSync(lockPath, "utf-8");
|
|
72
|
-
return JSON.parse(content);
|
|
73
|
-
} catch (error) {
|
|
74
|
-
throw new Error(`Failed to parse prompts-lock.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
170
|
static savePromptsLock(lock) {
|
|
78
171
|
const lockPath = this.getPromptsLockPath();
|
|
79
172
|
fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + "\n");
|
|
@@ -91,31 +184,6 @@ var FileManager = class {
|
|
|
91
184
|
}
|
|
92
185
|
return { created: false, path: lockPath };
|
|
93
186
|
}
|
|
94
|
-
static loadLocalPrompt(filePath) {
|
|
95
|
-
const fullPath = path.resolve(filePath);
|
|
96
|
-
if (!fs.existsSync(fullPath)) {
|
|
97
|
-
throw new Error(`Local prompt file not found: ${filePath}`);
|
|
98
|
-
}
|
|
99
|
-
try {
|
|
100
|
-
const content = fs.readFileSync(fullPath, "utf-8");
|
|
101
|
-
const rawData = yaml.load(content);
|
|
102
|
-
const result = _chunkAZHZ4NB4js.localPromptConfigSchema.safeParse(rawData);
|
|
103
|
-
if (!result.success) {
|
|
104
|
-
const prettyError = result.error.issues.map((issue) => `\u2716 ${issue.message}${issue.path.length > 0 ? `
|
|
105
|
-
\u2192 at ${issue.path.join(".")}` : ""}`).join("\n");
|
|
106
|
-
throw new Error(
|
|
107
|
-
`Invalid prompt configuration in ${_chalk2.default.yellow(filePath)}:
|
|
108
|
-
${prettyError}`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
return result.data;
|
|
112
|
-
} catch (error) {
|
|
113
|
-
if (error instanceof Error && error.message.includes("Invalid prompt configuration")) {
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
throw new Error(`Failed to parse local prompt file ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
187
|
static saveMaterializedPrompt(name, prompt) {
|
|
120
188
|
const materializedDir = this.getMaterializedDir();
|
|
121
189
|
const parts = name.split("/");
|
|
@@ -127,7 +195,7 @@ ${prettyError}`
|
|
|
127
195
|
}
|
|
128
196
|
}
|
|
129
197
|
const filePath = path.join(materializedDir, ...parts.slice(0, -1), fileName);
|
|
130
|
-
const yamlContent =
|
|
198
|
+
const yamlContent = PromptConverter.fromMaterializedToYaml(prompt);
|
|
131
199
|
const yamlString = yaml.dump(yamlContent, {
|
|
132
200
|
lineWidth: -1,
|
|
133
201
|
noRefs: true,
|
|
@@ -136,31 +204,6 @@ ${prettyError}`
|
|
|
136
204
|
fs.writeFileSync(filePath, yamlString);
|
|
137
205
|
return filePath;
|
|
138
206
|
}
|
|
139
|
-
static getLocalPromptFiles() {
|
|
140
|
-
const promptsDir = this.getPromptsDir();
|
|
141
|
-
const materializedDir = this.getMaterializedDir();
|
|
142
|
-
if (!fs.existsSync(promptsDir)) {
|
|
143
|
-
return [];
|
|
144
|
-
}
|
|
145
|
-
const files = [];
|
|
146
|
-
const walkDir = (dir, relativePath = "") => {
|
|
147
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
148
|
-
for (const entry of entries) {
|
|
149
|
-
const fullPath = path.join(dir, entry.name);
|
|
150
|
-
const relativeFilePath = path.join(relativePath, entry.name);
|
|
151
|
-
if (entry.isDirectory()) {
|
|
152
|
-
if (fullPath === materializedDir) {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
walkDir(fullPath, relativeFilePath);
|
|
156
|
-
} else if (entry.isFile() && entry.name.endsWith(".prompt.yaml")) {
|
|
157
|
-
files.push(path.join(promptsDir, relativeFilePath));
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
walkDir(promptsDir);
|
|
162
|
-
return files;
|
|
163
|
-
}
|
|
164
207
|
static promptNameFromPath(filePath) {
|
|
165
208
|
const promptsDir = this.getPromptsDir();
|
|
166
209
|
const relativePath = path.relative(promptsDir, filePath);
|
|
@@ -231,12 +274,79 @@ ${entry}
|
|
|
231
274
|
return { added: true, existed: false };
|
|
232
275
|
}
|
|
233
276
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
277
|
+
_FileManager.PROMPTS_CONFIG_FILE = "prompts.json";
|
|
278
|
+
_FileManager.PROMPTS_LOCK_FILE = "prompts-lock.json";
|
|
279
|
+
_FileManager.PROMPTS_DIR = "prompts";
|
|
280
|
+
_FileManager.MATERIALIZED_DIR = ".materialized";
|
|
281
|
+
_FileManager.loadPromptsLock = () => {
|
|
282
|
+
const lockPath = _FileManager.getPromptsLockPath();
|
|
283
|
+
if (!fs.existsSync(lockPath)) {
|
|
284
|
+
return {
|
|
285
|
+
lockfileVersion: 1,
|
|
286
|
+
prompts: {}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
try {
|
|
290
|
+
const content = fs.readFileSync(lockPath, "utf-8");
|
|
291
|
+
return JSON.parse(content);
|
|
292
|
+
} catch (error) {
|
|
293
|
+
throw new Error(`Failed to parse prompts-lock.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
_FileManager.loadLocalPrompt = (filePath) => {
|
|
297
|
+
const fullPath = path.resolve(filePath);
|
|
298
|
+
if (!fs.existsSync(fullPath)) {
|
|
299
|
+
throw new Error(`Local prompt file not found: ${filePath}`);
|
|
300
|
+
}
|
|
301
|
+
try {
|
|
302
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
303
|
+
const rawData = yaml.load(content);
|
|
304
|
+
const result = _chunkAZHZ4NB4js.localPromptConfigSchema.safeParse(rawData);
|
|
305
|
+
if (!result.success) {
|
|
306
|
+
const prettyError = result.error.issues.map((issue) => `\u2716 ${issue.message}${issue.path.length > 0 ? `
|
|
307
|
+
\u2192 at ${issue.path.join(".")}` : ""}`).join("\n");
|
|
308
|
+
throw new Error(
|
|
309
|
+
`Invalid prompt configuration in ${_chalk2.default.yellow(filePath)}:
|
|
310
|
+
${prettyError}`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
return result.data;
|
|
314
|
+
} catch (error) {
|
|
315
|
+
if (error instanceof Error && error.message.includes("Invalid prompt configuration")) {
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
throw new Error(`Failed to parse local prompt file ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
_FileManager.getLocalPromptFiles = () => {
|
|
322
|
+
const promptsDir = _FileManager.getPromptsDir();
|
|
323
|
+
const materializedDir = _FileManager.getMaterializedDir();
|
|
324
|
+
if (!fs.existsSync(promptsDir)) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
const files = [];
|
|
328
|
+
const walkDir = (dir, relativePath = "") => {
|
|
329
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
330
|
+
for (const entry of entries) {
|
|
331
|
+
const fullPath = path.join(dir, entry.name);
|
|
332
|
+
const relativeFilePath = path.join(relativePath, entry.name);
|
|
333
|
+
if (entry.isDirectory()) {
|
|
334
|
+
if (fullPath === materializedDir) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
walkDir(fullPath, relativeFilePath);
|
|
338
|
+
} else if (entry.isFile() && entry.name.endsWith(".prompt.yaml")) {
|
|
339
|
+
files.push(path.join(promptsDir, relativeFilePath));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
walkDir(promptsDir);
|
|
344
|
+
return files;
|
|
345
|
+
};
|
|
346
|
+
var FileManager = _FileManager;
|
|
347
|
+
|
|
238
348
|
|
|
239
349
|
|
|
240
350
|
|
|
241
|
-
exports.FileManager = FileManager;
|
|
242
|
-
//# sourceMappingURL=chunk-
|
|
351
|
+
exports.PromptConverter = PromptConverter; exports.FileManager = FileManager;
|
|
352
|
+
//# sourceMappingURL=chunk-36XAYVMC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/langwatch/langwatch/typescript-sdk/dist/chunk-36XAYVMC.js","../src/cli/utils/promptConverter.ts","../src/cli/utils/fileManager.ts"],"names":["_a"],"mappings":"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","file":"/home/runner/work/langwatch/langwatch/typescript-sdk/dist/chunk-36XAYVMC.js","sourcesContent":[null,"import type { LocalPromptConfig, MaterializedPrompt } from \"../types\";\nimport { type PromptResponse } from \"@/client-sdk/services/prompts/types\";\n\n/**\n * Converter utility for transforming between YAML prompt format and API service format.\n *\n * The YAML format follows the GitHub .prompt.yaml file format standard,\n * while the API format is our internal prompt service schema tied to the database.\n *\n * This separation allows us to maintain and evolve both formats independently\n * while keeping the conversion logic centralized and well-tested.\n */\nexport class PromptConverter {\n /**\n * Converts a Prompt instance from the API service to the MaterializedPrompt format\n * used for saving to the .materialized directory.\n */\n static fromApiToMaterialized(prompt: PromptResponse): MaterializedPrompt {\n return {\n id: prompt.id,\n name: prompt.name,\n version: prompt.version,\n versionId: prompt.versionId,\n model: prompt.model,\n messages: prompt.messages,\n prompt: prompt.prompt,\n temperature: prompt.temperature,\n maxTokens: prompt.maxTokens,\n inputs: prompt.inputs,\n outputs: prompt.outputs,\n updatedAt: prompt.updatedAt,\n };\n }\n\n /**\n * Converts a MaterializedPrompt to the YAML content structure\n * for saving to .prompt.yaml files.\n */\n static fromMaterializedToYaml(prompt: MaterializedPrompt): {\n model: string;\n modelParameters?: {\n temperature?: number;\n maxTokens?: number;\n };\n messages: Array<{\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n }>;\n } {\n const result: any = {\n model: prompt.model,\n messages: prompt.messages,\n };\n\n // Add modelParameters if temperature or maxTokens exist\n if (prompt.temperature !== undefined || prompt.maxTokens !== undefined) {\n result.modelParameters = {};\n if (prompt.temperature !== undefined) {\n result.modelParameters.temperature = prompt.temperature;\n }\n if (prompt.maxTokens !== undefined) {\n result.modelParameters.maxTokens = prompt.maxTokens;\n }\n }\n\n return result;\n }\n\n /**\n * Converts a LocalPromptConfig (loaded from YAML) to the format\n * expected by the API service for upserting.\n */\n static fromLocalToApiFormat(config: LocalPromptConfig): {\n model: string;\n modelParameters?: {\n temperature?: number;\n max_tokens?: number;\n };\n messages: Array<{\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n }>;\n } {\n return {\n model: config.model,\n modelParameters: config.modelParameters,\n messages: config.messages,\n };\n }\n\n /**\n * Extracts the system prompt from messages array.\n * Used when converting to API format that separates system prompt from messages.\n */\n static extractSystemPrompt(\n messages: Array<{ role: string; content: string }>,\n ): string {\n return messages.find((m) => m.role === \"system\")?.content ?? \"\";\n }\n\n /**\n * Filters out system messages from the messages array.\n * Used when converting to API format that handles system prompt separately.\n */\n static filterNonSystemMessages(\n messages: Array<{\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n }>,\n ): Array<{ role: \"user\" | \"assistant\"; content: string }> {\n return messages.filter((m) => m.role !== \"system\") as Array<{\n role: \"user\" | \"assistant\";\n content: string;\n }>;\n }\n\n /**\n * Converts version specification strings to actual version constraints.\n * Handles npm-style version specs like \"latest\", \"5\", \"^5\", etc.\n */\n static parseVersionSpec(versionSpec: string): {\n type: \"latest\" | \"exact\" | \"tag\";\n value: string;\n } {\n if (versionSpec === \"latest\") {\n return { type: \"latest\", value: \"latest\" };\n }\n\n // For now, treat everything else as tags until we implement proper semver\n if (/^\\d+$/.test(versionSpec)) {\n return { type: \"exact\", value: versionSpec };\n }\n\n // Handle prefixes like ^, ~, etc. as tags for now\n return { type: \"tag\", value: versionSpec };\n }\n\n /**\n * Validates that a YAML config can be safely converted to API format.\n * Returns validation errors if any, or null if valid.\n */\n static validateForApiConversion(config: LocalPromptConfig): string[] {\n const errors: string[] = [];\n\n if (!config.model?.trim()) {\n errors.push(\"Model is required and cannot be empty\");\n }\n\n if (!config.messages || config.messages.length === 0) {\n errors.push(\"At least one message is required\");\n }\n\n if (config.messages) {\n config.messages.forEach((message, index) => {\n if (![\"system\", \"user\", \"assistant\"].includes(message.role)) {\n errors.push(\n `Message ${index}: role must be 'system', 'user', or 'assistant'`,\n );\n }\n if (!message.content?.trim()) {\n errors.push(`Message ${index}: content cannot be empty`);\n }\n });\n }\n\n return errors;\n }\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as yaml from \"js-yaml\";\nimport chalk from \"chalk\";\nimport type { PromptsConfig, LocalPromptConfig, MaterializedPrompt, PromptsLock } from \"../types\";\nimport { localPromptConfigSchema } from \"../types\";\nimport { PromptConverter } from \"@/cli/utils/promptConverter\";\n\nexport class FileManager {\n private static readonly PROMPTS_CONFIG_FILE = \"prompts.json\";\n private static readonly PROMPTS_LOCK_FILE = \"prompts-lock.json\";\n private static readonly PROMPTS_DIR = \"prompts\";\n private static readonly MATERIALIZED_DIR = \".materialized\";\n\n static getPromptsConfigPath(): string {\n return path.join(process.cwd(), this.PROMPTS_CONFIG_FILE);\n }\n\n static getPromptsLockPath(): string {\n return path.join(process.cwd(), this.PROMPTS_LOCK_FILE);\n }\n\n static getPromptsDir(): string {\n return path.join(process.cwd(), this.PROMPTS_DIR);\n }\n\n static getMaterializedDir(): string {\n return path.join(this.getPromptsDir(), this.MATERIALIZED_DIR);\n }\n\n static ensureDirectories(): void {\n const promptsDir = this.getPromptsDir();\n const materializedDir = this.getMaterializedDir();\n\n if (!fs.existsSync(promptsDir)) {\n fs.mkdirSync(promptsDir, { recursive: true });\n }\n\n if (!fs.existsSync(materializedDir)) {\n fs.mkdirSync(materializedDir, { recursive: true });\n }\n }\n\n static loadPromptsConfig(): PromptsConfig {\n const configPath = this.getPromptsConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return { prompts: {} };\n }\n\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n return JSON.parse(content) as PromptsConfig;\n } catch (error) {\n throw new Error(`Failed to parse prompts.json: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n }\n\n static savePromptsConfig(config: PromptsConfig): void {\n const configPath = this.getPromptsConfigPath();\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\");\n }\n\n static initializePromptsConfig(): { created: boolean; path: string } {\n const configPath = this.getPromptsConfigPath();\n const existed = fs.existsSync(configPath);\n\n if (!existed) {\n const emptyConfig: PromptsConfig = { prompts: {} };\n this.savePromptsConfig(emptyConfig);\n return { created: true, path: configPath };\n }\n\n return { created: false, path: configPath };\n }\n\n static loadPromptsLock = (): PromptsLock => {\n const lockPath = this.getPromptsLockPath();\n\n if (!fs.existsSync(lockPath)) {\n return {\n lockfileVersion: 1,\n prompts: {}\n };\n }\n\n try {\n const content = fs.readFileSync(lockPath, \"utf-8\");\n return JSON.parse(content) as PromptsLock;\n } catch (error) {\n throw new Error(`Failed to parse prompts-lock.json: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n }\n\n static savePromptsLock(lock: PromptsLock): void {\n const lockPath = this.getPromptsLockPath();\n fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + \"\\n\");\n }\n\n static initializePromptsLock(): { created: boolean; path: string } {\n const lockPath = this.getPromptsLockPath();\n const existed = fs.existsSync(lockPath);\n\n if (!existed) {\n const emptyLock: PromptsLock = {\n lockfileVersion: 1,\n prompts: {}\n };\n this.savePromptsLock(emptyLock);\n return { created: true, path: lockPath };\n }\n\n return { created: false, path: lockPath };\n }\n\n static loadLocalPrompt = (filePath: string): LocalPromptConfig => {\n const fullPath = path.resolve(filePath);\n\n if (!fs.existsSync(fullPath)) {\n throw new Error(`Local prompt file not found: ${filePath}`);\n }\n\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const rawData = yaml.load(content);\n\n // Validate with zod and provide nice error messages\n const result = localPromptConfigSchema.safeParse(rawData);\n\n if (!result.success) {\n // Format zod errors nicely (manually since z.prettifyError might not be available)\n const prettyError = result.error.issues\n .map(issue => `✖ ${issue.message}${issue.path.length > 0 ? `\\n → at ${issue.path.join('.')}` : ''}`)\n .join('\\n');\n\n throw new Error(\n `Invalid prompt configuration in ${chalk.yellow(filePath)}:\\n${prettyError}`\n );\n }\n\n return result.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Invalid prompt configuration\")) {\n throw error; // Re-throw zod validation errors as-is\n }\n throw new Error(`Failed to parse local prompt file ${filePath}: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n }\n\n static saveMaterializedPrompt(name: string, prompt: MaterializedPrompt): string {\n const materializedDir = this.getMaterializedDir();\n const parts = name.split(\"/\");\n const fileName = `${parts[parts.length - 1]}.prompt.yaml`;\n\n // Create nested directories if needed\n if (parts.length > 1) {\n const subDir = path.join(materializedDir, ...parts.slice(0, -1));\n if (!fs.existsSync(subDir)) {\n fs.mkdirSync(subDir, { recursive: true });\n }\n }\n\n const filePath = path.join(materializedDir, ...parts.slice(0, -1), fileName);\n\n // Convert to YAML format using the converter\n const yamlContent = PromptConverter.fromMaterializedToYaml(prompt);\n\n const yamlString = yaml.dump(yamlContent, {\n lineWidth: -1,\n noRefs: true,\n sortKeys: false\n });\n\n fs.writeFileSync(filePath, yamlString);\n return filePath;\n }\n\n static getLocalPromptFiles = (): string[] => {\n const promptsDir = this.getPromptsDir();\n const materializedDir = this.getMaterializedDir();\n\n if (!fs.existsSync(promptsDir)) {\n return [];\n }\n\n const files: string[] = [];\n\n const walkDir = (dir: string, relativePath = \"\"): void => {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relativeFilePath = path.join(relativePath, entry.name);\n\n if (entry.isDirectory()) {\n // Skip the .materialized directory\n if (fullPath === materializedDir) {\n continue;\n }\n walkDir(fullPath, relativeFilePath);\n } else if (entry.isFile() && entry.name.endsWith(\".prompt.yaml\")) {\n files.push(path.join(promptsDir, relativeFilePath));\n }\n }\n };\n\n walkDir(promptsDir);\n return files;\n }\n\n static promptNameFromPath(filePath: string): string {\n const promptsDir = this.getPromptsDir();\n const relativePath = path.relative(promptsDir, filePath);\n return relativePath.replace(/\\.prompt\\.yaml$/, \"\");\n }\n\n static cleanupOrphanedMaterializedFiles(currentDependencies: Set<string>): string[] {\n const materializedDir = this.getMaterializedDir();\n\n if (!fs.existsSync(materializedDir)) {\n return [];\n }\n\n const cleaned: string[] = [];\n\n const cleanupDir = (dir: string, relativePath = \"\"): void => {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relativeFilePath = path.join(relativePath, entry.name);\n\n if (entry.isDirectory()) {\n cleanupDir(fullPath, relativeFilePath);\n\n // Remove empty directories\n try {\n const dirEntries = fs.readdirSync(fullPath);\n if (dirEntries.length === 0) {\n fs.rmdirSync(fullPath);\n }\n } catch {\n // Directory not empty or other error, ignore\n }\n } else if (entry.isFile() && entry.name.endsWith(\".prompt.yaml\")) {\n // Extract prompt name from materialized file path\n const promptName = relativeFilePath.replace(/\\.prompt\\.yaml$/, \"\");\n\n if (!currentDependencies.has(promptName)) {\n fs.unlinkSync(fullPath);\n cleaned.push(promptName);\n }\n }\n }\n };\n\n cleanupDir(materializedDir);\n return cleaned;\n }\n\n static updateLockEntry(lock: PromptsLock, name: string, prompt: MaterializedPrompt, materializedPath: string): void {\n const relativePath = path.relative(process.cwd(), materializedPath);\n\n lock.prompts[name] = {\n version: prompt.version,\n versionId: prompt.versionId,\n materialized: relativePath,\n };\n }\n\n static removeFromLock(lock: PromptsLock, names: string[]): void {\n for (const name of names) {\n delete lock.prompts[name];\n }\n }\n\n static addToGitignore(entry: string): { added: boolean; existed: boolean } {\n const gitignorePath = path.join(process.cwd(), \".gitignore\");\n\n // Check if .gitignore exists\n if (!fs.existsSync(gitignorePath)) {\n // Create new .gitignore with the entry\n fs.writeFileSync(gitignorePath, `${entry}\\n`);\n return { added: true, existed: false };\n }\n\n // Read existing .gitignore\n const content = fs.readFileSync(gitignorePath, \"utf-8\");\n const lines = content.split(\"\\n\").map(line => line.trim());\n\n // Check if entry already exists\n if (lines.includes(entry)) {\n return { added: false, existed: true };\n }\n\n // Add entry to .gitignore\n const newContent = content.endsWith(\"\\n\") ? `${content}${entry}\\n` : `${content}\\n${entry}\\n`;\n fs.writeFileSync(gitignorePath, newContent);\n\n return { added: true, existed: false };\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// package.json
|
|
2
|
-
var version = "0.
|
|
2
|
+
var version = "0.7.1";
|
|
3
3
|
|
|
4
4
|
// src/internal/runtime.ts
|
|
5
5
|
var _runtime;
|
|
@@ -60,4 +60,4 @@ var LOGS_PATH = "/api/otel/v1/logs";
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
exports.version = version; exports.LANGWATCH_SDK_RUNTIME = LANGWATCH_SDK_RUNTIME; exports.LANGWATCH_SDK_NAME_OBSERVABILITY = LANGWATCH_SDK_NAME_OBSERVABILITY; exports.LANGWATCH_SDK_NAME_CLIENT = LANGWATCH_SDK_NAME_CLIENT; exports.LANGWATCH_SDK_LANGUAGE = LANGWATCH_SDK_LANGUAGE; exports.LANGWATCH_SDK_VERSION = LANGWATCH_SDK_VERSION; exports.DEFAULT_ENDPOINT = DEFAULT_ENDPOINT; exports.DEFAULT_SERVICE_NAME = DEFAULT_SERVICE_NAME; exports.TRACES_PATH = TRACES_PATH; exports.LOGS_PATH = LOGS_PATH;
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-5HAVK64Q.js.map
|