langwatch 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-LBBS4I3H.js → add-35QACTIV.js} +34 -28
- package/dist/add-35QACTIV.js.map +1 -0
- package/dist/{add-RD3ZKFAT.mjs → add-TRJAXM4D.mjs} +22 -16
- package/dist/add-TRJAXM4D.mjs.map +1 -0
- package/dist/chunk-4ZSSHX6F.js +636 -0
- package/dist/chunk-4ZSSHX6F.js.map +1 -0
- package/dist/chunk-5EVBOHJY.js +155 -0
- package/dist/chunk-5EVBOHJY.js.map +1 -0
- package/dist/{chunk-YN4436PK.mjs → chunk-CU3443HD.mjs} +14 -9
- package/dist/{chunk-2JU376G7.js → chunk-D2CSG4SJ.js} +4 -4
- package/dist/chunk-D2CSG4SJ.js.map +1 -0
- package/dist/chunk-DISMHYXC.js +184 -0
- package/dist/chunk-DISMHYXC.js.map +1 -0
- package/dist/{chunk-E7UE2MPD.mjs → chunk-ECUXLXFT.mjs} +2 -2
- package/dist/chunk-EJWJXTPU.mjs +626 -0
- package/dist/chunk-EJWJXTPU.mjs.map +1 -0
- package/dist/chunk-GQMDZ4GY.mjs +155 -0
- package/dist/chunk-GQMDZ4GY.mjs.map +1 -0
- package/dist/{chunk-3GKPQB4R.mjs → chunk-HUI45ULC.mjs} +4 -4
- package/dist/chunk-HUI45ULC.mjs.map +1 -0
- package/dist/{chunk-HJU67C7H.js → chunk-K64Y6YUG.js} +10 -10
- package/dist/{chunk-HJU67C7H.js.map → chunk-K64Y6YUG.js.map} +1 -1
- package/dist/chunk-LP76VXI3.mjs +636 -0
- package/dist/chunk-LP76VXI3.mjs.map +1 -0
- package/dist/chunk-M4VUHTT2.js +626 -0
- package/dist/chunk-M4VUHTT2.js.map +1 -0
- package/dist/{chunk-PR3JDWC3.mjs → chunk-N2V6J3U2.mjs} +28 -3
- package/dist/chunk-N2V6J3U2.mjs.map +1 -0
- package/dist/chunk-OUCVXP4G.js +258 -0
- package/dist/chunk-OUCVXP4G.js.map +1 -0
- package/dist/{chunk-FJLK5CFL.js → chunk-OXBO24RB.js} +13 -8
- package/dist/chunk-OXBO24RB.js.map +1 -0
- package/dist/chunk-PGWR3OQY.mjs +258 -0
- package/dist/chunk-PGWR3OQY.mjs.map +1 -0
- package/dist/{chunk-SMXXAVMB.js → chunk-SGNJDRCT.js} +2 -2
- package/dist/chunk-SGNJDRCT.js.map +1 -0
- package/dist/{chunk-W5ZEP3CI.mjs → chunk-SYMZPWZE.mjs} +2 -2
- package/dist/chunk-SYMZPWZE.mjs.map +1 -0
- package/dist/{chunk-KGDAENGD.js → chunk-YH5TIVK2.js} +28 -3
- package/dist/chunk-YH5TIVK2.js.map +1 -0
- package/dist/chunk-YNQ44U6D.mjs +184 -0
- package/dist/chunk-YNQ44U6D.mjs.map +1 -0
- package/dist/cli/index.js +8 -8
- package/dist/cli/index.mjs +8 -8
- package/dist/{create-G5MTGOOH.js → create-7K2CC4KQ.js} +11 -11
- package/dist/{create-G5MTGOOH.js.map → create-7K2CC4KQ.js.map} +1 -1
- package/dist/{create-QUZYBMQB.mjs → create-MK7NEGCM.mjs} +8 -8
- package/dist/implementation-C4lvooSg.d.mts +576 -0
- package/dist/implementation-CzemP9jY.d.ts +576 -0
- package/dist/index-DTEZr0Jn.d.mts +34 -0
- package/dist/index-DTEZr0Jn.d.ts +34 -0
- package/dist/index.d.mts +121 -47
- package/dist/index.d.ts +121 -47
- package/dist/index.js +16 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -23
- package/dist/index.mjs.map +1 -1
- package/dist/init-GDKJICSS.js +16 -0
- package/dist/{init-XU2JFY6N.js.map → init-GDKJICSS.js.map} +1 -1
- package/dist/{init-H67RW22E.mjs → init-RINSTP4L.mjs} +5 -5
- package/dist/{list-7NPSX2E4.mjs → list-7L23G5DY.mjs} +28 -16
- package/dist/list-7L23G5DY.mjs.map +1 -0
- package/dist/{list-ZXFLAF52.js → list-OLLQ7XKZ.js} +29 -17
- package/dist/list-OLLQ7XKZ.js.map +1 -0
- package/dist/{login-EK4WVOI2.mjs → login-RCNKL5AM.mjs} +6 -5
- package/dist/login-RCNKL5AM.mjs.map +1 -0
- package/dist/{login-76NQIHKR.js → login-XF3BQQPV.js} +7 -6
- package/dist/login-XF3BQQPV.js.map +1 -0
- package/dist/observability-sdk/index.d.mts +134 -0
- package/dist/observability-sdk/index.d.ts +134 -0
- package/dist/observability-sdk/index.js +41 -0
- package/dist/observability-sdk/index.js.map +1 -0
- package/dist/observability-sdk/index.mjs +41 -0
- package/dist/observability-sdk/instrumentation/langchain/index.d.mts +69 -0
- package/dist/observability-sdk/instrumentation/langchain/index.d.ts +69 -0
- package/dist/observability-sdk/instrumentation/langchain/index.js +518 -0
- package/dist/observability-sdk/instrumentation/langchain/index.js.map +1 -0
- package/dist/observability-sdk/instrumentation/langchain/index.mjs +518 -0
- package/dist/observability-sdk/instrumentation/langchain/index.mjs.map +1 -0
- package/dist/observability-sdk/setup/node/index.d.mts +368 -0
- package/dist/observability-sdk/setup/node/index.d.ts +368 -0
- package/dist/observability-sdk/setup/node/index.js +276 -0
- package/dist/observability-sdk/setup/node/index.js.map +1 -0
- package/dist/observability-sdk/setup/node/index.mjs +276 -0
- package/dist/observability-sdk/setup/node/index.mjs.map +1 -0
- package/dist/{remove-SDJYEPAY.mjs → remove-3VLQNVHN.mjs} +11 -8
- package/dist/remove-3VLQNVHN.mjs.map +1 -0
- package/dist/{remove-XBNGIVMR.js → remove-L6JVJBWY.js} +18 -15
- package/dist/remove-L6JVJBWY.js.map +1 -0
- package/dist/{sync-ST2IWXSB.mjs → sync-DPMTUTVL.mjs} +39 -33
- package/dist/sync-DPMTUTVL.mjs.map +1 -0
- package/dist/{sync-EISKGPTL.js → sync-PSU3F5Z4.js} +52 -46
- package/dist/sync-PSU3F5Z4.js.map +1 -0
- package/dist/{prompt-D-jpMrLS.d.mts → types-1q5wIYP5.d.mts} +628 -14
- package/dist/{prompt-D-jpMrLS.d.ts → types-C9k5gGhU.d.ts} +628 -14
- package/dist/types-DRiQaKFG.d.mts +254 -0
- package/dist/types-DRiQaKFG.d.ts +254 -0
- package/dist/types-Dmazk5Bk.d.mts +44 -0
- package/dist/types-Dmazk5Bk.d.ts +44 -0
- package/package.json +39 -39
- package/dist/add-LBBS4I3H.js.map +0 -1
- package/dist/add-RD3ZKFAT.mjs.map +0 -1
- package/dist/chunk-2JU376G7.js.map +0 -1
- package/dist/chunk-2ODBGSBI.js +0 -4
- package/dist/chunk-2ODBGSBI.js.map +0 -1
- package/dist/chunk-3GKPQB4R.mjs.map +0 -1
- package/dist/chunk-52GXX3MA.js +0 -426
- package/dist/chunk-52GXX3MA.js.map +0 -1
- package/dist/chunk-5NC5ILKA.js +0 -94
- package/dist/chunk-5NC5ILKA.js.map +0 -1
- package/dist/chunk-AAROJADR.mjs +0 -49
- package/dist/chunk-AAROJADR.mjs.map +0 -1
- package/dist/chunk-DTEKFQ4U.js +0 -159
- package/dist/chunk-DTEKFQ4U.js.map +0 -1
- package/dist/chunk-F63YKTXA.mjs +0 -47
- package/dist/chunk-F63YKTXA.mjs.map +0 -1
- package/dist/chunk-FJLK5CFL.js.map +0 -1
- package/dist/chunk-GJSEBQXF.mjs +0 -392
- package/dist/chunk-GJSEBQXF.mjs.map +0 -1
- package/dist/chunk-IGHXIIIK.js +0 -49
- package/dist/chunk-IGHXIIIK.js.map +0 -1
- package/dist/chunk-J7ICRUU4.mjs +0 -426
- package/dist/chunk-J7ICRUU4.mjs.map +0 -1
- package/dist/chunk-KGDAENGD.js.map +0 -1
- package/dist/chunk-LD74LVRU.js +0 -47
- package/dist/chunk-LD74LVRU.js.map +0 -1
- package/dist/chunk-PCQVQ7SB.js +0 -45
- package/dist/chunk-PCQVQ7SB.js.map +0 -1
- package/dist/chunk-PR3JDWC3.mjs.map +0 -1
- package/dist/chunk-PWZBLTHR.js +0 -118
- package/dist/chunk-PWZBLTHR.js.map +0 -1
- package/dist/chunk-QEWDG5QE.mjs +0 -45
- package/dist/chunk-QEWDG5QE.mjs.map +0 -1
- package/dist/chunk-SMXXAVMB.js.map +0 -1
- package/dist/chunk-STV4ZVNA.mjs +0 -118
- package/dist/chunk-STV4ZVNA.mjs.map +0 -1
- package/dist/chunk-T5AZMMVS.mjs +0 -94
- package/dist/chunk-T5AZMMVS.mjs.map +0 -1
- package/dist/chunk-UU33HCCZ.mjs +0 -159
- package/dist/chunk-UU33HCCZ.mjs.map +0 -1
- package/dist/chunk-VGHLQXKB.js +0 -392
- package/dist/chunk-VGHLQXKB.js.map +0 -1
- package/dist/chunk-W5ZEP3CI.mjs.map +0 -1
- package/dist/chunk-Y666BJA5.mjs +0 -4
- package/dist/chunk-YN4436PK.mjs.map +0 -1
- package/dist/client-B2HqIKg6.d.ts +0 -51
- package/dist/client-XyCqclCi.d.mts +0 -51
- package/dist/client-browser.d.mts +0 -8
- package/dist/client-browser.d.ts +0 -8
- package/dist/client-browser.js +0 -88
- package/dist/client-browser.js.map +0 -1
- package/dist/client-browser.mjs +0 -88
- package/dist/client-browser.mjs.map +0 -1
- package/dist/client-node.d.mts +0 -8
- package/dist/client-node.d.ts +0 -8
- package/dist/client-node.js +0 -95
- package/dist/client-node.js.map +0 -1
- package/dist/client-node.mjs +0 -95
- package/dist/client-node.mjs.map +0 -1
- package/dist/evaluation/index.d.mts +0 -897
- package/dist/evaluation/index.d.ts +0 -897
- package/dist/evaluation/index.js +0 -14
- package/dist/evaluation/index.js.map +0 -1
- package/dist/evaluation/index.mjs +0 -14
- package/dist/filterable-batch-span-processor-zO5kcjBY.d.mts +0 -64
- package/dist/filterable-batch-span-processor-zO5kcjBY.d.ts +0 -64
- package/dist/init-XU2JFY6N.js +0 -16
- package/dist/list-7NPSX2E4.mjs.map +0 -1
- package/dist/list-ZXFLAF52.js.map +0 -1
- package/dist/login-76NQIHKR.js.map +0 -1
- package/dist/login-EK4WVOI2.mjs.map +0 -1
- package/dist/observability/index.d.mts +0 -260
- package/dist/observability/index.d.ts +0 -260
- package/dist/observability/index.js +0 -21
- package/dist/observability/index.js.map +0 -1
- package/dist/observability/index.mjs +0 -21
- package/dist/observability/index.mjs.map +0 -1
- package/dist/observability/instrumentation/langchain/index.d.mts +0 -40
- package/dist/observability/instrumentation/langchain/index.d.ts +0 -40
- package/dist/observability/instrumentation/langchain/index.js +0 -668
- package/dist/observability/instrumentation/langchain/index.js.map +0 -1
- package/dist/observability/instrumentation/langchain/index.mjs +0 -668
- package/dist/observability/instrumentation/langchain/index.mjs.map +0 -1
- package/dist/prompt/index.d.mts +0 -10
- package/dist/prompt/index.d.ts +0 -10
- package/dist/prompt/index.js +0 -22
- package/dist/prompt/index.js.map +0 -1
- package/dist/prompt/index.mjs +0 -22
- package/dist/prompt/index.mjs.map +0 -1
- package/dist/record-evaluation-CmxMXa-3.d.mts +0 -25
- package/dist/record-evaluation-CmxMXa-3.d.ts +0 -25
- package/dist/remove-SDJYEPAY.mjs.map +0 -1
- package/dist/remove-XBNGIVMR.js.map +0 -1
- package/dist/sync-EISKGPTL.js.map +0 -1
- package/dist/sync-ST2IWXSB.mjs.map +0 -1
- package/dist/trace-CqaKo0kZ.d.ts +0 -622
- package/dist/trace-DtVc5GhF.d.mts +0 -622
- /package/dist/{chunk-Y666BJA5.mjs.map → chunk-CU3443HD.mjs.map} +0 -0
- /package/dist/{chunk-E7UE2MPD.mjs.map → chunk-ECUXLXFT.mjs.map} +0 -0
- /package/dist/{create-QUZYBMQB.mjs.map → create-MK7NEGCM.mjs.map} +0 -0
- /package/dist/{init-H67RW22E.mjs.map → init-RINSTP4L.mjs.map} +0 -0
- /package/dist/{evaluation → observability-sdk}/index.mjs.map +0 -0
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureProjectInitialized
|
|
3
|
-
} from "./chunk-E7UE2MPD.mjs";
|
|
4
|
-
import {
|
|
5
|
-
FileManager
|
|
6
|
-
} from "./chunk-3GKPQB4R.mjs";
|
|
7
1
|
import {
|
|
8
2
|
checkApiKey
|
|
9
3
|
} from "./chunk-DHJKJVY7.mjs";
|
|
10
|
-
import "./chunk-4NRLVT2U.mjs";
|
|
11
4
|
import {
|
|
12
|
-
|
|
5
|
+
LangWatch
|
|
6
|
+
} from "./chunk-GQMDZ4GY.mjs";
|
|
7
|
+
import {
|
|
13
8
|
PromptsError
|
|
14
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LP76VXI3.mjs";
|
|
10
|
+
import "./chunk-N2V6J3U2.mjs";
|
|
11
|
+
import "./chunk-EJWJXTPU.mjs";
|
|
12
|
+
import "./chunk-PGWR3OQY.mjs";
|
|
13
|
+
import "./chunk-YNQ44U6D.mjs";
|
|
15
14
|
import {
|
|
16
|
-
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import
|
|
15
|
+
ensureProjectInitialized
|
|
16
|
+
} from "./chunk-ECUXLXFT.mjs";
|
|
17
|
+
import {
|
|
18
|
+
FileManager
|
|
19
|
+
} from "./chunk-HUI45ULC.mjs";
|
|
19
20
|
import {
|
|
20
|
-
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
PromptConverter
|
|
22
|
+
} from "./chunk-SYMZPWZE.mjs";
|
|
23
|
+
import "./chunk-4NRLVT2U.mjs";
|
|
24
|
+
import "./chunk-CU3443HD.mjs";
|
|
22
25
|
|
|
23
26
|
// src/cli/commands/sync.ts
|
|
24
27
|
import * as fs from "fs";
|
|
@@ -26,6 +29,7 @@ import * as path from "path";
|
|
|
26
29
|
import chalk from "chalk";
|
|
27
30
|
import ora from "ora";
|
|
28
31
|
import * as yaml from "js-yaml";
|
|
32
|
+
import readline from "readline";
|
|
29
33
|
var handleConflict = async (promptName, conflictInfo) => {
|
|
30
34
|
console.log(
|
|
31
35
|
chalk.yellow(
|
|
@@ -48,7 +52,6 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
48
52
|
console.log(" [l] Use local version (overwrite remote)");
|
|
49
53
|
console.log(" [r] Use remote version (overwrite local)");
|
|
50
54
|
console.log(" [a] Abort sync for this prompt");
|
|
51
|
-
const readline = __require("readline");
|
|
52
55
|
const rl = readline.createInterface({
|
|
53
56
|
input: process.stdin,
|
|
54
57
|
output: process.stdout
|
|
@@ -68,11 +71,11 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
68
71
|
});
|
|
69
72
|
};
|
|
70
73
|
var syncCommand = async () => {
|
|
71
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
72
75
|
const startTime = Date.now();
|
|
73
76
|
try {
|
|
74
77
|
checkApiKey();
|
|
75
|
-
const
|
|
78
|
+
const langwatch = new LangWatch();
|
|
76
79
|
await ensureProjectInitialized(false);
|
|
77
80
|
const config = FileManager.loadPromptsConfig();
|
|
78
81
|
const lock = FileManager.loadPromptsLock();
|
|
@@ -100,9 +103,9 @@ var syncCommand = async () => {
|
|
|
100
103
|
).start();
|
|
101
104
|
for (const [name, dependency] of remoteDeps) {
|
|
102
105
|
try {
|
|
103
|
-
const versionSpec = typeof dependency === "string" ? dependency : dependency.version
|
|
106
|
+
const versionSpec = typeof dependency === "string" ? dependency : (_a = dependency.version) != null ? _a : "latest";
|
|
104
107
|
const lockEntry = lock.prompts[name];
|
|
105
|
-
const prompt = await
|
|
108
|
+
const prompt = await langwatch.prompts.get(name);
|
|
106
109
|
if (prompt) {
|
|
107
110
|
const needsUpdate = !lockEntry || lockEntry.version !== prompt.version || !lockEntry.materialized || !fs.existsSync(path.resolve(lockEntry.materialized));
|
|
108
111
|
if (needsUpdate) {
|
|
@@ -154,19 +157,19 @@ var syncCommand = async () => {
|
|
|
154
157
|
try {
|
|
155
158
|
const filePath = dependency.slice(5);
|
|
156
159
|
const localConfig = FileManager.loadLocalPrompt(filePath);
|
|
157
|
-
const currentVersion = (
|
|
160
|
+
const currentVersion = (_b = lock.prompts[promptName]) == null ? void 0 : _b.version;
|
|
158
161
|
const configData = {
|
|
159
162
|
model: localConfig.model,
|
|
160
163
|
prompt: PromptConverter.extractSystemPrompt(localConfig.messages),
|
|
161
164
|
messages: PromptConverter.filterNonSystemMessages(
|
|
162
165
|
localConfig.messages
|
|
163
166
|
),
|
|
164
|
-
temperature: (
|
|
165
|
-
max_tokens: (
|
|
167
|
+
temperature: (_c = localConfig.modelParameters) == null ? void 0 : _c.temperature,
|
|
168
|
+
max_tokens: (_d = localConfig.modelParameters) == null ? void 0 : _d.max_tokens,
|
|
166
169
|
inputs: [{ identifier: "input", type: "str" }],
|
|
167
170
|
outputs: [{ identifier: "output", type: "str" }]
|
|
168
171
|
};
|
|
169
|
-
const syncResult = await
|
|
172
|
+
const syncResult = await langwatch.prompts.sync({
|
|
170
173
|
name: promptName,
|
|
171
174
|
configData,
|
|
172
175
|
localVersion: currentVersion,
|
|
@@ -199,7 +202,7 @@ var syncCommand = async () => {
|
|
|
199
202
|
role: "system",
|
|
200
203
|
content: syncResult.conflictInfo.remoteConfigData.prompt
|
|
201
204
|
},
|
|
202
|
-
...(
|
|
205
|
+
...(_e = syncResult.conflictInfo.remoteConfigData.messages) != null ? _e : []
|
|
203
206
|
]
|
|
204
207
|
};
|
|
205
208
|
const yamlContent = yaml.dump(remoteConfig, {
|
|
@@ -218,7 +221,7 @@ var syncCommand = async () => {
|
|
|
218
221
|
materialized: filePath
|
|
219
222
|
};
|
|
220
223
|
} else if (syncResult.action === "conflict") {
|
|
221
|
-
const remoteVersion = (
|
|
224
|
+
const remoteVersion = (_g = (_f = syncResult.conflictInfo) == null ? void 0 : _f.remoteVersion) != null ? _g : 0;
|
|
222
225
|
if (conflictResolution === "remote") {
|
|
223
226
|
lock.prompts[promptName] = {
|
|
224
227
|
version: remoteVersion,
|
|
@@ -241,7 +244,7 @@ var syncCommand = async () => {
|
|
|
241
244
|
actionText = "Pulled";
|
|
242
245
|
result.fetched.push({
|
|
243
246
|
name: promptName,
|
|
244
|
-
version: ((
|
|
247
|
+
version: (_i = (_h = syncResult.conflictInfo) == null ? void 0 : _h.remoteVersion) != null ? _i : 0,
|
|
245
248
|
versionSpec: "latest"
|
|
246
249
|
// Default for conflict resolution
|
|
247
250
|
});
|
|
@@ -249,7 +252,7 @@ var syncCommand = async () => {
|
|
|
249
252
|
actionText = "Pushed";
|
|
250
253
|
result.pushed.push({
|
|
251
254
|
name: promptName,
|
|
252
|
-
version: (((
|
|
255
|
+
version: ((_k = (_j = syncResult.conflictInfo) == null ? void 0 : _j.remoteVersion) != null ? _k : 0) + 1
|
|
253
256
|
// New version after push
|
|
254
257
|
});
|
|
255
258
|
}
|
|
@@ -257,19 +260,22 @@ var syncCommand = async () => {
|
|
|
257
260
|
actionText = "Up-to-date";
|
|
258
261
|
result.unchanged.push(promptName);
|
|
259
262
|
} else {
|
|
260
|
-
|
|
263
|
+
const actionMap = {
|
|
261
264
|
created: "Created",
|
|
262
|
-
updated: "Updated"
|
|
263
|
-
|
|
265
|
+
updated: "Updated",
|
|
266
|
+
conflict: "Conflict resolved",
|
|
267
|
+
up_to_date: "Up to date"
|
|
268
|
+
};
|
|
269
|
+
actionText = actionMap[syncResult.action] || "Pushed";
|
|
264
270
|
result.pushed.push({
|
|
265
271
|
name: promptName,
|
|
266
|
-
version: ((
|
|
272
|
+
version: (_m = (_l = syncResult.prompt) == null ? void 0 : _l.version) != null ? _m : 0
|
|
267
273
|
});
|
|
268
274
|
}
|
|
269
275
|
pushSpinner.text = `${actionText} ${chalk.cyan(
|
|
270
276
|
promptName
|
|
271
277
|
)} ${chalk.gray(
|
|
272
|
-
`(version ${((
|
|
278
|
+
`(version ${(_q = (_p = (_n = syncResult.prompt) == null ? void 0 : _n.version) != null ? _p : (_o = syncResult.conflictInfo) == null ? void 0 : _o.remoteVersion) != null ? _q : "unknown"})`
|
|
273
279
|
)} ${conflictResolution === "remote" ? "to" : "from"} ${chalk.gray(
|
|
274
280
|
relativePath
|
|
275
281
|
)}`;
|
|
@@ -400,4 +406,4 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
400
406
|
export {
|
|
401
407
|
syncCommand
|
|
402
408
|
};
|
|
403
|
-
//# sourceMappingURL=sync-
|
|
409
|
+
//# sourceMappingURL=sync-DPMTUTVL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/sync.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport * as yaml from \"js-yaml\";\nimport { PromptConverter } from \"@/cli/utils/promptConverter\";\nimport { type ConfigData, PromptsError, type SyncAction } from \"@/client-sdk/services/prompts\";\nimport { LangWatch } from \"@/client-sdk\";\nimport type { SyncResult } from \"../types\";\nimport { FileManager } from \"../utils/fileManager\";\nimport { ensureProjectInitialized } from \"../utils/init\";\nimport { checkApiKey } from \"../utils/apiKey\";\nimport readline from \"node:readline\";\n\n// Handle conflict resolution - show diff and ask user to choose\nconst handleConflict = async (\n promptName: string,\n conflictInfo: {\n localVersion: number;\n remoteVersion: number;\n differences: string[];\n remoteConfigData: any;\n },\n): Promise<\"local\" | \"remote\" | \"abort\"> => {\n console.log(\n chalk.yellow(\n `\\n⚠ Conflict detected for prompt: ${chalk.cyan(promptName)}`,\n ),\n );\n console.log(\n chalk.gray(\n `Local version: ${conflictInfo.localVersion}, Remote version: ${conflictInfo.remoteVersion}`,\n ),\n );\n\n if (conflictInfo.differences.length > 0) {\n console.log(chalk.yellow(\"\\nDifferences:\"));\n conflictInfo.differences.forEach((diff) => {\n console.log(chalk.gray(` • ${diff}`));\n });\n }\n\n console.log(chalk.yellow(\"\\nOptions:\"));\n console.log(\" [l] Use local version (overwrite remote)\");\n console.log(\" [r] Use remote version (overwrite local)\");\n console.log(\" [a] Abort sync for this prompt\");\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(\"Choose resolution (l/r/a): \", (answer: string) => {\n rl.close();\n const choice = answer.toLowerCase();\n if (choice === \"l\" || choice === \"local\") {\n resolve(\"local\");\n } else if (choice === \"r\" || choice === \"remote\") {\n resolve(\"remote\");\n } else {\n resolve(\"abort\");\n }\n });\n });\n};\n\nexport const syncCommand = async (): Promise<void> => {\n const startTime = Date.now();\n\n try {\n // Check API key before doing anything else\n checkApiKey();\n\n // Get LangWatch client\n const langwatch = new LangWatch();\n\n // Ensure project is initialized (prompts.json, lock file, directories)\n await ensureProjectInitialized(false); // Don't prompt for .gitignore in sync\n\n // Load prompts config and lock\n const config = FileManager.loadPromptsConfig();\n const lock = FileManager.loadPromptsLock();\n\n const result: SyncResult = {\n fetched: [],\n pushed: [],\n unchanged: [],\n cleaned: [],\n errors: [],\n };\n\n // Process remote prompts (fetch and materialize)\n const remoteDeps = Object.entries(config.prompts).filter(\n ([, dependency]) => {\n // Skip local file dependencies (both object format and string format)\n if (typeof dependency === \"object\" && dependency.file) {\n return false;\n }\n if (typeof dependency === \"string\" && dependency.startsWith(\"file:\")) {\n return false;\n }\n return true;\n },\n );\n\n if (remoteDeps.length > 0) {\n const fetchSpinner = ora(\n `Checking ${remoteDeps.length} remote prompts...`,\n ).start();\n\n for (const [name, dependency] of remoteDeps) {\n try {\n const versionSpec =\n typeof dependency === \"string\"\n ? dependency\n : dependency.version ?? \"latest\";\n\n // Check if we already have this prompt with the same version\n const lockEntry = lock.prompts[name];\n\n // Fetch the prompt from the API to check current version\n const prompt = await langwatch.prompts.get(name);\n\n if (prompt) {\n // Check if we need to update (new version or not materialized)\n const needsUpdate =\n !lockEntry ||\n lockEntry.version !== prompt.version ||\n !lockEntry.materialized ||\n !fs.existsSync(path.resolve(lockEntry.materialized));\n\n if (needsUpdate) {\n // Convert to MaterializedPrompt format using the converter\n const materializedPrompt =\n PromptConverter.fromApiToMaterialized(prompt);\n\n const savedPath = FileManager.saveMaterializedPrompt(\n name,\n materializedPrompt,\n );\n const relativePath = path.relative(process.cwd(), savedPath);\n result.fetched.push({\n name,\n version: prompt.version,\n versionSpec,\n });\n\n // Update lock file entry\n FileManager.updateLockEntry(\n lock,\n name,\n materializedPrompt,\n savedPath,\n );\n\n fetchSpinner.text = `Fetched ${chalk.cyan(\n `${name}@${versionSpec}`,\n )} ${chalk.gray(`(version ${prompt.version})`)} → ${chalk.gray(\n relativePath,\n )}`;\n } else {\n // No change needed, track as unchanged\n result.unchanged.push(name);\n }\n } else {\n result.errors.push({ name, error: \"Prompt not found\" });\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n result.errors.push({ name, error: errorMessage });\n }\n }\n\n fetchSpinner.stop();\n }\n\n // Process local prompts (push to API) - only those explicitly declared in prompts.json\n const localFileRefs = Object.entries(config.prompts).filter(\n ([, dependency]) => {\n return typeof dependency === \"string\" && dependency.startsWith(\"file:\");\n },\n );\n\n if (localFileRefs.length > 0) {\n const pushSpinner = ora(\n `Pushing ${localFileRefs.length} local prompts...`,\n ).start();\n\n // Use the existing lock file instead of reloading it\n // const lock = FileManager.loadPromptsLock(); // Don't reload - use existing lock\n\n for (const [promptName, dependency] of localFileRefs) {\n try {\n const filePath = (dependency as string).slice(5); // Remove \"file:\" prefix\n\n // Load local prompt config\n const localConfig = FileManager.loadLocalPrompt(filePath);\n\n // Get current version from lock file\n const currentVersion = lock.prompts[promptName]?.version;\n\n // Convert local config to API configData format\n const configData: ConfigData = {\n model: localConfig.model,\n prompt: PromptConverter.extractSystemPrompt(localConfig.messages),\n messages: PromptConverter.filterNonSystemMessages(\n localConfig.messages,\n ) as Array<{\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n }>,\n temperature: localConfig.modelParameters?.temperature,\n max_tokens: localConfig.modelParameters?.max_tokens,\n inputs: [{ identifier: \"input\", type: \"str\" }],\n outputs: [{ identifier: \"output\", type: \"str\" }],\n };\n\n // Use new sync API with conflict detection\n const syncResult = await langwatch.prompts.sync({\n name: promptName,\n configData,\n localVersion: currentVersion,\n commitMessage: `Synced from local file: ${path.basename(filePath)}`,\n });\n\n const relativePath = path.relative(process.cwd(), filePath);\n\n let conflictResolution: \"local\" | \"remote\" | \"abort\" | null = null;\n if (syncResult.action === \"conflict\") {\n // Handle conflict - prompt user for resolution\n pushSpinner.stop();\n conflictResolution = await handleConflict(\n promptName,\n syncResult.conflictInfo!,\n );\n if (conflictResolution === \"abort\") {\n result.errors.push({\n name: promptName,\n error: \"Sync aborted due to conflict\",\n });\n continue;\n }\n\n // If user chose remote, we should pull the remote version to local file\n if (conflictResolution === \"remote\" && syncResult.conflictInfo) {\n // Update local file with remote content\n const remoteConfig = {\n model: syncResult.conflictInfo.remoteConfigData.model,\n modelParameters: {\n temperature:\n syncResult.conflictInfo.remoteConfigData.temperature,\n max_tokens:\n syncResult.conflictInfo.remoteConfigData.max_tokens,\n },\n messages: [\n {\n role: \"system\" as const,\n content: syncResult.conflictInfo.remoteConfigData.prompt,\n },\n ...(syncResult.conflictInfo.remoteConfigData.messages ?? []),\n ],\n };\n\n const yamlContent = yaml.dump(remoteConfig, {\n lineWidth: -1,\n noRefs: true,\n sortKeys: false,\n });\n\n fs.writeFileSync(filePath, yamlContent);\n }\n\n // If user chose to proceed, we continue with the sync\n pushSpinner.start();\n }\n\n // Update lock file with new version info\n if (syncResult.prompt) {\n lock.prompts[promptName] = {\n version: syncResult.prompt.version,\n versionId: syncResult.prompt.versionId,\n materialized: filePath,\n };\n } else if (syncResult.action === \"conflict\") {\n const remoteVersion = syncResult.conflictInfo?.remoteVersion ?? 0;\n if (conflictResolution === \"remote\") {\n // User chose remote - use remote version\n lock.prompts[promptName] = {\n version: remoteVersion,\n versionId: \"remote_version\", // We don't have the actual versionId from conflict info\n materialized: filePath,\n };\n } else {\n // User chose local - create new version (remote + 1)\n lock.prompts[promptName] = {\n version: remoteVersion + 1,\n versionId: \"conflict_resolved\", // Temporary until we get actual versionId\n materialized: filePath,\n };\n }\n }\n\n // Determine the action text based on sync result and conflict resolution\n let actionText: string;\n if (syncResult.action === \"conflict\") {\n if (conflictResolution === \"remote\") {\n actionText = \"Pulled\"; // User chose to use remote version\n result.fetched.push({\n name: promptName,\n version: syncResult.conflictInfo?.remoteVersion ?? 0,\n versionSpec: \"latest\", // Default for conflict resolution\n });\n } else {\n actionText = \"Pushed\"; // User chose to use local version (or forced push)\n result.pushed.push({\n name: promptName,\n version: (syncResult.conflictInfo?.remoteVersion ?? 0) + 1, // New version after push\n });\n }\n } else if (syncResult.action === \"up_to_date\") {\n // For up-to-date prompts, add to unchanged instead of pushed\n actionText = \"Up-to-date\";\n result.unchanged.push(promptName);\n } else {\n const actionMap: Record<SyncAction, string> = {\n created: \"Created\",\n updated: \"Updated\",\n conflict: \"Conflict resolved\",\n up_to_date: \"Up to date\",\n };\n actionText = actionMap[syncResult.action as SyncAction] || \"Pushed\";\n result.pushed.push({\n name: promptName,\n version: syncResult.prompt?.version ?? 0,\n });\n }\n\n pushSpinner.text = `${actionText} ${chalk.cyan(\n promptName,\n )} ${chalk.gray(\n `(version ${\n syncResult.prompt?.version ??\n syncResult.conflictInfo?.remoteVersion ??\n \"unknown\"\n })`,\n )} ${conflictResolution === \"remote\" ? \"to\" : \"from\"} ${chalk.gray(\n relativePath,\n )}`;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n result.errors.push({ name: promptName, error: errorMessage });\n }\n }\n\n // Save lock file with all updates\n FileManager.savePromptsLock(lock);\n\n pushSpinner.stop();\n }\n\n // Check for orphan local prompt files and show helpful warnings\n const discoveredLocalFiles = FileManager.getLocalPromptFiles();\n const orphanFiles = discoveredLocalFiles.filter((filePath) => {\n const promptName = FileManager.promptNameFromPath(filePath);\n return !config.prompts[promptName]; // Not declared in prompts.json\n });\n\n if (orphanFiles.length > 0) {\n console.log(\n chalk.yellow(\n `\\n⚠ Found ${orphanFiles.length} orphan prompt file${\n orphanFiles.length > 1 ? \"s\" : \"\"\n }:`,\n ),\n );\n\n for (const filePath of orphanFiles) {\n const promptName = FileManager.promptNameFromPath(filePath);\n const relativePath = path.relative(process.cwd(), filePath);\n\n console.log(chalk.yellow(` ${relativePath}`));\n console.log(\n chalk.gray(\n ` Add to prompts.json: \"${promptName}\": \"file:${relativePath}\"`,\n ),\n );\n }\n\n console.log(\n chalk.gray(\n `\\nTip: Add these to prompts.json to include them in sync operations.`,\n ),\n );\n }\n\n // Cleanup orphaned materialized files\n const currentDependencies = new Set(\n Object.keys(config.prompts).filter((name) => {\n const dependency = config.prompts[name];\n // Only include remote dependencies (not local file: dependencies)\n if (typeof dependency === \"object\" && dependency.file) {\n return false;\n }\n if (typeof dependency === \"string\" && dependency.startsWith(\"file:\")) {\n return false;\n }\n return true;\n }),\n );\n\n const cleanedFiles =\n FileManager.cleanupOrphanedMaterializedFiles(currentDependencies);\n if (cleanedFiles.length > 0) {\n result.cleaned = cleanedFiles;\n FileManager.removeFromLock(lock, cleanedFiles);\n }\n\n // Save the updated lock file\n FileManager.savePromptsLock(lock);\n\n // Print individual results if there were actions\n if (result.fetched.length > 0) {\n for (const { name, version, versionSpec } of result.fetched) {\n // Get the actual saved path from lock file for display consistency\n const lockEntry = lock.prompts[name];\n const displayPath = lockEntry?.materialized\n ? `./${lockEntry.materialized}`\n : `./prompts/.materialized/${name}.prompt.yaml`;\n\n console.log(\n chalk.green(\n `✓ Pulled ${chalk.cyan(`${name}@${versionSpec}`)} ${chalk.gray(\n `(version ${version})`,\n )} → ${chalk.gray(displayPath)}`,\n ),\n );\n }\n }\n\n if (result.pushed.length > 0) {\n for (const { name, version } of result.pushed) {\n const localPath = `./prompts/${name}.prompt.yaml`;\n console.log(\n chalk.green(\n `✓ Pushed ${chalk.cyan(name)} ${chalk.gray(`(version ${version})`)} from ${chalk.gray(localPath)}`,\n ),\n );\n }\n }\n\n // Print cleaned up files\n if (result.cleaned.length > 0) {\n for (const name of result.cleaned) {\n console.log(\n chalk.yellow(\n `✓ Cleaned ${chalk.cyan(name)} (no longer in dependencies)`,\n ),\n );\n }\n }\n\n // Print errors\n if (result.errors.length > 0) {\n for (const { name, error } of result.errors) {\n console.log(chalk.red(`✗ Failed ${chalk.cyan(name)}: ${error}`));\n }\n }\n\n // Print summary\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n const totalActions =\n result.fetched.length + result.pushed.length + result.cleaned.length;\n\n if (totalActions === 0 && result.errors.length === 0) {\n console.log(chalk.gray(`Synced in ${duration}s, no changes`));\n } else {\n const summary = [];\n if (result.fetched.length > 0)\n summary.push(`${result.fetched.length} fetched`);\n if (result.pushed.length > 0)\n summary.push(`${result.pushed.length} pushed`);\n if (result.cleaned.length > 0)\n summary.push(`${result.cleaned.length} cleaned`);\n if (result.errors.length > 0)\n summary.push(`${result.errors.length} errors`);\n\n console.log(chalk.gray(`Synced ${summary.join(\", \")} in ${duration}s`));\n }\n\n if (result.errors.length > 0) {\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":["resolve"]}
|
|
@@ -1,24 +1,27 @@
|
|
|
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
|
|
4
|
-
|
|
3
|
+
var _chunkF6E4XQQUjs = require('./chunk-F6E4XQQU.js');
|
|
5
4
|
|
|
6
|
-
var _chunk2JU376G7js = require('./chunk-2JU376G7.js');
|
|
7
5
|
|
|
6
|
+
var _chunk5EVBOHJYjs = require('./chunk-5EVBOHJY.js');
|
|
8
7
|
|
|
9
|
-
var _chunkF6E4XQQUjs = require('./chunk-F6E4XQQU.js');
|
|
10
|
-
require('./chunk-HA3LI5IK.js');
|
|
11
8
|
|
|
9
|
+
var _chunk4ZSSHX6Fjs = require('./chunk-4ZSSHX6F.js');
|
|
10
|
+
require('./chunk-YH5TIVK2.js');
|
|
11
|
+
require('./chunk-M4VUHTT2.js');
|
|
12
|
+
require('./chunk-OUCVXP4G.js');
|
|
13
|
+
require('./chunk-DISMHYXC.js');
|
|
12
14
|
|
|
13
15
|
|
|
14
|
-
var
|
|
16
|
+
var _chunkK64Y6YUGjs = require('./chunk-K64Y6YUG.js');
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
var
|
|
18
|
-
require('./chunk-PCQVQ7SB.js');
|
|
19
|
+
var _chunkD2CSG4SJjs = require('./chunk-D2CSG4SJ.js');
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
var
|
|
22
|
+
var _chunkSGNJDRCTjs = require('./chunk-SGNJDRCT.js');
|
|
23
|
+
require('./chunk-HA3LI5IK.js');
|
|
24
|
+
require('./chunk-OXBO24RB.js');
|
|
22
25
|
|
|
23
26
|
// src/cli/commands/sync.ts
|
|
24
27
|
var _fs = require('fs'); var fs = _interopRequireWildcard(_fs);
|
|
@@ -26,6 +29,7 @@ var _path = require('path'); var path = _interopRequireWildcard(_path);
|
|
|
26
29
|
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
27
30
|
var _ora = require('ora'); var _ora2 = _interopRequireDefault(_ora);
|
|
28
31
|
var _jsyaml = require('js-yaml'); var yaml = _interopRequireWildcard(_jsyaml);
|
|
32
|
+
var _readline = require('readline'); var _readline2 = _interopRequireDefault(_readline);
|
|
29
33
|
var handleConflict = async (promptName, conflictInfo) => {
|
|
30
34
|
console.log(
|
|
31
35
|
_chalk2.default.yellow(
|
|
@@ -48,8 +52,7 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
48
52
|
console.log(" [l] Use local version (overwrite remote)");
|
|
49
53
|
console.log(" [r] Use remote version (overwrite local)");
|
|
50
54
|
console.log(" [a] Abort sync for this prompt");
|
|
51
|
-
const
|
|
52
|
-
const rl = readline.createInterface({
|
|
55
|
+
const rl = _readline2.default.createInterface({
|
|
53
56
|
input: process.stdin,
|
|
54
57
|
output: process.stdout
|
|
55
58
|
});
|
|
@@ -68,14 +71,14 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
68
71
|
});
|
|
69
72
|
};
|
|
70
73
|
var syncCommand = async () => {
|
|
71
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
72
75
|
const startTime = Date.now();
|
|
73
76
|
try {
|
|
74
77
|
_chunkF6E4XQQUjs.checkApiKey.call(void 0, );
|
|
75
|
-
const
|
|
76
|
-
await
|
|
77
|
-
const config =
|
|
78
|
-
const lock =
|
|
78
|
+
const langwatch = new (0, _chunk5EVBOHJYjs.LangWatch)();
|
|
79
|
+
await _chunkK64Y6YUGjs.ensureProjectInitialized.call(void 0, false);
|
|
80
|
+
const config = _chunkD2CSG4SJjs.FileManager.loadPromptsConfig();
|
|
81
|
+
const lock = _chunkD2CSG4SJjs.FileManager.loadPromptsLock();
|
|
79
82
|
const result = {
|
|
80
83
|
fetched: [],
|
|
81
84
|
pushed: [],
|
|
@@ -100,14 +103,14 @@ var syncCommand = async () => {
|
|
|
100
103
|
).start();
|
|
101
104
|
for (const [name, dependency] of remoteDeps) {
|
|
102
105
|
try {
|
|
103
|
-
const versionSpec = typeof dependency === "string" ? dependency : dependency.version
|
|
106
|
+
const versionSpec = typeof dependency === "string" ? dependency : (_a = dependency.version) != null ? _a : "latest";
|
|
104
107
|
const lockEntry = lock.prompts[name];
|
|
105
|
-
const prompt = await
|
|
108
|
+
const prompt = await langwatch.prompts.get(name);
|
|
106
109
|
if (prompt) {
|
|
107
110
|
const needsUpdate = !lockEntry || lockEntry.version !== prompt.version || !lockEntry.materialized || !fs.existsSync(path.resolve(lockEntry.materialized));
|
|
108
111
|
if (needsUpdate) {
|
|
109
|
-
const materializedPrompt =
|
|
110
|
-
const savedPath =
|
|
112
|
+
const materializedPrompt = _chunkSGNJDRCTjs.PromptConverter.fromApiToMaterialized(prompt);
|
|
113
|
+
const savedPath = _chunkD2CSG4SJjs.FileManager.saveMaterializedPrompt(
|
|
111
114
|
name,
|
|
112
115
|
materializedPrompt
|
|
113
116
|
);
|
|
@@ -117,7 +120,7 @@ var syncCommand = async () => {
|
|
|
117
120
|
version: prompt.version,
|
|
118
121
|
versionSpec
|
|
119
122
|
});
|
|
120
|
-
|
|
123
|
+
_chunkD2CSG4SJjs.FileManager.updateLockEntry(
|
|
121
124
|
lock,
|
|
122
125
|
name,
|
|
123
126
|
materializedPrompt,
|
|
@@ -153,20 +156,20 @@ var syncCommand = async () => {
|
|
|
153
156
|
for (const [promptName, dependency] of localFileRefs) {
|
|
154
157
|
try {
|
|
155
158
|
const filePath = dependency.slice(5);
|
|
156
|
-
const localConfig =
|
|
157
|
-
const currentVersion = (
|
|
159
|
+
const localConfig = _chunkD2CSG4SJjs.FileManager.loadLocalPrompt(filePath);
|
|
160
|
+
const currentVersion = (_b = lock.prompts[promptName]) == null ? void 0 : _b.version;
|
|
158
161
|
const configData = {
|
|
159
162
|
model: localConfig.model,
|
|
160
|
-
prompt:
|
|
161
|
-
messages:
|
|
163
|
+
prompt: _chunkSGNJDRCTjs.PromptConverter.extractSystemPrompt(localConfig.messages),
|
|
164
|
+
messages: _chunkSGNJDRCTjs.PromptConverter.filterNonSystemMessages(
|
|
162
165
|
localConfig.messages
|
|
163
166
|
),
|
|
164
|
-
temperature: (
|
|
165
|
-
max_tokens: (
|
|
167
|
+
temperature: (_c = localConfig.modelParameters) == null ? void 0 : _c.temperature,
|
|
168
|
+
max_tokens: (_d = localConfig.modelParameters) == null ? void 0 : _d.max_tokens,
|
|
166
169
|
inputs: [{ identifier: "input", type: "str" }],
|
|
167
170
|
outputs: [{ identifier: "output", type: "str" }]
|
|
168
171
|
};
|
|
169
|
-
const syncResult = await
|
|
172
|
+
const syncResult = await langwatch.prompts.sync({
|
|
170
173
|
name: promptName,
|
|
171
174
|
configData,
|
|
172
175
|
localVersion: currentVersion,
|
|
@@ -199,7 +202,7 @@ var syncCommand = async () => {
|
|
|
199
202
|
role: "system",
|
|
200
203
|
content: syncResult.conflictInfo.remoteConfigData.prompt
|
|
201
204
|
},
|
|
202
|
-
...(
|
|
205
|
+
...(_e = syncResult.conflictInfo.remoteConfigData.messages) != null ? _e : []
|
|
203
206
|
]
|
|
204
207
|
};
|
|
205
208
|
const yamlContent = yaml.dump(remoteConfig, {
|
|
@@ -218,7 +221,7 @@ var syncCommand = async () => {
|
|
|
218
221
|
materialized: filePath
|
|
219
222
|
};
|
|
220
223
|
} else if (syncResult.action === "conflict") {
|
|
221
|
-
const remoteVersion = (
|
|
224
|
+
const remoteVersion = (_g = (_f = syncResult.conflictInfo) == null ? void 0 : _f.remoteVersion) != null ? _g : 0;
|
|
222
225
|
if (conflictResolution === "remote") {
|
|
223
226
|
lock.prompts[promptName] = {
|
|
224
227
|
version: remoteVersion,
|
|
@@ -241,7 +244,7 @@ var syncCommand = async () => {
|
|
|
241
244
|
actionText = "Pulled";
|
|
242
245
|
result.fetched.push({
|
|
243
246
|
name: promptName,
|
|
244
|
-
version: ((
|
|
247
|
+
version: (_i = (_h = syncResult.conflictInfo) == null ? void 0 : _h.remoteVersion) != null ? _i : 0,
|
|
245
248
|
versionSpec: "latest"
|
|
246
249
|
// Default for conflict resolution
|
|
247
250
|
});
|
|
@@ -249,7 +252,7 @@ var syncCommand = async () => {
|
|
|
249
252
|
actionText = "Pushed";
|
|
250
253
|
result.pushed.push({
|
|
251
254
|
name: promptName,
|
|
252
|
-
version: (((
|
|
255
|
+
version: ((_k = (_j = syncResult.conflictInfo) == null ? void 0 : _j.remoteVersion) != null ? _k : 0) + 1
|
|
253
256
|
// New version after push
|
|
254
257
|
});
|
|
255
258
|
}
|
|
@@ -257,19 +260,22 @@ var syncCommand = async () => {
|
|
|
257
260
|
actionText = "Up-to-date";
|
|
258
261
|
result.unchanged.push(promptName);
|
|
259
262
|
} else {
|
|
260
|
-
|
|
263
|
+
const actionMap = {
|
|
261
264
|
created: "Created",
|
|
262
|
-
updated: "Updated"
|
|
263
|
-
|
|
265
|
+
updated: "Updated",
|
|
266
|
+
conflict: "Conflict resolved",
|
|
267
|
+
up_to_date: "Up to date"
|
|
268
|
+
};
|
|
269
|
+
actionText = actionMap[syncResult.action] || "Pushed";
|
|
264
270
|
result.pushed.push({
|
|
265
271
|
name: promptName,
|
|
266
|
-
version: ((
|
|
272
|
+
version: (_m = (_l = syncResult.prompt) == null ? void 0 : _l.version) != null ? _m : 0
|
|
267
273
|
});
|
|
268
274
|
}
|
|
269
275
|
pushSpinner.text = `${actionText} ${_chalk2.default.cyan(
|
|
270
276
|
promptName
|
|
271
277
|
)} ${_chalk2.default.gray(
|
|
272
|
-
`(version ${((
|
|
278
|
+
`(version ${(_q = (_p = (_n = syncResult.prompt) == null ? void 0 : _n.version) != null ? _p : (_o = syncResult.conflictInfo) == null ? void 0 : _o.remoteVersion) != null ? _q : "unknown"})`
|
|
273
279
|
)} ${conflictResolution === "remote" ? "to" : "from"} ${_chalk2.default.gray(
|
|
274
280
|
relativePath
|
|
275
281
|
)}`;
|
|
@@ -278,12 +284,12 @@ var syncCommand = async () => {
|
|
|
278
284
|
result.errors.push({ name: promptName, error: errorMessage });
|
|
279
285
|
}
|
|
280
286
|
}
|
|
281
|
-
|
|
287
|
+
_chunkD2CSG4SJjs.FileManager.savePromptsLock(lock);
|
|
282
288
|
pushSpinner.stop();
|
|
283
289
|
}
|
|
284
|
-
const discoveredLocalFiles =
|
|
290
|
+
const discoveredLocalFiles = _chunkD2CSG4SJjs.FileManager.getLocalPromptFiles();
|
|
285
291
|
const orphanFiles = discoveredLocalFiles.filter((filePath) => {
|
|
286
|
-
const promptName =
|
|
292
|
+
const promptName = _chunkD2CSG4SJjs.FileManager.promptNameFromPath(filePath);
|
|
287
293
|
return !config.prompts[promptName];
|
|
288
294
|
});
|
|
289
295
|
if (orphanFiles.length > 0) {
|
|
@@ -294,7 +300,7 @@ var syncCommand = async () => {
|
|
|
294
300
|
)
|
|
295
301
|
);
|
|
296
302
|
for (const filePath of orphanFiles) {
|
|
297
|
-
const promptName =
|
|
303
|
+
const promptName = _chunkD2CSG4SJjs.FileManager.promptNameFromPath(filePath);
|
|
298
304
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
299
305
|
console.log(_chalk2.default.yellow(` ${relativePath}`));
|
|
300
306
|
console.log(
|
|
@@ -322,12 +328,12 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
322
328
|
return true;
|
|
323
329
|
})
|
|
324
330
|
);
|
|
325
|
-
const cleanedFiles =
|
|
331
|
+
const cleanedFiles = _chunkD2CSG4SJjs.FileManager.cleanupOrphanedMaterializedFiles(currentDependencies);
|
|
326
332
|
if (cleanedFiles.length > 0) {
|
|
327
333
|
result.cleaned = cleanedFiles;
|
|
328
|
-
|
|
334
|
+
_chunkD2CSG4SJjs.FileManager.removeFromLock(lock, cleanedFiles);
|
|
329
335
|
}
|
|
330
|
-
|
|
336
|
+
_chunkD2CSG4SJjs.FileManager.savePromptsLock(lock);
|
|
331
337
|
if (result.fetched.length > 0) {
|
|
332
338
|
for (const { name, version, versionSpec } of result.fetched) {
|
|
333
339
|
const lockEntry = lock.prompts[name];
|
|
@@ -385,7 +391,7 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
385
391
|
process.exit(1);
|
|
386
392
|
}
|
|
387
393
|
} catch (error) {
|
|
388
|
-
if (error instanceof
|
|
394
|
+
if (error instanceof _chunk4ZSSHX6Fjs.PromptsError) {
|
|
389
395
|
console.error(_chalk2.default.red(`Error: ${error.message}`));
|
|
390
396
|
} else {
|
|
391
397
|
console.error(
|
|
@@ -400,4 +406,4 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
400
406
|
|
|
401
407
|
|
|
402
408
|
exports.syncCommand = syncCommand;
|
|
403
|
-
//# sourceMappingURL=sync-
|
|
409
|
+
//# sourceMappingURL=sync-PSU3F5Z4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/langwatch/langwatch/typescript-sdk/dist/sync-PSU3F5Z4.js","../src/cli/commands/sync.ts"],"names":[],"mappings":"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","file":"/home/runner/work/langwatch/langwatch/typescript-sdk/dist/sync-PSU3F5Z4.js","sourcesContent":[null,"import * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport * as yaml from \"js-yaml\";\nimport { PromptConverter } from \"@/cli/utils/promptConverter\";\nimport { type ConfigData, PromptsError, type SyncAction } from \"@/client-sdk/services/prompts\";\nimport { LangWatch } from \"@/client-sdk\";\nimport type { SyncResult } from \"../types\";\nimport { FileManager } from \"../utils/fileManager\";\nimport { ensureProjectInitialized } from \"../utils/init\";\nimport { checkApiKey } from \"../utils/apiKey\";\nimport readline from \"node:readline\";\n\n// Handle conflict resolution - show diff and ask user to choose\nconst handleConflict = async (\n promptName: string,\n conflictInfo: {\n localVersion: number;\n remoteVersion: number;\n differences: string[];\n remoteConfigData: any;\n },\n): Promise<\"local\" | \"remote\" | \"abort\"> => {\n console.log(\n chalk.yellow(\n `\\n⚠ Conflict detected for prompt: ${chalk.cyan(promptName)}`,\n ),\n );\n console.log(\n chalk.gray(\n `Local version: ${conflictInfo.localVersion}, Remote version: ${conflictInfo.remoteVersion}`,\n ),\n );\n\n if (conflictInfo.differences.length > 0) {\n console.log(chalk.yellow(\"\\nDifferences:\"));\n conflictInfo.differences.forEach((diff) => {\n console.log(chalk.gray(` • ${diff}`));\n });\n }\n\n console.log(chalk.yellow(\"\\nOptions:\"));\n console.log(\" [l] Use local version (overwrite remote)\");\n console.log(\" [r] Use remote version (overwrite local)\");\n console.log(\" [a] Abort sync for this prompt\");\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(\"Choose resolution (l/r/a): \", (answer: string) => {\n rl.close();\n const choice = answer.toLowerCase();\n if (choice === \"l\" || choice === \"local\") {\n resolve(\"local\");\n } else if (choice === \"r\" || choice === \"remote\") {\n resolve(\"remote\");\n } else {\n resolve(\"abort\");\n }\n });\n });\n};\n\nexport const syncCommand = async (): Promise<void> => {\n const startTime = Date.now();\n\n try {\n // Check API key before doing anything else\n checkApiKey();\n\n // Get LangWatch client\n const langwatch = new LangWatch();\n\n // Ensure project is initialized (prompts.json, lock file, directories)\n await ensureProjectInitialized(false); // Don't prompt for .gitignore in sync\n\n // Load prompts config and lock\n const config = FileManager.loadPromptsConfig();\n const lock = FileManager.loadPromptsLock();\n\n const result: SyncResult = {\n fetched: [],\n pushed: [],\n unchanged: [],\n cleaned: [],\n errors: [],\n };\n\n // Process remote prompts (fetch and materialize)\n const remoteDeps = Object.entries(config.prompts).filter(\n ([, dependency]) => {\n // Skip local file dependencies (both object format and string format)\n if (typeof dependency === \"object\" && dependency.file) {\n return false;\n }\n if (typeof dependency === \"string\" && dependency.startsWith(\"file:\")) {\n return false;\n }\n return true;\n },\n );\n\n if (remoteDeps.length > 0) {\n const fetchSpinner = ora(\n `Checking ${remoteDeps.length} remote prompts...`,\n ).start();\n\n for (const [name, dependency] of remoteDeps) {\n try {\n const versionSpec =\n typeof dependency === \"string\"\n ? dependency\n : dependency.version ?? \"latest\";\n\n // Check if we already have this prompt with the same version\n const lockEntry = lock.prompts[name];\n\n // Fetch the prompt from the API to check current version\n const prompt = await langwatch.prompts.get(name);\n\n if (prompt) {\n // Check if we need to update (new version or not materialized)\n const needsUpdate =\n !lockEntry ||\n lockEntry.version !== prompt.version ||\n !lockEntry.materialized ||\n !fs.existsSync(path.resolve(lockEntry.materialized));\n\n if (needsUpdate) {\n // Convert to MaterializedPrompt format using the converter\n const materializedPrompt =\n PromptConverter.fromApiToMaterialized(prompt);\n\n const savedPath = FileManager.saveMaterializedPrompt(\n name,\n materializedPrompt,\n );\n const relativePath = path.relative(process.cwd(), savedPath);\n result.fetched.push({\n name,\n version: prompt.version,\n versionSpec,\n });\n\n // Update lock file entry\n FileManager.updateLockEntry(\n lock,\n name,\n materializedPrompt,\n savedPath,\n );\n\n fetchSpinner.text = `Fetched ${chalk.cyan(\n `${name}@${versionSpec}`,\n )} ${chalk.gray(`(version ${prompt.version})`)} → ${chalk.gray(\n relativePath,\n )}`;\n } else {\n // No change needed, track as unchanged\n result.unchanged.push(name);\n }\n } else {\n result.errors.push({ name, error: \"Prompt not found\" });\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n result.errors.push({ name, error: errorMessage });\n }\n }\n\n fetchSpinner.stop();\n }\n\n // Process local prompts (push to API) - only those explicitly declared in prompts.json\n const localFileRefs = Object.entries(config.prompts).filter(\n ([, dependency]) => {\n return typeof dependency === \"string\" && dependency.startsWith(\"file:\");\n },\n );\n\n if (localFileRefs.length > 0) {\n const pushSpinner = ora(\n `Pushing ${localFileRefs.length} local prompts...`,\n ).start();\n\n // Use the existing lock file instead of reloading it\n // const lock = FileManager.loadPromptsLock(); // Don't reload - use existing lock\n\n for (const [promptName, dependency] of localFileRefs) {\n try {\n const filePath = (dependency as string).slice(5); // Remove \"file:\" prefix\n\n // Load local prompt config\n const localConfig = FileManager.loadLocalPrompt(filePath);\n\n // Get current version from lock file\n const currentVersion = lock.prompts[promptName]?.version;\n\n // Convert local config to API configData format\n const configData: ConfigData = {\n model: localConfig.model,\n prompt: PromptConverter.extractSystemPrompt(localConfig.messages),\n messages: PromptConverter.filterNonSystemMessages(\n localConfig.messages,\n ) as Array<{\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n }>,\n temperature: localConfig.modelParameters?.temperature,\n max_tokens: localConfig.modelParameters?.max_tokens,\n inputs: [{ identifier: \"input\", type: \"str\" }],\n outputs: [{ identifier: \"output\", type: \"str\" }],\n };\n\n // Use new sync API with conflict detection\n const syncResult = await langwatch.prompts.sync({\n name: promptName,\n configData,\n localVersion: currentVersion,\n commitMessage: `Synced from local file: ${path.basename(filePath)}`,\n });\n\n const relativePath = path.relative(process.cwd(), filePath);\n\n let conflictResolution: \"local\" | \"remote\" | \"abort\" | null = null;\n if (syncResult.action === \"conflict\") {\n // Handle conflict - prompt user for resolution\n pushSpinner.stop();\n conflictResolution = await handleConflict(\n promptName,\n syncResult.conflictInfo!,\n );\n if (conflictResolution === \"abort\") {\n result.errors.push({\n name: promptName,\n error: \"Sync aborted due to conflict\",\n });\n continue;\n }\n\n // If user chose remote, we should pull the remote version to local file\n if (conflictResolution === \"remote\" && syncResult.conflictInfo) {\n // Update local file with remote content\n const remoteConfig = {\n model: syncResult.conflictInfo.remoteConfigData.model,\n modelParameters: {\n temperature:\n syncResult.conflictInfo.remoteConfigData.temperature,\n max_tokens:\n syncResult.conflictInfo.remoteConfigData.max_tokens,\n },\n messages: [\n {\n role: \"system\" as const,\n content: syncResult.conflictInfo.remoteConfigData.prompt,\n },\n ...(syncResult.conflictInfo.remoteConfigData.messages ?? []),\n ],\n };\n\n const yamlContent = yaml.dump(remoteConfig, {\n lineWidth: -1,\n noRefs: true,\n sortKeys: false,\n });\n\n fs.writeFileSync(filePath, yamlContent);\n }\n\n // If user chose to proceed, we continue with the sync\n pushSpinner.start();\n }\n\n // Update lock file with new version info\n if (syncResult.prompt) {\n lock.prompts[promptName] = {\n version: syncResult.prompt.version,\n versionId: syncResult.prompt.versionId,\n materialized: filePath,\n };\n } else if (syncResult.action === \"conflict\") {\n const remoteVersion = syncResult.conflictInfo?.remoteVersion ?? 0;\n if (conflictResolution === \"remote\") {\n // User chose remote - use remote version\n lock.prompts[promptName] = {\n version: remoteVersion,\n versionId: \"remote_version\", // We don't have the actual versionId from conflict info\n materialized: filePath,\n };\n } else {\n // User chose local - create new version (remote + 1)\n lock.prompts[promptName] = {\n version: remoteVersion + 1,\n versionId: \"conflict_resolved\", // Temporary until we get actual versionId\n materialized: filePath,\n };\n }\n }\n\n // Determine the action text based on sync result and conflict resolution\n let actionText: string;\n if (syncResult.action === \"conflict\") {\n if (conflictResolution === \"remote\") {\n actionText = \"Pulled\"; // User chose to use remote version\n result.fetched.push({\n name: promptName,\n version: syncResult.conflictInfo?.remoteVersion ?? 0,\n versionSpec: \"latest\", // Default for conflict resolution\n });\n } else {\n actionText = \"Pushed\"; // User chose to use local version (or forced push)\n result.pushed.push({\n name: promptName,\n version: (syncResult.conflictInfo?.remoteVersion ?? 0) + 1, // New version after push\n });\n }\n } else if (syncResult.action === \"up_to_date\") {\n // For up-to-date prompts, add to unchanged instead of pushed\n actionText = \"Up-to-date\";\n result.unchanged.push(promptName);\n } else {\n const actionMap: Record<SyncAction, string> = {\n created: \"Created\",\n updated: \"Updated\",\n conflict: \"Conflict resolved\",\n up_to_date: \"Up to date\",\n };\n actionText = actionMap[syncResult.action as SyncAction] || \"Pushed\";\n result.pushed.push({\n name: promptName,\n version: syncResult.prompt?.version ?? 0,\n });\n }\n\n pushSpinner.text = `${actionText} ${chalk.cyan(\n promptName,\n )} ${chalk.gray(\n `(version ${\n syncResult.prompt?.version ??\n syncResult.conflictInfo?.remoteVersion ??\n \"unknown\"\n })`,\n )} ${conflictResolution === \"remote\" ? \"to\" : \"from\"} ${chalk.gray(\n relativePath,\n )}`;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n result.errors.push({ name: promptName, error: errorMessage });\n }\n }\n\n // Save lock file with all updates\n FileManager.savePromptsLock(lock);\n\n pushSpinner.stop();\n }\n\n // Check for orphan local prompt files and show helpful warnings\n const discoveredLocalFiles = FileManager.getLocalPromptFiles();\n const orphanFiles = discoveredLocalFiles.filter((filePath) => {\n const promptName = FileManager.promptNameFromPath(filePath);\n return !config.prompts[promptName]; // Not declared in prompts.json\n });\n\n if (orphanFiles.length > 0) {\n console.log(\n chalk.yellow(\n `\\n⚠ Found ${orphanFiles.length} orphan prompt file${\n orphanFiles.length > 1 ? \"s\" : \"\"\n }:`,\n ),\n );\n\n for (const filePath of orphanFiles) {\n const promptName = FileManager.promptNameFromPath(filePath);\n const relativePath = path.relative(process.cwd(), filePath);\n\n console.log(chalk.yellow(` ${relativePath}`));\n console.log(\n chalk.gray(\n ` Add to prompts.json: \"${promptName}\": \"file:${relativePath}\"`,\n ),\n );\n }\n\n console.log(\n chalk.gray(\n `\\nTip: Add these to prompts.json to include them in sync operations.`,\n ),\n );\n }\n\n // Cleanup orphaned materialized files\n const currentDependencies = new Set(\n Object.keys(config.prompts).filter((name) => {\n const dependency = config.prompts[name];\n // Only include remote dependencies (not local file: dependencies)\n if (typeof dependency === \"object\" && dependency.file) {\n return false;\n }\n if (typeof dependency === \"string\" && dependency.startsWith(\"file:\")) {\n return false;\n }\n return true;\n }),\n );\n\n const cleanedFiles =\n FileManager.cleanupOrphanedMaterializedFiles(currentDependencies);\n if (cleanedFiles.length > 0) {\n result.cleaned = cleanedFiles;\n FileManager.removeFromLock(lock, cleanedFiles);\n }\n\n // Save the updated lock file\n FileManager.savePromptsLock(lock);\n\n // Print individual results if there were actions\n if (result.fetched.length > 0) {\n for (const { name, version, versionSpec } of result.fetched) {\n // Get the actual saved path from lock file for display consistency\n const lockEntry = lock.prompts[name];\n const displayPath = lockEntry?.materialized\n ? `./${lockEntry.materialized}`\n : `./prompts/.materialized/${name}.prompt.yaml`;\n\n console.log(\n chalk.green(\n `✓ Pulled ${chalk.cyan(`${name}@${versionSpec}`)} ${chalk.gray(\n `(version ${version})`,\n )} → ${chalk.gray(displayPath)}`,\n ),\n );\n }\n }\n\n if (result.pushed.length > 0) {\n for (const { name, version } of result.pushed) {\n const localPath = `./prompts/${name}.prompt.yaml`;\n console.log(\n chalk.green(\n `✓ Pushed ${chalk.cyan(name)} ${chalk.gray(`(version ${version})`)} from ${chalk.gray(localPath)}`,\n ),\n );\n }\n }\n\n // Print cleaned up files\n if (result.cleaned.length > 0) {\n for (const name of result.cleaned) {\n console.log(\n chalk.yellow(\n `✓ Cleaned ${chalk.cyan(name)} (no longer in dependencies)`,\n ),\n );\n }\n }\n\n // Print errors\n if (result.errors.length > 0) {\n for (const { name, error } of result.errors) {\n console.log(chalk.red(`✗ Failed ${chalk.cyan(name)}: ${error}`));\n }\n }\n\n // Print summary\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n const totalActions =\n result.fetched.length + result.pushed.length + result.cleaned.length;\n\n if (totalActions === 0 && result.errors.length === 0) {\n console.log(chalk.gray(`Synced in ${duration}s, no changes`));\n } else {\n const summary = [];\n if (result.fetched.length > 0)\n summary.push(`${result.fetched.length} fetched`);\n if (result.pushed.length > 0)\n summary.push(`${result.pushed.length} pushed`);\n if (result.cleaned.length > 0)\n summary.push(`${result.cleaned.length} cleaned`);\n if (result.errors.length > 0)\n summary.push(`${result.errors.length} errors`);\n\n console.log(chalk.gray(`Synced ${summary.join(\", \")} in ${duration}s`));\n }\n\n if (result.errors.length > 0) {\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"]}
|