langwatch 0.3.2 → 0.4.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/dist/{add-LBBS4I3H.js → add-RGWB3264.js} +35 -28
- package/dist/add-RGWB3264.js.map +1 -0
- package/dist/{add-RD3ZKFAT.mjs → add-WLUMK5VQ.mjs} +23 -16
- package/dist/add-WLUMK5VQ.mjs.map +1 -0
- package/dist/chunk-4ILMGMAP.mjs +155 -0
- package/dist/chunk-4ILMGMAP.mjs.map +1 -0
- package/dist/chunk-4TF2O2TH.js +207 -0
- package/dist/chunk-4TF2O2TH.js.map +1 -0
- package/dist/chunk-5N5BUR2Z.js +636 -0
- package/dist/chunk-5N5BUR2Z.js.map +1 -0
- package/dist/chunk-AZELEDOV.js +155 -0
- package/dist/chunk-AZELEDOV.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-DEVJ7BPE.js +63 -0
- package/dist/chunk-DEVJ7BPE.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-FQSWUK5N.mjs +63 -0
- package/dist/chunk-FQSWUK5N.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-IZ2U3ABC.mjs +636 -0
- package/dist/chunk-IZ2U3ABC.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-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-FJLK5CFL.js → chunk-OXBO24RB.js} +13 -8
- package/dist/chunk-OXBO24RB.js.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/chunk-ZJZ3MIWE.mjs +207 -0
- package/dist/chunk-ZJZ3MIWE.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 +17 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -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-ZXFLAF52.js → list-DBUK47MA.js} +30 -17
- package/dist/list-DBUK47MA.js.map +1 -0
- package/dist/{list-7NPSX2E4.mjs → list-ZOMRKOBV.mjs} +29 -16
- package/dist/list-ZOMRKOBV.mjs.map +1 -0
- package/dist/{login-76NQIHKR.js → login-A7LEPNBR.js} +8 -4
- package/dist/login-A7LEPNBR.js.map +1 -0
- package/dist/{login-EK4WVOI2.mjs → login-ULPHWIAX.mjs} +8 -4
- package/dist/login-ULPHWIAX.mjs.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 +42 -0
- package/dist/observability-sdk/index.js.map +1 -0
- package/dist/observability-sdk/index.mjs +42 -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 +279 -0
- package/dist/observability-sdk/setup/node/index.js.map +1 -0
- package/dist/observability-sdk/setup/node/index.mjs +279 -0
- package/dist/observability-sdk/setup/node/index.mjs.map +1 -0
- package/dist/{remove-XBNGIVMR.js → remove-ODTJLFWR.js} +19 -15
- package/dist/remove-ODTJLFWR.js.map +1 -0
- package/dist/{remove-SDJYEPAY.mjs → remove-RAJBGHQQ.mjs} +12 -8
- package/dist/remove-RAJBGHQQ.mjs.map +1 -0
- package/dist/{sync-ST2IWXSB.mjs → sync-2IXPWN64.mjs} +40 -33
- package/dist/sync-2IXPWN64.mjs.map +1 -0
- package/dist/{sync-EISKGPTL.js → sync-PBOL5ODF.js} +53 -46
- package/dist/sync-PBOL5ODF.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,28 @@
|
|
|
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-4ILMGMAP.mjs";
|
|
7
|
+
import {
|
|
13
8
|
PromptsError
|
|
14
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IZ2U3ABC.mjs";
|
|
10
|
+
import "./chunk-N2V6J3U2.mjs";
|
|
11
|
+
import "./chunk-EJWJXTPU.mjs";
|
|
12
|
+
import "./chunk-ZJZ3MIWE.mjs";
|
|
13
|
+
import "./chunk-FQSWUK5N.mjs";
|
|
14
|
+
import "./chunk-YNQ44U6D.mjs";
|
|
15
15
|
import {
|
|
16
|
-
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import
|
|
16
|
+
ensureProjectInitialized
|
|
17
|
+
} from "./chunk-ECUXLXFT.mjs";
|
|
18
|
+
import {
|
|
19
|
+
FileManager
|
|
20
|
+
} from "./chunk-HUI45ULC.mjs";
|
|
19
21
|
import {
|
|
20
|
-
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
PromptConverter
|
|
23
|
+
} from "./chunk-SYMZPWZE.mjs";
|
|
24
|
+
import "./chunk-4NRLVT2U.mjs";
|
|
25
|
+
import "./chunk-CU3443HD.mjs";
|
|
22
26
|
|
|
23
27
|
// src/cli/commands/sync.ts
|
|
24
28
|
import * as fs from "fs";
|
|
@@ -26,6 +30,7 @@ import * as path from "path";
|
|
|
26
30
|
import chalk from "chalk";
|
|
27
31
|
import ora from "ora";
|
|
28
32
|
import * as yaml from "js-yaml";
|
|
33
|
+
import readline from "readline";
|
|
29
34
|
var handleConflict = async (promptName, conflictInfo) => {
|
|
30
35
|
console.log(
|
|
31
36
|
chalk.yellow(
|
|
@@ -48,7 +53,6 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
48
53
|
console.log(" [l] Use local version (overwrite remote)");
|
|
49
54
|
console.log(" [r] Use remote version (overwrite local)");
|
|
50
55
|
console.log(" [a] Abort sync for this prompt");
|
|
51
|
-
const readline = __require("readline");
|
|
52
56
|
const rl = readline.createInterface({
|
|
53
57
|
input: process.stdin,
|
|
54
58
|
output: process.stdout
|
|
@@ -68,11 +72,11 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
68
72
|
});
|
|
69
73
|
};
|
|
70
74
|
var syncCommand = async () => {
|
|
71
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
75
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
72
76
|
const startTime = Date.now();
|
|
73
77
|
try {
|
|
74
78
|
checkApiKey();
|
|
75
|
-
const
|
|
79
|
+
const langwatch = new LangWatch();
|
|
76
80
|
await ensureProjectInitialized(false);
|
|
77
81
|
const config = FileManager.loadPromptsConfig();
|
|
78
82
|
const lock = FileManager.loadPromptsLock();
|
|
@@ -100,9 +104,9 @@ var syncCommand = async () => {
|
|
|
100
104
|
).start();
|
|
101
105
|
for (const [name, dependency] of remoteDeps) {
|
|
102
106
|
try {
|
|
103
|
-
const versionSpec = typeof dependency === "string" ? dependency : dependency.version
|
|
107
|
+
const versionSpec = typeof dependency === "string" ? dependency : (_a = dependency.version) != null ? _a : "latest";
|
|
104
108
|
const lockEntry = lock.prompts[name];
|
|
105
|
-
const prompt = await
|
|
109
|
+
const prompt = await langwatch.prompts.get(name);
|
|
106
110
|
if (prompt) {
|
|
107
111
|
const needsUpdate = !lockEntry || lockEntry.version !== prompt.version || !lockEntry.materialized || !fs.existsSync(path.resolve(lockEntry.materialized));
|
|
108
112
|
if (needsUpdate) {
|
|
@@ -154,19 +158,19 @@ var syncCommand = async () => {
|
|
|
154
158
|
try {
|
|
155
159
|
const filePath = dependency.slice(5);
|
|
156
160
|
const localConfig = FileManager.loadLocalPrompt(filePath);
|
|
157
|
-
const currentVersion = (
|
|
161
|
+
const currentVersion = (_b = lock.prompts[promptName]) == null ? void 0 : _b.version;
|
|
158
162
|
const configData = {
|
|
159
163
|
model: localConfig.model,
|
|
160
164
|
prompt: PromptConverter.extractSystemPrompt(localConfig.messages),
|
|
161
165
|
messages: PromptConverter.filterNonSystemMessages(
|
|
162
166
|
localConfig.messages
|
|
163
167
|
),
|
|
164
|
-
temperature: (
|
|
165
|
-
max_tokens: (
|
|
168
|
+
temperature: (_c = localConfig.modelParameters) == null ? void 0 : _c.temperature,
|
|
169
|
+
max_tokens: (_d = localConfig.modelParameters) == null ? void 0 : _d.max_tokens,
|
|
166
170
|
inputs: [{ identifier: "input", type: "str" }],
|
|
167
171
|
outputs: [{ identifier: "output", type: "str" }]
|
|
168
172
|
};
|
|
169
|
-
const syncResult = await
|
|
173
|
+
const syncResult = await langwatch.prompts.sync({
|
|
170
174
|
name: promptName,
|
|
171
175
|
configData,
|
|
172
176
|
localVersion: currentVersion,
|
|
@@ -199,7 +203,7 @@ var syncCommand = async () => {
|
|
|
199
203
|
role: "system",
|
|
200
204
|
content: syncResult.conflictInfo.remoteConfigData.prompt
|
|
201
205
|
},
|
|
202
|
-
...(
|
|
206
|
+
...(_e = syncResult.conflictInfo.remoteConfigData.messages) != null ? _e : []
|
|
203
207
|
]
|
|
204
208
|
};
|
|
205
209
|
const yamlContent = yaml.dump(remoteConfig, {
|
|
@@ -218,7 +222,7 @@ var syncCommand = async () => {
|
|
|
218
222
|
materialized: filePath
|
|
219
223
|
};
|
|
220
224
|
} else if (syncResult.action === "conflict") {
|
|
221
|
-
const remoteVersion = (
|
|
225
|
+
const remoteVersion = (_g = (_f = syncResult.conflictInfo) == null ? void 0 : _f.remoteVersion) != null ? _g : 0;
|
|
222
226
|
if (conflictResolution === "remote") {
|
|
223
227
|
lock.prompts[promptName] = {
|
|
224
228
|
version: remoteVersion,
|
|
@@ -241,7 +245,7 @@ var syncCommand = async () => {
|
|
|
241
245
|
actionText = "Pulled";
|
|
242
246
|
result.fetched.push({
|
|
243
247
|
name: promptName,
|
|
244
|
-
version: ((
|
|
248
|
+
version: (_i = (_h = syncResult.conflictInfo) == null ? void 0 : _h.remoteVersion) != null ? _i : 0,
|
|
245
249
|
versionSpec: "latest"
|
|
246
250
|
// Default for conflict resolution
|
|
247
251
|
});
|
|
@@ -249,7 +253,7 @@ var syncCommand = async () => {
|
|
|
249
253
|
actionText = "Pushed";
|
|
250
254
|
result.pushed.push({
|
|
251
255
|
name: promptName,
|
|
252
|
-
version: (((
|
|
256
|
+
version: ((_k = (_j = syncResult.conflictInfo) == null ? void 0 : _j.remoteVersion) != null ? _k : 0) + 1
|
|
253
257
|
// New version after push
|
|
254
258
|
});
|
|
255
259
|
}
|
|
@@ -257,19 +261,22 @@ var syncCommand = async () => {
|
|
|
257
261
|
actionText = "Up-to-date";
|
|
258
262
|
result.unchanged.push(promptName);
|
|
259
263
|
} else {
|
|
260
|
-
|
|
264
|
+
const actionMap = {
|
|
261
265
|
created: "Created",
|
|
262
|
-
updated: "Updated"
|
|
263
|
-
|
|
266
|
+
updated: "Updated",
|
|
267
|
+
conflict: "Conflict resolved",
|
|
268
|
+
up_to_date: "Up to date"
|
|
269
|
+
};
|
|
270
|
+
actionText = actionMap[syncResult.action] || "Pushed";
|
|
264
271
|
result.pushed.push({
|
|
265
272
|
name: promptName,
|
|
266
|
-
version: ((
|
|
273
|
+
version: (_m = (_l = syncResult.prompt) == null ? void 0 : _l.version) != null ? _m : 0
|
|
267
274
|
});
|
|
268
275
|
}
|
|
269
276
|
pushSpinner.text = `${actionText} ${chalk.cyan(
|
|
270
277
|
promptName
|
|
271
278
|
)} ${chalk.gray(
|
|
272
|
-
`(version ${((
|
|
279
|
+
`(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
280
|
)} ${conflictResolution === "remote" ? "to" : "from"} ${chalk.gray(
|
|
274
281
|
relativePath
|
|
275
282
|
)}`;
|
|
@@ -400,4 +407,4 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
400
407
|
export {
|
|
401
408
|
syncCommand
|
|
402
409
|
};
|
|
403
|
-
//# sourceMappingURL=sync-
|
|
410
|
+
//# sourceMappingURL=sync-2IXPWN64.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,28 @@
|
|
|
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 _chunkAZELEDOVjs = require('./chunk-AZELEDOV.js');
|
|
8
7
|
|
|
9
|
-
var _chunkF6E4XQQUjs = require('./chunk-F6E4XQQU.js');
|
|
10
|
-
require('./chunk-HA3LI5IK.js');
|
|
11
8
|
|
|
9
|
+
var _chunk5N5BUR2Zjs = require('./chunk-5N5BUR2Z.js');
|
|
10
|
+
require('./chunk-YH5TIVK2.js');
|
|
11
|
+
require('./chunk-M4VUHTT2.js');
|
|
12
|
+
require('./chunk-4TF2O2TH.js');
|
|
13
|
+
require('./chunk-DEVJ7BPE.js');
|
|
14
|
+
require('./chunk-DISMHYXC.js');
|
|
12
15
|
|
|
13
16
|
|
|
14
|
-
var
|
|
17
|
+
var _chunkK64Y6YUGjs = require('./chunk-K64Y6YUG.js');
|
|
15
18
|
|
|
16
19
|
|
|
17
|
-
var
|
|
18
|
-
require('./chunk-PCQVQ7SB.js');
|
|
20
|
+
var _chunkD2CSG4SJjs = require('./chunk-D2CSG4SJ.js');
|
|
19
21
|
|
|
20
22
|
|
|
21
|
-
var
|
|
23
|
+
var _chunkSGNJDRCTjs = require('./chunk-SGNJDRCT.js');
|
|
24
|
+
require('./chunk-HA3LI5IK.js');
|
|
25
|
+
require('./chunk-OXBO24RB.js');
|
|
22
26
|
|
|
23
27
|
// src/cli/commands/sync.ts
|
|
24
28
|
var _fs = require('fs'); var fs = _interopRequireWildcard(_fs);
|
|
@@ -26,6 +30,7 @@ var _path = require('path'); var path = _interopRequireWildcard(_path);
|
|
|
26
30
|
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
27
31
|
var _ora = require('ora'); var _ora2 = _interopRequireDefault(_ora);
|
|
28
32
|
var _jsyaml = require('js-yaml'); var yaml = _interopRequireWildcard(_jsyaml);
|
|
33
|
+
var _readline = require('readline'); var _readline2 = _interopRequireDefault(_readline);
|
|
29
34
|
var handleConflict = async (promptName, conflictInfo) => {
|
|
30
35
|
console.log(
|
|
31
36
|
_chalk2.default.yellow(
|
|
@@ -48,8 +53,7 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
48
53
|
console.log(" [l] Use local version (overwrite remote)");
|
|
49
54
|
console.log(" [r] Use remote version (overwrite local)");
|
|
50
55
|
console.log(" [a] Abort sync for this prompt");
|
|
51
|
-
const
|
|
52
|
-
const rl = readline.createInterface({
|
|
56
|
+
const rl = _readline2.default.createInterface({
|
|
53
57
|
input: process.stdin,
|
|
54
58
|
output: process.stdout
|
|
55
59
|
});
|
|
@@ -68,14 +72,14 @@ var handleConflict = async (promptName, conflictInfo) => {
|
|
|
68
72
|
});
|
|
69
73
|
};
|
|
70
74
|
var syncCommand = async () => {
|
|
71
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
75
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
72
76
|
const startTime = Date.now();
|
|
73
77
|
try {
|
|
74
78
|
_chunkF6E4XQQUjs.checkApiKey.call(void 0, );
|
|
75
|
-
const
|
|
76
|
-
await
|
|
77
|
-
const config =
|
|
78
|
-
const lock =
|
|
79
|
+
const langwatch = new (0, _chunkAZELEDOVjs.LangWatch)();
|
|
80
|
+
await _chunkK64Y6YUGjs.ensureProjectInitialized.call(void 0, false);
|
|
81
|
+
const config = _chunkD2CSG4SJjs.FileManager.loadPromptsConfig();
|
|
82
|
+
const lock = _chunkD2CSG4SJjs.FileManager.loadPromptsLock();
|
|
79
83
|
const result = {
|
|
80
84
|
fetched: [],
|
|
81
85
|
pushed: [],
|
|
@@ -100,14 +104,14 @@ var syncCommand = async () => {
|
|
|
100
104
|
).start();
|
|
101
105
|
for (const [name, dependency] of remoteDeps) {
|
|
102
106
|
try {
|
|
103
|
-
const versionSpec = typeof dependency === "string" ? dependency : dependency.version
|
|
107
|
+
const versionSpec = typeof dependency === "string" ? dependency : (_a = dependency.version) != null ? _a : "latest";
|
|
104
108
|
const lockEntry = lock.prompts[name];
|
|
105
|
-
const prompt = await
|
|
109
|
+
const prompt = await langwatch.prompts.get(name);
|
|
106
110
|
if (prompt) {
|
|
107
111
|
const needsUpdate = !lockEntry || lockEntry.version !== prompt.version || !lockEntry.materialized || !fs.existsSync(path.resolve(lockEntry.materialized));
|
|
108
112
|
if (needsUpdate) {
|
|
109
|
-
const materializedPrompt =
|
|
110
|
-
const savedPath =
|
|
113
|
+
const materializedPrompt = _chunkSGNJDRCTjs.PromptConverter.fromApiToMaterialized(prompt);
|
|
114
|
+
const savedPath = _chunkD2CSG4SJjs.FileManager.saveMaterializedPrompt(
|
|
111
115
|
name,
|
|
112
116
|
materializedPrompt
|
|
113
117
|
);
|
|
@@ -117,7 +121,7 @@ var syncCommand = async () => {
|
|
|
117
121
|
version: prompt.version,
|
|
118
122
|
versionSpec
|
|
119
123
|
});
|
|
120
|
-
|
|
124
|
+
_chunkD2CSG4SJjs.FileManager.updateLockEntry(
|
|
121
125
|
lock,
|
|
122
126
|
name,
|
|
123
127
|
materializedPrompt,
|
|
@@ -153,20 +157,20 @@ var syncCommand = async () => {
|
|
|
153
157
|
for (const [promptName, dependency] of localFileRefs) {
|
|
154
158
|
try {
|
|
155
159
|
const filePath = dependency.slice(5);
|
|
156
|
-
const localConfig =
|
|
157
|
-
const currentVersion = (
|
|
160
|
+
const localConfig = _chunkD2CSG4SJjs.FileManager.loadLocalPrompt(filePath);
|
|
161
|
+
const currentVersion = (_b = lock.prompts[promptName]) == null ? void 0 : _b.version;
|
|
158
162
|
const configData = {
|
|
159
163
|
model: localConfig.model,
|
|
160
|
-
prompt:
|
|
161
|
-
messages:
|
|
164
|
+
prompt: _chunkSGNJDRCTjs.PromptConverter.extractSystemPrompt(localConfig.messages),
|
|
165
|
+
messages: _chunkSGNJDRCTjs.PromptConverter.filterNonSystemMessages(
|
|
162
166
|
localConfig.messages
|
|
163
167
|
),
|
|
164
|
-
temperature: (
|
|
165
|
-
max_tokens: (
|
|
168
|
+
temperature: (_c = localConfig.modelParameters) == null ? void 0 : _c.temperature,
|
|
169
|
+
max_tokens: (_d = localConfig.modelParameters) == null ? void 0 : _d.max_tokens,
|
|
166
170
|
inputs: [{ identifier: "input", type: "str" }],
|
|
167
171
|
outputs: [{ identifier: "output", type: "str" }]
|
|
168
172
|
};
|
|
169
|
-
const syncResult = await
|
|
173
|
+
const syncResult = await langwatch.prompts.sync({
|
|
170
174
|
name: promptName,
|
|
171
175
|
configData,
|
|
172
176
|
localVersion: currentVersion,
|
|
@@ -199,7 +203,7 @@ var syncCommand = async () => {
|
|
|
199
203
|
role: "system",
|
|
200
204
|
content: syncResult.conflictInfo.remoteConfigData.prompt
|
|
201
205
|
},
|
|
202
|
-
...(
|
|
206
|
+
...(_e = syncResult.conflictInfo.remoteConfigData.messages) != null ? _e : []
|
|
203
207
|
]
|
|
204
208
|
};
|
|
205
209
|
const yamlContent = yaml.dump(remoteConfig, {
|
|
@@ -218,7 +222,7 @@ var syncCommand = async () => {
|
|
|
218
222
|
materialized: filePath
|
|
219
223
|
};
|
|
220
224
|
} else if (syncResult.action === "conflict") {
|
|
221
|
-
const remoteVersion = (
|
|
225
|
+
const remoteVersion = (_g = (_f = syncResult.conflictInfo) == null ? void 0 : _f.remoteVersion) != null ? _g : 0;
|
|
222
226
|
if (conflictResolution === "remote") {
|
|
223
227
|
lock.prompts[promptName] = {
|
|
224
228
|
version: remoteVersion,
|
|
@@ -241,7 +245,7 @@ var syncCommand = async () => {
|
|
|
241
245
|
actionText = "Pulled";
|
|
242
246
|
result.fetched.push({
|
|
243
247
|
name: promptName,
|
|
244
|
-
version: ((
|
|
248
|
+
version: (_i = (_h = syncResult.conflictInfo) == null ? void 0 : _h.remoteVersion) != null ? _i : 0,
|
|
245
249
|
versionSpec: "latest"
|
|
246
250
|
// Default for conflict resolution
|
|
247
251
|
});
|
|
@@ -249,7 +253,7 @@ var syncCommand = async () => {
|
|
|
249
253
|
actionText = "Pushed";
|
|
250
254
|
result.pushed.push({
|
|
251
255
|
name: promptName,
|
|
252
|
-
version: (((
|
|
256
|
+
version: ((_k = (_j = syncResult.conflictInfo) == null ? void 0 : _j.remoteVersion) != null ? _k : 0) + 1
|
|
253
257
|
// New version after push
|
|
254
258
|
});
|
|
255
259
|
}
|
|
@@ -257,19 +261,22 @@ var syncCommand = async () => {
|
|
|
257
261
|
actionText = "Up-to-date";
|
|
258
262
|
result.unchanged.push(promptName);
|
|
259
263
|
} else {
|
|
260
|
-
|
|
264
|
+
const actionMap = {
|
|
261
265
|
created: "Created",
|
|
262
|
-
updated: "Updated"
|
|
263
|
-
|
|
266
|
+
updated: "Updated",
|
|
267
|
+
conflict: "Conflict resolved",
|
|
268
|
+
up_to_date: "Up to date"
|
|
269
|
+
};
|
|
270
|
+
actionText = actionMap[syncResult.action] || "Pushed";
|
|
264
271
|
result.pushed.push({
|
|
265
272
|
name: promptName,
|
|
266
|
-
version: ((
|
|
273
|
+
version: (_m = (_l = syncResult.prompt) == null ? void 0 : _l.version) != null ? _m : 0
|
|
267
274
|
});
|
|
268
275
|
}
|
|
269
276
|
pushSpinner.text = `${actionText} ${_chalk2.default.cyan(
|
|
270
277
|
promptName
|
|
271
278
|
)} ${_chalk2.default.gray(
|
|
272
|
-
`(version ${((
|
|
279
|
+
`(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
280
|
)} ${conflictResolution === "remote" ? "to" : "from"} ${_chalk2.default.gray(
|
|
274
281
|
relativePath
|
|
275
282
|
)}`;
|
|
@@ -278,12 +285,12 @@ var syncCommand = async () => {
|
|
|
278
285
|
result.errors.push({ name: promptName, error: errorMessage });
|
|
279
286
|
}
|
|
280
287
|
}
|
|
281
|
-
|
|
288
|
+
_chunkD2CSG4SJjs.FileManager.savePromptsLock(lock);
|
|
282
289
|
pushSpinner.stop();
|
|
283
290
|
}
|
|
284
|
-
const discoveredLocalFiles =
|
|
291
|
+
const discoveredLocalFiles = _chunkD2CSG4SJjs.FileManager.getLocalPromptFiles();
|
|
285
292
|
const orphanFiles = discoveredLocalFiles.filter((filePath) => {
|
|
286
|
-
const promptName =
|
|
293
|
+
const promptName = _chunkD2CSG4SJjs.FileManager.promptNameFromPath(filePath);
|
|
287
294
|
return !config.prompts[promptName];
|
|
288
295
|
});
|
|
289
296
|
if (orphanFiles.length > 0) {
|
|
@@ -294,7 +301,7 @@ var syncCommand = async () => {
|
|
|
294
301
|
)
|
|
295
302
|
);
|
|
296
303
|
for (const filePath of orphanFiles) {
|
|
297
|
-
const promptName =
|
|
304
|
+
const promptName = _chunkD2CSG4SJjs.FileManager.promptNameFromPath(filePath);
|
|
298
305
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
299
306
|
console.log(_chalk2.default.yellow(` ${relativePath}`));
|
|
300
307
|
console.log(
|
|
@@ -322,12 +329,12 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
322
329
|
return true;
|
|
323
330
|
})
|
|
324
331
|
);
|
|
325
|
-
const cleanedFiles =
|
|
332
|
+
const cleanedFiles = _chunkD2CSG4SJjs.FileManager.cleanupOrphanedMaterializedFiles(currentDependencies);
|
|
326
333
|
if (cleanedFiles.length > 0) {
|
|
327
334
|
result.cleaned = cleanedFiles;
|
|
328
|
-
|
|
335
|
+
_chunkD2CSG4SJjs.FileManager.removeFromLock(lock, cleanedFiles);
|
|
329
336
|
}
|
|
330
|
-
|
|
337
|
+
_chunkD2CSG4SJjs.FileManager.savePromptsLock(lock);
|
|
331
338
|
if (result.fetched.length > 0) {
|
|
332
339
|
for (const { name, version, versionSpec } of result.fetched) {
|
|
333
340
|
const lockEntry = lock.prompts[name];
|
|
@@ -385,7 +392,7 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
385
392
|
process.exit(1);
|
|
386
393
|
}
|
|
387
394
|
} catch (error) {
|
|
388
|
-
if (error instanceof
|
|
395
|
+
if (error instanceof _chunk5N5BUR2Zjs.PromptsError) {
|
|
389
396
|
console.error(_chalk2.default.red(`Error: ${error.message}`));
|
|
390
397
|
} else {
|
|
391
398
|
console.error(
|
|
@@ -400,4 +407,4 @@ Tip: Add these to prompts.json to include them in sync operations.`
|
|
|
400
407
|
|
|
401
408
|
|
|
402
409
|
exports.syncCommand = syncCommand;
|
|
403
|
-
//# sourceMappingURL=sync-
|
|
410
|
+
//# sourceMappingURL=sync-PBOL5ODF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/langwatch/langwatch/typescript-sdk/dist/sync-PBOL5ODF.js","../src/cli/commands/sync.ts"],"names":[],"mappings":"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","file":"/home/runner/work/langwatch/langwatch/typescript-sdk/dist/sync-PBOL5ODF.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"]}
|