@wayai/cli 0.3.47 → 0.3.49
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/index.js +258 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -343,6 +343,16 @@ var init_api_client = __esm({
|
|
|
343
343
|
if (opts?.limit) params.set("limit", String(opts.limit));
|
|
344
344
|
return this.request("GET", `/api/evals/sessions/${sessionId}/runs?${params.toString()}`);
|
|
345
345
|
}
|
|
346
|
+
/** Delete a single eval session (cascades runs/results/conversations server-side). */
|
|
347
|
+
async deleteEvalSession(hubId, sessionId) {
|
|
348
|
+
const params = new URLSearchParams({ hub_id: hubId });
|
|
349
|
+
return this.request("DELETE", `/api/evals/sessions/${sessionId}?${params.toString()}`);
|
|
350
|
+
}
|
|
351
|
+
/** Delete ALL eval sessions for a hub (each cascades server-side). */
|
|
352
|
+
async deleteAllEvalSessions(hubId) {
|
|
353
|
+
const params = new URLSearchParams({ hub_id: hubId });
|
|
354
|
+
return this.request("DELETE", `/api/evals/sessions?${params.toString()}`);
|
|
355
|
+
}
|
|
346
356
|
async listScenarioSets(hubId) {
|
|
347
357
|
const params = new URLSearchParams({ hub_id: hubId });
|
|
348
358
|
return this.request("GET", `/api/evals/scenario-sets?${params.toString()}`);
|
|
@@ -5031,6 +5041,22 @@ function slugifyKebab(input, maxLength = 64) {
|
|
|
5031
5041
|
if (typeof input !== "string") return "";
|
|
5032
5042
|
return foldDiacritics(input).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").slice(0, maxLength).replace(/^-|-$/g, "");
|
|
5033
5043
|
}
|
|
5044
|
+
function ensureUniqueSlug(slug, used) {
|
|
5045
|
+
if (!used.has(slug)) {
|
|
5046
|
+
used.add(slug);
|
|
5047
|
+
return slug;
|
|
5048
|
+
}
|
|
5049
|
+
for (let i = 2; i < 1e6; i++) {
|
|
5050
|
+
const suffix = `_${i}`;
|
|
5051
|
+
const baseLen = Math.max(1, 50 - suffix.length);
|
|
5052
|
+
const candidate = `${slug.slice(0, baseLen)}${suffix}`;
|
|
5053
|
+
if (!used.has(candidate)) {
|
|
5054
|
+
used.add(candidate);
|
|
5055
|
+
return candidate;
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
5058
|
+
throw new Error(`slug collision space exhausted for "${slug}"`);
|
|
5059
|
+
}
|
|
5034
5060
|
function slugifySkillName(name) {
|
|
5035
5061
|
return slugifyKebab(name, 64);
|
|
5036
5062
|
}
|
|
@@ -9508,6 +9534,7 @@ function writeHubFolder(hubFolder, payload) {
|
|
|
9508
9534
|
}
|
|
9509
9535
|
writeResourceFiles(hubFolder, payload.resources || []);
|
|
9510
9536
|
writeEvalYamlFiles(hubFolder, payload.evals || []);
|
|
9537
|
+
writeJourneyYamlFiles(hubFolder, payload.journeys || []);
|
|
9511
9538
|
}
|
|
9512
9539
|
function buildYamlPayload(payload) {
|
|
9513
9540
|
const result = {
|
|
@@ -9634,6 +9661,60 @@ function cleanEvalOrphans(evalsDir, writtenRelPaths) {
|
|
|
9634
9661
|
}
|
|
9635
9662
|
}
|
|
9636
9663
|
}
|
|
9664
|
+
function buildJourneyYamlObject(journeyEntry, slug) {
|
|
9665
|
+
const out = {};
|
|
9666
|
+
if (journeyEntry.id) out.id = journeyEntry.id;
|
|
9667
|
+
if (journeyEntry.name !== slug) out.name = journeyEntry.name;
|
|
9668
|
+
out.agent = journeyEntry.agent;
|
|
9669
|
+
if (journeyEntry.agent_id) out.agent_id = journeyEntry.agent_id;
|
|
9670
|
+
if (journeyEntry.enabled === false) {
|
|
9671
|
+
out.enabled = false;
|
|
9672
|
+
}
|
|
9673
|
+
if (journeyEntry.evaluator_instructions) {
|
|
9674
|
+
out.evaluator_instructions = journeyEntry.evaluator_instructions;
|
|
9675
|
+
}
|
|
9676
|
+
if (journeyEntry.transcript && journeyEntry.transcript.length > 0) {
|
|
9677
|
+
out.transcript = journeyEntry.transcript;
|
|
9678
|
+
}
|
|
9679
|
+
if (journeyEntry.step_config && Object.keys(journeyEntry.step_config).length > 0) {
|
|
9680
|
+
out.step_config = journeyEntry.step_config;
|
|
9681
|
+
}
|
|
9682
|
+
return out;
|
|
9683
|
+
}
|
|
9684
|
+
function writeJourneyYamlFiles(hubFolder, journeys) {
|
|
9685
|
+
const journeysDir = path11.join(hubFolder, "journeys");
|
|
9686
|
+
if (journeys.length === 0) {
|
|
9687
|
+
if (fs9.existsSync(journeysDir)) {
|
|
9688
|
+
cleanJourneyOrphans(journeysDir, /* @__PURE__ */ new Set());
|
|
9689
|
+
try {
|
|
9690
|
+
if (fs9.readdirSync(journeysDir).length === 0) fs9.rmdirSync(journeysDir);
|
|
9691
|
+
} catch {
|
|
9692
|
+
}
|
|
9693
|
+
}
|
|
9694
|
+
return;
|
|
9695
|
+
}
|
|
9696
|
+
if (!fs9.existsSync(journeysDir)) {
|
|
9697
|
+
fs9.mkdirSync(journeysDir, { recursive: true });
|
|
9698
|
+
}
|
|
9699
|
+
const writtenFiles = /* @__PURE__ */ new Set();
|
|
9700
|
+
const usedSlugs = /* @__PURE__ */ new Set();
|
|
9701
|
+
for (const journeyEntry of journeys) {
|
|
9702
|
+
const slug = ensureUniqueSlug(slugify(journeyEntry.name), usedSlugs);
|
|
9703
|
+
const fileName = `${slug}.yaml`;
|
|
9704
|
+
const yamlContent = yaml4.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
|
|
9705
|
+
fs9.writeFileSync(path11.join(journeysDir, fileName), yamlContent, "utf-8");
|
|
9706
|
+
writtenFiles.add(fileName);
|
|
9707
|
+
}
|
|
9708
|
+
cleanJourneyOrphans(journeysDir, writtenFiles);
|
|
9709
|
+
}
|
|
9710
|
+
function cleanJourneyOrphans(journeysDir, writtenFiles) {
|
|
9711
|
+
const entries = fs9.readdirSync(journeysDir, { withFileTypes: true });
|
|
9712
|
+
for (const entry of entries) {
|
|
9713
|
+
if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
|
|
9714
|
+
fs9.unlinkSync(path11.join(journeysDir, entry.name));
|
|
9715
|
+
}
|
|
9716
|
+
}
|
|
9717
|
+
}
|
|
9637
9718
|
function writeResourceFiles(hubFolder, resources) {
|
|
9638
9719
|
const resourcesDir = path11.join(hubFolder, "resources");
|
|
9639
9720
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
@@ -9656,6 +9737,7 @@ var YAML_DUMP_OPTIONS;
|
|
|
9656
9737
|
var init_yaml_writer = __esm({
|
|
9657
9738
|
"src/lib/yaml-writer.ts"() {
|
|
9658
9739
|
"use strict";
|
|
9740
|
+
init_dist();
|
|
9659
9741
|
init_utils();
|
|
9660
9742
|
init_resource_files();
|
|
9661
9743
|
YAML_DUMP_OPTIONS = {
|
|
@@ -9777,6 +9859,10 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
9777
9859
|
if (evals.length > 0) {
|
|
9778
9860
|
payload.evals = evals;
|
|
9779
9861
|
}
|
|
9862
|
+
const journeys = scanJourneyYamlFiles(hubFolder);
|
|
9863
|
+
if (journeys.length > 0) {
|
|
9864
|
+
payload.journeys = journeys;
|
|
9865
|
+
}
|
|
9780
9866
|
return payload;
|
|
9781
9867
|
}
|
|
9782
9868
|
function scanEvalYamlFiles(hubFolder) {
|
|
@@ -9865,6 +9951,76 @@ function parseEvalYaml(filePath, relPath, setName) {
|
|
|
9865
9951
|
}
|
|
9866
9952
|
return evalEntry;
|
|
9867
9953
|
}
|
|
9954
|
+
function scanJourneyYamlFiles(hubFolder) {
|
|
9955
|
+
const journeysDir = path12.join(hubFolder, "journeys");
|
|
9956
|
+
if (!fs10.existsSync(journeysDir)) return [];
|
|
9957
|
+
const journeys = [];
|
|
9958
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9959
|
+
const entries = fs10.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
9960
|
+
for (const entry of entries) {
|
|
9961
|
+
if (entry.isDirectory()) {
|
|
9962
|
+
throw expected(
|
|
9963
|
+
`Subfolders are not supported under journeys/: ${path12.relative(hubFolder, path12.join(journeysDir, entry.name))}. A journey owns its own managed scenario set \u2014 put each journey in a single journeys/<slug>.yaml file.`
|
|
9964
|
+
);
|
|
9965
|
+
}
|
|
9966
|
+
if (!entry.isFile() || !entry.name.endsWith(".yaml")) continue;
|
|
9967
|
+
const journeyEntry = parseJourneyYaml(path12.join(journeysDir, entry.name), `journeys/${entry.name}`);
|
|
9968
|
+
if (!journeyEntry) continue;
|
|
9969
|
+
if (seen.has(journeyEntry.name)) {
|
|
9970
|
+
throw expected(
|
|
9971
|
+
`Duplicate journey: "${journeyEntry.name}" (in ${entry.name}). Each journey name must be unique.`
|
|
9972
|
+
);
|
|
9973
|
+
}
|
|
9974
|
+
seen.add(journeyEntry.name);
|
|
9975
|
+
journeys.push(journeyEntry);
|
|
9976
|
+
}
|
|
9977
|
+
return journeys;
|
|
9978
|
+
}
|
|
9979
|
+
function parseJourneyYaml(filePath, relPath) {
|
|
9980
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
9981
|
+
let raw;
|
|
9982
|
+
try {
|
|
9983
|
+
raw = yaml5.load(content);
|
|
9984
|
+
} catch (err) {
|
|
9985
|
+
if (err instanceof yaml5.YAMLException) {
|
|
9986
|
+
throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
|
|
9987
|
+
}
|
|
9988
|
+
throw err;
|
|
9989
|
+
}
|
|
9990
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
9991
|
+
console.warn(` Warning: skipping ${relPath} (not a YAML object)`);
|
|
9992
|
+
return null;
|
|
9993
|
+
}
|
|
9994
|
+
const data = raw;
|
|
9995
|
+
const fileSlug = path12.basename(filePath, ".yaml");
|
|
9996
|
+
const journeyName = typeof data.name === "string" && data.name.trim().length > 0 ? data.name : fileSlug;
|
|
9997
|
+
if (typeof data.agent !== "string" || data.agent.trim().length === 0) {
|
|
9998
|
+
throw expected(`Journey "${journeyName}" in ${relPath}: missing required field "agent" (string).`);
|
|
9999
|
+
}
|
|
10000
|
+
if (data.transcript !== void 0 && !Array.isArray(data.transcript)) {
|
|
10001
|
+
throw expected(`Journey "${journeyName}" in ${relPath}: "transcript" must be an array.`);
|
|
10002
|
+
}
|
|
10003
|
+
if (data.step_config !== void 0 && (typeof data.step_config !== "object" || Array.isArray(data.step_config) || data.step_config === null)) {
|
|
10004
|
+
throw expected(`Journey "${journeyName}" in ${relPath}: "step_config" must be an object keyed by step_id.`);
|
|
10005
|
+
}
|
|
10006
|
+
const journeyEntry = {
|
|
10007
|
+
name: journeyName,
|
|
10008
|
+
agent: data.agent
|
|
10009
|
+
};
|
|
10010
|
+
if (typeof data.id === "string") journeyEntry.id = data.id;
|
|
10011
|
+
if (typeof data.agent_id === "string") journeyEntry.agent_id = data.agent_id;
|
|
10012
|
+
if (data.enabled === false) journeyEntry.enabled = false;
|
|
10013
|
+
if (typeof data.evaluator_instructions === "string") {
|
|
10014
|
+
journeyEntry.evaluator_instructions = data.evaluator_instructions;
|
|
10015
|
+
}
|
|
10016
|
+
if (Array.isArray(data.transcript)) {
|
|
10017
|
+
journeyEntry.transcript = data.transcript;
|
|
10018
|
+
}
|
|
10019
|
+
if (data.step_config && typeof data.step_config === "object" && !Array.isArray(data.step_config)) {
|
|
10020
|
+
journeyEntry.step_config = data.step_config;
|
|
10021
|
+
}
|
|
10022
|
+
return journeyEntry;
|
|
10023
|
+
}
|
|
9868
10024
|
function scanAgentYamlFiles(hubFolder) {
|
|
9869
10025
|
const agentsDir = path12.join(hubFolder, "agents");
|
|
9870
10026
|
if (!fs10.existsSync(agentsDir)) return [];
|
|
@@ -10179,6 +10335,12 @@ Sync complete. Preview hub: ${result.preview_hub_id}`);
|
|
|
10179
10335
|
if (c.states_created > 0) parts.push(`${c.states_created} state(s) created`);
|
|
10180
10336
|
if (c.states_updated > 0) parts.push(`${c.states_updated} state(s) updated`);
|
|
10181
10337
|
if (c.states_deleted > 0) parts.push(`${c.states_deleted} state(s) deleted`);
|
|
10338
|
+
if (c.evals_created > 0) parts.push(`${c.evals_created} eval(s) created`);
|
|
10339
|
+
if (c.evals_updated > 0) parts.push(`${c.evals_updated} eval(s) updated`);
|
|
10340
|
+
if (c.evals_deleted > 0) parts.push(`${c.evals_deleted} eval(s) deleted`);
|
|
10341
|
+
if (c.journeys_created > 0) parts.push(`${c.journeys_created} journey(s) created`);
|
|
10342
|
+
if (c.journeys_updated > 0) parts.push(`${c.journeys_updated} journey(s) updated`);
|
|
10343
|
+
if (c.journeys_deleted > 0) parts.push(`${c.journeys_deleted} journey(s) deleted`);
|
|
10182
10344
|
if (c.teams_created > 0) parts.push(`${c.teams_created} team(s) created`);
|
|
10183
10345
|
if (c.teams_updated > 0) parts.push(`${c.teams_updated} team(s) updated`);
|
|
10184
10346
|
if (c.teams_deleted > 0) parts.push(`${c.teams_deleted} team(s) deleted`);
|
|
@@ -12048,6 +12210,80 @@ var init_journey_capture = __esm({
|
|
|
12048
12210
|
}
|
|
12049
12211
|
});
|
|
12050
12212
|
|
|
12213
|
+
// src/commands/eval-session-delete.ts
|
|
12214
|
+
var eval_session_delete_exports = {};
|
|
12215
|
+
__export(eval_session_delete_exports, {
|
|
12216
|
+
evalSessionDeleteCommand: () => evalSessionDeleteCommand
|
|
12217
|
+
});
|
|
12218
|
+
async function evalSessionDeleteCommand(args2) {
|
|
12219
|
+
const hubId = resolveActiveHubId(args2);
|
|
12220
|
+
const { config, accessToken } = await requireAuth();
|
|
12221
|
+
requireRepoConfig();
|
|
12222
|
+
const skipConfirm = args2.includes("-y") || args2.includes("--yes");
|
|
12223
|
+
const deleteAll = args2.includes("--all");
|
|
12224
|
+
const sessionId = args2.find((a) => !a.startsWith("-"));
|
|
12225
|
+
if (deleteAll && sessionId) {
|
|
12226
|
+
console.error("Pass either a session id or --all, not both.");
|
|
12227
|
+
process.exit(1);
|
|
12228
|
+
}
|
|
12229
|
+
if (!deleteAll && !sessionId) {
|
|
12230
|
+
console.error("Usage: wayai eval session delete <session_id>");
|
|
12231
|
+
console.error(" wayai eval session delete --all");
|
|
12232
|
+
process.exit(1);
|
|
12233
|
+
}
|
|
12234
|
+
if (sessionId && !UUID_RE.test(sessionId)) {
|
|
12235
|
+
console.error(`Invalid session id: ${sessionId}`);
|
|
12236
|
+
process.exit(1);
|
|
12237
|
+
}
|
|
12238
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
12239
|
+
if (deleteAll) {
|
|
12240
|
+
if (!skipConfirm) {
|
|
12241
|
+
const confirmed = await confirm(
|
|
12242
|
+
"This will permanently delete ALL eval sessions on this hub and their conversations. Continue?"
|
|
12243
|
+
);
|
|
12244
|
+
if (!confirmed) {
|
|
12245
|
+
console.log("Aborted.");
|
|
12246
|
+
return;
|
|
12247
|
+
}
|
|
12248
|
+
}
|
|
12249
|
+
const result = await client.deleteAllEvalSessions(hubId);
|
|
12250
|
+
console.log(
|
|
12251
|
+
`Deleted ${result.data.deleted_sessions} session(s) and ${result.data.deleted_conversations} eval conversation(s).`
|
|
12252
|
+
);
|
|
12253
|
+
return;
|
|
12254
|
+
}
|
|
12255
|
+
if (!skipConfirm) {
|
|
12256
|
+
const confirmed = await confirm(
|
|
12257
|
+
"This will permanently delete this eval session and its conversations. Continue?"
|
|
12258
|
+
);
|
|
12259
|
+
if (!confirmed) {
|
|
12260
|
+
console.log("Aborted.");
|
|
12261
|
+
return;
|
|
12262
|
+
}
|
|
12263
|
+
}
|
|
12264
|
+
try {
|
|
12265
|
+
const result = await client.deleteEvalSession(hubId, sessionId);
|
|
12266
|
+
const deletedConversations = result.data?.deleted_conversations ?? 0;
|
|
12267
|
+
console.log(`Deleted session ${sessionId} (${deletedConversations} eval conversation(s)).`);
|
|
12268
|
+
} catch (err) {
|
|
12269
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
12270
|
+
console.error(`Eval session not found: ${sessionId}`);
|
|
12271
|
+
process.exit(1);
|
|
12272
|
+
}
|
|
12273
|
+
throw err;
|
|
12274
|
+
}
|
|
12275
|
+
}
|
|
12276
|
+
var init_eval_session_delete = __esm({
|
|
12277
|
+
"src/commands/eval-session-delete.ts"() {
|
|
12278
|
+
"use strict";
|
|
12279
|
+
init_auth();
|
|
12280
|
+
init_repo_config();
|
|
12281
|
+
init_workspace();
|
|
12282
|
+
init_api_client();
|
|
12283
|
+
init_utils();
|
|
12284
|
+
}
|
|
12285
|
+
});
|
|
12286
|
+
|
|
12051
12287
|
// src/commands/eval.ts
|
|
12052
12288
|
var eval_exports = {};
|
|
12053
12289
|
__export(eval_exports, {
|
|
@@ -12077,6 +12313,18 @@ async function evalCommand(args2) {
|
|
|
12077
12313
|
process.exit(1);
|
|
12078
12314
|
return;
|
|
12079
12315
|
}
|
|
12316
|
+
case "session": {
|
|
12317
|
+
const [sessionSub, ...sessionRest] = rest;
|
|
12318
|
+
if (sessionSub === "delete") {
|
|
12319
|
+
const { evalSessionDeleteCommand: evalSessionDeleteCommand2 } = await Promise.resolve().then(() => (init_eval_session_delete(), eval_session_delete_exports));
|
|
12320
|
+
await evalSessionDeleteCommand2(sessionRest);
|
|
12321
|
+
return;
|
|
12322
|
+
}
|
|
12323
|
+
console.error(`Unknown eval session subcommand: ${sessionSub ?? "(none)"}`);
|
|
12324
|
+
printHelp();
|
|
12325
|
+
process.exit(1);
|
|
12326
|
+
return;
|
|
12327
|
+
}
|
|
12080
12328
|
case "help":
|
|
12081
12329
|
case "--help":
|
|
12082
12330
|
case "-h":
|
|
@@ -12100,6 +12348,9 @@ Subcommands:
|
|
|
12100
12348
|
exchange as a scenario YAML in evals/.
|
|
12101
12349
|
journey capture <conversation_id> Capture a real conversation's FULL
|
|
12102
12350
|
transcript as a platform-managed journey.
|
|
12351
|
+
session delete <session_id> Delete one eval session (and its
|
|
12352
|
+
conversations). Destructive, irreversible.
|
|
12353
|
+
session delete --all Delete every eval session on the hub.
|
|
12103
12354
|
|
|
12104
12355
|
Capture flags (scenario):
|
|
12105
12356
|
--set <name> Scenario set folder (created if missing). Default: "Default".
|
|
@@ -12110,10 +12361,16 @@ Journey capture flags:
|
|
|
12110
12361
|
--name <journey_name> Journey name. Default: derived from conversation ID.
|
|
12111
12362
|
--instructions <text> Default evaluator instructions for the journey's steps.
|
|
12112
12363
|
|
|
12364
|
+
Session delete flags:
|
|
12365
|
+
--all Delete ALL sessions on the hub instead of one.
|
|
12366
|
+
-y, --yes Skip the confirmation prompt.
|
|
12367
|
+
|
|
12113
12368
|
Examples:
|
|
12114
12369
|
wayai eval capture 11111111-2222-3333-4444-555555555555
|
|
12115
12370
|
wayai eval capture <conv_id> --set regression-suite --name "Cancel order"
|
|
12116
12371
|
wayai eval journey capture <conv_id> --name "Refund happy path"
|
|
12372
|
+
wayai eval session delete 11111111-2222-3333-4444-555555555555
|
|
12373
|
+
wayai eval session delete --all -y
|
|
12117
12374
|
|
|
12118
12375
|
Authoring evals (create/update/delete) is file-driven \u2014 edit YAML in
|
|
12119
12376
|
evals/ and run \`wayai push\`. Capture commands are for production replay only.
|
|
@@ -17373,6 +17630,7 @@ Commands:
|
|
|
17373
17630
|
run-eval Run all enabled evals and show results
|
|
17374
17631
|
eval-results View results from a completed eval session
|
|
17375
17632
|
eval capture Capture a real conversation as a scenario YAML
|
|
17633
|
+
eval session delete Delete one eval session (\`--all\` for every session on the hub)
|
|
17376
17634
|
sync-skills Sync skills to Anthropic/OpenAI provider connections
|
|
17377
17635
|
sync-mcp Re-discover an MCP connection's tools (refresh stale schemas)
|
|
17378
17636
|
list List organizations and hubs
|