@wayai/cli 0.3.102 → 0.3.104
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 +1044 -428
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -441,11 +441,11 @@ function captureException2(error, context) {
|
|
|
441
441
|
Sentry.captureException(error);
|
|
442
442
|
});
|
|
443
443
|
}
|
|
444
|
-
function addApiBreadcrumb(method,
|
|
444
|
+
function addApiBreadcrumb(method, path30) {
|
|
445
445
|
if (!initialized) return;
|
|
446
446
|
Sentry.addBreadcrumb({
|
|
447
447
|
category: "http",
|
|
448
|
-
message: `${method} ${
|
|
448
|
+
message: `${method} ${path30}`,
|
|
449
449
|
level: "info"
|
|
450
450
|
});
|
|
451
451
|
}
|
|
@@ -503,13 +503,13 @@ var init_api_client = __esm({
|
|
|
503
503
|
init_sentry();
|
|
504
504
|
init_mask_secrets();
|
|
505
505
|
RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
|
|
506
|
-
delay = (ms) => new Promise((
|
|
506
|
+
delay = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
507
507
|
ApiError = class extends Error {
|
|
508
508
|
status;
|
|
509
509
|
body;
|
|
510
|
-
constructor(method,
|
|
510
|
+
constructor(method, path30, status, body) {
|
|
511
511
|
const safeBody = maskSecretsInMessage(body);
|
|
512
|
-
super(`API request failed: ${method} ${
|
|
512
|
+
super(`API request failed: ${method} ${path30} (${status}): ${safeBody}`);
|
|
513
513
|
this.name = "ApiError";
|
|
514
514
|
this.status = status;
|
|
515
515
|
this.body = safeBody;
|
|
@@ -657,8 +657,8 @@ var init_api_client = __esm({
|
|
|
657
657
|
...organizationId && { organization_id: organizationId }
|
|
658
658
|
});
|
|
659
659
|
}
|
|
660
|
-
async lookup(
|
|
661
|
-
const params = new URLSearchParams({ path:
|
|
660
|
+
async lookup(path30, opts) {
|
|
661
|
+
const params = new URLSearchParams({ path: path30 });
|
|
662
662
|
if (opts?.organizationId) params.set("organization_id", opts.organizationId);
|
|
663
663
|
return this.request("GET", `/api/ci/lookup?${params.toString()}`);
|
|
664
664
|
}
|
|
@@ -1058,9 +1058,9 @@ var init_api_client = __esm({
|
|
|
1058
1058
|
* sandbox for this conversation, or the blob was purged).
|
|
1059
1059
|
*/
|
|
1060
1060
|
async downloadArchiveSandboxFs(hubId, conversationId) {
|
|
1061
|
-
const
|
|
1062
|
-
addApiBreadcrumb("GET",
|
|
1063
|
-
const url = `${this.apiUrl}${
|
|
1061
|
+
const path30 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
|
|
1062
|
+
addApiBreadcrumb("GET", path30);
|
|
1063
|
+
const url = `${this.apiUrl}${path30}`;
|
|
1064
1064
|
let response = await this.send(url, "GET");
|
|
1065
1065
|
if (response.status === 401 && this.onUnauthorized) {
|
|
1066
1066
|
let refreshed;
|
|
@@ -1074,7 +1074,7 @@ var init_api_client = __esm({
|
|
|
1074
1074
|
}
|
|
1075
1075
|
}
|
|
1076
1076
|
if (!response.ok) {
|
|
1077
|
-
throw new ApiError("GET",
|
|
1077
|
+
throw new ApiError("GET", path30, response.status, await response.text());
|
|
1078
1078
|
}
|
|
1079
1079
|
return new Uint8Array(await response.arrayBuffer());
|
|
1080
1080
|
}
|
|
@@ -1114,9 +1114,9 @@ var init_api_client = __esm({
|
|
|
1114
1114
|
`/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
|
|
1115
1115
|
);
|
|
1116
1116
|
}
|
|
1117
|
-
async request(method,
|
|
1118
|
-
addApiBreadcrumb(method,
|
|
1119
|
-
const url = `${this.apiUrl}${
|
|
1117
|
+
async request(method, path30, body) {
|
|
1118
|
+
addApiBreadcrumb(method, path30);
|
|
1119
|
+
const url = `${this.apiUrl}${path30}`;
|
|
1120
1120
|
let refreshedOn401 = false;
|
|
1121
1121
|
for (let retry = 0; ; retry++) {
|
|
1122
1122
|
let response = await this.send(url, method, body);
|
|
@@ -1140,7 +1140,7 @@ var init_api_client = __esm({
|
|
|
1140
1140
|
await delay(RETRYABLE_BACKOFF_MS[retry]);
|
|
1141
1141
|
continue;
|
|
1142
1142
|
}
|
|
1143
|
-
throw new ApiError(method,
|
|
1143
|
+
throw new ApiError(method, path30, response.status, errorBody);
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
/** Issue a single authenticated request with the client's current token. */
|
|
@@ -1575,8 +1575,8 @@ var init_parseUtil = __esm({
|
|
|
1575
1575
|
init_errors();
|
|
1576
1576
|
init_en();
|
|
1577
1577
|
makeIssue = (params) => {
|
|
1578
|
-
const { data, path:
|
|
1579
|
-
const fullPath = [...
|
|
1578
|
+
const { data, path: path30, errorMaps, issueData } = params;
|
|
1579
|
+
const fullPath = [...path30, ...issueData.path || []];
|
|
1580
1580
|
const fullIssue = {
|
|
1581
1581
|
...issueData,
|
|
1582
1582
|
path: fullPath
|
|
@@ -1887,11 +1887,11 @@ var init_types = __esm({
|
|
|
1887
1887
|
init_parseUtil();
|
|
1888
1888
|
init_util();
|
|
1889
1889
|
ParseInputLazyPath = class {
|
|
1890
|
-
constructor(parent, value,
|
|
1890
|
+
constructor(parent, value, path30, key) {
|
|
1891
1891
|
this._cachedPath = [];
|
|
1892
1892
|
this.parent = parent;
|
|
1893
1893
|
this.data = value;
|
|
1894
|
-
this._path =
|
|
1894
|
+
this._path = path30;
|
|
1895
1895
|
this._key = key;
|
|
1896
1896
|
}
|
|
1897
1897
|
get path() {
|
|
@@ -5375,12 +5375,12 @@ function typeMatches(typeField, allowed) {
|
|
|
5375
5375
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
5376
5376
|
return false;
|
|
5377
5377
|
}
|
|
5378
|
-
function validateSchema(schema,
|
|
5378
|
+
function validateSchema(schema, path30, errors, opts = {}) {
|
|
5379
5379
|
if (typeof schema === "boolean") return;
|
|
5380
5380
|
const depth = opts.depth ?? 0;
|
|
5381
5381
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
5382
5382
|
errors.push({
|
|
5383
|
-
path:
|
|
5383
|
+
path: path30 || "<root>",
|
|
5384
5384
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
|
|
5385
5385
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
5386
5386
|
});
|
|
@@ -5388,7 +5388,7 @@ function validateSchema(schema, path28, errors, opts = {}) {
|
|
|
5388
5388
|
}
|
|
5389
5389
|
if (!isRecord(schema)) {
|
|
5390
5390
|
errors.push({
|
|
5391
|
-
path:
|
|
5391
|
+
path: path30,
|
|
5392
5392
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
5393
5393
|
});
|
|
5394
5394
|
return;
|
|
@@ -5396,14 +5396,14 @@ function validateSchema(schema, path28, errors, opts = {}) {
|
|
|
5396
5396
|
if (opts.isRoot) {
|
|
5397
5397
|
if ("type" in schema && schema.type !== "object") {
|
|
5398
5398
|
errors.push({
|
|
5399
|
-
path:
|
|
5399
|
+
path: path30 ? `${path30}.type` : "type",
|
|
5400
5400
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
5401
5401
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
5402
5402
|
});
|
|
5403
5403
|
}
|
|
5404
5404
|
} else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
|
|
5405
5405
|
errors.push({
|
|
5406
|
-
path: `${
|
|
5406
|
+
path: `${path30}.type`,
|
|
5407
5407
|
message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
5408
5408
|
});
|
|
5409
5409
|
}
|
|
@@ -5412,25 +5412,25 @@ function validateSchema(schema, path28, errors, opts = {}) {
|
|
|
5412
5412
|
if (typeof e === "string") {
|
|
5413
5413
|
const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
|
|
5414
5414
|
errors.push({
|
|
5415
|
-
path: `${
|
|
5415
|
+
path: `${path30}.enum`,
|
|
5416
5416
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
5417
5417
|
suggestion: isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
|
|
5418
5418
|
});
|
|
5419
5419
|
} else if (!Array.isArray(e)) {
|
|
5420
5420
|
errors.push({
|
|
5421
|
-
path: `${
|
|
5421
|
+
path: `${path30}.enum`,
|
|
5422
5422
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
5423
5423
|
});
|
|
5424
5424
|
} else if (e.length === 0) {
|
|
5425
5425
|
errors.push({
|
|
5426
|
-
path: `${
|
|
5426
|
+
path: `${path30}.enum`,
|
|
5427
5427
|
message: "enum must not be empty"
|
|
5428
5428
|
});
|
|
5429
5429
|
} else {
|
|
5430
5430
|
for (let i = 0; i < e.length; i++) {
|
|
5431
5431
|
if (!isPrimitive(e[i])) {
|
|
5432
5432
|
errors.push({
|
|
5433
|
-
path: `${
|
|
5433
|
+
path: `${path30}.enum[${i}]`,
|
|
5434
5434
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
5435
5435
|
});
|
|
5436
5436
|
}
|
|
@@ -5440,7 +5440,7 @@ function validateSchema(schema, path28, errors, opts = {}) {
|
|
|
5440
5440
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
5441
5441
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
5442
5442
|
errors.push({
|
|
5443
|
-
path: `${
|
|
5443
|
+
path: `${path30}.${key}`,
|
|
5444
5444
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
5445
5445
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
5446
5446
|
});
|
|
@@ -5449,45 +5449,45 @@ function validateSchema(schema, path28, errors, opts = {}) {
|
|
|
5449
5449
|
if ("properties" in schema) {
|
|
5450
5450
|
if (!isRecord(schema.properties)) {
|
|
5451
5451
|
errors.push({
|
|
5452
|
-
path: `${
|
|
5452
|
+
path: `${path30}.properties`,
|
|
5453
5453
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
5454
5454
|
});
|
|
5455
5455
|
} else {
|
|
5456
5456
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
5457
|
-
validateSchema(propSchema, `${
|
|
5457
|
+
validateSchema(propSchema, `${path30}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
5458
5458
|
}
|
|
5459
5459
|
}
|
|
5460
5460
|
}
|
|
5461
5461
|
if (schemaTypeIncludes(schema, "array") && "items" in schema) {
|
|
5462
5462
|
if (Array.isArray(schema.items)) {
|
|
5463
|
-
schema.items.forEach((sub, i) => validateSchema(sub, `${
|
|
5463
|
+
schema.items.forEach((sub, i) => validateSchema(sub, `${path30}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
5464
5464
|
} else {
|
|
5465
|
-
validateSchema(schema.items, `${
|
|
5465
|
+
validateSchema(schema.items, `${path30}.items`, errors, { depth: depth + 1 });
|
|
5466
5466
|
}
|
|
5467
5467
|
}
|
|
5468
5468
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
|
|
5469
5469
|
if (key in schema && isRecord(schema[key])) {
|
|
5470
|
-
validateSchema(schema[key], `${
|
|
5470
|
+
validateSchema(schema[key], `${path30}.${key}`, errors, { depth: depth + 1 });
|
|
5471
5471
|
}
|
|
5472
5472
|
}
|
|
5473
5473
|
for (const key of SUBSCHEMA_LIST_KEYWORDS) {
|
|
5474
5474
|
const list = schema[key];
|
|
5475
5475
|
if (Array.isArray(list)) {
|
|
5476
|
-
list.forEach((sub, i) => validateSchema(sub, `${
|
|
5476
|
+
list.forEach((sub, i) => validateSchema(sub, `${path30}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
5477
5477
|
}
|
|
5478
5478
|
}
|
|
5479
5479
|
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
5480
5480
|
const map = schema[key];
|
|
5481
5481
|
if (isRecord(map)) {
|
|
5482
5482
|
for (const [name, sub] of Object.entries(map)) {
|
|
5483
|
-
validateSchema(sub, `${
|
|
5483
|
+
validateSchema(sub, `${path30}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
5484
5484
|
}
|
|
5485
5485
|
}
|
|
5486
5486
|
}
|
|
5487
5487
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
5488
5488
|
for (const [k, v] of Object.entries(schema)) {
|
|
5489
5489
|
if (typeof v !== "string") continue;
|
|
5490
|
-
const fieldPath = `${
|
|
5490
|
+
const fieldPath = `${path30}.${k}`;
|
|
5491
5491
|
if (reportedPaths.has(fieldPath)) continue;
|
|
5492
5492
|
for (const token of PLACEHOLDER_TOKENS) {
|
|
5493
5493
|
if (v === token) {
|
|
@@ -5562,15 +5562,17 @@ function describeRole(role) {
|
|
|
5562
5562
|
return `a ${typeof role}`;
|
|
5563
5563
|
}
|
|
5564
5564
|
function asEvalInputRecord(input) {
|
|
5565
|
-
const value =
|
|
5566
|
-
try {
|
|
5567
|
-
return JSON.parse(input);
|
|
5568
|
-
} catch {
|
|
5569
|
-
return null;
|
|
5570
|
-
}
|
|
5571
|
-
})() : input;
|
|
5565
|
+
const value = parseMaybeJson(input);
|
|
5572
5566
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
5573
5567
|
}
|
|
5568
|
+
function parseMaybeJson(value) {
|
|
5569
|
+
if (typeof value !== "string") return value;
|
|
5570
|
+
try {
|
|
5571
|
+
return JSON.parse(value);
|
|
5572
|
+
} catch {
|
|
5573
|
+
return null;
|
|
5574
|
+
}
|
|
5575
|
+
}
|
|
5574
5576
|
function evalInputRoleError(input) {
|
|
5575
5577
|
const record = asEvalInputRecord(input);
|
|
5576
5578
|
if (record === null) return null;
|
|
@@ -5581,6 +5583,32 @@ function evalInputRoleError(input) {
|
|
|
5581
5583
|
}
|
|
5582
5584
|
return `role must be ${EVAL_INPUT_ROLE_LIST} (received ${describeRole(role)}) \u2014 an eval trigger is what the responder answers, and an assistant or tool role gives it nothing to answer`;
|
|
5583
5585
|
}
|
|
5586
|
+
function evalTurnAttachmentsError(turn) {
|
|
5587
|
+
const record = asEvalInputRecord(turn);
|
|
5588
|
+
if (record === null) return null;
|
|
5589
|
+
const attachments = record.attachments;
|
|
5590
|
+
if (attachments === void 0 || attachments === null) return null;
|
|
5591
|
+
if (!Array.isArray(attachments)) return "attachments must be an array";
|
|
5592
|
+
if (attachments.length === 0) return null;
|
|
5593
|
+
if (attachments.length > MAX_ATTACHMENTS_PER_MESSAGE) {
|
|
5594
|
+
return `attachments must have at most ${MAX_ATTACHMENTS_PER_MESSAGE} items`;
|
|
5595
|
+
}
|
|
5596
|
+
if (!turnMayCarryAttachments({ role: String(record.role), attachments })) {
|
|
5597
|
+
return ATTACHMENTS_USER_ONLY_MESSAGE;
|
|
5598
|
+
}
|
|
5599
|
+
for (let i = 0; i < attachments.length; i++) {
|
|
5600
|
+
const parsed = evalAttachmentRef.safeParse(attachments[i]);
|
|
5601
|
+
if (!parsed.success) {
|
|
5602
|
+
const issue = parsed.error.issues[0];
|
|
5603
|
+
return `attachments[${i}].${issue?.path.join(".") || "?"} is invalid: ${issue?.message ?? "malformed"}`;
|
|
5604
|
+
}
|
|
5605
|
+
}
|
|
5606
|
+
return null;
|
|
5607
|
+
}
|
|
5608
|
+
function asEvalHistoryArray(history) {
|
|
5609
|
+
const value = parseMaybeJson(history);
|
|
5610
|
+
return Array.isArray(value) ? value : null;
|
|
5611
|
+
}
|
|
5584
5612
|
function refineEvalMessageTextRole(value, ctx) {
|
|
5585
5613
|
const error = evalInputRoleError(value.eval.message_text);
|
|
5586
5614
|
if (error) {
|
|
@@ -5591,6 +5619,64 @@ function refineEvalMessageTextRole(value, ctx) {
|
|
|
5591
5619
|
});
|
|
5592
5620
|
}
|
|
5593
5621
|
}
|
|
5622
|
+
function refineEvalAttachments(value, ctx) {
|
|
5623
|
+
const triggerError = evalTurnAttachmentsError(value.eval.message_text);
|
|
5624
|
+
if (triggerError) {
|
|
5625
|
+
ctx.addIssue({
|
|
5626
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5627
|
+
path: ["eval", "message_text", "attachments"],
|
|
5628
|
+
message: triggerError
|
|
5629
|
+
});
|
|
5630
|
+
}
|
|
5631
|
+
const history = asEvalHistoryArray(value.eval.message_history);
|
|
5632
|
+
if (!history) return;
|
|
5633
|
+
for (let i = 0; i < history.length; i++) {
|
|
5634
|
+
const error = evalTurnAttachmentsError(history[i]);
|
|
5635
|
+
if (error) {
|
|
5636
|
+
ctx.addIssue({
|
|
5637
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5638
|
+
path: ["eval", "message_history", i, "attachments"],
|
|
5639
|
+
message: error
|
|
5640
|
+
});
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
function collectTurnAttachmentHashes(turn) {
|
|
5645
|
+
const atts = asEvalInputRecord(turn)?.attachments;
|
|
5646
|
+
if (!Array.isArray(atts)) return [];
|
|
5647
|
+
const hashes = [];
|
|
5648
|
+
for (const a of atts) {
|
|
5649
|
+
const parsed = evalAttachmentRef.safeParse(a);
|
|
5650
|
+
if (parsed.success) hashes.push(parsed.data.hash);
|
|
5651
|
+
}
|
|
5652
|
+
return hashes;
|
|
5653
|
+
}
|
|
5654
|
+
function foldDiacritics(input) {
|
|
5655
|
+
return input.normalize("NFKD").replace(/[̀-ͯ]/g, "");
|
|
5656
|
+
}
|
|
5657
|
+
function slugifyKebab(input, maxLength = 64) {
|
|
5658
|
+
if (typeof input !== "string") return "";
|
|
5659
|
+
return foldDiacritics(input).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").slice(0, maxLength).replace(/^-|-$/g, "");
|
|
5660
|
+
}
|
|
5661
|
+
function ensureUniqueSlug(slug, used) {
|
|
5662
|
+
if (!used.has(slug)) {
|
|
5663
|
+
used.add(slug);
|
|
5664
|
+
return slug;
|
|
5665
|
+
}
|
|
5666
|
+
for (let i = 2; i < 1e6; i++) {
|
|
5667
|
+
const suffix = `_${i}`;
|
|
5668
|
+
const baseLen = Math.max(1, 50 - suffix.length);
|
|
5669
|
+
const candidate = `${slug.slice(0, baseLen)}${suffix}`;
|
|
5670
|
+
if (!used.has(candidate)) {
|
|
5671
|
+
used.add(candidate);
|
|
5672
|
+
return candidate;
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
throw new Error(`slug collision space exhausted for "${slug}"`);
|
|
5676
|
+
}
|
|
5677
|
+
function slugifySkillName(name) {
|
|
5678
|
+
return slugifyKebab(name, 64);
|
|
5679
|
+
}
|
|
5594
5680
|
function refineHubAsCodeCustomTools(config, ctx) {
|
|
5595
5681
|
const agents = config.agents;
|
|
5596
5682
|
if (!Array.isArray(agents)) return;
|
|
@@ -5698,10 +5784,84 @@ function refineHubAsCodeEvals(config, ctx) {
|
|
|
5698
5784
|
}
|
|
5699
5785
|
}
|
|
5700
5786
|
}
|
|
5701
|
-
function
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
const
|
|
5787
|
+
function refineHubAsCodeEvalAttachments(config, ctx) {
|
|
5788
|
+
const cfg = config;
|
|
5789
|
+
const referencedHashes = /* @__PURE__ */ new Set();
|
|
5790
|
+
const addTurnIssue = (path30, turn, name) => {
|
|
5791
|
+
const error = evalTurnAttachmentsError(turn);
|
|
5792
|
+
if (error) {
|
|
5793
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path30, message: `${name}: ${error}` });
|
|
5794
|
+
return;
|
|
5795
|
+
}
|
|
5796
|
+
for (const hash of collectTurnAttachmentHashes(turn)) referencedHashes.add(hash);
|
|
5797
|
+
};
|
|
5798
|
+
if (Array.isArray(cfg.evals)) {
|
|
5799
|
+
cfg.evals.forEach((entry, e) => {
|
|
5800
|
+
const ev = entry;
|
|
5801
|
+
const name = `eval "${ev?.name ?? "<unnamed>"}"`;
|
|
5802
|
+
addTurnIssue(["evals", e, "input"], ev?.input, name);
|
|
5803
|
+
if (Array.isArray(ev?.history)) {
|
|
5804
|
+
ev.history.forEach((turn, h) => addTurnIssue(["evals", e, "history", h], turn, name));
|
|
5805
|
+
}
|
|
5806
|
+
});
|
|
5807
|
+
}
|
|
5808
|
+
if (Array.isArray(cfg.journeys)) {
|
|
5809
|
+
cfg.journeys.forEach((entry, j) => {
|
|
5810
|
+
const jr = entry;
|
|
5811
|
+
const name = `journey "${jr?.name ?? "<unnamed>"}"`;
|
|
5812
|
+
if (Array.isArray(jr?.transcript)) {
|
|
5813
|
+
jr.transcript.forEach((turn, t) => addTurnIssue(["journeys", j, "transcript", t], turn, name));
|
|
5814
|
+
}
|
|
5815
|
+
});
|
|
5816
|
+
}
|
|
5817
|
+
const carriedHashes = /* @__PURE__ */ new Set();
|
|
5818
|
+
const files = cfg.eval_attachment_files;
|
|
5819
|
+
if (Array.isArray(files)) {
|
|
5820
|
+
if (files.length > MAX_EVAL_ATTACHMENT_CARRIERS) {
|
|
5821
|
+
ctx.addIssue({
|
|
5822
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5823
|
+
path: ["eval_attachment_files"],
|
|
5824
|
+
message: `too many attachment carriers (${files.length}); the maximum is ${MAX_EVAL_ATTACHMENT_CARRIERS}`
|
|
5825
|
+
});
|
|
5826
|
+
}
|
|
5827
|
+
let aggregateEncoded = 0;
|
|
5828
|
+
files.forEach((f, i) => {
|
|
5829
|
+
const h = f?.hash;
|
|
5830
|
+
if (typeof h === "string") carriedHashes.add(h);
|
|
5831
|
+
const b64 = f?.content_base64;
|
|
5832
|
+
if (typeof b64 === "string") {
|
|
5833
|
+
aggregateEncoded += b64.length;
|
|
5834
|
+
if (b64.length > MAX_EVAL_ATTACHMENT_ENCODED_BYTES) {
|
|
5835
|
+
ctx.addIssue({
|
|
5836
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5837
|
+
path: ["eval_attachment_files", i, "content_base64"],
|
|
5838
|
+
message: `attachment ${typeof h === "string" ? `${h.slice(0, 12)}\u2026 ` : ""}exceeds the ${(MAX_RESOURCE_FILE_SIZE / 1024 / 1024).toFixed(0)}MB size limit`
|
|
5839
|
+
});
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
});
|
|
5843
|
+
if (aggregateEncoded > MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES) {
|
|
5844
|
+
ctx.addIssue({
|
|
5845
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5846
|
+
path: ["eval_attachment_files"],
|
|
5847
|
+
message: `total attachment bytes exceed the ${(MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES / 1024 / 1024).toFixed(0)}MB per-push limit \u2014 split the push or reduce attachments`
|
|
5848
|
+
});
|
|
5849
|
+
}
|
|
5850
|
+
}
|
|
5851
|
+
for (const hash of referencedHashes) {
|
|
5852
|
+
if (!carriedHashes.has(hash)) {
|
|
5853
|
+
ctx.addIssue({
|
|
5854
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5855
|
+
path: ["eval_attachment_files"],
|
|
5856
|
+
message: `attachment ${hash.slice(0, 12)}\u2026 is referenced by a turn but its bytes are missing from eval_attachment_files`
|
|
5857
|
+
});
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
}
|
|
5861
|
+
function isSafeTemplatePath(path30) {
|
|
5862
|
+
if (path30.length === 0 || path30.length > 300) return false;
|
|
5863
|
+
if (path30.startsWith("/") || path30.includes("\\")) return false;
|
|
5864
|
+
const segments = path30.split("/");
|
|
5705
5865
|
return segments.every(
|
|
5706
5866
|
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
5707
5867
|
);
|
|
@@ -5711,32 +5871,6 @@ function identifyTokenType(token) {
|
|
|
5711
5871
|
if (token.startsWith("eyJ")) return "jwt";
|
|
5712
5872
|
return "unknown";
|
|
5713
5873
|
}
|
|
5714
|
-
function foldDiacritics(input) {
|
|
5715
|
-
return input.normalize("NFKD").replace(/[̀-ͯ]/g, "");
|
|
5716
|
-
}
|
|
5717
|
-
function slugifyKebab(input, maxLength = 64) {
|
|
5718
|
-
if (typeof input !== "string") return "";
|
|
5719
|
-
return foldDiacritics(input).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").slice(0, maxLength).replace(/^-|-$/g, "");
|
|
5720
|
-
}
|
|
5721
|
-
function ensureUniqueSlug(slug, used) {
|
|
5722
|
-
if (!used.has(slug)) {
|
|
5723
|
-
used.add(slug);
|
|
5724
|
-
return slug;
|
|
5725
|
-
}
|
|
5726
|
-
for (let i = 2; i < 1e6; i++) {
|
|
5727
|
-
const suffix = `_${i}`;
|
|
5728
|
-
const baseLen = Math.max(1, 50 - suffix.length);
|
|
5729
|
-
const candidate = `${slug.slice(0, baseLen)}${suffix}`;
|
|
5730
|
-
if (!used.has(candidate)) {
|
|
5731
|
-
used.add(candidate);
|
|
5732
|
-
return candidate;
|
|
5733
|
-
}
|
|
5734
|
-
}
|
|
5735
|
-
throw new Error(`slug collision space exhausted for "${slug}"`);
|
|
5736
|
-
}
|
|
5737
|
-
function slugifySkillName(name) {
|
|
5738
|
-
return slugifyKebab(name, 64);
|
|
5739
|
-
}
|
|
5740
5874
|
function findStepBoundaries(transcript) {
|
|
5741
5875
|
const out = [];
|
|
5742
5876
|
const n = transcript.length;
|
|
@@ -5771,7 +5905,7 @@ function findStepBoundaries(transcript) {
|
|
|
5771
5905
|
}
|
|
5772
5906
|
return out;
|
|
5773
5907
|
}
|
|
5774
|
-
var UUID_RE, HEX_RE, WORKOS_ID_RE, OPAQUE_SECRET_RE, BASE64_SECRET_RE, BASE64_MARKER_RE, TOKEN_RE, SENSITIVE_FIELDS, SENSITIVE_KEY_ALTERNATION, SENSITIVE_KEY_PATTERN, JSON_CREDENTIAL_RE, QUERY_CREDENTIAL_RE, REDACTED, PROVIDER_TOKEN_RE, APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_CONTENT_BRAND, LlmProviderContentError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, uuidSchema, paginationSchema, timestampSchema, idParamSchema, clientOptionalString, clientOptionalBoolean, clientOptionalNumber, messageAttachment, MAX_MESSAGE_BODY_BYTES, MAX_ATTACHMENTS_PER_MESSAGE, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, summarizationThresholdField, monitorConfigField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, PREVIEW_LABEL_MAX_LENGTH, MAX_ENDED_INDEX_RETENTION_DAYS, previewLabelField, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, updateChannelTestIdentitiesBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, variantAiModeSchema, experimentStatusSchema, overlayUpdateSchema, experimentIdParam, variantIdParam, listExperimentsQuery, listVariantsQuery, listOverridesQuery, deleteOverrideQuery, createExperimentBody, updateExperimentBody, setExperimentStatusBody, createVariantBody, updateVariantBody, upsertOverrideBody, orgTagIdParam, listOrgTagsQuery, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlSchemaQuery, EVAL_PACING_PRESET_NAMES, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, getConversationsQuery, getMessagesQuery, appMessageSenderType, appMessageReceiverType, appMessageBody, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, sendMessageBody, listConversationsQuery, getConversationDetailParams, getConversationDetailQuery, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, uuidPattern, ciUuidSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminHubIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, adminSetOrgHarnessBody, adminSetHubHarnessBody, adminScopedTargetBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysQuery, dataExplorerKvKeyParam, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteQuery, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, sandboxEgressPolicy, SANDBOX_EXEC_MAX_CMD_LENGTH, SANDBOX_EXEC_MAX_ALLOWLIST, SANDBOX_EXEC_MAX_TIMEOUT_MS, adminSandboxExecBody, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, sentryRefStatusSchema, createReportBody, editReportBody, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, discordTier, discordBillingCycle, discordMetadata, discordOAuthStartResponse, discordOAuthFinalizeBody, discordOAuthFinalizeResponse, discordDisconnectResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, templateLocaleSchema, TEMPLATE_SLUG_REGEX, templateSlugSchema, templateStatusSchema, templateFileMapSchema, templateTextSchema, templateUsesEntrySchema, templateUsesSchema, templateYamlLocaleEntry, templateYamlWayaiBlock, templateTagsSchema, templateYamlSchema, templateHeroSchema, templatePushLocaleSchema, templatePushBody, templateListQuery, templateSlugParam, templateDetailQuery, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, WAYAI_WORKSPACE_LAYOUT, MAX_RESOURCE_FILE_SIZE;
|
|
5908
|
+
var UUID_RE, HEX_RE, WORKOS_ID_RE, OPAQUE_SECRET_RE, BASE64_SECRET_RE, BASE64_MARKER_RE, TOKEN_RE, SENSITIVE_FIELDS, SENSITIVE_KEY_ALTERNATION, SENSITIVE_KEY_PATTERN, JSON_CREDENTIAL_RE, QUERY_CREDENTIAL_RE, REDACTED, PROVIDER_TOKEN_RE, APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_CONTENT_BRAND, LlmProviderContentError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, uuidSchema, paginationSchema, timestampSchema, idParamSchema, clientOptionalString, clientOptionalBoolean, clientOptionalNumber, messageAttachment, MAX_MESSAGE_BODY_BYTES, MAX_ATTACHMENTS_PER_MESSAGE, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, summarizationThresholdField, monitorConfigField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, PREVIEW_LABEL_MAX_LENGTH, MAX_ENDED_INDEX_RETENTION_DAYS, previewLabelField, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, updateChannelTestIdentitiesBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, variantAiModeSchema, experimentStatusSchema, overlayUpdateSchema, experimentIdParam, variantIdParam, listExperimentsQuery, listVariantsQuery, listOverridesQuery, deleteOverrideQuery, createExperimentBody, updateExperimentBody, setExperimentStatusBody, createVariantBody, updateVariantBody, upsertOverrideBody, orgTagIdParam, listOrgTagsQuery, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlSchemaQuery, EVAL_PACING_PRESET_NAMES, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, EVAL_ATTACHMENT_HASH_REGEX, evalAttachmentRef, turnMayCarryAttachments, ATTACHMENTS_USER_ONLY_MESSAGE, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, getConversationsQuery, getMessagesQuery, appMessageSenderType, appMessageReceiverType, appMessageBody, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, sendMessageBody, listConversationsQuery, getConversationDetailParams, getConversationDetailQuery, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, MAX_RESOURCE_FILE_SIZE, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, uuidPattern, ciUuidSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminHubIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, adminSetOrgHarnessBody, adminSetHubHarnessBody, adminScopedTargetBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysQuery, dataExplorerKvKeyParam, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteQuery, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, sandboxEgressPolicy, SANDBOX_EXEC_MAX_CMD_LENGTH, SANDBOX_EXEC_MAX_ALLOWLIST, SANDBOX_EXEC_MAX_TIMEOUT_MS, adminSandboxExecBody, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, sentryRefStatusSchema, createReportBody, editReportBody, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, discordTier, discordBillingCycle, discordMetadata, discordOAuthStartResponse, discordOAuthFinalizeBody, discordOAuthFinalizeResponse, discordDisconnectResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, templateLocaleSchema, TEMPLATE_SLUG_REGEX, templateSlugSchema, templateStatusSchema, templateFileMapSchema, templateTextSchema, templateUsesEntrySchema, templateUsesSchema, templateYamlLocaleEntry, templateYamlWayaiBlock, templateTagsSchema, templateYamlSchema, templateHeroSchema, templatePushLocaleSchema, templatePushBody, templateListQuery, templateSlugParam, templateDetailQuery, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, WAYAI_WORKSPACE_LAYOUT;
|
|
5775
5909
|
var init_dist = __esm({
|
|
5776
5910
|
"../../packages/core/dist/index.js"() {
|
|
5777
5911
|
"use strict";
|
|
@@ -7100,10 +7234,10 @@ var init_dist = __esm({
|
|
|
7100
7234
|
ROLE_ECHO_MAX = 40;
|
|
7101
7235
|
createEvalBody = external_exports.object({
|
|
7102
7236
|
eval: external_exports.record(external_exports.unknown())
|
|
7103
|
-
}).superRefine(refineEvalMessageTextRole);
|
|
7237
|
+
}).superRefine(refineEvalMessageTextRole).superRefine(refineEvalAttachments);
|
|
7104
7238
|
updateEvalBody = external_exports.object({
|
|
7105
7239
|
eval: external_exports.record(external_exports.unknown())
|
|
7106
|
-
}).superRefine(refineEvalMessageTextRole);
|
|
7240
|
+
}).superRefine(refineEvalMessageTextRole).superRefine(refineEvalAttachments);
|
|
7107
7241
|
getEvalsQuery = external_exports.object({
|
|
7108
7242
|
hub_id: external_exports.string().uuid(),
|
|
7109
7243
|
agent_id: external_exports.string().uuid().optional(),
|
|
@@ -7230,6 +7364,15 @@ var init_dist = __esm({
|
|
|
7230
7364
|
journey_name: external_exports.string().min(1).max(200),
|
|
7231
7365
|
evaluator_instructions: external_exports.string().max(4e3).optional()
|
|
7232
7366
|
});
|
|
7367
|
+
EVAL_ATTACHMENT_HASH_REGEX = /^[a-f0-9]{64}$/;
|
|
7368
|
+
evalAttachmentRef = external_exports.object({
|
|
7369
|
+
hash: external_exports.string().regex(EVAL_ATTACHMENT_HASH_REGEX),
|
|
7370
|
+
file_name: external_exports.string().min(1).max(255),
|
|
7371
|
+
mime_type: external_exports.string().min(1).max(255),
|
|
7372
|
+
file_size: external_exports.number().int().positive().optional()
|
|
7373
|
+
});
|
|
7374
|
+
turnMayCarryAttachments = (turn) => !turn.attachments || turn.attachments.length === 0 || turn.role === "user";
|
|
7375
|
+
ATTACHMENTS_USER_ONLY_MESSAGE = "attachments are only valid on user turns";
|
|
7233
7376
|
journeyIdParam = external_exports.object({ id: external_exports.string().uuid() });
|
|
7234
7377
|
journeyToolCallSchema = external_exports.object({
|
|
7235
7378
|
id: external_exports.string(),
|
|
@@ -7241,7 +7384,10 @@ var init_dist = __esm({
|
|
|
7241
7384
|
content: external_exports.string().nullable().optional(),
|
|
7242
7385
|
tool_calls: external_exports.array(journeyToolCallSchema).optional(),
|
|
7243
7386
|
tool_call_id: external_exports.string().optional(),
|
|
7244
|
-
step_id: external_exports.string().optional()
|
|
7387
|
+
step_id: external_exports.string().optional(),
|
|
7388
|
+
attachments: external_exports.array(evalAttachmentRef).max(MAX_ATTACHMENTS_PER_MESSAGE).optional()
|
|
7389
|
+
}).refine(turnMayCarryAttachments, {
|
|
7390
|
+
message: ATTACHMENTS_USER_ONLY_MESSAGE
|
|
7245
7391
|
});
|
|
7246
7392
|
journeyStepOverrideSchema = external_exports.object({
|
|
7247
7393
|
number_of_runs: external_exports.number().int().positive().max(100).optional(),
|
|
@@ -7746,6 +7892,10 @@ var init_dist = __esm({
|
|
|
7746
7892
|
agent_id: external_exports.string().uuid().nullable().optional(),
|
|
7747
7893
|
trigger_message: external_exports.string().nullable().optional()
|
|
7748
7894
|
});
|
|
7895
|
+
MAX_RESOURCE_FILE_SIZE = 10 * 1024 * 1024;
|
|
7896
|
+
MAX_EVAL_ATTACHMENT_ENCODED_BYTES = Math.ceil(MAX_RESOURCE_FILE_SIZE / 3) * 4 + 16;
|
|
7897
|
+
MAX_EVAL_ATTACHMENT_CARRIERS = 1e3;
|
|
7898
|
+
MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES = 16 * 1024 * 1024;
|
|
7749
7899
|
uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7750
7900
|
ciUuidSchema = external_exports.string().regex(uuidPattern, "must be a valid UUID");
|
|
7751
7901
|
hubAsCodeConfigSchema = external_exports.object({
|
|
@@ -7758,6 +7908,7 @@ var init_dist = __esm({
|
|
|
7758
7908
|
refineHubAsCodeKanbanStatuses(config, ctx);
|
|
7759
7909
|
refineHubAsCodeLanes(config, ctx);
|
|
7760
7910
|
refineHubAsCodeEvals(config, ctx);
|
|
7911
|
+
refineHubAsCodeEvalAttachments(config, ctx);
|
|
7761
7912
|
});
|
|
7762
7913
|
ciPullHubIdParam = external_exports.object({
|
|
7763
7914
|
hub_id: ciUuidSchema
|
|
@@ -8589,7 +8740,6 @@ var init_dist = __esm({
|
|
|
8589
8740
|
/** Subdir of `wsDir` holding org-as-code. */
|
|
8590
8741
|
orgSubdir: "org"
|
|
8591
8742
|
};
|
|
8592
|
-
MAX_RESOURCE_FILE_SIZE = 10 * 1024 * 1024;
|
|
8593
8743
|
}
|
|
8594
8744
|
});
|
|
8595
8745
|
|
|
@@ -9145,24 +9295,24 @@ import * as path4 from "path";
|
|
|
9145
9295
|
import * as readline from "readline";
|
|
9146
9296
|
function prompt(question) {
|
|
9147
9297
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9148
|
-
return new Promise((
|
|
9298
|
+
return new Promise((resolve6) => {
|
|
9149
9299
|
rl.question(question, (answer) => {
|
|
9150
9300
|
rl.close();
|
|
9151
|
-
|
|
9301
|
+
resolve6(answer.trim());
|
|
9152
9302
|
});
|
|
9153
9303
|
});
|
|
9154
9304
|
}
|
|
9155
9305
|
function confirm(question) {
|
|
9156
9306
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9157
|
-
return new Promise((
|
|
9307
|
+
return new Promise((resolve6) => {
|
|
9158
9308
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
9159
9309
|
rl.close();
|
|
9160
|
-
|
|
9310
|
+
resolve6(answer.trim().toLowerCase() === "y");
|
|
9161
9311
|
});
|
|
9162
9312
|
});
|
|
9163
9313
|
}
|
|
9164
9314
|
function promptSecret(question) {
|
|
9165
|
-
return new Promise((
|
|
9315
|
+
return new Promise((resolve6) => {
|
|
9166
9316
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9167
9317
|
const originalWrite = rl._writeToOutput;
|
|
9168
9318
|
let firstWrite = true;
|
|
@@ -9178,18 +9328,18 @@ function promptSecret(question) {
|
|
|
9178
9328
|
rl._writeToOutput = originalWrite;
|
|
9179
9329
|
process.stdout.write("\n");
|
|
9180
9330
|
rl.close();
|
|
9181
|
-
|
|
9331
|
+
resolve6(answer);
|
|
9182
9332
|
});
|
|
9183
9333
|
});
|
|
9184
9334
|
}
|
|
9185
9335
|
function readStdin() {
|
|
9186
|
-
return new Promise((
|
|
9336
|
+
return new Promise((resolve6, reject) => {
|
|
9187
9337
|
let data = "";
|
|
9188
9338
|
process.stdin.setEncoding("utf-8");
|
|
9189
9339
|
process.stdin.on("data", (chunk) => {
|
|
9190
9340
|
data += chunk;
|
|
9191
9341
|
});
|
|
9192
|
-
process.stdin.on("end", () =>
|
|
9342
|
+
process.stdin.on("end", () => resolve6(data.trim()));
|
|
9193
9343
|
process.stdin.on("error", reject);
|
|
9194
9344
|
});
|
|
9195
9345
|
}
|
|
@@ -9351,9 +9501,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
9351
9501
|
}
|
|
9352
9502
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
9353
9503
|
try {
|
|
9354
|
-
const
|
|
9355
|
-
if (!existsSync4(
|
|
9356
|
-
const parsed = JSON.parse(readFileSync5(
|
|
9504
|
+
const path30 = getVersionCachePath(filename);
|
|
9505
|
+
if (!existsSync4(path30)) return null;
|
|
9506
|
+
const parsed = JSON.parse(readFileSync5(path30, "utf-8"));
|
|
9357
9507
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
9358
9508
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
9359
9509
|
return parsed;
|
|
@@ -9373,10 +9523,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
9373
9523
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
9374
9524
|
}
|
|
9375
9525
|
function writeVersionCache(filename, cache) {
|
|
9376
|
-
const
|
|
9377
|
-
const dir = dirname3(
|
|
9526
|
+
const path30 = getVersionCachePath(filename);
|
|
9527
|
+
const dir = dirname3(path30);
|
|
9378
9528
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
9379
|
-
writeFileSync2(
|
|
9529
|
+
writeFileSync2(path30, JSON.stringify(cache));
|
|
9380
9530
|
}
|
|
9381
9531
|
function touchVersionCache(filename) {
|
|
9382
9532
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -9415,14 +9565,14 @@ function parseFrontmatterVersion(content) {
|
|
|
9415
9565
|
function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
9416
9566
|
const found = [];
|
|
9417
9567
|
for (const rel of paths) {
|
|
9418
|
-
const
|
|
9419
|
-
if (!existsSync5(
|
|
9568
|
+
const path30 = join7(projectRoot, rel);
|
|
9569
|
+
if (!existsSync5(path30)) continue;
|
|
9420
9570
|
let version = null;
|
|
9421
9571
|
try {
|
|
9422
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
9572
|
+
version = parseFrontmatterVersion(readFileSync6(path30, "utf-8"));
|
|
9423
9573
|
} catch {
|
|
9424
9574
|
}
|
|
9425
|
-
found.push({ path:
|
|
9575
|
+
found.push({ path: path30, version });
|
|
9426
9576
|
}
|
|
9427
9577
|
return found;
|
|
9428
9578
|
}
|
|
@@ -9883,7 +10033,7 @@ async function validateToken(apiUrl, token) {
|
|
|
9883
10033
|
}
|
|
9884
10034
|
}
|
|
9885
10035
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
9886
|
-
return new Promise((
|
|
10036
|
+
return new Promise((resolve6, reject) => {
|
|
9887
10037
|
const server = http.createServer((req, res) => {
|
|
9888
10038
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
9889
10039
|
if (url.pathname === "/callback") {
|
|
@@ -9909,7 +10059,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
9909
10059
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9910
10060
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
9911
10061
|
server.close();
|
|
9912
|
-
|
|
10062
|
+
resolve6({ code, port });
|
|
9913
10063
|
} else {
|
|
9914
10064
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
9915
10065
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -10119,10 +10269,10 @@ import * as readline2 from "readline";
|
|
|
10119
10269
|
function prompt2(question, defaultValue) {
|
|
10120
10270
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
10121
10271
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
10122
|
-
return new Promise((
|
|
10272
|
+
return new Promise((resolve6) => {
|
|
10123
10273
|
rl.question(display, (answer) => {
|
|
10124
10274
|
rl.close();
|
|
10125
|
-
|
|
10275
|
+
resolve6(answer.trim() || defaultValue || "");
|
|
10126
10276
|
});
|
|
10127
10277
|
});
|
|
10128
10278
|
}
|
|
@@ -10240,8 +10390,8 @@ async function tryOpenBrowser(url) {
|
|
|
10240
10390
|
cmd = "xdg-open";
|
|
10241
10391
|
args2 = [url];
|
|
10242
10392
|
}
|
|
10243
|
-
return new Promise((
|
|
10244
|
-
execFile(cmd, args2, (err) =>
|
|
10393
|
+
return new Promise((resolve6) => {
|
|
10394
|
+
execFile(cmd, args2, (err) => resolve6(!err));
|
|
10245
10395
|
});
|
|
10246
10396
|
} catch {
|
|
10247
10397
|
return false;
|
|
@@ -10881,9 +11031,86 @@ var init_init = __esm({
|
|
|
10881
11031
|
}
|
|
10882
11032
|
});
|
|
10883
11033
|
|
|
10884
|
-
// src/lib/
|
|
11034
|
+
// src/lib/fs-safety.ts
|
|
10885
11035
|
import * as fs9 from "fs";
|
|
10886
11036
|
import * as path11 from "path";
|
|
11037
|
+
function realpathContained(root, abs) {
|
|
11038
|
+
let realRoot;
|
|
11039
|
+
let realAbs;
|
|
11040
|
+
try {
|
|
11041
|
+
realRoot = fs9.realpathSync(root);
|
|
11042
|
+
realAbs = fs9.realpathSync(abs);
|
|
11043
|
+
} catch {
|
|
11044
|
+
return false;
|
|
11045
|
+
}
|
|
11046
|
+
return realAbs === realRoot || realAbs.startsWith(realRoot + path11.sep);
|
|
11047
|
+
}
|
|
11048
|
+
function mkdirTolerateRace(dir) {
|
|
11049
|
+
try {
|
|
11050
|
+
fs9.mkdirSync(dir);
|
|
11051
|
+
return true;
|
|
11052
|
+
} catch (err) {
|
|
11053
|
+
if (err.code !== "EEXIST") throw err;
|
|
11054
|
+
let st;
|
|
11055
|
+
try {
|
|
11056
|
+
st = fs9.lstatSync(dir);
|
|
11057
|
+
} catch {
|
|
11058
|
+
st = void 0;
|
|
11059
|
+
}
|
|
11060
|
+
return !!st?.isDirectory();
|
|
11061
|
+
}
|
|
11062
|
+
}
|
|
11063
|
+
function ensureRealSubdirNoSymlink(root, target, create) {
|
|
11064
|
+
const rootResolved = path11.resolve(root);
|
|
11065
|
+
const targetResolved = path11.resolve(target);
|
|
11066
|
+
if (targetResolved !== rootResolved && !targetResolved.startsWith(rootResolved + path11.sep)) return false;
|
|
11067
|
+
try {
|
|
11068
|
+
if (!fs9.lstatSync(rootResolved).isDirectory()) return false;
|
|
11069
|
+
} catch {
|
|
11070
|
+
return false;
|
|
11071
|
+
}
|
|
11072
|
+
const rel = path11.relative(rootResolved, targetResolved);
|
|
11073
|
+
if (rel === "") return true;
|
|
11074
|
+
let cur = rootResolved;
|
|
11075
|
+
for (const segment of rel.split(path11.sep)) {
|
|
11076
|
+
cur = path11.join(cur, segment);
|
|
11077
|
+
let st;
|
|
11078
|
+
try {
|
|
11079
|
+
st = fs9.lstatSync(cur);
|
|
11080
|
+
} catch {
|
|
11081
|
+
st = void 0;
|
|
11082
|
+
}
|
|
11083
|
+
if (st) {
|
|
11084
|
+
if (!st.isDirectory()) return false;
|
|
11085
|
+
} else if (create) {
|
|
11086
|
+
if (!mkdirTolerateRace(cur)) return false;
|
|
11087
|
+
} else {
|
|
11088
|
+
return true;
|
|
11089
|
+
}
|
|
11090
|
+
}
|
|
11091
|
+
return true;
|
|
11092
|
+
}
|
|
11093
|
+
function writeFileNoFollow(root, abs, data) {
|
|
11094
|
+
const parent = path11.dirname(abs);
|
|
11095
|
+
if (!ensureRealSubdirNoSymlink(root, parent, true)) return false;
|
|
11096
|
+
let st;
|
|
11097
|
+
try {
|
|
11098
|
+
st = fs9.lstatSync(abs);
|
|
11099
|
+
} catch {
|
|
11100
|
+
}
|
|
11101
|
+
if (st?.isSymbolicLink()) fs9.rmSync(abs);
|
|
11102
|
+
fs9.writeFileSync(abs, data);
|
|
11103
|
+
return true;
|
|
11104
|
+
}
|
|
11105
|
+
var init_fs_safety = __esm({
|
|
11106
|
+
"src/lib/fs-safety.ts"() {
|
|
11107
|
+
"use strict";
|
|
11108
|
+
}
|
|
11109
|
+
});
|
|
11110
|
+
|
|
11111
|
+
// src/lib/resource-files.ts
|
|
11112
|
+
import * as fs10 from "fs";
|
|
11113
|
+
import * as path12 from "path";
|
|
10887
11114
|
import * as crypto3 from "crypto";
|
|
10888
11115
|
function isBinaryFile(filename) {
|
|
10889
11116
|
const ext = filename.split(".").pop()?.toLowerCase() || "";
|
|
@@ -10929,14 +11156,14 @@ function computeHash(data) {
|
|
|
10929
11156
|
}
|
|
10930
11157
|
function scanResourceFiles(dir, prefix = "") {
|
|
10931
11158
|
const files = [];
|
|
10932
|
-
const entries =
|
|
11159
|
+
const entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
10933
11160
|
for (const entry of entries) {
|
|
10934
11161
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
10935
11162
|
if (entry.isDirectory()) {
|
|
10936
|
-
files.push(...scanResourceFiles(
|
|
11163
|
+
files.push(...scanResourceFiles(path12.join(dir, entry.name), relPath));
|
|
10937
11164
|
} else if (entry.isFile()) {
|
|
10938
|
-
const fullPath =
|
|
10939
|
-
const stat =
|
|
11165
|
+
const fullPath = path12.join(dir, entry.name);
|
|
11166
|
+
const stat = fs10.statSync(fullPath);
|
|
10940
11167
|
if (stat.size > MAX_RESOURCE_FILE_SIZE2) {
|
|
10941
11168
|
console.warn(` Warning: skipping ${relPath} (${(stat.size / 1024 / 1024).toFixed(1)}MB exceeds 10MB limit)`);
|
|
10942
11169
|
continue;
|
|
@@ -10946,7 +11173,7 @@ function scanResourceFiles(dir, prefix = "") {
|
|
|
10946
11173
|
mime_type: guessMimeType(entry.name),
|
|
10947
11174
|
file_size: stat.size
|
|
10948
11175
|
};
|
|
10949
|
-
const data =
|
|
11176
|
+
const data = fs10.readFileSync(fullPath);
|
|
10950
11177
|
fileEntry.hash = computeHash(data);
|
|
10951
11178
|
if (isBinaryFile(entry.name)) {
|
|
10952
11179
|
fileEntry.content_base64 = data.toString("base64");
|
|
@@ -10958,49 +11185,61 @@ function scanResourceFiles(dir, prefix = "") {
|
|
|
10958
11185
|
}
|
|
10959
11186
|
return files;
|
|
10960
11187
|
}
|
|
10961
|
-
function writeResourceFileTree(resDir, files) {
|
|
11188
|
+
function writeResourceFileTree(resDir, files, root) {
|
|
11189
|
+
if (!ensureRealSubdirNoSymlink(root, resDir, files.length > 0)) {
|
|
11190
|
+
console.warn(` Warning: skipping resource dir (not reachable inside the workspace without a symlink)`);
|
|
11191
|
+
return;
|
|
11192
|
+
}
|
|
10962
11193
|
if (files.length === 0) {
|
|
10963
|
-
if (
|
|
11194
|
+
if (fs10.existsSync(resDir)) cleanOrphanFiles(resDir, "", /* @__PURE__ */ new Set());
|
|
10964
11195
|
return;
|
|
10965
11196
|
}
|
|
10966
11197
|
const writtenPaths = /* @__PURE__ */ new Set();
|
|
10967
11198
|
for (const file of files) {
|
|
10968
|
-
const filePath =
|
|
10969
|
-
if (!filePath.startsWith(resDir +
|
|
11199
|
+
const filePath = path12.join(resDir, file.path);
|
|
11200
|
+
if (!filePath.startsWith(resDir + path12.sep) && filePath !== resDir) {
|
|
10970
11201
|
console.warn(` Warning: skipping ${file.path} (path traversal detected)`);
|
|
10971
11202
|
continue;
|
|
10972
11203
|
}
|
|
10973
|
-
const fileDir = path11.dirname(filePath);
|
|
10974
|
-
if (!fs9.existsSync(fileDir)) fs9.mkdirSync(fileDir, { recursive: true });
|
|
10975
11204
|
writtenPaths.add(file.path);
|
|
10976
11205
|
if (file.content !== void 0) {
|
|
10977
|
-
|
|
11206
|
+
if (!writeFileNoFollow(resDir, filePath, Buffer.from(file.content, "utf-8"))) {
|
|
11207
|
+
console.warn(` Warning: skipping ${file.path} (destination escapes the resource folder via a symlink)`);
|
|
11208
|
+
writtenPaths.delete(file.path);
|
|
11209
|
+
}
|
|
10978
11210
|
} else if (file.content_base64) {
|
|
10979
|
-
|
|
11211
|
+
if (!writeFileNoFollow(resDir, filePath, Buffer.from(file.content_base64, "base64"))) {
|
|
11212
|
+
console.warn(` Warning: skipping ${file.path} (destination escapes the resource folder via a symlink)`);
|
|
11213
|
+
writtenPaths.delete(file.path);
|
|
11214
|
+
}
|
|
10980
11215
|
}
|
|
10981
11216
|
}
|
|
10982
|
-
if (
|
|
11217
|
+
if (fs10.existsSync(resDir)) cleanOrphanFiles(resDir, "", writtenPaths);
|
|
10983
11218
|
}
|
|
10984
11219
|
function cleanOrphanFiles(dir, prefix, writtenPaths) {
|
|
10985
|
-
const entries =
|
|
11220
|
+
const entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
10986
11221
|
for (const entry of entries) {
|
|
10987
11222
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
10988
|
-
const fullPath =
|
|
11223
|
+
const fullPath = path12.join(dir, entry.name);
|
|
10989
11224
|
if (entry.isDirectory()) {
|
|
10990
11225
|
cleanOrphanFiles(fullPath, relPath, writtenPaths);
|
|
10991
|
-
if (
|
|
11226
|
+
if (fs10.readdirSync(fullPath).length === 0) fs10.rmdirSync(fullPath);
|
|
10992
11227
|
} else if (!writtenPaths.has(relPath)) {
|
|
10993
|
-
|
|
11228
|
+
fs10.unlinkSync(fullPath);
|
|
10994
11229
|
}
|
|
10995
11230
|
}
|
|
10996
11231
|
}
|
|
10997
|
-
async function downloadBinaryFiles(resDir, files) {
|
|
11232
|
+
async function downloadBinaryFiles(resDir, files, root) {
|
|
11233
|
+
if (!ensureRealSubdirNoSymlink(root, resDir, true)) {
|
|
11234
|
+
console.warn(` Warning: skipping resource downloads (dir not reachable inside the workspace without a symlink)`);
|
|
11235
|
+
return 0;
|
|
11236
|
+
}
|
|
10998
11237
|
let count = 0;
|
|
10999
11238
|
for (const file of files) {
|
|
11000
11239
|
if (!file.download_url || file.content !== void 0) continue;
|
|
11001
11240
|
try {
|
|
11002
|
-
const filePath =
|
|
11003
|
-
if (!filePath.startsWith(resDir +
|
|
11241
|
+
const filePath = path12.join(resDir, file.path);
|
|
11242
|
+
if (!filePath.startsWith(resDir + path12.sep) && filePath !== resDir) {
|
|
11004
11243
|
console.warn(` Warning: skipping ${file.path} (path traversal detected)`);
|
|
11005
11244
|
continue;
|
|
11006
11245
|
}
|
|
@@ -11010,10 +11249,8 @@ async function downloadBinaryFiles(resDir, files) {
|
|
|
11010
11249
|
continue;
|
|
11011
11250
|
}
|
|
11012
11251
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
11013
|
-
|
|
11014
|
-
|
|
11015
|
-
fs9.writeFileSync(filePath, buffer);
|
|
11016
|
-
count++;
|
|
11252
|
+
if (writeFileNoFollow(resDir, filePath, buffer)) count++;
|
|
11253
|
+
else console.warn(` Warning: skipping ${file.path} (destination escapes the resource folder via a symlink)`);
|
|
11017
11254
|
} catch (err) {
|
|
11018
11255
|
console.warn(` Warning: failed to download ${file.path} (${err instanceof Error ? err.message : String(err)})`);
|
|
11019
11256
|
}
|
|
@@ -11024,6 +11261,7 @@ var BINARY_EXTENSIONS, MAX_RESOURCE_FILE_SIZE2;
|
|
|
11024
11261
|
var init_resource_files = __esm({
|
|
11025
11262
|
"src/lib/resource-files.ts"() {
|
|
11026
11263
|
"use strict";
|
|
11264
|
+
init_fs_safety();
|
|
11027
11265
|
BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
11028
11266
|
"pdf",
|
|
11029
11267
|
"png",
|
|
@@ -11049,8 +11287,8 @@ var init_resource_files = __esm({
|
|
|
11049
11287
|
});
|
|
11050
11288
|
|
|
11051
11289
|
// src/lib/yaml-writer.ts
|
|
11052
|
-
import * as
|
|
11053
|
-
import * as
|
|
11290
|
+
import * as fs11 from "fs";
|
|
11291
|
+
import * as path13 from "path";
|
|
11054
11292
|
import * as yaml4 from "js-yaml";
|
|
11055
11293
|
function buildEvalYamlObject(evalEntry, slug) {
|
|
11056
11294
|
const out = {};
|
|
@@ -11084,42 +11322,42 @@ function buildEvalYamlObject(evalEntry, slug) {
|
|
|
11084
11322
|
return out;
|
|
11085
11323
|
}
|
|
11086
11324
|
function writeHubFolder(hubFolder, payload, options = {}) {
|
|
11087
|
-
const agentsDir =
|
|
11088
|
-
if (!
|
|
11089
|
-
|
|
11325
|
+
const agentsDir = path13.join(hubFolder, "agents");
|
|
11326
|
+
if (!fs11.existsSync(hubFolder)) {
|
|
11327
|
+
fs11.mkdirSync(hubFolder, { recursive: true });
|
|
11090
11328
|
}
|
|
11091
|
-
if (!
|
|
11092
|
-
|
|
11329
|
+
if (!fs11.existsSync(agentsDir)) {
|
|
11330
|
+
fs11.mkdirSync(agentsDir, { recursive: true });
|
|
11093
11331
|
}
|
|
11094
11332
|
const yamlPayload = buildYamlPayload(payload);
|
|
11095
11333
|
const agentFiles = extractAgentFiles(payload);
|
|
11096
11334
|
const yamlContent = yaml4.dump(yamlPayload, YAML_DUMP_OPTIONS);
|
|
11097
|
-
|
|
11335
|
+
fs11.writeFileSync(path13.join(hubFolder, "hub.yaml"), yamlContent, "utf-8");
|
|
11098
11336
|
if (options.seedAgentContext ?? true) {
|
|
11099
|
-
writeIfAbsent(
|
|
11100
|
-
writeIfAbsent(
|
|
11337
|
+
writeIfAbsent(path13.join(hubFolder, "AGENTS.md"), perHubAgentsMd(path13.basename(hubFolder)));
|
|
11338
|
+
writeIfAbsent(path13.join(hubFolder, "CLAUDE.md"), CLAUDE_MD_SHIM);
|
|
11101
11339
|
}
|
|
11102
|
-
const oldYamlPath =
|
|
11103
|
-
if (
|
|
11104
|
-
|
|
11340
|
+
const oldYamlPath = path13.join(hubFolder, "wayai.yaml");
|
|
11341
|
+
if (fs11.existsSync(oldYamlPath)) {
|
|
11342
|
+
fs11.unlinkSync(oldYamlPath);
|
|
11105
11343
|
}
|
|
11106
11344
|
const yamlSlugs = writeAgentYamlFiles(agentsDir, payload.agents || []);
|
|
11107
11345
|
const mdSlugs = /* @__PURE__ */ new Set();
|
|
11108
11346
|
for (const { slug, content } of agentFiles) {
|
|
11109
11347
|
mdSlugs.add(slug);
|
|
11110
|
-
|
|
11348
|
+
fs11.writeFileSync(path13.join(agentsDir, `${slug}.md`), content, "utf-8");
|
|
11111
11349
|
}
|
|
11112
|
-
const existingFiles =
|
|
11350
|
+
const existingFiles = fs11.readdirSync(agentsDir);
|
|
11113
11351
|
for (const file of existingFiles) {
|
|
11114
11352
|
if (file.endsWith(".yaml")) {
|
|
11115
11353
|
const slug = file.slice(0, -5);
|
|
11116
11354
|
if (!yamlSlugs.has(slug)) {
|
|
11117
|
-
|
|
11355
|
+
fs11.unlinkSync(path13.join(agentsDir, file));
|
|
11118
11356
|
}
|
|
11119
11357
|
} else if (file.endsWith(".md")) {
|
|
11120
11358
|
const slug = file.slice(0, -3);
|
|
11121
11359
|
if (!mdSlugs.has(slug)) {
|
|
11122
|
-
|
|
11360
|
+
fs11.unlinkSync(path13.join(agentsDir, file));
|
|
11123
11361
|
}
|
|
11124
11362
|
}
|
|
11125
11363
|
}
|
|
@@ -11130,10 +11368,10 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
11130
11368
|
function setPreviewLabelInHubYaml(hubFolder, label) {
|
|
11131
11369
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
11132
11370
|
if (!yamlPath) return;
|
|
11133
|
-
const obj = yaml4.load(
|
|
11371
|
+
const obj = yaml4.load(fs11.readFileSync(yamlPath, "utf-8")) ?? {};
|
|
11134
11372
|
if (label) obj.preview_label = label;
|
|
11135
11373
|
else delete obj.preview_label;
|
|
11136
|
-
|
|
11374
|
+
fs11.writeFileSync(yamlPath, yaml4.dump(obj, YAML_DUMP_OPTIONS), "utf-8");
|
|
11137
11375
|
}
|
|
11138
11376
|
function buildYamlPayload(payload) {
|
|
11139
11377
|
const result = {
|
|
@@ -11179,7 +11417,7 @@ function writeAgentYamlFiles(agentsDir, agents) {
|
|
|
11179
11417
|
const entry = { ...agent };
|
|
11180
11418
|
delete entry.instructions;
|
|
11181
11419
|
const yamlContent = yaml4.dump(entry, YAML_DUMP_OPTIONS);
|
|
11182
|
-
|
|
11420
|
+
fs11.writeFileSync(path13.join(agentsDir, `${slug}.yaml`), yamlContent, "utf-8");
|
|
11183
11421
|
}
|
|
11184
11422
|
return slugs;
|
|
11185
11423
|
}
|
|
@@ -11196,65 +11434,65 @@ function extractAgentFiles(payload) {
|
|
|
11196
11434
|
return files;
|
|
11197
11435
|
}
|
|
11198
11436
|
function writeEvalYamlFiles(hubFolder, evals) {
|
|
11199
|
-
const evalsDir =
|
|
11437
|
+
const evalsDir = path13.join(hubFolder, "evals");
|
|
11200
11438
|
if (evals.length === 0) {
|
|
11201
|
-
if (
|
|
11439
|
+
if (fs11.existsSync(evalsDir)) {
|
|
11202
11440
|
cleanEvalOrphans(evalsDir, /* @__PURE__ */ new Set());
|
|
11203
11441
|
try {
|
|
11204
|
-
if (
|
|
11442
|
+
if (fs11.readdirSync(evalsDir).length === 0) fs11.rmdirSync(evalsDir);
|
|
11205
11443
|
} catch {
|
|
11206
11444
|
}
|
|
11207
11445
|
}
|
|
11208
11446
|
return;
|
|
11209
11447
|
}
|
|
11210
|
-
if (!
|
|
11211
|
-
|
|
11448
|
+
if (!fs11.existsSync(evalsDir)) {
|
|
11449
|
+
fs11.mkdirSync(evalsDir, { recursive: true });
|
|
11212
11450
|
}
|
|
11213
11451
|
const writtenRelPaths = /* @__PURE__ */ new Set();
|
|
11214
11452
|
for (const evalEntry of evals) {
|
|
11215
11453
|
const slug = slugify(evalEntry.name);
|
|
11216
11454
|
const setName = evalEntry.path && evalEntry.path.trim().length > 0 ? evalEntry.path : null;
|
|
11217
11455
|
const relPath = setName ? `${setName}/${slug}.yaml` : `${slug}.yaml`;
|
|
11218
|
-
const targetPath =
|
|
11219
|
-
if (!targetPath.startsWith(evalsDir +
|
|
11456
|
+
const targetPath = path13.join(evalsDir, relPath);
|
|
11457
|
+
if (!targetPath.startsWith(evalsDir + path13.sep)) {
|
|
11220
11458
|
console.warn(` Warning: skipping eval "${evalEntry.name}" (scenario set "${setName}" escapes evals/ \u2014 possible bad backend data)`);
|
|
11221
11459
|
continue;
|
|
11222
11460
|
}
|
|
11223
11461
|
if (setName) {
|
|
11224
|
-
const setDir =
|
|
11225
|
-
if (!
|
|
11226
|
-
|
|
11462
|
+
const setDir = path13.join(evalsDir, setName);
|
|
11463
|
+
if (!fs11.existsSync(setDir)) {
|
|
11464
|
+
fs11.mkdirSync(setDir, { recursive: true });
|
|
11227
11465
|
}
|
|
11228
11466
|
}
|
|
11229
11467
|
const yamlContent = yaml4.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
|
|
11230
|
-
|
|
11468
|
+
fs11.writeFileSync(targetPath, yamlContent, "utf-8");
|
|
11231
11469
|
writtenRelPaths.add(relPath);
|
|
11232
11470
|
}
|
|
11233
11471
|
cleanEvalOrphans(evalsDir, writtenRelPaths);
|
|
11234
11472
|
}
|
|
11235
11473
|
function cleanEvalOrphans(evalsDir, writtenRelPaths) {
|
|
11236
|
-
const entries =
|
|
11474
|
+
const entries = fs11.readdirSync(evalsDir, { withFileTypes: true });
|
|
11237
11475
|
for (const entry of entries) {
|
|
11238
|
-
const fullPath =
|
|
11476
|
+
const fullPath = path13.join(evalsDir, entry.name);
|
|
11239
11477
|
if (entry.isFile()) {
|
|
11240
11478
|
if (entry.name.endsWith(".yaml") && !writtenRelPaths.has(entry.name)) {
|
|
11241
|
-
|
|
11479
|
+
fs11.unlinkSync(fullPath);
|
|
11242
11480
|
}
|
|
11243
11481
|
continue;
|
|
11244
11482
|
}
|
|
11245
11483
|
if (entry.isDirectory()) {
|
|
11246
11484
|
const setName = entry.name;
|
|
11247
|
-
const subEntries =
|
|
11485
|
+
const subEntries = fs11.readdirSync(fullPath, { withFileTypes: true });
|
|
11248
11486
|
for (const sub of subEntries) {
|
|
11249
11487
|
if (sub.isFile() && sub.name.endsWith(".yaml")) {
|
|
11250
11488
|
const relPath = `${setName}/${sub.name}`;
|
|
11251
11489
|
if (!writtenRelPaths.has(relPath)) {
|
|
11252
|
-
|
|
11490
|
+
fs11.unlinkSync(path13.join(fullPath, sub.name));
|
|
11253
11491
|
}
|
|
11254
11492
|
}
|
|
11255
11493
|
}
|
|
11256
11494
|
try {
|
|
11257
|
-
if (
|
|
11495
|
+
if (fs11.readdirSync(fullPath).length === 0) fs11.rmdirSync(fullPath);
|
|
11258
11496
|
} catch {
|
|
11259
11497
|
}
|
|
11260
11498
|
}
|
|
@@ -11290,19 +11528,19 @@ function buildJourneyYamlObject(journeyEntry, slug) {
|
|
|
11290
11528
|
return out;
|
|
11291
11529
|
}
|
|
11292
11530
|
function writeJourneyYamlFiles(hubFolder, journeys) {
|
|
11293
|
-
const journeysDir =
|
|
11531
|
+
const journeysDir = path13.join(hubFolder, "journeys");
|
|
11294
11532
|
if (journeys.length === 0) {
|
|
11295
|
-
if (
|
|
11533
|
+
if (fs11.existsSync(journeysDir)) {
|
|
11296
11534
|
cleanJourneyOrphans(journeysDir, /* @__PURE__ */ new Set());
|
|
11297
11535
|
try {
|
|
11298
|
-
if (
|
|
11536
|
+
if (fs11.readdirSync(journeysDir).length === 0) fs11.rmdirSync(journeysDir);
|
|
11299
11537
|
} catch {
|
|
11300
11538
|
}
|
|
11301
11539
|
}
|
|
11302
11540
|
return;
|
|
11303
11541
|
}
|
|
11304
|
-
if (!
|
|
11305
|
-
|
|
11542
|
+
if (!fs11.existsSync(journeysDir)) {
|
|
11543
|
+
fs11.mkdirSync(journeysDir, { recursive: true });
|
|
11306
11544
|
}
|
|
11307
11545
|
const writtenFiles = /* @__PURE__ */ new Set();
|
|
11308
11546
|
const usedSlugs = /* @__PURE__ */ new Set();
|
|
@@ -11310,33 +11548,33 @@ function writeJourneyYamlFiles(hubFolder, journeys) {
|
|
|
11310
11548
|
const slug = ensureUniqueSlug(slugify(journeyEntry.name), usedSlugs);
|
|
11311
11549
|
const fileName = `${slug}.yaml`;
|
|
11312
11550
|
const yamlContent = yaml4.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
|
|
11313
|
-
|
|
11551
|
+
fs11.writeFileSync(path13.join(journeysDir, fileName), yamlContent, "utf-8");
|
|
11314
11552
|
writtenFiles.add(fileName);
|
|
11315
11553
|
}
|
|
11316
11554
|
cleanJourneyOrphans(journeysDir, writtenFiles);
|
|
11317
11555
|
}
|
|
11318
11556
|
function cleanJourneyOrphans(journeysDir, writtenFiles) {
|
|
11319
|
-
const entries =
|
|
11557
|
+
const entries = fs11.readdirSync(journeysDir, { withFileTypes: true });
|
|
11320
11558
|
for (const entry of entries) {
|
|
11321
11559
|
if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
|
|
11322
|
-
|
|
11560
|
+
fs11.unlinkSync(path13.join(journeysDir, entry.name));
|
|
11323
11561
|
}
|
|
11324
11562
|
}
|
|
11325
11563
|
}
|
|
11326
11564
|
function writeResourceFiles(hubFolder, resources) {
|
|
11327
|
-
const resourcesDir =
|
|
11565
|
+
const resourcesDir = path13.join(hubFolder, "resources");
|
|
11328
11566
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
11329
11567
|
for (const resource of resources) {
|
|
11330
11568
|
const resSlug = slugify(resource.name);
|
|
11331
11569
|
currentSlugs.add(resSlug);
|
|
11332
|
-
const resDir =
|
|
11333
|
-
writeResourceFileTree(resDir, resource.files || []);
|
|
11570
|
+
const resDir = path13.join(resourcesDir, resSlug);
|
|
11571
|
+
writeResourceFileTree(resDir, resource.files || [], hubFolder);
|
|
11334
11572
|
}
|
|
11335
|
-
if (
|
|
11336
|
-
const existingDirs =
|
|
11573
|
+
if (fs11.existsSync(resourcesDir)) {
|
|
11574
|
+
const existingDirs = fs11.readdirSync(resourcesDir, { withFileTypes: true });
|
|
11337
11575
|
for (const entry of existingDirs) {
|
|
11338
11576
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
11339
|
-
|
|
11577
|
+
fs11.rmSync(path13.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
11340
11578
|
}
|
|
11341
11579
|
}
|
|
11342
11580
|
}
|
|
@@ -11361,9 +11599,187 @@ var init_yaml_writer = __esm({
|
|
|
11361
11599
|
}
|
|
11362
11600
|
});
|
|
11363
11601
|
|
|
11602
|
+
// src/lib/eval-attachments.ts
|
|
11603
|
+
import * as fs12 from "fs";
|
|
11604
|
+
import * as path14 from "path";
|
|
11605
|
+
function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
11606
|
+
const raw = turn.attachments;
|
|
11607
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
11608
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
11609
|
+
if (Array.isArray(raw)) return void 0;
|
|
11610
|
+
throw expected(`${label}: "attachments" must be a list of file paths.`);
|
|
11611
|
+
}
|
|
11612
|
+
if (turn.role !== "user") {
|
|
11613
|
+
throw expected(`${label}: attachments are only allowed on user turns (this turn is "${String(turn.role)}").`);
|
|
11614
|
+
}
|
|
11615
|
+
const refs = [];
|
|
11616
|
+
for (const entry of raw) {
|
|
11617
|
+
if (typeof entry !== "string" || !entry.trim()) {
|
|
11618
|
+
throw expected(`${label}: each attachment must be a hub-relative file path string.`);
|
|
11619
|
+
}
|
|
11620
|
+
const abs = path14.resolve(hubFolder, entry);
|
|
11621
|
+
const root = path14.resolve(hubFolder);
|
|
11622
|
+
if (abs !== root && !abs.startsWith(root + path14.sep)) {
|
|
11623
|
+
throw expected(`${label}: attachment "${entry}" escapes the hub folder.`);
|
|
11624
|
+
}
|
|
11625
|
+
let stat;
|
|
11626
|
+
try {
|
|
11627
|
+
stat = fs12.statSync(abs);
|
|
11628
|
+
} catch {
|
|
11629
|
+
}
|
|
11630
|
+
if (!stat?.isFile()) {
|
|
11631
|
+
throw expected(`${label}: attachment "${entry}" not found.`);
|
|
11632
|
+
}
|
|
11633
|
+
if (!realpathContained(root, abs)) {
|
|
11634
|
+
throw expected(`${label}: attachment "${entry}" resolves outside the hub folder (symlinks are not allowed).`);
|
|
11635
|
+
}
|
|
11636
|
+
if (stat.size > MAX_RESOURCE_FILE_SIZE2) {
|
|
11637
|
+
throw expected(
|
|
11638
|
+
`${label}: attachment "${entry}" is ${(stat.size / 1024 / 1024).toFixed(1)}MB, over the 10MB limit.`
|
|
11639
|
+
);
|
|
11640
|
+
}
|
|
11641
|
+
const data = fs12.readFileSync(abs);
|
|
11642
|
+
const hash = computeHash(data);
|
|
11643
|
+
const fileName = path14.basename(abs);
|
|
11644
|
+
const mimeType = guessMimeType(fileName) ?? "application/octet-stream";
|
|
11645
|
+
refs.push({ hash, file_name: fileName, mime_type: mimeType, file_size: stat.size });
|
|
11646
|
+
if (!bytesByHash.has(hash)) {
|
|
11647
|
+
bytesByHash.set(hash, {
|
|
11648
|
+
hash,
|
|
11649
|
+
content_base64: data.toString("base64"),
|
|
11650
|
+
file_name: fileName,
|
|
11651
|
+
mime_type: mimeType,
|
|
11652
|
+
file_size: stat.size
|
|
11653
|
+
});
|
|
11654
|
+
}
|
|
11655
|
+
}
|
|
11656
|
+
return refs;
|
|
11657
|
+
}
|
|
11658
|
+
function applyTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
11659
|
+
const refs = resolveTurnAttachments(hubFolder, turn, label, bytesByHash);
|
|
11660
|
+
if (refs) turn.attachments = refs;
|
|
11661
|
+
else delete turn.attachments;
|
|
11662
|
+
}
|
|
11663
|
+
function forEachAttachableTurn(payload, fn) {
|
|
11664
|
+
for (const ev of payload.evals ?? []) {
|
|
11665
|
+
if (ev.input) fn(ev.input);
|
|
11666
|
+
for (const t of ev.history ?? []) fn(t);
|
|
11667
|
+
}
|
|
11668
|
+
for (const jr of payload.journeys ?? []) {
|
|
11669
|
+
for (const t of jr.transcript ?? []) fn(t);
|
|
11670
|
+
}
|
|
11671
|
+
}
|
|
11672
|
+
function rewriteEvalAttachmentsToLocalPaths(payload) {
|
|
11673
|
+
const urlByHash = new Map((payload.eval_attachment_files ?? []).map((f) => [f.hash, f.download_url]));
|
|
11674
|
+
const safeName = (ref) => {
|
|
11675
|
+
const base = path14.basename(ref.file_name);
|
|
11676
|
+
return base === "" || base === "." || base === ".." ? ref.hash.slice(0, 16) : base;
|
|
11677
|
+
};
|
|
11678
|
+
const hashesByName = /* @__PURE__ */ new Map();
|
|
11679
|
+
const collect = (turn) => {
|
|
11680
|
+
if (!Array.isArray(turn.attachments)) return;
|
|
11681
|
+
for (const ref of turn.attachments) {
|
|
11682
|
+
if (!ref?.hash || !ref.file_name) continue;
|
|
11683
|
+
const name = safeName(ref);
|
|
11684
|
+
let set = hashesByName.get(name);
|
|
11685
|
+
if (!set) {
|
|
11686
|
+
set = /* @__PURE__ */ new Set();
|
|
11687
|
+
hashesByName.set(name, set);
|
|
11688
|
+
}
|
|
11689
|
+
set.add(ref.hash);
|
|
11690
|
+
}
|
|
11691
|
+
};
|
|
11692
|
+
forEachAttachableTurn(payload, collect);
|
|
11693
|
+
const pathByKey = /* @__PURE__ */ new Map();
|
|
11694
|
+
const usedLower = /* @__PURE__ */ new Set();
|
|
11695
|
+
const localPathFor = (ref) => {
|
|
11696
|
+
const name = safeName(ref);
|
|
11697
|
+
const key = `${ref.hash} ${name}`;
|
|
11698
|
+
const existing = pathByKey.get(key);
|
|
11699
|
+
if (existing) return existing;
|
|
11700
|
+
const ext = path14.extname(name);
|
|
11701
|
+
const stem = path14.basename(name, ext);
|
|
11702
|
+
const collides = (hashesByName.get(name)?.size ?? 0) > 1;
|
|
11703
|
+
let rel = collides ? `${ATTACHMENTS_DIR}/${stem}-${ref.hash.slice(0, 8)}${ext}` : `${ATTACHMENTS_DIR}/${name}`;
|
|
11704
|
+
if (usedLower.has(rel.toLowerCase())) {
|
|
11705
|
+
let n = 12;
|
|
11706
|
+
while (usedLower.has(rel.toLowerCase()) && n <= ref.hash.length) {
|
|
11707
|
+
rel = `${ATTACHMENTS_DIR}/${stem}-${ref.hash.slice(0, n)}${ext}`;
|
|
11708
|
+
n += 4;
|
|
11709
|
+
}
|
|
11710
|
+
for (let extra = 2; usedLower.has(rel.toLowerCase()); extra++) {
|
|
11711
|
+
rel = `${ATTACHMENTS_DIR}/${stem}-${ref.hash}-${extra}${ext}`;
|
|
11712
|
+
}
|
|
11713
|
+
}
|
|
11714
|
+
usedLower.add(rel.toLowerCase());
|
|
11715
|
+
pathByKey.set(key, rel);
|
|
11716
|
+
return rel;
|
|
11717
|
+
};
|
|
11718
|
+
const downloads = /* @__PURE__ */ new Map();
|
|
11719
|
+
forEachAttachableTurn(payload, (turn) => {
|
|
11720
|
+
if (!Array.isArray(turn.attachments)) return;
|
|
11721
|
+
turn.attachments = turn.attachments.map((ref) => {
|
|
11722
|
+
const rel = localPathFor(ref);
|
|
11723
|
+
const url = urlByHash.get(ref.hash);
|
|
11724
|
+
if (url && !downloads.has(rel)) downloads.set(rel, { relPath: rel, url, hash: ref.hash });
|
|
11725
|
+
return rel;
|
|
11726
|
+
});
|
|
11727
|
+
});
|
|
11728
|
+
delete payload.eval_attachment_files;
|
|
11729
|
+
return [...downloads.values()];
|
|
11730
|
+
}
|
|
11731
|
+
async function downloadEvalAttachments(hubFolder, downloads) {
|
|
11732
|
+
const attachDir = path14.resolve(hubFolder, ATTACHMENTS_DIR);
|
|
11733
|
+
let written = 0;
|
|
11734
|
+
if (!ensureRealSubdirNoSymlink(hubFolder, attachDir, downloads.length > 0)) {
|
|
11735
|
+
console.warn(` Warning: ${ATTACHMENTS_DIR}/ is not reachable inside the hub folder without a symlink; skipping attachment sync.`);
|
|
11736
|
+
return written;
|
|
11737
|
+
}
|
|
11738
|
+
if (!fs12.existsSync(attachDir)) return written;
|
|
11739
|
+
for (const dl of downloads) {
|
|
11740
|
+
const abs = path14.resolve(hubFolder, dl.relPath);
|
|
11741
|
+
if (abs !== attachDir && !abs.startsWith(attachDir + path14.sep)) continue;
|
|
11742
|
+
let existing;
|
|
11743
|
+
try {
|
|
11744
|
+
existing = fs12.lstatSync(abs);
|
|
11745
|
+
} catch {
|
|
11746
|
+
}
|
|
11747
|
+
if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(fs12.readFileSync(abs)) === dl.hash) {
|
|
11748
|
+
continue;
|
|
11749
|
+
}
|
|
11750
|
+
try {
|
|
11751
|
+
const res = await fetch(dl.url);
|
|
11752
|
+
if (!res.ok) {
|
|
11753
|
+
console.warn(` Warning: failed to download ${dl.relPath} (HTTP ${res.status})`);
|
|
11754
|
+
continue;
|
|
11755
|
+
}
|
|
11756
|
+
if (writeFileNoFollow(hubFolder, abs, Buffer.from(await res.arrayBuffer()))) written++;
|
|
11757
|
+
} catch (err) {
|
|
11758
|
+
console.warn(` Warning: failed to download ${dl.relPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11759
|
+
}
|
|
11760
|
+
}
|
|
11761
|
+
const keep = new Set(downloads.map((d) => path14.resolve(hubFolder, d.relPath)));
|
|
11762
|
+
for (const name of fs12.readdirSync(attachDir)) {
|
|
11763
|
+
const abs = path14.join(attachDir, name);
|
|
11764
|
+
const st = fs12.lstatSync(abs);
|
|
11765
|
+
if ((st.isFile() || st.isSymbolicLink()) && !keep.has(abs)) fs12.rmSync(abs);
|
|
11766
|
+
}
|
|
11767
|
+
return written;
|
|
11768
|
+
}
|
|
11769
|
+
var ATTACHMENTS_DIR;
|
|
11770
|
+
var init_eval_attachments = __esm({
|
|
11771
|
+
"src/lib/eval-attachments.ts"() {
|
|
11772
|
+
"use strict";
|
|
11773
|
+
init_resource_files();
|
|
11774
|
+
init_fs_safety();
|
|
11775
|
+
init_parser();
|
|
11776
|
+
ATTACHMENTS_DIR = "attachments";
|
|
11777
|
+
}
|
|
11778
|
+
});
|
|
11779
|
+
|
|
11364
11780
|
// src/lib/parser.ts
|
|
11365
|
-
import * as
|
|
11366
|
-
import * as
|
|
11781
|
+
import * as fs13 from "fs";
|
|
11782
|
+
import * as path15 from "path";
|
|
11367
11783
|
import * as yaml5 from "js-yaml";
|
|
11368
11784
|
function expected(message) {
|
|
11369
11785
|
const err = new Error(message);
|
|
@@ -11377,7 +11793,7 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
11377
11793
|
err.isExpected = true;
|
|
11378
11794
|
throw err;
|
|
11379
11795
|
}
|
|
11380
|
-
const yamlContent =
|
|
11796
|
+
const yamlContent = fs13.readFileSync(yamlPath, "utf-8");
|
|
11381
11797
|
let config;
|
|
11382
11798
|
try {
|
|
11383
11799
|
config = yaml5.load(yamlContent);
|
|
@@ -11412,9 +11828,9 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
11412
11828
|
const resolved = { ...agent };
|
|
11413
11829
|
if (typeof resolved.instructions === "string" && resolved.instructions.endsWith(".md")) {
|
|
11414
11830
|
const instrValue = resolved.instructions;
|
|
11415
|
-
const instructionsPath = instrValue.startsWith("agents/") ?
|
|
11416
|
-
if (
|
|
11417
|
-
resolved.instructions =
|
|
11831
|
+
const instructionsPath = instrValue.startsWith("agents/") ? path15.join(hubFolder, instrValue) : path15.join(hubFolder, "agents", instrValue);
|
|
11832
|
+
if (fs13.existsSync(instructionsPath)) {
|
|
11833
|
+
resolved.instructions = fs13.readFileSync(instructionsPath, "utf-8");
|
|
11418
11834
|
} else {
|
|
11419
11835
|
const err = new Error(
|
|
11420
11836
|
`Agent instructions file not found: ${instructionsPath} (referenced by agent "${agent.name}")`
|
|
@@ -11423,9 +11839,9 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
11423
11839
|
throw err;
|
|
11424
11840
|
}
|
|
11425
11841
|
} else if (resolved.instructions === void 0 && typeof agent.name === "string") {
|
|
11426
|
-
const conventionPath =
|
|
11427
|
-
if (
|
|
11428
|
-
resolved.instructions =
|
|
11842
|
+
const conventionPath = path15.join(hubFolder, "agents", `${slugify(agent.name)}.md`);
|
|
11843
|
+
if (fs13.existsSync(conventionPath)) {
|
|
11844
|
+
resolved.instructions = fs13.readFileSync(conventionPath, "utf-8");
|
|
11429
11845
|
}
|
|
11430
11846
|
}
|
|
11431
11847
|
return resolved;
|
|
@@ -11464,58 +11880,62 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
11464
11880
|
if (config.outbound_schedules && config.outbound_schedules.length > 0) {
|
|
11465
11881
|
payload.outbound_schedules = config.outbound_schedules;
|
|
11466
11882
|
}
|
|
11467
|
-
const
|
|
11883
|
+
const bytesByHash = /* @__PURE__ */ new Map();
|
|
11884
|
+
const evals = scanEvalYamlFiles(hubFolder, bytesByHash);
|
|
11468
11885
|
if (evals.length > 0) {
|
|
11469
11886
|
payload.evals = evals;
|
|
11470
11887
|
}
|
|
11471
|
-
const journeys = scanJourneyYamlFiles(hubFolder);
|
|
11888
|
+
const journeys = scanJourneyYamlFiles(hubFolder, bytesByHash);
|
|
11472
11889
|
if (journeys.length > 0) {
|
|
11473
11890
|
payload.journeys = journeys;
|
|
11474
11891
|
}
|
|
11892
|
+
if (bytesByHash.size > 0) {
|
|
11893
|
+
payload.eval_attachment_files = [...bytesByHash.values()];
|
|
11894
|
+
}
|
|
11475
11895
|
return payload;
|
|
11476
11896
|
}
|
|
11477
|
-
function scanEvalYamlFiles(hubFolder) {
|
|
11478
|
-
const evalsDir =
|
|
11479
|
-
if (!
|
|
11897
|
+
function scanEvalYamlFiles(hubFolder, bytesByHash) {
|
|
11898
|
+
const evalsDir = path15.join(hubFolder, "evals");
|
|
11899
|
+
if (!fs13.existsSync(evalsDir)) return [];
|
|
11480
11900
|
const evals = [];
|
|
11481
11901
|
const seen = /* @__PURE__ */ new Set();
|
|
11482
|
-
const topEntries =
|
|
11902
|
+
const topEntries = fs13.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
11483
11903
|
for (const entry of topEntries) {
|
|
11484
11904
|
if (entry.isFile() && entry.name.endsWith(".yaml")) {
|
|
11485
|
-
collectEval(evals, seen,
|
|
11905
|
+
collectEval(evals, seen, path15.join(evalsDir, entry.name), `evals/${entry.name}`, null, hubFolder, bytesByHash);
|
|
11486
11906
|
} else if (entry.isDirectory()) {
|
|
11487
11907
|
const setName = entry.name;
|
|
11488
|
-
const setDir =
|
|
11489
|
-
const setEntries =
|
|
11908
|
+
const setDir = path15.join(evalsDir, setName);
|
|
11909
|
+
const setEntries = fs13.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
11490
11910
|
for (const sub of setEntries) {
|
|
11491
11911
|
if (sub.isDirectory()) {
|
|
11492
11912
|
throw expected(
|
|
11493
|
-
`Nested scenario sets are not supported: ${
|
|
11913
|
+
`Nested scenario sets are not supported: ${path15.relative(hubFolder, path15.join(setDir, sub.name))}. Move scenarios up to evals/${setName}/.`
|
|
11494
11914
|
);
|
|
11495
11915
|
}
|
|
11496
11916
|
if (sub.isFile() && sub.name.endsWith(".yaml")) {
|
|
11497
|
-
collectEval(evals, seen,
|
|
11917
|
+
collectEval(evals, seen, path15.join(setDir, sub.name), `evals/${setName}/${sub.name}`, setName, hubFolder, bytesByHash);
|
|
11498
11918
|
}
|
|
11499
11919
|
}
|
|
11500
11920
|
}
|
|
11501
11921
|
}
|
|
11502
11922
|
return evals;
|
|
11503
11923
|
}
|
|
11504
|
-
function collectEval(evals, seen, filePath, relPath, setName) {
|
|
11505
|
-
const evalEntry = parseEvalYaml(filePath, relPath, setName);
|
|
11924
|
+
function collectEval(evals, seen, filePath, relPath, setName, hubFolder, bytesByHash) {
|
|
11925
|
+
const evalEntry = parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash);
|
|
11506
11926
|
if (!evalEntry) return;
|
|
11507
11927
|
const key = `${evalEntry.name}|${setName ?? ""}`;
|
|
11508
11928
|
if (seen.has(key)) {
|
|
11509
11929
|
const where = setName ? `scenario set "${setName}"` : "root";
|
|
11510
11930
|
throw expected(
|
|
11511
|
-
`Duplicate eval at ${where}: "${evalEntry.name}" (in ${
|
|
11931
|
+
`Duplicate eval at ${where}: "${evalEntry.name}" (in ${path15.basename(filePath)}). Each (name, scenario set) pair must be unique.`
|
|
11512
11932
|
);
|
|
11513
11933
|
}
|
|
11514
11934
|
seen.add(key);
|
|
11515
11935
|
evals.push(evalEntry);
|
|
11516
11936
|
}
|
|
11517
|
-
function parseEvalYaml(filePath, relPath, setName) {
|
|
11518
|
-
const content =
|
|
11937
|
+
function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
|
|
11938
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
11519
11939
|
let raw;
|
|
11520
11940
|
try {
|
|
11521
11941
|
raw = yaml5.load(content);
|
|
@@ -11530,7 +11950,7 @@ function parseEvalYaml(filePath, relPath, setName) {
|
|
|
11530
11950
|
return null;
|
|
11531
11951
|
}
|
|
11532
11952
|
const data = raw;
|
|
11533
|
-
const fileSlug =
|
|
11953
|
+
const fileSlug = path15.basename(filePath, ".yaml");
|
|
11534
11954
|
const evalName = typeof data.name === "string" && data.name.trim().length > 0 ? data.name : fileSlug;
|
|
11535
11955
|
if (typeof data.agent !== "string" || data.agent.trim().length === 0) {
|
|
11536
11956
|
throw expected(`Eval "${evalName}" in ${relPath}: missing required field "agent" (string).`);
|
|
@@ -11541,11 +11961,13 @@ function parseEvalYaml(filePath, relPath, setName) {
|
|
|
11541
11961
|
if (!data.expected || typeof data.expected !== "object" || Array.isArray(data.expected)) {
|
|
11542
11962
|
throw expected(`Eval "${evalName}" in ${relPath}: missing required field "expected" (object).`);
|
|
11543
11963
|
}
|
|
11964
|
+
const input = { ...data.input };
|
|
11965
|
+
applyTurnAttachments(hubFolder, input, `Eval "${evalName}" input`, bytesByHash);
|
|
11544
11966
|
const evalEntry = {
|
|
11545
11967
|
name: evalName,
|
|
11546
11968
|
agent: data.agent,
|
|
11547
11969
|
path: setName,
|
|
11548
|
-
input
|
|
11970
|
+
input,
|
|
11549
11971
|
expected: data.expected
|
|
11550
11972
|
};
|
|
11551
11973
|
if (typeof data.id === "string") evalEntry.id = data.id;
|
|
@@ -11553,7 +11975,11 @@ function parseEvalYaml(filePath, relPath, setName) {
|
|
|
11553
11975
|
if (typeof data.runs === "number") evalEntry.runs = data.runs;
|
|
11554
11976
|
if (data.enabled === false) evalEntry.enabled = false;
|
|
11555
11977
|
if (Array.isArray(data.history)) {
|
|
11556
|
-
evalEntry.history = data.history
|
|
11978
|
+
evalEntry.history = data.history.map((turn, i) => {
|
|
11979
|
+
const t = { ...turn };
|
|
11980
|
+
applyTurnAttachments(hubFolder, t, `Eval "${evalName}" history[${i}]`, bytesByHash);
|
|
11981
|
+
return t;
|
|
11982
|
+
});
|
|
11557
11983
|
}
|
|
11558
11984
|
if (typeof data.evaluator_instructions === "string") {
|
|
11559
11985
|
evalEntry.evaluator_instructions = data.evaluator_instructions;
|
|
@@ -11583,20 +12009,20 @@ function parseFixtureField(raw, label, key) {
|
|
|
11583
12009
|
const trimmed = raw.trim();
|
|
11584
12010
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
11585
12011
|
}
|
|
11586
|
-
function scanJourneyYamlFiles(hubFolder) {
|
|
11587
|
-
const journeysDir =
|
|
11588
|
-
if (!
|
|
12012
|
+
function scanJourneyYamlFiles(hubFolder, bytesByHash) {
|
|
12013
|
+
const journeysDir = path15.join(hubFolder, "journeys");
|
|
12014
|
+
if (!fs13.existsSync(journeysDir)) return [];
|
|
11589
12015
|
const journeys = [];
|
|
11590
12016
|
const seen = /* @__PURE__ */ new Set();
|
|
11591
|
-
const entries =
|
|
12017
|
+
const entries = fs13.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
11592
12018
|
for (const entry of entries) {
|
|
11593
12019
|
if (entry.isDirectory()) {
|
|
11594
12020
|
throw expected(
|
|
11595
|
-
`Subfolders are not supported under journeys/: ${
|
|
12021
|
+
`Subfolders are not supported under journeys/: ${path15.relative(hubFolder, path15.join(journeysDir, entry.name))}. A journey owns its own managed scenario set \u2014 put each journey in a single journeys/<slug>.yaml file.`
|
|
11596
12022
|
);
|
|
11597
12023
|
}
|
|
11598
12024
|
if (!entry.isFile() || !entry.name.endsWith(".yaml")) continue;
|
|
11599
|
-
const journeyEntry = parseJourneyYaml(
|
|
12025
|
+
const journeyEntry = parseJourneyYaml(path15.join(journeysDir, entry.name), `journeys/${entry.name}`, hubFolder, bytesByHash);
|
|
11600
12026
|
if (!journeyEntry) continue;
|
|
11601
12027
|
if (seen.has(journeyEntry.name)) {
|
|
11602
12028
|
throw expected(
|
|
@@ -11608,8 +12034,8 @@ function scanJourneyYamlFiles(hubFolder) {
|
|
|
11608
12034
|
}
|
|
11609
12035
|
return journeys;
|
|
11610
12036
|
}
|
|
11611
|
-
function parseJourneyYaml(filePath, relPath) {
|
|
11612
|
-
const content =
|
|
12037
|
+
function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
|
|
12038
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
11613
12039
|
let raw;
|
|
11614
12040
|
try {
|
|
11615
12041
|
raw = yaml5.load(content);
|
|
@@ -11624,7 +12050,7 @@ function parseJourneyYaml(filePath, relPath) {
|
|
|
11624
12050
|
return null;
|
|
11625
12051
|
}
|
|
11626
12052
|
const data = raw;
|
|
11627
|
-
const fileSlug =
|
|
12053
|
+
const fileSlug = path15.basename(filePath, ".yaml");
|
|
11628
12054
|
const journeyName = typeof data.name === "string" && data.name.trim().length > 0 ? data.name : fileSlug;
|
|
11629
12055
|
if (typeof data.agent !== "string" || data.agent.trim().length === 0) {
|
|
11630
12056
|
throw expected(`Journey "${journeyName}" in ${relPath}: missing required field "agent" (string).`);
|
|
@@ -11646,7 +12072,11 @@ function parseJourneyYaml(filePath, relPath) {
|
|
|
11646
12072
|
journeyEntry.evaluator_instructions = data.evaluator_instructions;
|
|
11647
12073
|
}
|
|
11648
12074
|
if (Array.isArray(data.transcript)) {
|
|
11649
|
-
journeyEntry.transcript = data.transcript
|
|
12075
|
+
journeyEntry.transcript = data.transcript.map((turn, i) => {
|
|
12076
|
+
const t = { ...turn };
|
|
12077
|
+
applyTurnAttachments(hubFolder, t, `Journey "${journeyName}" transcript[${i}]`, bytesByHash);
|
|
12078
|
+
return t;
|
|
12079
|
+
});
|
|
11650
12080
|
}
|
|
11651
12081
|
if (data.step_config && typeof data.step_config === "object" && !Array.isArray(data.step_config)) {
|
|
11652
12082
|
journeyEntry.step_config = data.step_config;
|
|
@@ -11660,14 +12090,14 @@ function parseJourneyYaml(filePath, relPath) {
|
|
|
11660
12090
|
return journeyEntry;
|
|
11661
12091
|
}
|
|
11662
12092
|
function scanAgentYamlFiles(hubFolder) {
|
|
11663
|
-
const agentsDir =
|
|
11664
|
-
if (!
|
|
11665
|
-
const yamlFiles =
|
|
12093
|
+
const agentsDir = path15.join(hubFolder, "agents");
|
|
12094
|
+
if (!fs13.existsSync(agentsDir)) return [];
|
|
12095
|
+
const yamlFiles = fs13.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
|
|
11666
12096
|
if (yamlFiles.length === 0) return [];
|
|
11667
12097
|
const agents = [];
|
|
11668
12098
|
for (const file of yamlFiles) {
|
|
11669
|
-
const filePath =
|
|
11670
|
-
const content =
|
|
12099
|
+
const filePath = path15.join(agentsDir, file);
|
|
12100
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
11671
12101
|
let agent;
|
|
11672
12102
|
try {
|
|
11673
12103
|
agent = yaml5.load(content);
|
|
@@ -11689,7 +12119,7 @@ function scanAgentYamlFiles(hubFolder) {
|
|
|
11689
12119
|
return agents;
|
|
11690
12120
|
}
|
|
11691
12121
|
function parseResources(hubFolder, configResources) {
|
|
11692
|
-
const resourcesDir =
|
|
12122
|
+
const resourcesDir = path15.join(hubFolder, "resources");
|
|
11693
12123
|
const results = [];
|
|
11694
12124
|
for (const res of configResources) {
|
|
11695
12125
|
const resource = {
|
|
@@ -11702,8 +12132,8 @@ function parseResources(hubFolder, configResources) {
|
|
|
11702
12132
|
if (res.user_browsable) resource.user_browsable = res.user_browsable;
|
|
11703
12133
|
if (res.skill_name) resource.skill_name = res.skill_name;
|
|
11704
12134
|
const resSlug = slugify(resource.name);
|
|
11705
|
-
const resDir =
|
|
11706
|
-
if (
|
|
12135
|
+
const resDir = path15.join(resourcesDir, resSlug);
|
|
12136
|
+
if (fs13.existsSync(resDir)) {
|
|
11707
12137
|
const files = scanResourceFiles(resDir, "");
|
|
11708
12138
|
if (files.length > 0) {
|
|
11709
12139
|
resource.files = files;
|
|
@@ -11718,6 +12148,7 @@ var init_parser = __esm({
|
|
|
11718
12148
|
"use strict";
|
|
11719
12149
|
init_utils();
|
|
11720
12150
|
init_resource_files();
|
|
12151
|
+
init_eval_attachments();
|
|
11721
12152
|
}
|
|
11722
12153
|
});
|
|
11723
12154
|
|
|
@@ -11757,8 +12188,8 @@ __export(pull_exports, {
|
|
|
11757
12188
|
resolveHubTarget: () => resolveHubTarget,
|
|
11758
12189
|
writeProductionMirror: () => writeProductionMirror
|
|
11759
12190
|
});
|
|
11760
|
-
import * as
|
|
11761
|
-
import * as
|
|
12191
|
+
import * as fs14 from "fs";
|
|
12192
|
+
import * as path16 from "path";
|
|
11762
12193
|
function parseArgs4(args2) {
|
|
11763
12194
|
let autoConfirm = false;
|
|
11764
12195
|
let hubSelector;
|
|
@@ -11777,7 +12208,7 @@ function resolveHubTarget(workspaceDir, selector) {
|
|
|
11777
12208
|
const allHubs = scanWorkspaceHubs(workspaceDir);
|
|
11778
12209
|
if (selector) {
|
|
11779
12210
|
const match = allHubs.find(
|
|
11780
|
-
(h) => h.hubId === selector ||
|
|
12211
|
+
(h) => h.hubId === selector || path16.basename(h.hubFolder) === selector
|
|
11781
12212
|
);
|
|
11782
12213
|
if (match) return { hubId: match.hubId, hubFolder: match.hubFolder };
|
|
11783
12214
|
if (UUID_RE2.test(selector)) return { hubId: selector, hubFolder: null };
|
|
@@ -11794,7 +12225,7 @@ function resolveHubTarget(workspaceDir, selector) {
|
|
|
11794
12225
|
}
|
|
11795
12226
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
11796
12227
|
for (const h of previewHubs) {
|
|
11797
|
-
console.error(` ${
|
|
12228
|
+
console.error(` ${path16.basename(h.hubFolder)} (${h.hubId})`);
|
|
11798
12229
|
}
|
|
11799
12230
|
process.exit(1);
|
|
11800
12231
|
}
|
|
@@ -11821,6 +12252,7 @@ async function pullCommand(args2) {
|
|
|
11821
12252
|
return;
|
|
11822
12253
|
}
|
|
11823
12254
|
assertHubMatchesBinding(hubId);
|
|
12255
|
+
const attachmentDownloads = rewriteEvalAttachmentsToLocalPaths(payload);
|
|
11824
12256
|
let hubFolder = existingFolder;
|
|
11825
12257
|
let wroteFiles = false;
|
|
11826
12258
|
if (!hubFolder) {
|
|
@@ -11832,10 +12264,11 @@ async function pullCommand(args2) {
|
|
|
11832
12264
|
payload.preview_label,
|
|
11833
12265
|
payload.branch_name
|
|
11834
12266
|
);
|
|
11835
|
-
|
|
12267
|
+
fs14.mkdirSync(path16.dirname(hubFolder), { recursive: true });
|
|
11836
12268
|
console.log("Writing hub configuration...");
|
|
11837
12269
|
writeHubFolder(hubFolder, payload);
|
|
11838
12270
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
12271
|
+
await downloadEvalAttachments(hubFolder, attachmentDownloads);
|
|
11839
12272
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
11840
12273
|
console.log(`Hub configuration written to ${finalFolder}`);
|
|
11841
12274
|
wroteFiles = true;
|
|
@@ -11848,6 +12281,7 @@ async function pullCommand(args2) {
|
|
|
11848
12281
|
if (!diffResult.has_changes && !connectionsChanged) {
|
|
11849
12282
|
writeHubFolder(hubFolder, payload);
|
|
11850
12283
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
12284
|
+
await downloadEvalAttachments(hubFolder, attachmentDownloads);
|
|
11851
12285
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
11852
12286
|
wroteFiles = true;
|
|
11853
12287
|
if (finalFolder === hubFolder) {
|
|
@@ -11871,6 +12305,7 @@ async function pullCommand(args2) {
|
|
|
11871
12305
|
if (!cancelled) {
|
|
11872
12306
|
writeHubFolder(hubFolder, payload);
|
|
11873
12307
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
12308
|
+
await downloadEvalAttachments(hubFolder, attachmentDownloads);
|
|
11874
12309
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
11875
12310
|
console.log(`Hub configuration written to ${finalFolder}`);
|
|
11876
12311
|
wroteFiles = true;
|
|
@@ -11880,6 +12315,7 @@ async function pullCommand(args2) {
|
|
|
11880
12315
|
console.log("Writing hub configuration...");
|
|
11881
12316
|
writeHubFolder(hubFolder, payload);
|
|
11882
12317
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
12318
|
+
await downloadEvalAttachments(hubFolder, attachmentDownloads);
|
|
11883
12319
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
11884
12320
|
console.log(`Hub configuration written to ${finalFolder}`);
|
|
11885
12321
|
wroteFiles = true;
|
|
@@ -11893,9 +12329,11 @@ async function pullCommand(args2) {
|
|
|
11893
12329
|
}
|
|
11894
12330
|
async function writeProductionMirror(workspaceDir, prodPayload) {
|
|
11895
12331
|
const folder = resolveHubFolder(workspaceDir, prodPayload.hub_id, prodPayload.hub.name, "production", null, null);
|
|
11896
|
-
|
|
12332
|
+
fs14.mkdirSync(path16.dirname(folder), { recursive: true });
|
|
12333
|
+
const attachmentDownloads = rewriteEvalAttachmentsToLocalPaths(prodPayload);
|
|
11897
12334
|
writeHubFolder(folder, prodPayload, { seedAgentContext: false });
|
|
11898
12335
|
await downloadBinaryResourceFiles(folder, prodPayload);
|
|
12336
|
+
await downloadEvalAttachments(folder, attachmentDownloads);
|
|
11899
12337
|
const finalFolder = autoRenameHubFolder(folder, prodPayload.hub.name, "production", prodPayload.hub_id, null, null);
|
|
11900
12338
|
prependMirrorMarker(finalFolder, prodPayload.hub_id);
|
|
11901
12339
|
return finalFolder;
|
|
@@ -11910,13 +12348,13 @@ async function mirrorLinkedProduction(client, workspaceDir, productionHubId, org
|
|
|
11910
12348
|
}
|
|
11911
12349
|
}
|
|
11912
12350
|
function prependMirrorMarker(hubFolder, productionHubId) {
|
|
11913
|
-
const hubYaml =
|
|
12351
|
+
const hubYaml = path16.join(hubFolder, "hub.yaml");
|
|
11914
12352
|
try {
|
|
11915
|
-
const content =
|
|
12353
|
+
const content = fs14.readFileSync(hubYaml, "utf-8");
|
|
11916
12354
|
if (content.startsWith(MIRROR_MARKER_PREFIX)) return;
|
|
11917
12355
|
const marker = `${MIRROR_MARKER_PREFIX} ${productionHubId}. Edits are ignored; push is blocked. Edit the linked preview hub instead.
|
|
11918
12356
|
`;
|
|
11919
|
-
|
|
12357
|
+
fs14.writeFileSync(hubYaml, marker + content, "utf-8");
|
|
11920
12358
|
} catch {
|
|
11921
12359
|
}
|
|
11922
12360
|
}
|
|
@@ -11925,8 +12363,8 @@ async function downloadBinaryResourceFiles(hubFolder, payload) {
|
|
|
11925
12363
|
let downloadCount = 0;
|
|
11926
12364
|
for (const resource of resources) {
|
|
11927
12365
|
if (!resource.files) continue;
|
|
11928
|
-
const resDir =
|
|
11929
|
-
downloadCount += await downloadBinaryFiles(resDir, resource.files);
|
|
12366
|
+
const resDir = path16.join(hubFolder, "resources", slugify(resource.name));
|
|
12367
|
+
downloadCount += await downloadBinaryFiles(resDir, resource.files, hubFolder);
|
|
11930
12368
|
}
|
|
11931
12369
|
if (downloadCount > 0) {
|
|
11932
12370
|
console.log(`Downloaded ${downloadCount} binary resource file(s).`);
|
|
@@ -11956,6 +12394,7 @@ var init_pull = __esm({
|
|
|
11956
12394
|
init_diff_display();
|
|
11957
12395
|
init_utils();
|
|
11958
12396
|
init_resource_files();
|
|
12397
|
+
init_eval_attachments();
|
|
11959
12398
|
init_workspace();
|
|
11960
12399
|
init_layout();
|
|
11961
12400
|
init_workspace_files();
|
|
@@ -11970,6 +12409,7 @@ var push_exports = {};
|
|
|
11970
12409
|
__export(push_exports, {
|
|
11971
12410
|
autoRenameAgentFiles: () => autoRenameAgentFiles,
|
|
11972
12411
|
createAndPushNewHub: () => createAndPushNewHub,
|
|
12412
|
+
printErrors: () => printErrors,
|
|
11973
12413
|
printSyncResult: () => printSyncResult,
|
|
11974
12414
|
printWarnings: () => printWarnings,
|
|
11975
12415
|
pushCommand: () => pushCommand,
|
|
@@ -11977,8 +12417,8 @@ __export(push_exports, {
|
|
|
11977
12417
|
selectExistingHub: () => selectExistingHub,
|
|
11978
12418
|
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel
|
|
11979
12419
|
});
|
|
11980
|
-
import * as
|
|
11981
|
-
import * as
|
|
12420
|
+
import * as fs15 from "fs";
|
|
12421
|
+
import * as path17 from "path";
|
|
11982
12422
|
import * as yaml6 from "js-yaml";
|
|
11983
12423
|
function parseArgs5(args2) {
|
|
11984
12424
|
let autoConfirm = false;
|
|
@@ -12000,6 +12440,10 @@ function shouldWarnIgnoredPreviewLabel(localLabel, serverLabel) {
|
|
|
12000
12440
|
return Boolean(localLabel) && serverLabel !== void 0 && localLabel !== serverLabel;
|
|
12001
12441
|
}
|
|
12002
12442
|
function printSyncResult(result) {
|
|
12443
|
+
if (result.errors && result.errors.length > 0) {
|
|
12444
|
+
printErrors(result.errors);
|
|
12445
|
+
throw new Error(`Sync failed with ${result.errors.length} error(s). No completion was reported; inspect the errors above.`);
|
|
12446
|
+
}
|
|
12003
12447
|
console.log(`
|
|
12004
12448
|
Sync complete. Preview hub: ${result.preview_hub_id}`);
|
|
12005
12449
|
const c = result.changes;
|
|
@@ -12046,9 +12490,6 @@ Sync complete. Preview hub: ${result.preview_hub_id}`);
|
|
|
12046
12490
|
if (parts.length > 0) {
|
|
12047
12491
|
console.log(`Changes: ${parts.join(", ")}`);
|
|
12048
12492
|
}
|
|
12049
|
-
if (result.errors && result.errors.length > 0) {
|
|
12050
|
-
printWarnings(result.errors);
|
|
12051
|
-
}
|
|
12052
12493
|
if (result.warnings && result.warnings.length > 0) {
|
|
12053
12494
|
printWarnings(result.warnings.map((w) => w.message));
|
|
12054
12495
|
}
|
|
@@ -12061,14 +12502,22 @@ function printWarnings(warnings) {
|
|
|
12061
12502
|
console.log(` \x1B[33m! ${w}\x1B[0m`);
|
|
12062
12503
|
}
|
|
12063
12504
|
}
|
|
12505
|
+
function printErrors(errors) {
|
|
12506
|
+
if (errors.length === 0) return;
|
|
12507
|
+
console.error(`
|
|
12508
|
+
\x1B[31mErrors (${errors.length}):\x1B[0m`);
|
|
12509
|
+
for (const error of errors) {
|
|
12510
|
+
console.error(` \x1B[31m! ${error}\x1B[0m`);
|
|
12511
|
+
}
|
|
12512
|
+
}
|
|
12064
12513
|
async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
12065
|
-
const agentsDir =
|
|
12514
|
+
const agentsDir = path17.join(hubFolder, "agents");
|
|
12066
12515
|
let agentsWithIds = [];
|
|
12067
|
-
if (
|
|
12068
|
-
const yamlFiles =
|
|
12516
|
+
if (fs15.existsSync(agentsDir)) {
|
|
12517
|
+
const yamlFiles = fs15.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
|
|
12069
12518
|
for (const file of yamlFiles) {
|
|
12070
12519
|
try {
|
|
12071
|
-
const content =
|
|
12520
|
+
const content = fs15.readFileSync(path17.join(agentsDir, file), "utf-8");
|
|
12072
12521
|
const agent = yaml6.load(content);
|
|
12073
12522
|
if (agent?.id && agent.name) {
|
|
12074
12523
|
agentsWithIds.push({ id: agent.id, name: agent.name });
|
|
@@ -12081,7 +12530,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12081
12530
|
if (agentsWithIds.length === 0) {
|
|
12082
12531
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
12083
12532
|
if (!yamlPath) return;
|
|
12084
|
-
const yamlContent =
|
|
12533
|
+
const yamlContent = fs15.readFileSync(yamlPath, "utf-8");
|
|
12085
12534
|
const config = yaml6.load(yamlContent);
|
|
12086
12535
|
agentsWithIds = (config.agents || []).filter((a) => !!a.id && !!a.name);
|
|
12087
12536
|
}
|
|
@@ -12111,18 +12560,18 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12111
12560
|
}
|
|
12112
12561
|
}
|
|
12113
12562
|
if (renames.length === 0) return;
|
|
12114
|
-
if (!
|
|
12115
|
-
for (const file of
|
|
12563
|
+
if (!fs15.existsSync(agentsDir)) return;
|
|
12564
|
+
for (const file of fs15.readdirSync(agentsDir)) {
|
|
12116
12565
|
if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
|
|
12117
12566
|
console.warn(` Warning: removing orphaned temp file agents/${file}`);
|
|
12118
|
-
|
|
12567
|
+
fs15.unlinkSync(path17.join(agentsDir, file));
|
|
12119
12568
|
}
|
|
12120
12569
|
}
|
|
12121
12570
|
const renameFileIfExists = (dir, oldName, newName) => {
|
|
12122
|
-
const oldPath =
|
|
12123
|
-
const newPath =
|
|
12124
|
-
if (!
|
|
12125
|
-
|
|
12571
|
+
const oldPath = path17.join(dir, oldName);
|
|
12572
|
+
const newPath = path17.join(dir, newName);
|
|
12573
|
+
if (!fs15.existsSync(oldPath)) return false;
|
|
12574
|
+
fs15.renameSync(oldPath, newPath);
|
|
12126
12575
|
return true;
|
|
12127
12576
|
};
|
|
12128
12577
|
const oldSlugs = new Set(renames.map((r) => r.oldSlug));
|
|
@@ -12155,9 +12604,9 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12155
12604
|
}
|
|
12156
12605
|
} else {
|
|
12157
12606
|
for (const { oldSlug, newSlug } of renames) {
|
|
12158
|
-
const hasOldFile = extensions.some((ext) =>
|
|
12607
|
+
const hasOldFile = extensions.some((ext) => fs15.existsSync(path17.join(agentsDir, `${oldSlug}${ext}`)));
|
|
12159
12608
|
if (!hasOldFile) continue;
|
|
12160
|
-
const hasNewFile = extensions.some((ext) =>
|
|
12609
|
+
const hasNewFile = extensions.some((ext) => fs15.existsSync(path17.join(agentsDir, `${newSlug}${ext}`)));
|
|
12161
12610
|
if (hasNewFile) {
|
|
12162
12611
|
console.warn(` Warning: skipping rename agents/${oldSlug}.* \u2192 agents/${newSlug}.* (target already exists)`);
|
|
12163
12612
|
continue;
|
|
@@ -12172,7 +12621,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12172
12621
|
if (completedRenames.length === 0) return;
|
|
12173
12622
|
const mainYamlPath = resolveHubYamlPath(hubFolder);
|
|
12174
12623
|
if (mainYamlPath) {
|
|
12175
|
-
const mainYamlContent =
|
|
12624
|
+
const mainYamlContent = fs15.readFileSync(mainYamlPath, "utf-8");
|
|
12176
12625
|
const substitutionMap = /* @__PURE__ */ new Map();
|
|
12177
12626
|
for (const { oldSlug, newSlug } of completedRenames) {
|
|
12178
12627
|
substitutionMap.set(`agents/${oldSlug}.md`, `agents/${newSlug}.md`);
|
|
@@ -12183,8 +12632,8 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12183
12632
|
(_match, prefix, pathMatch) => `${prefix}${substitutionMap.get(pathMatch) ?? pathMatch}`
|
|
12184
12633
|
);
|
|
12185
12634
|
if (updatedYaml !== mainYamlContent) {
|
|
12186
|
-
|
|
12187
|
-
console.log(` Updated instructions paths in ${
|
|
12635
|
+
fs15.writeFileSync(mainYamlPath, updatedYaml, "utf-8");
|
|
12636
|
+
console.log(` Updated instructions paths in ${path17.basename(mainYamlPath)}`);
|
|
12188
12637
|
}
|
|
12189
12638
|
}
|
|
12190
12639
|
}
|
|
@@ -12245,7 +12694,7 @@ async function pushSingleHub(client, hubId, hubFolder, autoConfirm, organization
|
|
|
12245
12694
|
function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
|
|
12246
12695
|
if (selector) {
|
|
12247
12696
|
const match = allHubs.find(
|
|
12248
|
-
(h) => h.hubId === selector ||
|
|
12697
|
+
(h) => h.hubId === selector || path17.basename(h.hubFolder) === selector
|
|
12249
12698
|
);
|
|
12250
12699
|
if (!match) {
|
|
12251
12700
|
console.error(`No hub matching --hub ${selector} found in ${wsLabel}/.`);
|
|
@@ -12288,7 +12737,7 @@ New hub: "${newHub.hubName}" (${hubType})`);
|
|
|
12288
12737
|
process.exit(1);
|
|
12289
12738
|
}
|
|
12290
12739
|
console.log(`Hub created: ${createdHub.hub_name} (${hubId})`);
|
|
12291
|
-
const content =
|
|
12740
|
+
const content = fs15.readFileSync(hubYamlPath, "utf-8");
|
|
12292
12741
|
const hasVersion = content.match(/^version:\s/m);
|
|
12293
12742
|
let updated;
|
|
12294
12743
|
if (hasVersion) {
|
|
@@ -12304,7 +12753,7 @@ hub_id: "${hubId}"
|
|
|
12304
12753
|
hub_environment: preview
|
|
12305
12754
|
${content}`;
|
|
12306
12755
|
}
|
|
12307
|
-
|
|
12756
|
+
fs15.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
12308
12757
|
autoBindIfUnbound(hubId);
|
|
12309
12758
|
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
12310
12759
|
}
|
|
@@ -12313,7 +12762,7 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
|
|
|
12313
12762
|
if (existingHubs.length > 0) {
|
|
12314
12763
|
console.error(`No pushable hub found in ${wsLabel}/ \u2014 only read-only production mirror folder(s). Edit the linked preview hub, pull one, or create a new hub with \`wayai create\`:`);
|
|
12315
12764
|
for (const h of existingHubs) {
|
|
12316
|
-
console.error(` ${
|
|
12765
|
+
console.error(` ${path17.basename(h.hubFolder)} (${h.hubId}, production mirror)`);
|
|
12317
12766
|
}
|
|
12318
12767
|
} else {
|
|
12319
12768
|
console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` and run \`wayai push\` (or \`wayai create\`).`);
|
|
@@ -12326,10 +12775,10 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
|
|
|
12326
12775
|
console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
12327
12776
|
}
|
|
12328
12777
|
for (const h of existingHubs) {
|
|
12329
|
-
console.error(` ${
|
|
12778
|
+
console.error(` ${path17.basename(h.hubFolder)} (${h.hubId})`);
|
|
12330
12779
|
}
|
|
12331
12780
|
for (const h of newHubs) {
|
|
12332
|
-
console.error(` ${
|
|
12781
|
+
console.error(` ${path17.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
12333
12782
|
}
|
|
12334
12783
|
process.exit(1);
|
|
12335
12784
|
}
|
|
@@ -12348,7 +12797,7 @@ async function pushCommand(args2) {
|
|
|
12348
12797
|
console.error(`Created ${file}`);
|
|
12349
12798
|
}
|
|
12350
12799
|
}
|
|
12351
|
-
if (!
|
|
12800
|
+
if (!fs15.existsSync(workspaceDir)) {
|
|
12352
12801
|
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
12353
12802
|
process.exit(1);
|
|
12354
12803
|
}
|
|
@@ -12367,8 +12816,8 @@ async function pushCommand(args2) {
|
|
|
12367
12816
|
if (label) {
|
|
12368
12817
|
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
12369
12818
|
}
|
|
12370
|
-
console.log(`Target hub: ${
|
|
12371
|
-
assertHubMatchesBinding(existing.hubId,
|
|
12819
|
+
console.log(`Target hub: ${path17.basename(existing.hubFolder)} (${existing.hubId})`);
|
|
12820
|
+
assertHubMatchesBinding(existing.hubId, path17.basename(existing.hubFolder));
|
|
12372
12821
|
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
12373
12822
|
return;
|
|
12374
12823
|
}
|
|
@@ -12398,8 +12847,8 @@ var create_exports = {};
|
|
|
12398
12847
|
__export(create_exports, {
|
|
12399
12848
|
createCommand: () => createCommand
|
|
12400
12849
|
});
|
|
12401
|
-
import * as
|
|
12402
|
-
import * as
|
|
12850
|
+
import * as path18 from "path";
|
|
12851
|
+
import * as fs16 from "fs";
|
|
12403
12852
|
function parseArgs6(args2) {
|
|
12404
12853
|
let autoConfirm = false;
|
|
12405
12854
|
let folderSelector;
|
|
@@ -12426,7 +12875,7 @@ async function createCommand(args2) {
|
|
|
12426
12875
|
const gitRoot = findGitRoot();
|
|
12427
12876
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
12428
12877
|
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
12429
|
-
if (!
|
|
12878
|
+
if (!fs16.existsSync(workspaceDir)) {
|
|
12430
12879
|
console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
|
|
12431
12880
|
process.exit(1);
|
|
12432
12881
|
}
|
|
@@ -12435,7 +12884,7 @@ async function createCommand(args2) {
|
|
|
12435
12884
|
const resolution = resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, folderSelector);
|
|
12436
12885
|
if (!resolution.ok) {
|
|
12437
12886
|
if (resolution.reason === "exists") {
|
|
12438
|
-
const folder =
|
|
12887
|
+
const folder = path18.basename(resolution.existing.hubFolder);
|
|
12439
12888
|
console.error(`Hub "${folder}" already exists (${resolution.existing.hubId}). Use \`wayai push --hub ${folder}\` to update it.`);
|
|
12440
12889
|
process.exit(1);
|
|
12441
12890
|
}
|
|
@@ -12449,7 +12898,7 @@ async function createCommand(args2) {
|
|
|
12449
12898
|
}
|
|
12450
12899
|
console.error(`Multiple new hub folders found in ${wsLabel}/. Pass the folder name (\`wayai create <folder>\`) or run from inside one:`);
|
|
12451
12900
|
for (const h of newHubs) {
|
|
12452
|
-
console.error(` ${
|
|
12901
|
+
console.error(` ${path18.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
12453
12902
|
}
|
|
12454
12903
|
process.exit(1);
|
|
12455
12904
|
}
|
|
@@ -12631,12 +13080,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
12631
13080
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
12632
13081
|
return false;
|
|
12633
13082
|
}
|
|
12634
|
-
function validateSchema2(schema,
|
|
13083
|
+
function validateSchema2(schema, path30, errors, opts = {}) {
|
|
12635
13084
|
if (typeof schema === "boolean") return;
|
|
12636
13085
|
const depth = opts.depth ?? 0;
|
|
12637
13086
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
12638
13087
|
errors.push({
|
|
12639
|
-
path:
|
|
13088
|
+
path: path30 || "<root>",
|
|
12640
13089
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
12641
13090
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
12642
13091
|
});
|
|
@@ -12644,7 +13093,7 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12644
13093
|
}
|
|
12645
13094
|
if (!isRecord2(schema)) {
|
|
12646
13095
|
errors.push({
|
|
12647
|
-
path:
|
|
13096
|
+
path: path30,
|
|
12648
13097
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
12649
13098
|
});
|
|
12650
13099
|
return;
|
|
@@ -12652,14 +13101,14 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12652
13101
|
if (opts.isRoot) {
|
|
12653
13102
|
if ("type" in schema && schema.type !== "object") {
|
|
12654
13103
|
errors.push({
|
|
12655
|
-
path:
|
|
13104
|
+
path: path30 ? `${path30}.type` : "type",
|
|
12656
13105
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
12657
13106
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
12658
13107
|
});
|
|
12659
13108
|
}
|
|
12660
13109
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
12661
13110
|
errors.push({
|
|
12662
|
-
path: `${
|
|
13111
|
+
path: `${path30}.type`,
|
|
12663
13112
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
12664
13113
|
});
|
|
12665
13114
|
}
|
|
@@ -12668,25 +13117,25 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12668
13117
|
if (typeof e === "string") {
|
|
12669
13118
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
12670
13119
|
errors.push({
|
|
12671
|
-
path: `${
|
|
13120
|
+
path: `${path30}.enum`,
|
|
12672
13121
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
12673
13122
|
suggestion: isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
|
|
12674
13123
|
});
|
|
12675
13124
|
} else if (!Array.isArray(e)) {
|
|
12676
13125
|
errors.push({
|
|
12677
|
-
path: `${
|
|
13126
|
+
path: `${path30}.enum`,
|
|
12678
13127
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
12679
13128
|
});
|
|
12680
13129
|
} else if (e.length === 0) {
|
|
12681
13130
|
errors.push({
|
|
12682
|
-
path: `${
|
|
13131
|
+
path: `${path30}.enum`,
|
|
12683
13132
|
message: "enum must not be empty"
|
|
12684
13133
|
});
|
|
12685
13134
|
} else {
|
|
12686
13135
|
for (let i = 0; i < e.length; i++) {
|
|
12687
13136
|
if (!isPrimitive2(e[i])) {
|
|
12688
13137
|
errors.push({
|
|
12689
|
-
path: `${
|
|
13138
|
+
path: `${path30}.enum[${i}]`,
|
|
12690
13139
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
12691
13140
|
});
|
|
12692
13141
|
}
|
|
@@ -12696,7 +13145,7 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12696
13145
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
12697
13146
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
12698
13147
|
errors.push({
|
|
12699
|
-
path: `${
|
|
13148
|
+
path: `${path30}.${key}`,
|
|
12700
13149
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
12701
13150
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
12702
13151
|
});
|
|
@@ -12705,45 +13154,45 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12705
13154
|
if ("properties" in schema) {
|
|
12706
13155
|
if (!isRecord2(schema.properties)) {
|
|
12707
13156
|
errors.push({
|
|
12708
|
-
path: `${
|
|
13157
|
+
path: `${path30}.properties`,
|
|
12709
13158
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
12710
13159
|
});
|
|
12711
13160
|
} else {
|
|
12712
13161
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
12713
|
-
validateSchema2(propSchema, `${
|
|
13162
|
+
validateSchema2(propSchema, `${path30}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
12714
13163
|
}
|
|
12715
13164
|
}
|
|
12716
13165
|
}
|
|
12717
13166
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
12718
13167
|
if (Array.isArray(schema.items)) {
|
|
12719
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
13168
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path30}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
12720
13169
|
} else {
|
|
12721
|
-
validateSchema2(schema.items, `${
|
|
13170
|
+
validateSchema2(schema.items, `${path30}.items`, errors, { depth: depth + 1 });
|
|
12722
13171
|
}
|
|
12723
13172
|
}
|
|
12724
13173
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
12725
13174
|
if (key in schema && isRecord2(schema[key])) {
|
|
12726
|
-
validateSchema2(schema[key], `${
|
|
13175
|
+
validateSchema2(schema[key], `${path30}.${key}`, errors, { depth: depth + 1 });
|
|
12727
13176
|
}
|
|
12728
13177
|
}
|
|
12729
13178
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
12730
13179
|
const list = schema[key];
|
|
12731
13180
|
if (Array.isArray(list)) {
|
|
12732
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
13181
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path30}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
12733
13182
|
}
|
|
12734
13183
|
}
|
|
12735
13184
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
12736
13185
|
const map = schema[key];
|
|
12737
13186
|
if (isRecord2(map)) {
|
|
12738
13187
|
for (const [name, sub] of Object.entries(map)) {
|
|
12739
|
-
validateSchema2(sub, `${
|
|
13188
|
+
validateSchema2(sub, `${path30}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
12740
13189
|
}
|
|
12741
13190
|
}
|
|
12742
13191
|
}
|
|
12743
13192
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
12744
13193
|
for (const [k, v] of Object.entries(schema)) {
|
|
12745
13194
|
if (typeof v !== "string") continue;
|
|
12746
|
-
const fieldPath = `${
|
|
13195
|
+
const fieldPath = `${path30}.${k}`;
|
|
12747
13196
|
if (reportedPaths.has(fieldPath)) continue;
|
|
12748
13197
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
12749
13198
|
if (v === token) {
|
|
@@ -12818,15 +13267,17 @@ function describeRole2(role) {
|
|
|
12818
13267
|
return `a ${typeof role}`;
|
|
12819
13268
|
}
|
|
12820
13269
|
function asEvalInputRecord2(input) {
|
|
12821
|
-
const value =
|
|
12822
|
-
try {
|
|
12823
|
-
return JSON.parse(input);
|
|
12824
|
-
} catch {
|
|
12825
|
-
return null;
|
|
12826
|
-
}
|
|
12827
|
-
})() : input;
|
|
13270
|
+
const value = parseMaybeJson2(input);
|
|
12828
13271
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
12829
13272
|
}
|
|
13273
|
+
function parseMaybeJson2(value) {
|
|
13274
|
+
if (typeof value !== "string") return value;
|
|
13275
|
+
try {
|
|
13276
|
+
return JSON.parse(value);
|
|
13277
|
+
} catch {
|
|
13278
|
+
return null;
|
|
13279
|
+
}
|
|
13280
|
+
}
|
|
12830
13281
|
function evalInputRoleError2(input) {
|
|
12831
13282
|
const record = asEvalInputRecord2(input);
|
|
12832
13283
|
if (record === null) return null;
|
|
@@ -12837,6 +13288,32 @@ function evalInputRoleError2(input) {
|
|
|
12837
13288
|
}
|
|
12838
13289
|
return `role must be ${EVAL_INPUT_ROLE_LIST2} (received ${describeRole2(role)}) \u2014 an eval trigger is what the responder answers, and an assistant or tool role gives it nothing to answer`;
|
|
12839
13290
|
}
|
|
13291
|
+
function evalTurnAttachmentsError2(turn) {
|
|
13292
|
+
const record = asEvalInputRecord2(turn);
|
|
13293
|
+
if (record === null) return null;
|
|
13294
|
+
const attachments = record.attachments;
|
|
13295
|
+
if (attachments === void 0 || attachments === null) return null;
|
|
13296
|
+
if (!Array.isArray(attachments)) return "attachments must be an array";
|
|
13297
|
+
if (attachments.length === 0) return null;
|
|
13298
|
+
if (attachments.length > MAX_ATTACHMENTS_PER_MESSAGE2) {
|
|
13299
|
+
return `attachments must have at most ${MAX_ATTACHMENTS_PER_MESSAGE2} items`;
|
|
13300
|
+
}
|
|
13301
|
+
if (!turnMayCarryAttachments2({ role: String(record.role), attachments })) {
|
|
13302
|
+
return ATTACHMENTS_USER_ONLY_MESSAGE2;
|
|
13303
|
+
}
|
|
13304
|
+
for (let i = 0; i < attachments.length; i++) {
|
|
13305
|
+
const parsed = evalAttachmentRef2.safeParse(attachments[i]);
|
|
13306
|
+
if (!parsed.success) {
|
|
13307
|
+
const issue = parsed.error.issues[0];
|
|
13308
|
+
return `attachments[${i}].${issue?.path.join(".") || "?"} is invalid: ${issue?.message ?? "malformed"}`;
|
|
13309
|
+
}
|
|
13310
|
+
}
|
|
13311
|
+
return null;
|
|
13312
|
+
}
|
|
13313
|
+
function asEvalHistoryArray2(history) {
|
|
13314
|
+
const value = parseMaybeJson2(history);
|
|
13315
|
+
return Array.isArray(value) ? value : null;
|
|
13316
|
+
}
|
|
12840
13317
|
function refineEvalMessageTextRole2(value, ctx) {
|
|
12841
13318
|
const error = evalInputRoleError2(value.eval.message_text);
|
|
12842
13319
|
if (error) {
|
|
@@ -12847,6 +13324,38 @@ function refineEvalMessageTextRole2(value, ctx) {
|
|
|
12847
13324
|
});
|
|
12848
13325
|
}
|
|
12849
13326
|
}
|
|
13327
|
+
function refineEvalAttachments2(value, ctx) {
|
|
13328
|
+
const triggerError = evalTurnAttachmentsError2(value.eval.message_text);
|
|
13329
|
+
if (triggerError) {
|
|
13330
|
+
ctx.addIssue({
|
|
13331
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13332
|
+
path: ["eval", "message_text", "attachments"],
|
|
13333
|
+
message: triggerError
|
|
13334
|
+
});
|
|
13335
|
+
}
|
|
13336
|
+
const history = asEvalHistoryArray2(value.eval.message_history);
|
|
13337
|
+
if (!history) return;
|
|
13338
|
+
for (let i = 0; i < history.length; i++) {
|
|
13339
|
+
const error = evalTurnAttachmentsError2(history[i]);
|
|
13340
|
+
if (error) {
|
|
13341
|
+
ctx.addIssue({
|
|
13342
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13343
|
+
path: ["eval", "message_history", i, "attachments"],
|
|
13344
|
+
message: error
|
|
13345
|
+
});
|
|
13346
|
+
}
|
|
13347
|
+
}
|
|
13348
|
+
}
|
|
13349
|
+
function collectTurnAttachmentHashes2(turn) {
|
|
13350
|
+
const atts = asEvalInputRecord2(turn)?.attachments;
|
|
13351
|
+
if (!Array.isArray(atts)) return [];
|
|
13352
|
+
const hashes = [];
|
|
13353
|
+
for (const a of atts) {
|
|
13354
|
+
const parsed = evalAttachmentRef2.safeParse(a);
|
|
13355
|
+
if (parsed.success) hashes.push(parsed.data.hash);
|
|
13356
|
+
}
|
|
13357
|
+
return hashes;
|
|
13358
|
+
}
|
|
12850
13359
|
function refineHubAsCodeCustomTools2(config, ctx) {
|
|
12851
13360
|
const agents = config.agents;
|
|
12852
13361
|
if (!Array.isArray(agents)) return;
|
|
@@ -12954,10 +13463,84 @@ function refineHubAsCodeEvals2(config, ctx) {
|
|
|
12954
13463
|
}
|
|
12955
13464
|
}
|
|
12956
13465
|
}
|
|
12957
|
-
function
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
const
|
|
13466
|
+
function refineHubAsCodeEvalAttachments2(config, ctx) {
|
|
13467
|
+
const cfg = config;
|
|
13468
|
+
const referencedHashes = /* @__PURE__ */ new Set();
|
|
13469
|
+
const addTurnIssue = (path30, turn, name) => {
|
|
13470
|
+
const error = evalTurnAttachmentsError2(turn);
|
|
13471
|
+
if (error) {
|
|
13472
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path30, message: `${name}: ${error}` });
|
|
13473
|
+
return;
|
|
13474
|
+
}
|
|
13475
|
+
for (const hash of collectTurnAttachmentHashes2(turn)) referencedHashes.add(hash);
|
|
13476
|
+
};
|
|
13477
|
+
if (Array.isArray(cfg.evals)) {
|
|
13478
|
+
cfg.evals.forEach((entry, e) => {
|
|
13479
|
+
const ev = entry;
|
|
13480
|
+
const name = `eval "${ev?.name ?? "<unnamed>"}"`;
|
|
13481
|
+
addTurnIssue(["evals", e, "input"], ev?.input, name);
|
|
13482
|
+
if (Array.isArray(ev?.history)) {
|
|
13483
|
+
ev.history.forEach((turn, h) => addTurnIssue(["evals", e, "history", h], turn, name));
|
|
13484
|
+
}
|
|
13485
|
+
});
|
|
13486
|
+
}
|
|
13487
|
+
if (Array.isArray(cfg.journeys)) {
|
|
13488
|
+
cfg.journeys.forEach((entry, j) => {
|
|
13489
|
+
const jr = entry;
|
|
13490
|
+
const name = `journey "${jr?.name ?? "<unnamed>"}"`;
|
|
13491
|
+
if (Array.isArray(jr?.transcript)) {
|
|
13492
|
+
jr.transcript.forEach((turn, t) => addTurnIssue(["journeys", j, "transcript", t], turn, name));
|
|
13493
|
+
}
|
|
13494
|
+
});
|
|
13495
|
+
}
|
|
13496
|
+
const carriedHashes = /* @__PURE__ */ new Set();
|
|
13497
|
+
const files = cfg.eval_attachment_files;
|
|
13498
|
+
if (Array.isArray(files)) {
|
|
13499
|
+
if (files.length > MAX_EVAL_ATTACHMENT_CARRIERS2) {
|
|
13500
|
+
ctx.addIssue({
|
|
13501
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13502
|
+
path: ["eval_attachment_files"],
|
|
13503
|
+
message: `too many attachment carriers (${files.length}); the maximum is ${MAX_EVAL_ATTACHMENT_CARRIERS2}`
|
|
13504
|
+
});
|
|
13505
|
+
}
|
|
13506
|
+
let aggregateEncoded = 0;
|
|
13507
|
+
files.forEach((f, i) => {
|
|
13508
|
+
const h = f?.hash;
|
|
13509
|
+
if (typeof h === "string") carriedHashes.add(h);
|
|
13510
|
+
const b64 = f?.content_base64;
|
|
13511
|
+
if (typeof b64 === "string") {
|
|
13512
|
+
aggregateEncoded += b64.length;
|
|
13513
|
+
if (b64.length > MAX_EVAL_ATTACHMENT_ENCODED_BYTES2) {
|
|
13514
|
+
ctx.addIssue({
|
|
13515
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13516
|
+
path: ["eval_attachment_files", i, "content_base64"],
|
|
13517
|
+
message: `attachment ${typeof h === "string" ? `${h.slice(0, 12)}\u2026 ` : ""}exceeds the ${(MAX_RESOURCE_FILE_SIZE3 / 1024 / 1024).toFixed(0)}MB size limit`
|
|
13518
|
+
});
|
|
13519
|
+
}
|
|
13520
|
+
}
|
|
13521
|
+
});
|
|
13522
|
+
if (aggregateEncoded > MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2) {
|
|
13523
|
+
ctx.addIssue({
|
|
13524
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13525
|
+
path: ["eval_attachment_files"],
|
|
13526
|
+
message: `total attachment bytes exceed the ${(MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2 / 1024 / 1024).toFixed(0)}MB per-push limit \u2014 split the push or reduce attachments`
|
|
13527
|
+
});
|
|
13528
|
+
}
|
|
13529
|
+
}
|
|
13530
|
+
for (const hash of referencedHashes) {
|
|
13531
|
+
if (!carriedHashes.has(hash)) {
|
|
13532
|
+
ctx.addIssue({
|
|
13533
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13534
|
+
path: ["eval_attachment_files"],
|
|
13535
|
+
message: `attachment ${hash.slice(0, 12)}\u2026 is referenced by a turn but its bytes are missing from eval_attachment_files`
|
|
13536
|
+
});
|
|
13537
|
+
}
|
|
13538
|
+
}
|
|
13539
|
+
}
|
|
13540
|
+
function isSafeTemplatePath2(path30) {
|
|
13541
|
+
if (path30.length === 0 || path30.length > 300) return false;
|
|
13542
|
+
if (path30.startsWith("/") || path30.includes("\\")) return false;
|
|
13543
|
+
const segments = path30.split("/");
|
|
12961
13544
|
return segments.every(
|
|
12962
13545
|
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
12963
13546
|
);
|
|
@@ -12985,14 +13568,14 @@ function isPlainObject(value) {
|
|
|
12985
13568
|
const proto = Object.getPrototypeOf(value);
|
|
12986
13569
|
return proto === Object.prototype || proto === null;
|
|
12987
13570
|
}
|
|
12988
|
-
function isSanitizableSliceFile(
|
|
12989
|
-
if (!/\.ya?ml$/i.test(
|
|
12990
|
-
return
|
|
13571
|
+
function isSanitizableSliceFile(path30) {
|
|
13572
|
+
if (!/\.ya?ml$/i.test(path30)) return false;
|
|
13573
|
+
return path30 !== "resources" && !path30.startsWith("resources/");
|
|
12991
13574
|
}
|
|
12992
13575
|
function distinctUsesBackends(uses) {
|
|
12993
13576
|
return [...new Set((uses ?? []).map((u) => u.backend))];
|
|
12994
13577
|
}
|
|
12995
|
-
var uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, clientOptionalString2, clientOptionalBoolean2, clientOptionalNumber2, messageAttachment2, MAX_MESSAGE_BODY_BYTES2, MAX_ATTACHMENTS_PER_MESSAGE2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, AUTH_TYPE3, ORG_CREDENTIAL_AUTH_TYPES3, AUTH_TYPE_DISPLAY3, LEGACY_AUTH_TYPE_MAP3, VALID_AUTH_TYPES3, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, summarizationThresholdField2, monitorConfigField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, PREVIEW_LABEL_MAX_LENGTH2, MAX_ENDED_INDEX_RETENTION_DAYS2, previewLabelField2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, updateChannelTestIdentitiesBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, PRODUCTION_DIRECT_FIELDS2, setProductionCredentialBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, variantAiModeSchema2, experimentStatusSchema2, overlayUpdateSchema2, experimentIdParam2, variantIdParam2, listExperimentsQuery2, listVariantsQuery2, listOverridesQuery2, deleteOverrideQuery2, createExperimentBody2, updateExperimentBody2, setExperimentStatusBody2, createVariantBody2, updateVariantBody2, upsertOverrideBody2, orgTagIdParam2, listOrgTagsQuery2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlSchemaQuery2, EVAL_PACING_PRESET_NAMES2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, EVAL_INPUT_ROLES2, EVAL_INPUT_ROLE_LIST2, ROLE_ECHO_MAX2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, fixtureField2, createJourneyBody2, updateJourneyBody2, getConversationsQuery2, getMessagesQuery2, appMessageSenderType2, appMessageReceiverType2, appMessageBody2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, sendMessageBody2, listConversationsQuery2, getConversationDetailParams2, getConversationDetailQuery2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, uuidPattern2, ciUuidSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminHubIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminSetOrgHarnessBody2, adminSetHubHarnessBody2, adminScopedTargetBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysQuery2, dataExplorerKvKeyParam2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteQuery2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, sandboxEgressPolicy2, SANDBOX_EXEC_MAX_CMD_LENGTH2, SANDBOX_EXEC_MAX_ALLOWLIST2, SANDBOX_EXEC_MAX_TIMEOUT_MS2, adminSandboxExecBody2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, discordTier2, discordBillingCycle2, discordMetadata2, discordOAuthStartResponse2, discordOAuthFinalizeBody2, discordOAuthFinalizeResponse2, discordDisconnectResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, templateLocaleSchema2, TEMPLATE_SLUG_REGEX2, templateSlugSchema2, templateStatusSchema2, templateFileMapSchema2, TEMPLATE_INSTANCE_ID_KEYS, TEMPLATE_OPAQUE_BLOB_KEYS, TEMPLATE_AUTHOR_DATA_KEYS, templateTextSchema2, templateUsesEntrySchema2, templateUsesSchema2, templateYamlLocaleEntry2, templateYamlWayaiBlock2, templateTagsSchema2, templateYamlSchema2, templateHeroSchema2, templatePushLocaleSchema2, templatePushBody2, templateListQuery2, templateSlugParam2, templateDetailQuery2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2;
|
|
13578
|
+
var uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, clientOptionalString2, clientOptionalBoolean2, clientOptionalNumber2, messageAttachment2, MAX_MESSAGE_BODY_BYTES2, MAX_ATTACHMENTS_PER_MESSAGE2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, AUTH_TYPE3, ORG_CREDENTIAL_AUTH_TYPES3, AUTH_TYPE_DISPLAY3, LEGACY_AUTH_TYPE_MAP3, VALID_AUTH_TYPES3, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, summarizationThresholdField2, monitorConfigField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, PREVIEW_LABEL_MAX_LENGTH2, MAX_ENDED_INDEX_RETENTION_DAYS2, previewLabelField2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, updateChannelTestIdentitiesBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, PRODUCTION_DIRECT_FIELDS2, setProductionCredentialBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, variantAiModeSchema2, experimentStatusSchema2, overlayUpdateSchema2, experimentIdParam2, variantIdParam2, listExperimentsQuery2, listVariantsQuery2, listOverridesQuery2, deleteOverrideQuery2, createExperimentBody2, updateExperimentBody2, setExperimentStatusBody2, createVariantBody2, updateVariantBody2, upsertOverrideBody2, orgTagIdParam2, listOrgTagsQuery2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlSchemaQuery2, EVAL_PACING_PRESET_NAMES2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, EVAL_INPUT_ROLES2, EVAL_INPUT_ROLE_LIST2, ROLE_ECHO_MAX2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, EVAL_ATTACHMENT_HASH_REGEX2, evalAttachmentRef2, turnMayCarryAttachments2, ATTACHMENTS_USER_ONLY_MESSAGE2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, fixtureField2, createJourneyBody2, updateJourneyBody2, getConversationsQuery2, getMessagesQuery2, appMessageSenderType2, appMessageReceiverType2, appMessageBody2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, sendMessageBody2, listConversationsQuery2, getConversationDetailParams2, getConversationDetailQuery2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, MAX_RESOURCE_FILE_SIZE3, MAX_EVAL_ATTACHMENT_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_CARRIERS2, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2, uuidPattern2, ciUuidSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminHubIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminSetOrgHarnessBody2, adminSetHubHarnessBody2, adminScopedTargetBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysQuery2, dataExplorerKvKeyParam2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteQuery2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, sandboxEgressPolicy2, SANDBOX_EXEC_MAX_CMD_LENGTH2, SANDBOX_EXEC_MAX_ALLOWLIST2, SANDBOX_EXEC_MAX_TIMEOUT_MS2, adminSandboxExecBody2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, discordTier2, discordBillingCycle2, discordMetadata2, discordOAuthStartResponse2, discordOAuthFinalizeBody2, discordOAuthFinalizeResponse2, discordDisconnectResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, templateLocaleSchema2, TEMPLATE_SLUG_REGEX2, templateSlugSchema2, templateStatusSchema2, templateFileMapSchema2, TEMPLATE_INSTANCE_ID_KEYS, TEMPLATE_OPAQUE_BLOB_KEYS, TEMPLATE_AUTHOR_DATA_KEYS, templateTextSchema2, templateUsesEntrySchema2, templateUsesSchema2, templateYamlLocaleEntry2, templateYamlWayaiBlock2, templateTagsSchema2, templateYamlSchema2, templateHeroSchema2, templatePushLocaleSchema2, templatePushBody2, templateListQuery2, templateSlugParam2, templateDetailQuery2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2;
|
|
12996
13579
|
var init_contracts = __esm({
|
|
12997
13580
|
"../../packages/core/dist/contracts/index.js"() {
|
|
12998
13581
|
"use strict";
|
|
@@ -14164,10 +14747,10 @@ var init_contracts = __esm({
|
|
|
14164
14747
|
ROLE_ECHO_MAX2 = 40;
|
|
14165
14748
|
createEvalBody2 = external_exports.object({
|
|
14166
14749
|
eval: external_exports.record(external_exports.unknown())
|
|
14167
|
-
}).superRefine(refineEvalMessageTextRole2);
|
|
14750
|
+
}).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2);
|
|
14168
14751
|
updateEvalBody2 = external_exports.object({
|
|
14169
14752
|
eval: external_exports.record(external_exports.unknown())
|
|
14170
|
-
}).superRefine(refineEvalMessageTextRole2);
|
|
14753
|
+
}).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2);
|
|
14171
14754
|
getEvalsQuery2 = external_exports.object({
|
|
14172
14755
|
hub_id: external_exports.string().uuid(),
|
|
14173
14756
|
agent_id: external_exports.string().uuid().optional(),
|
|
@@ -14294,6 +14877,15 @@ var init_contracts = __esm({
|
|
|
14294
14877
|
journey_name: external_exports.string().min(1).max(200),
|
|
14295
14878
|
evaluator_instructions: external_exports.string().max(4e3).optional()
|
|
14296
14879
|
});
|
|
14880
|
+
EVAL_ATTACHMENT_HASH_REGEX2 = /^[a-f0-9]{64}$/;
|
|
14881
|
+
evalAttachmentRef2 = external_exports.object({
|
|
14882
|
+
hash: external_exports.string().regex(EVAL_ATTACHMENT_HASH_REGEX2),
|
|
14883
|
+
file_name: external_exports.string().min(1).max(255),
|
|
14884
|
+
mime_type: external_exports.string().min(1).max(255),
|
|
14885
|
+
file_size: external_exports.number().int().positive().optional()
|
|
14886
|
+
});
|
|
14887
|
+
turnMayCarryAttachments2 = (turn) => !turn.attachments || turn.attachments.length === 0 || turn.role === "user";
|
|
14888
|
+
ATTACHMENTS_USER_ONLY_MESSAGE2 = "attachments are only valid on user turns";
|
|
14297
14889
|
journeyIdParam2 = external_exports.object({ id: external_exports.string().uuid() });
|
|
14298
14890
|
journeyToolCallSchema2 = external_exports.object({
|
|
14299
14891
|
id: external_exports.string(),
|
|
@@ -14305,7 +14897,10 @@ var init_contracts = __esm({
|
|
|
14305
14897
|
content: external_exports.string().nullable().optional(),
|
|
14306
14898
|
tool_calls: external_exports.array(journeyToolCallSchema2).optional(),
|
|
14307
14899
|
tool_call_id: external_exports.string().optional(),
|
|
14308
|
-
step_id: external_exports.string().optional()
|
|
14900
|
+
step_id: external_exports.string().optional(),
|
|
14901
|
+
attachments: external_exports.array(evalAttachmentRef2).max(MAX_ATTACHMENTS_PER_MESSAGE2).optional()
|
|
14902
|
+
}).refine(turnMayCarryAttachments2, {
|
|
14903
|
+
message: ATTACHMENTS_USER_ONLY_MESSAGE2
|
|
14309
14904
|
});
|
|
14310
14905
|
journeyStepOverrideSchema2 = external_exports.object({
|
|
14311
14906
|
number_of_runs: external_exports.number().int().positive().max(100).optional(),
|
|
@@ -14810,6 +15405,10 @@ var init_contracts = __esm({
|
|
|
14810
15405
|
agent_id: external_exports.string().uuid().nullable().optional(),
|
|
14811
15406
|
trigger_message: external_exports.string().nullable().optional()
|
|
14812
15407
|
});
|
|
15408
|
+
MAX_RESOURCE_FILE_SIZE3 = 10 * 1024 * 1024;
|
|
15409
|
+
MAX_EVAL_ATTACHMENT_ENCODED_BYTES2 = Math.ceil(MAX_RESOURCE_FILE_SIZE3 / 3) * 4 + 16;
|
|
15410
|
+
MAX_EVAL_ATTACHMENT_CARRIERS2 = 1e3;
|
|
15411
|
+
MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2 = 16 * 1024 * 1024;
|
|
14813
15412
|
uuidPattern2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
14814
15413
|
ciUuidSchema2 = external_exports.string().regex(uuidPattern2, "must be a valid UUID");
|
|
14815
15414
|
hubAsCodeConfigSchema2 = external_exports.object({
|
|
@@ -14822,6 +15421,7 @@ var init_contracts = __esm({
|
|
|
14822
15421
|
refineHubAsCodeKanbanStatuses2(config, ctx);
|
|
14823
15422
|
refineHubAsCodeLanes2(config, ctx);
|
|
14824
15423
|
refineHubAsCodeEvals2(config, ctx);
|
|
15424
|
+
refineHubAsCodeEvalAttachments2(config, ctx);
|
|
14825
15425
|
});
|
|
14826
15426
|
ciPullHubIdParam2 = external_exports.object({
|
|
14827
15427
|
hub_id: ciUuidSchema2
|
|
@@ -15711,8 +16311,8 @@ var replicate_exports = {};
|
|
|
15711
16311
|
__export(replicate_exports, {
|
|
15712
16312
|
replicateCommand: () => replicateCommand
|
|
15713
16313
|
});
|
|
15714
|
-
import * as
|
|
15715
|
-
import * as
|
|
16314
|
+
import * as fs17 from "fs";
|
|
16315
|
+
import * as path19 from "path";
|
|
15716
16316
|
function parseArgs8(args2) {
|
|
15717
16317
|
let label;
|
|
15718
16318
|
let hubSelector;
|
|
@@ -15758,7 +16358,7 @@ async function replicateCommand(args2) {
|
|
|
15758
16358
|
payload.preview_label,
|
|
15759
16359
|
payload.branch_name
|
|
15760
16360
|
);
|
|
15761
|
-
|
|
16361
|
+
fs17.mkdirSync(path19.dirname(hubFolder), { recursive: true });
|
|
15762
16362
|
writeHubFolder(hubFolder, payload);
|
|
15763
16363
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
15764
16364
|
hubFolder = autoRenameHubFolder(
|
|
@@ -15770,8 +16370,8 @@ async function replicateCommand(args2) {
|
|
|
15770
16370
|
payload.branch_name
|
|
15771
16371
|
);
|
|
15772
16372
|
autoBindIfUnbound(previewHubId);
|
|
15773
|
-
console.log(`Preview written to ${
|
|
15774
|
-
console.log(` Switch to it with: wayai use ${
|
|
16373
|
+
console.log(`Preview written to ${path19.basename(hubFolder)}`);
|
|
16374
|
+
console.log(` Switch to it with: wayai use ${path19.basename(hubFolder)}`);
|
|
15775
16375
|
}
|
|
15776
16376
|
var init_replicate = __esm({
|
|
15777
16377
|
"src/commands/replicate.ts"() {
|
|
@@ -15793,7 +16393,7 @@ var relabel_exports = {};
|
|
|
15793
16393
|
__export(relabel_exports, {
|
|
15794
16394
|
relabelCommand: () => relabelCommand
|
|
15795
16395
|
});
|
|
15796
|
-
import * as
|
|
16396
|
+
import * as path20 from "path";
|
|
15797
16397
|
function parseArgs9(args2) {
|
|
15798
16398
|
let label;
|
|
15799
16399
|
let clear = false;
|
|
@@ -15837,7 +16437,7 @@ async function relabelCommand(args2) {
|
|
|
15837
16437
|
} else {
|
|
15838
16438
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
15839
16439
|
for (const h of previewHubs) {
|
|
15840
|
-
console.error(` ${
|
|
16440
|
+
console.error(` ${path20.basename(h.hubFolder)} (${h.hubId})`);
|
|
15841
16441
|
}
|
|
15842
16442
|
}
|
|
15843
16443
|
process.exit(1);
|
|
@@ -15846,7 +16446,7 @@ async function relabelCommand(args2) {
|
|
|
15846
16446
|
console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
|
|
15847
16447
|
return;
|
|
15848
16448
|
}
|
|
15849
|
-
assertHubMatchesBinding(target.hubId,
|
|
16449
|
+
assertHubMatchesBinding(target.hubId, path20.basename(target.hubFolder));
|
|
15850
16450
|
console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
|
|
15851
16451
|
const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
|
|
15852
16452
|
const row = data[0];
|
|
@@ -15862,7 +16462,7 @@ async function relabelCommand(args2) {
|
|
|
15862
16462
|
);
|
|
15863
16463
|
console.log(serverLabel ? `Preview label set to "${serverLabel}".` : "Preview label cleared.");
|
|
15864
16464
|
if (finalFolder !== target.hubFolder) {
|
|
15865
|
-
console.log(`Hub folder is now ${
|
|
16465
|
+
console.log(`Hub folder is now ${path20.basename(finalFolder)}`);
|
|
15866
16466
|
}
|
|
15867
16467
|
}
|
|
15868
16468
|
var init_relabel = __esm({
|
|
@@ -15888,7 +16488,7 @@ __export(publish_exports, {
|
|
|
15888
16488
|
renderHubDiff: () => renderHubDiff,
|
|
15889
16489
|
runPublish: () => runPublish
|
|
15890
16490
|
});
|
|
15891
|
-
import * as
|
|
16491
|
+
import * as path21 from "path";
|
|
15892
16492
|
function parseArgs10(args2) {
|
|
15893
16493
|
let autoConfirm = false;
|
|
15894
16494
|
let hubSelector;
|
|
@@ -15994,7 +16594,7 @@ async function publishCommand(args2) {
|
|
|
15994
16594
|
return;
|
|
15995
16595
|
}
|
|
15996
16596
|
}
|
|
15997
|
-
assertHubMatchesBinding(hubId, hubFolder ?
|
|
16597
|
+
assertHubMatchesBinding(hubId, hubFolder ? path21.basename(hubFolder) : void 0);
|
|
15998
16598
|
await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
|
|
15999
16599
|
}
|
|
16000
16600
|
var STATUS_STYLE;
|
|
@@ -16026,7 +16626,7 @@ var use_exports = {};
|
|
|
16026
16626
|
__export(use_exports, {
|
|
16027
16627
|
useCommand: () => useCommand
|
|
16028
16628
|
});
|
|
16029
|
-
import * as
|
|
16629
|
+
import * as path22 from "path";
|
|
16030
16630
|
async function useCommand(args2) {
|
|
16031
16631
|
const target = args2[0];
|
|
16032
16632
|
if (!target || target.startsWith("-")) {
|
|
@@ -16048,7 +16648,7 @@ async function useCommand(args2) {
|
|
|
16048
16648
|
const match = findHubByFolderName(workspaceDir, target);
|
|
16049
16649
|
if (!match) {
|
|
16050
16650
|
const newHubs = scanNewHubs(workspaceDir);
|
|
16051
|
-
const pending = newHubs.find((h) =>
|
|
16651
|
+
const pending = newHubs.find((h) => path22.basename(h.hubFolder) === target);
|
|
16052
16652
|
if (pending) {
|
|
16053
16653
|
console.error(
|
|
16054
16654
|
`"${target}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
|
|
@@ -16059,10 +16659,10 @@ Create it first \u2014 the worktree binds automatically afterward:
|
|
|
16059
16659
|
}
|
|
16060
16660
|
console.error(`No hub matching "${target}" found in ${wsLabel}/. Pass a UUID or a folder name from:`);
|
|
16061
16661
|
for (const h of scanWorkspaceHubs(workspaceDir)) {
|
|
16062
|
-
console.error(` ${
|
|
16662
|
+
console.error(` ${path22.basename(h.hubFolder)} (${h.hubId})`);
|
|
16063
16663
|
}
|
|
16064
16664
|
for (const h of newHubs) {
|
|
16065
|
-
console.error(` ${
|
|
16665
|
+
console.error(` ${path22.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path22.basename(h.hubFolder)}\`)`);
|
|
16066
16666
|
}
|
|
16067
16667
|
process.exit(1);
|
|
16068
16668
|
}
|
|
@@ -16101,11 +16701,11 @@ __export(migrate_exports, {
|
|
|
16101
16701
|
migrateCommand: () => migrateCommand
|
|
16102
16702
|
});
|
|
16103
16703
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
16104
|
-
import * as
|
|
16105
|
-
import * as
|
|
16704
|
+
import * as fs18 from "fs";
|
|
16705
|
+
import * as path23 from "path";
|
|
16106
16706
|
function isTracked(gitRoot, p) {
|
|
16107
16707
|
try {
|
|
16108
|
-
execFileSync3("git", ["ls-files", "--error-unmatch", "--",
|
|
16708
|
+
execFileSync3("git", ["ls-files", "--error-unmatch", "--", path23.relative(gitRoot, p)], {
|
|
16109
16709
|
cwd: gitRoot,
|
|
16110
16710
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16111
16711
|
});
|
|
@@ -16115,10 +16715,10 @@ function isTracked(gitRoot, p) {
|
|
|
16115
16715
|
}
|
|
16116
16716
|
}
|
|
16117
16717
|
function moveDir(gitRoot, from, to) {
|
|
16118
|
-
|
|
16718
|
+
fs18.mkdirSync(path23.dirname(to), { recursive: true });
|
|
16119
16719
|
if (isTracked(gitRoot, from)) {
|
|
16120
16720
|
try {
|
|
16121
|
-
execFileSync3("git", ["mv",
|
|
16721
|
+
execFileSync3("git", ["mv", path23.relative(gitRoot, from), path23.relative(gitRoot, to)], {
|
|
16122
16722
|
cwd: gitRoot,
|
|
16123
16723
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16124
16724
|
});
|
|
@@ -16126,7 +16726,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
16126
16726
|
} catch {
|
|
16127
16727
|
}
|
|
16128
16728
|
}
|
|
16129
|
-
|
|
16729
|
+
fs18.renameSync(from, to);
|
|
16130
16730
|
return "fs";
|
|
16131
16731
|
}
|
|
16132
16732
|
async function migrateCommand(_args) {
|
|
@@ -16135,12 +16735,12 @@ async function migrateCommand(_args) {
|
|
|
16135
16735
|
console.error("Not inside a git repository.");
|
|
16136
16736
|
process.exit(1);
|
|
16137
16737
|
}
|
|
16138
|
-
const rel = (p) =>
|
|
16139
|
-
const newWs =
|
|
16140
|
-
const legacyWs =
|
|
16141
|
-
const legacyOrg =
|
|
16142
|
-
const newHubs =
|
|
16143
|
-
const newOrg =
|
|
16738
|
+
const rel = (p) => path23.relative(gitRoot, p);
|
|
16739
|
+
const newWs = path23.join(gitRoot, WAYAI_LAYOUT.wsDir);
|
|
16740
|
+
const legacyWs = path23.join(gitRoot, WAYAI_LAYOUT.legacy.wsDir);
|
|
16741
|
+
const legacyOrg = path23.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);
|
|
16742
|
+
const newHubs = path23.join(newWs, WAYAI_LAYOUT.hubsSubdir);
|
|
16743
|
+
const newOrg = path23.join(newWs, WAYAI_LAYOUT.orgSubdir);
|
|
16144
16744
|
const hasLegacyWs = isDirectory(legacyWs);
|
|
16145
16745
|
const hasLegacyOrg = isDirectory(legacyOrg);
|
|
16146
16746
|
if (!hasLegacyWs && !hasLegacyOrg) {
|
|
@@ -16214,12 +16814,12 @@ var send_message_exports = {};
|
|
|
16214
16814
|
__export(send_message_exports, {
|
|
16215
16815
|
sendMessageCommand: () => sendMessageCommand
|
|
16216
16816
|
});
|
|
16217
|
-
import * as
|
|
16218
|
-
import * as
|
|
16817
|
+
import * as fs19 from "fs";
|
|
16818
|
+
import * as path24 from "path";
|
|
16219
16819
|
function statAttachment(filePath) {
|
|
16220
16820
|
let stat;
|
|
16221
16821
|
try {
|
|
16222
|
-
stat =
|
|
16822
|
+
stat = fs19.statSync(filePath);
|
|
16223
16823
|
} catch {
|
|
16224
16824
|
console.error(`Error: file not found: ${filePath}`);
|
|
16225
16825
|
process.exit(1);
|
|
@@ -16231,11 +16831,11 @@ function statAttachment(filePath) {
|
|
|
16231
16831
|
return { filePath, size: stat.size };
|
|
16232
16832
|
}
|
|
16233
16833
|
function readAttachment(filePath, size) {
|
|
16234
|
-
const fileName =
|
|
16235
|
-
const ext =
|
|
16834
|
+
const fileName = path24.basename(filePath);
|
|
16835
|
+
const ext = path24.extname(fileName).replace(/^\./, "");
|
|
16236
16836
|
return {
|
|
16237
16837
|
file_name: fileName,
|
|
16238
|
-
file_binary:
|
|
16838
|
+
file_binary: fs19.readFileSync(filePath).toString("base64"),
|
|
16239
16839
|
file_size: size,
|
|
16240
16840
|
...ext && { file_extension: ext }
|
|
16241
16841
|
};
|
|
@@ -16282,7 +16882,7 @@ async function sendMessageCommand(args2) {
|
|
|
16282
16882
|
}
|
|
16283
16883
|
const stats = filePaths.map(statAttachment);
|
|
16284
16884
|
const filesTotal = stats.reduce((sum, s) => sum + base64Length(s.size), 0);
|
|
16285
|
-
const fileDetail = () => stats.map((s) => `${
|
|
16885
|
+
const fileDetail = () => stats.map((s) => `${path24.basename(s.filePath)} ${asMb(s.size)} MB`).join(", ");
|
|
16286
16886
|
if (filesTotal > MAX_MESSAGE_BODY_BYTES2) {
|
|
16287
16887
|
console.error(
|
|
16288
16888
|
`Error: ${fileDetail()} encode to ~${asMb(filesTotal)} MB, over the ${asMb(MAX_MESSAGE_BODY_BYTES2)} MB per-request limit.`
|
|
@@ -17517,7 +18117,7 @@ Timeout after ${timeoutSeconds}s. Session is still running.`);
|
|
|
17517
18117
|
console.log(`Check results: wayai eval-results --session ${sessionId}`);
|
|
17518
18118
|
}
|
|
17519
18119
|
function sleep(ms) {
|
|
17520
|
-
return new Promise((
|
|
18120
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
17521
18121
|
}
|
|
17522
18122
|
function parsePacing(raw) {
|
|
17523
18123
|
const NAMED = EVAL_PACING_PRESET_NAMES.filter((p) => p !== "custom");
|
|
@@ -17742,8 +18342,8 @@ var eval_capture_exports = {};
|
|
|
17742
18342
|
__export(eval_capture_exports, {
|
|
17743
18343
|
evalCaptureCommand: () => evalCaptureCommand
|
|
17744
18344
|
});
|
|
17745
|
-
import * as
|
|
17746
|
-
import * as
|
|
18345
|
+
import * as fs20 from "fs";
|
|
18346
|
+
import * as path25 from "path";
|
|
17747
18347
|
import * as yaml7 from "js-yaml";
|
|
17748
18348
|
function isValidSetName(name) {
|
|
17749
18349
|
if (name.length === 0 || name === "." || name === "..") return false;
|
|
@@ -17809,15 +18409,15 @@ async function evalCaptureCommand(args2) {
|
|
|
17809
18409
|
const setFolderName = targetSetName;
|
|
17810
18410
|
const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;
|
|
17811
18411
|
const slug = slugify(scenarioName);
|
|
17812
|
-
const evalsDir =
|
|
17813
|
-
const targetDir =
|
|
17814
|
-
const targetPath =
|
|
17815
|
-
if (!targetPath.startsWith(evalsDir +
|
|
17816
|
-
console.error(`Resolved path "${
|
|
18412
|
+
const evalsDir = path25.join(hubFolder, "evals");
|
|
18413
|
+
const targetDir = path25.join(evalsDir, setFolderName);
|
|
18414
|
+
const targetPath = path25.join(targetDir, `${slug}.yaml`);
|
|
18415
|
+
if (!targetPath.startsWith(evalsDir + path25.sep)) {
|
|
18416
|
+
console.error(`Resolved path "${path25.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
|
|
17817
18417
|
process.exit(1);
|
|
17818
18418
|
}
|
|
17819
|
-
if (
|
|
17820
|
-
console.error(`File already exists: ${
|
|
18419
|
+
if (fs20.existsSync(targetPath)) {
|
|
18420
|
+
console.error(`File already exists: ${path25.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
|
|
17821
18421
|
process.exit(1);
|
|
17822
18422
|
}
|
|
17823
18423
|
console.log("Resolving scenario set...");
|
|
@@ -17849,9 +18449,9 @@ async function evalCaptureCommand(args2) {
|
|
|
17849
18449
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
17850
18450
|
};
|
|
17851
18451
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
17852
|
-
|
|
17853
|
-
|
|
17854
|
-
const relPath =
|
|
18452
|
+
fs20.mkdirSync(targetDir, { recursive: true });
|
|
18453
|
+
fs20.writeFileSync(targetPath, yaml7.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8");
|
|
18454
|
+
const relPath = path25.relative(process.cwd(), targetPath);
|
|
17855
18455
|
console.log(`
|
|
17856
18456
|
Wrote ${relPath}`);
|
|
17857
18457
|
console.log("Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.");
|
|
@@ -19078,23 +19678,23 @@ var init_set_connection_credential = __esm({
|
|
|
19078
19678
|
});
|
|
19079
19679
|
|
|
19080
19680
|
// src/lib/org-workspace.ts
|
|
19081
|
-
import * as
|
|
19082
|
-
import * as
|
|
19681
|
+
import * as fs21 from "fs";
|
|
19682
|
+
import * as path26 from "path";
|
|
19083
19683
|
import * as yaml8 from "js-yaml";
|
|
19084
19684
|
function getOrgDir(gitRoot) {
|
|
19085
19685
|
return resolveLayout(gitRoot).orgDir;
|
|
19086
19686
|
}
|
|
19087
19687
|
function orgManifestExists(orgDir) {
|
|
19088
|
-
return
|
|
19688
|
+
return fs21.existsSync(path26.join(orgDir, ORG_MANIFEST_NAME));
|
|
19089
19689
|
}
|
|
19090
19690
|
function parseOrgResources(orgDir) {
|
|
19091
|
-
const manifestPath =
|
|
19691
|
+
const manifestPath = path26.join(orgDir, ORG_MANIFEST_NAME);
|
|
19092
19692
|
let manifest = {};
|
|
19093
|
-
if (
|
|
19094
|
-
manifest = yaml8.load(
|
|
19693
|
+
if (fs21.existsSync(manifestPath)) {
|
|
19694
|
+
manifest = yaml8.load(fs21.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
19095
19695
|
}
|
|
19096
19696
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
19097
|
-
const resourcesDir =
|
|
19697
|
+
const resourcesDir = path26.join(orgDir, "resources");
|
|
19098
19698
|
const resources = rawResources.map((res) => {
|
|
19099
19699
|
const resource = { name: res.name };
|
|
19100
19700
|
if (res.id) resource.id = res.id;
|
|
@@ -19106,8 +19706,8 @@ function parseOrgResources(orgDir) {
|
|
|
19106
19706
|
if (res.environment) resource.environment = res.environment;
|
|
19107
19707
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
19108
19708
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
19109
|
-
const resDir =
|
|
19110
|
-
if (
|
|
19709
|
+
const resDir = path26.join(resourcesDir, slugify(resource.name));
|
|
19710
|
+
if (fs21.existsSync(resDir)) {
|
|
19111
19711
|
const files = scanResourceFiles(resDir, "");
|
|
19112
19712
|
if (files.length > 0) resource.files = files;
|
|
19113
19713
|
}
|
|
@@ -19116,28 +19716,28 @@ function parseOrgResources(orgDir) {
|
|
|
19116
19716
|
return { version: 1, resources };
|
|
19117
19717
|
}
|
|
19118
19718
|
function writeOrgResources(orgDir, payload) {
|
|
19119
|
-
|
|
19719
|
+
fs21.mkdirSync(orgDir, { recursive: true });
|
|
19120
19720
|
const resources = payload.resources ?? [];
|
|
19121
19721
|
const manifestResources = resources.map((r) => {
|
|
19122
19722
|
const { files: _files, ...rest } = r;
|
|
19123
19723
|
return rest;
|
|
19124
19724
|
});
|
|
19125
|
-
|
|
19126
|
-
|
|
19725
|
+
fs21.writeFileSync(
|
|
19726
|
+
path26.join(orgDir, ORG_MANIFEST_NAME),
|
|
19127
19727
|
yaml8.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
19128
19728
|
"utf-8"
|
|
19129
19729
|
);
|
|
19130
|
-
const resourcesDir =
|
|
19730
|
+
const resourcesDir = path26.join(orgDir, "resources");
|
|
19131
19731
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
19132
19732
|
for (const resource of resources) {
|
|
19133
19733
|
const resSlug = slugify(resource.name);
|
|
19134
19734
|
currentSlugs.add(resSlug);
|
|
19135
|
-
writeResourceFileTree(
|
|
19735
|
+
writeResourceFileTree(path26.join(resourcesDir, resSlug), resource.files || [], orgDir);
|
|
19136
19736
|
}
|
|
19137
|
-
if (
|
|
19138
|
-
for (const entry of
|
|
19737
|
+
if (fs21.existsSync(resourcesDir)) {
|
|
19738
|
+
for (const entry of fs21.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
19139
19739
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
19140
|
-
|
|
19740
|
+
fs21.rmSync(path26.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
19141
19741
|
}
|
|
19142
19742
|
}
|
|
19143
19743
|
}
|
|
@@ -19146,8 +19746,8 @@ async function downloadOrgBinaryFiles(orgDir, payload) {
|
|
|
19146
19746
|
let count = 0;
|
|
19147
19747
|
for (const resource of payload.resources ?? []) {
|
|
19148
19748
|
if (!resource.files) continue;
|
|
19149
|
-
const resDir =
|
|
19150
|
-
count += await downloadBinaryFiles(resDir, resource.files);
|
|
19749
|
+
const resDir = path26.join(orgDir, "resources", slugify(resource.name));
|
|
19750
|
+
count += await downloadBinaryFiles(resDir, resource.files, orgDir);
|
|
19151
19751
|
}
|
|
19152
19752
|
if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);
|
|
19153
19753
|
}
|
|
@@ -19402,20 +20002,20 @@ var init_list = __esm({
|
|
|
19402
20002
|
});
|
|
19403
20003
|
|
|
19404
20004
|
// src/lib/template-files.ts
|
|
19405
|
-
import * as
|
|
19406
|
-
import * as
|
|
20005
|
+
import * as fs22 from "fs";
|
|
20006
|
+
import * as path27 from "path";
|
|
19407
20007
|
function readDirToFileMap(rootDir) {
|
|
19408
20008
|
const out = {};
|
|
19409
20009
|
function walk(dir, prefix) {
|
|
19410
|
-
const entries =
|
|
20010
|
+
const entries = fs22.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
19411
20011
|
for (const entry of entries) {
|
|
19412
|
-
const abs =
|
|
20012
|
+
const abs = path27.join(dir, entry.name);
|
|
19413
20013
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19414
20014
|
if (entry.isDirectory()) walk(abs, rel);
|
|
19415
|
-
else if (entry.isFile()) out[rel] =
|
|
20015
|
+
else if (entry.isFile()) out[rel] = fs22.readFileSync(abs, "utf-8");
|
|
19416
20016
|
}
|
|
19417
20017
|
}
|
|
19418
|
-
if (
|
|
20018
|
+
if (fs22.existsSync(rootDir)) walk(rootDir, "");
|
|
19419
20019
|
return out;
|
|
19420
20020
|
}
|
|
19421
20021
|
function detectCollisions(targetDir, files) {
|
|
@@ -19424,7 +20024,7 @@ function detectCollisions(targetDir, files) {
|
|
|
19424
20024
|
if (!isSafeTemplatePath2(rel)) {
|
|
19425
20025
|
throw new Error(`Refusing to inspect unsafe template path: ${rel}`);
|
|
19426
20026
|
}
|
|
19427
|
-
if (
|
|
20027
|
+
if (fs22.existsSync(path27.join(targetDir, rel))) collisions.push(rel);
|
|
19428
20028
|
}
|
|
19429
20029
|
return collisions.sort((a, b) => a.localeCompare(b));
|
|
19430
20030
|
}
|
|
@@ -19434,9 +20034,9 @@ function writeFileMap(targetDir, files) {
|
|
|
19434
20034
|
if (!isSafeTemplatePath2(rel)) {
|
|
19435
20035
|
throw new Error(`Refusing to write unsafe template path: ${rel}`);
|
|
19436
20036
|
}
|
|
19437
|
-
const abs =
|
|
19438
|
-
|
|
19439
|
-
|
|
20037
|
+
const abs = path27.join(targetDir, rel);
|
|
20038
|
+
fs22.mkdirSync(path27.dirname(abs), { recursive: true });
|
|
20039
|
+
fs22.writeFileSync(abs, body, "utf-8");
|
|
19440
20040
|
written.push(rel);
|
|
19441
20041
|
}
|
|
19442
20042
|
return written;
|
|
@@ -19444,20 +20044,20 @@ function writeFileMap(targetDir, files) {
|
|
|
19444
20044
|
function listDirRelFiles(dir) {
|
|
19445
20045
|
const out = [];
|
|
19446
20046
|
function walk(d, prefix) {
|
|
19447
|
-
for (const entry of
|
|
20047
|
+
for (const entry of fs22.readdirSync(d, { withFileTypes: true })) {
|
|
19448
20048
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19449
|
-
if (entry.isDirectory()) walk(
|
|
20049
|
+
if (entry.isDirectory()) walk(path27.join(d, entry.name), rel);
|
|
19450
20050
|
else if (entry.isFile()) out.push(rel);
|
|
19451
20051
|
}
|
|
19452
20052
|
}
|
|
19453
|
-
if (
|
|
20053
|
+
if (fs22.existsSync(dir)) walk(dir, "");
|
|
19454
20054
|
return out;
|
|
19455
20055
|
}
|
|
19456
20056
|
function writeSliceSnapshot(targetDir, files) {
|
|
19457
20057
|
const keep = new Set(Object.keys(files));
|
|
19458
20058
|
const removed = listDirRelFiles(targetDir).filter((rel) => !keep.has(rel)).sort((a, b) => a.localeCompare(b));
|
|
19459
20059
|
const written = writeFileMap(targetDir, files).sort((a, b) => a.localeCompare(b));
|
|
19460
|
-
if (
|
|
20060
|
+
if (fs22.existsSync(targetDir)) cleanOrphanFiles(targetDir, "", keep);
|
|
19461
20061
|
return { written, removed };
|
|
19462
20062
|
}
|
|
19463
20063
|
var init_template_files = __esm({
|
|
@@ -19473,7 +20073,7 @@ var templates_exports = {};
|
|
|
19473
20073
|
__export(templates_exports, {
|
|
19474
20074
|
templateCommand: () => templateCommand
|
|
19475
20075
|
});
|
|
19476
|
-
import * as
|
|
20076
|
+
import * as path28 from "path";
|
|
19477
20077
|
async function templateCommand(args2) {
|
|
19478
20078
|
const [sub, ...rest] = args2;
|
|
19479
20079
|
switch (sub) {
|
|
@@ -19589,8 +20189,8 @@ async function runTemplatePull(rest) {
|
|
|
19589
20189
|
console.log(`Template "${slug}" has no WayAI slice${hint}`);
|
|
19590
20190
|
return;
|
|
19591
20191
|
}
|
|
19592
|
-
const targetDir =
|
|
19593
|
-
const relTarget =
|
|
20192
|
+
const targetDir = path28.join(resolveLayout(gitRoot).hubsDir, slug);
|
|
20193
|
+
const relTarget = path28.relative(gitRoot, targetDir);
|
|
19594
20194
|
const collisions = detectCollisions(targetDir, detail.files);
|
|
19595
20195
|
if (dryRun) {
|
|
19596
20196
|
const planned = Object.keys(detail.files).sort((a, b) => a.localeCompare(b));
|
|
@@ -19716,21 +20316,37 @@ import * as yaml9 from "js-yaml";
|
|
|
19716
20316
|
function sanitizeWayaiSliceFiles(files) {
|
|
19717
20317
|
const out = {};
|
|
19718
20318
|
for (const [filePath, body] of Object.entries(files)) {
|
|
19719
|
-
out[filePath] = isSanitizableSliceFile(filePath) ? sanitizeOne(body) : body;
|
|
20319
|
+
out[filePath] = isSanitizableSliceFile(filePath) ? sanitizeOne(filePath, body) : body;
|
|
19720
20320
|
}
|
|
19721
20321
|
return out;
|
|
19722
20322
|
}
|
|
19723
|
-
function sanitizeOne(body) {
|
|
20323
|
+
function sanitizeOne(filePath, body) {
|
|
19724
20324
|
let parsed;
|
|
19725
20325
|
try {
|
|
19726
20326
|
parsed = yaml9.load(body);
|
|
19727
20327
|
} catch {
|
|
19728
20328
|
return body;
|
|
19729
20329
|
}
|
|
19730
|
-
const scrubbed = excludeTemplateAuthorData(stripTemplateInstanceIds(parsed));
|
|
20330
|
+
const scrubbed = stripEvalAttachments(filePath, excludeTemplateAuthorData(stripTemplateInstanceIds(parsed)));
|
|
19731
20331
|
if (JSON.stringify(parsed) === JSON.stringify(scrubbed)) return body;
|
|
19732
20332
|
return yaml9.dump(scrubbed, YAML_DUMP_OPTIONS);
|
|
19733
20333
|
}
|
|
20334
|
+
function stripEvalAttachments(filePath, value) {
|
|
20335
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
20336
|
+
const doc = { ...value };
|
|
20337
|
+
const dropOnTurn = (turn) => {
|
|
20338
|
+
if (!turn || typeof turn !== "object" || Array.isArray(turn) || !("attachments" in turn)) return turn;
|
|
20339
|
+
const { attachments: _drop, ...rest } = turn;
|
|
20340
|
+
return rest;
|
|
20341
|
+
};
|
|
20342
|
+
if (/^evals\//.test(filePath)) {
|
|
20343
|
+
if ("input" in doc) doc.input = dropOnTurn(doc.input);
|
|
20344
|
+
if (Array.isArray(doc.history)) doc.history = doc.history.map(dropOnTurn);
|
|
20345
|
+
} else if (/^journeys\//.test(filePath)) {
|
|
20346
|
+
if (Array.isArray(doc.transcript)) doc.transcript = doc.transcript.map(dropOnTurn);
|
|
20347
|
+
}
|
|
20348
|
+
return doc;
|
|
20349
|
+
}
|
|
19734
20350
|
var init_template_sanitize = __esm({
|
|
19735
20351
|
"src/lib/template-sanitize.ts"() {
|
|
19736
20352
|
"use strict";
|
|
@@ -19764,8 +20380,8 @@ var admin_exports = {};
|
|
|
19764
20380
|
__export(admin_exports, {
|
|
19765
20381
|
adminCommand: () => adminCommand
|
|
19766
20382
|
});
|
|
19767
|
-
import * as
|
|
19768
|
-
import * as
|
|
20383
|
+
import * as fs23 from "fs";
|
|
20384
|
+
import * as path29 from "path";
|
|
19769
20385
|
import * as yaml10 from "js-yaml";
|
|
19770
20386
|
async function adminCommand(args2) {
|
|
19771
20387
|
const [group, ...afterGroup] = args2;
|
|
@@ -20087,7 +20703,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
20087
20703
|
exitOnApiError(err);
|
|
20088
20704
|
throw err;
|
|
20089
20705
|
}
|
|
20090
|
-
|
|
20706
|
+
fs23.writeFileSync(outPath, zip);
|
|
20091
20707
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
20092
20708
|
return;
|
|
20093
20709
|
}
|
|
@@ -20219,15 +20835,15 @@ function loadTemplateManifest(slug) {
|
|
|
20219
20835
|
console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
|
|
20220
20836
|
process.exit(1);
|
|
20221
20837
|
}
|
|
20222
|
-
const templateDir =
|
|
20223
|
-
const manifestPath =
|
|
20224
|
-
if (!
|
|
20225
|
-
console.error(`template.yaml not found at ${
|
|
20838
|
+
const templateDir = path29.join(resolveTemplatesDir(gitRoot), slug);
|
|
20839
|
+
const manifestPath = path29.join(templateDir, "template.yaml");
|
|
20840
|
+
if (!fs23.existsSync(manifestPath)) {
|
|
20841
|
+
console.error(`template.yaml not found at ${path29.relative(gitRoot, manifestPath)}`);
|
|
20226
20842
|
process.exit(1);
|
|
20227
20843
|
}
|
|
20228
20844
|
let manifest;
|
|
20229
20845
|
try {
|
|
20230
|
-
manifest = templateYamlSchema2.parse(yaml10.load(
|
|
20846
|
+
manifest = templateYamlSchema2.parse(yaml10.load(fs23.readFileSync(manifestPath, "utf-8")));
|
|
20231
20847
|
} catch (err) {
|
|
20232
20848
|
console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
|
|
20233
20849
|
process.exit(1);
|
|
@@ -20257,20 +20873,20 @@ async function runTemplatePush(positional) {
|
|
|
20257
20873
|
const wayaiEntry = manifest.wayai.locales[locale];
|
|
20258
20874
|
let wayaiFiles;
|
|
20259
20875
|
if (wayaiEntry) {
|
|
20260
|
-
const sliceDir =
|
|
20261
|
-
if (!
|
|
20876
|
+
const sliceDir = path29.resolve(templateDir, wayaiEntry.source);
|
|
20877
|
+
if (!fs23.existsSync(sliceDir)) {
|
|
20262
20878
|
console.error(`wayai source not found for ${locale}: ${wayaiEntry.source} (resolved ${sliceDir})`);
|
|
20263
20879
|
process.exit(1);
|
|
20264
20880
|
}
|
|
20265
20881
|
if (!isInsideTemplateDir(sliceDir, templateDir)) {
|
|
20266
20882
|
console.warn(
|
|
20267
|
-
`Note: ${locale} source points at a live hub (${wayaiEntry.source}); it can go stale on a hub recreate. Run \`wayai admin template freeze ${slug} --locale ${locale} --from ${
|
|
20883
|
+
`Note: ${locale} source points at a live hub (${wayaiEntry.source}); it can go stale on a hub recreate. Run \`wayai admin template freeze ${slug} --locale ${locale} --from ${path29.basename(sliceDir)}\` to commit a stable frozen slice.`
|
|
20268
20884
|
);
|
|
20269
20885
|
}
|
|
20270
20886
|
wayaiFiles = readDirToFileMap(sliceDir);
|
|
20271
20887
|
}
|
|
20272
|
-
const readmePath =
|
|
20273
|
-
const readmeMarkdown =
|
|
20888
|
+
const readmePath = path29.join(templateDir, `README.${locale}.md`);
|
|
20889
|
+
const readmeMarkdown = fs23.existsSync(readmePath) ? fs23.readFileSync(readmePath, "utf-8") : "";
|
|
20274
20890
|
locales[locale] = {
|
|
20275
20891
|
readmeMarkdown,
|
|
20276
20892
|
...wayaiFiles && { wayaiFiles },
|
|
@@ -20281,9 +20897,9 @@ async function runTemplatePush(positional) {
|
|
|
20281
20897
|
}
|
|
20282
20898
|
let hero;
|
|
20283
20899
|
if (manifest.hero) {
|
|
20284
|
-
const heroPath =
|
|
20285
|
-
if (
|
|
20286
|
-
hero = { filename:
|
|
20900
|
+
const heroPath = path29.resolve(templateDir, manifest.hero);
|
|
20901
|
+
if (fs23.existsSync(heroPath)) {
|
|
20902
|
+
hero = { filename: path29.basename(heroPath), dataBase64: fs23.readFileSync(heroPath).toString("base64") };
|
|
20287
20903
|
} else {
|
|
20288
20904
|
console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
|
|
20289
20905
|
}
|
|
@@ -20309,7 +20925,7 @@ async function runTemplatePush(positional) {
|
|
|
20309
20925
|
}
|
|
20310
20926
|
}
|
|
20311
20927
|
function isInsideTemplateDir(dest, templateDir) {
|
|
20312
|
-
return dest === templateDir || dest.startsWith(templateDir +
|
|
20928
|
+
return dest === templateDir || dest.startsWith(templateDir + path29.sep);
|
|
20313
20929
|
}
|
|
20314
20930
|
async function runTemplateFreeze(positional, flagArgs) {
|
|
20315
20931
|
const slug = positional[0];
|
|
@@ -20370,7 +20986,7 @@ async function runTemplateFreeze(positional, flagArgs) {
|
|
|
20370
20986
|
process.exit(1);
|
|
20371
20987
|
}
|
|
20372
20988
|
const entry = manifest.wayai.locales[targetLocale];
|
|
20373
|
-
const dest =
|
|
20989
|
+
const dest = path29.resolve(templateDir, entry.source);
|
|
20374
20990
|
if (!isInsideTemplateDir(dest, templateDir) || dest === templateDir) {
|
|
20375
20991
|
console.error(
|
|
20376
20992
|
`source for "${targetLocale}" must be a committed path inside ${slug}/ (e.g. "./${targetLocale}/slice"), but resolved to:
|
|
@@ -20389,7 +21005,7 @@ Set it to a subdir of the template folder and re-run freeze.`
|
|
|
20389
21005
|
const hubs = scanWorkspaceHubs(hubsDir);
|
|
20390
21006
|
if (hubs.length) {
|
|
20391
21007
|
console.error("Available hubs:");
|
|
20392
|
-
for (const h of hubs) console.error(` ${
|
|
21008
|
+
for (const h of hubs) console.error(` ${path29.basename(h.hubFolder)} (${h.hubId})`);
|
|
20393
21009
|
}
|
|
20394
21010
|
console.error(`
|
|
20395
21011
|
Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`);
|
|
@@ -20397,12 +21013,12 @@ Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`
|
|
|
20397
21013
|
}
|
|
20398
21014
|
const liveFiles = readDirToFileMap(hubFolder);
|
|
20399
21015
|
if (Object.keys(liveFiles).length === 0) {
|
|
20400
|
-
console.error(`Source hub folder has no files to freeze: ${
|
|
21016
|
+
console.error(`Source hub folder has no files to freeze: ${path29.relative(gitRoot, hubFolder)}`);
|
|
20401
21017
|
process.exit(1);
|
|
20402
21018
|
}
|
|
20403
21019
|
const sanitized = sanitizeWayaiSliceFiles(liveFiles);
|
|
20404
|
-
const relDest =
|
|
20405
|
-
const relSrc =
|
|
21020
|
+
const relDest = path29.relative(gitRoot, dest);
|
|
21021
|
+
const relSrc = path29.relative(gitRoot, hubFolder);
|
|
20406
21022
|
if (dryRun) {
|
|
20407
21023
|
const existing = new Set(listDirRelFiles(dest));
|
|
20408
21024
|
const nextKeys = new Set(Object.keys(sanitized));
|
|
@@ -20462,7 +21078,7 @@ async function runTemplatePull2(positional, flagArgs) {
|
|
|
20462
21078
|
console.log(JSON.stringify(detail, null, 2));
|
|
20463
21079
|
return;
|
|
20464
21080
|
}
|
|
20465
|
-
const target = outDir ?
|
|
21081
|
+
const target = outDir ? path29.resolve(outDir) : path29.join(process.cwd(), "template-store-pull", slug);
|
|
20466
21082
|
const written = writeFileMap(target, detail.files);
|
|
20467
21083
|
console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
20468
21084
|
const uses = detail.uses ?? [];
|
|
@@ -20485,13 +21101,13 @@ async function runSkillInstall(positional) {
|
|
|
20485
21101
|
throw err;
|
|
20486
21102
|
}
|
|
20487
21103
|
const root = findGitRoot() ?? process.cwd();
|
|
20488
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
21104
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs23.existsSync(path29.join(root, dir)));
|
|
20489
21105
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
20490
21106
|
const fileCount = Object.keys(res.files).length;
|
|
20491
21107
|
const relDirs = targets.map((harness) => {
|
|
20492
|
-
const targetDir =
|
|
21108
|
+
const targetDir = path29.join(root, harness, "skills", name);
|
|
20493
21109
|
writeFileMap(targetDir, res.files);
|
|
20494
|
-
return `${
|
|
21110
|
+
return `${path29.relative(root, targetDir)}/`;
|
|
20495
21111
|
});
|
|
20496
21112
|
console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
|
|
20497
21113
|
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
@@ -21833,9 +22449,9 @@ var init_update = __esm({
|
|
|
21833
22449
|
|
|
21834
22450
|
// src/index.ts
|
|
21835
22451
|
init_sentry();
|
|
21836
|
-
import { readFileSync as
|
|
22452
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
21837
22453
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
21838
|
-
import { dirname as dirname9, join as
|
|
22454
|
+
import { dirname as dirname9, join as join27 } from "path";
|
|
21839
22455
|
|
|
21840
22456
|
// src/lib/errors.ts
|
|
21841
22457
|
init_api_client();
|
|
@@ -21867,7 +22483,7 @@ init_skill_version();
|
|
|
21867
22483
|
import { exec } from "child_process";
|
|
21868
22484
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
21869
22485
|
function refreshCliCache() {
|
|
21870
|
-
return new Promise((
|
|
22486
|
+
return new Promise((resolve6) => {
|
|
21871
22487
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
21872
22488
|
if (!err) {
|
|
21873
22489
|
const latest = stdout.trim();
|
|
@@ -21878,7 +22494,7 @@ function refreshCliCache() {
|
|
|
21878
22494
|
}
|
|
21879
22495
|
}
|
|
21880
22496
|
}
|
|
21881
|
-
|
|
22497
|
+
resolve6();
|
|
21882
22498
|
});
|
|
21883
22499
|
});
|
|
21884
22500
|
}
|
|
@@ -21904,8 +22520,8 @@ async function refreshSkillCache() {
|
|
|
21904
22520
|
}
|
|
21905
22521
|
async function refreshAdminSkillCache() {
|
|
21906
22522
|
let timer;
|
|
21907
|
-
const deadline = new Promise((
|
|
21908
|
-
timer = setTimeout(
|
|
22523
|
+
const deadline = new Promise((resolve6) => {
|
|
22524
|
+
timer = setTimeout(resolve6, REFRESH_TIMEOUT_MS);
|
|
21909
22525
|
});
|
|
21910
22526
|
await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
|
|
21911
22527
|
})]);
|
|
@@ -22015,7 +22631,7 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
22015
22631
|
|
|
22016
22632
|
// src/index.ts
|
|
22017
22633
|
var __dirname = dirname9(fileURLToPath2(import.meta.url));
|
|
22018
|
-
var pkg = JSON.parse(
|
|
22634
|
+
var pkg = JSON.parse(readFileSync20(join27(__dirname, "..", "package.json"), "utf-8"));
|
|
22019
22635
|
var [, , command, ...args] = process.argv;
|
|
22020
22636
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
22021
22637
|
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|