@wayai/cli 0.3.103 → 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 +1031 -425
- 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();
|
|
@@ -11978,8 +12417,8 @@ __export(push_exports, {
|
|
|
11978
12417
|
selectExistingHub: () => selectExistingHub,
|
|
11979
12418
|
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel
|
|
11980
12419
|
});
|
|
11981
|
-
import * as
|
|
11982
|
-
import * as
|
|
12420
|
+
import * as fs15 from "fs";
|
|
12421
|
+
import * as path17 from "path";
|
|
11983
12422
|
import * as yaml6 from "js-yaml";
|
|
11984
12423
|
function parseArgs5(args2) {
|
|
11985
12424
|
let autoConfirm = false;
|
|
@@ -12072,13 +12511,13 @@ function printErrors(errors) {
|
|
|
12072
12511
|
}
|
|
12073
12512
|
}
|
|
12074
12513
|
async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
12075
|
-
const agentsDir =
|
|
12514
|
+
const agentsDir = path17.join(hubFolder, "agents");
|
|
12076
12515
|
let agentsWithIds = [];
|
|
12077
|
-
if (
|
|
12078
|
-
const yamlFiles =
|
|
12516
|
+
if (fs15.existsSync(agentsDir)) {
|
|
12517
|
+
const yamlFiles = fs15.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
|
|
12079
12518
|
for (const file of yamlFiles) {
|
|
12080
12519
|
try {
|
|
12081
|
-
const content =
|
|
12520
|
+
const content = fs15.readFileSync(path17.join(agentsDir, file), "utf-8");
|
|
12082
12521
|
const agent = yaml6.load(content);
|
|
12083
12522
|
if (agent?.id && agent.name) {
|
|
12084
12523
|
agentsWithIds.push({ id: agent.id, name: agent.name });
|
|
@@ -12091,7 +12530,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12091
12530
|
if (agentsWithIds.length === 0) {
|
|
12092
12531
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
12093
12532
|
if (!yamlPath) return;
|
|
12094
|
-
const yamlContent =
|
|
12533
|
+
const yamlContent = fs15.readFileSync(yamlPath, "utf-8");
|
|
12095
12534
|
const config = yaml6.load(yamlContent);
|
|
12096
12535
|
agentsWithIds = (config.agents || []).filter((a) => !!a.id && !!a.name);
|
|
12097
12536
|
}
|
|
@@ -12121,18 +12560,18 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12121
12560
|
}
|
|
12122
12561
|
}
|
|
12123
12562
|
if (renames.length === 0) return;
|
|
12124
|
-
if (!
|
|
12125
|
-
for (const file of
|
|
12563
|
+
if (!fs15.existsSync(agentsDir)) return;
|
|
12564
|
+
for (const file of fs15.readdirSync(agentsDir)) {
|
|
12126
12565
|
if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
|
|
12127
12566
|
console.warn(` Warning: removing orphaned temp file agents/${file}`);
|
|
12128
|
-
|
|
12567
|
+
fs15.unlinkSync(path17.join(agentsDir, file));
|
|
12129
12568
|
}
|
|
12130
12569
|
}
|
|
12131
12570
|
const renameFileIfExists = (dir, oldName, newName) => {
|
|
12132
|
-
const oldPath =
|
|
12133
|
-
const newPath =
|
|
12134
|
-
if (!
|
|
12135
|
-
|
|
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);
|
|
12136
12575
|
return true;
|
|
12137
12576
|
};
|
|
12138
12577
|
const oldSlugs = new Set(renames.map((r) => r.oldSlug));
|
|
@@ -12165,9 +12604,9 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12165
12604
|
}
|
|
12166
12605
|
} else {
|
|
12167
12606
|
for (const { oldSlug, newSlug } of renames) {
|
|
12168
|
-
const hasOldFile = extensions.some((ext) =>
|
|
12607
|
+
const hasOldFile = extensions.some((ext) => fs15.existsSync(path17.join(agentsDir, `${oldSlug}${ext}`)));
|
|
12169
12608
|
if (!hasOldFile) continue;
|
|
12170
|
-
const hasNewFile = extensions.some((ext) =>
|
|
12609
|
+
const hasNewFile = extensions.some((ext) => fs15.existsSync(path17.join(agentsDir, `${newSlug}${ext}`)));
|
|
12171
12610
|
if (hasNewFile) {
|
|
12172
12611
|
console.warn(` Warning: skipping rename agents/${oldSlug}.* \u2192 agents/${newSlug}.* (target already exists)`);
|
|
12173
12612
|
continue;
|
|
@@ -12182,7 +12621,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12182
12621
|
if (completedRenames.length === 0) return;
|
|
12183
12622
|
const mainYamlPath = resolveHubYamlPath(hubFolder);
|
|
12184
12623
|
if (mainYamlPath) {
|
|
12185
|
-
const mainYamlContent =
|
|
12624
|
+
const mainYamlContent = fs15.readFileSync(mainYamlPath, "utf-8");
|
|
12186
12625
|
const substitutionMap = /* @__PURE__ */ new Map();
|
|
12187
12626
|
for (const { oldSlug, newSlug } of completedRenames) {
|
|
12188
12627
|
substitutionMap.set(`agents/${oldSlug}.md`, `agents/${newSlug}.md`);
|
|
@@ -12193,8 +12632,8 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId) {
|
|
|
12193
12632
|
(_match, prefix, pathMatch) => `${prefix}${substitutionMap.get(pathMatch) ?? pathMatch}`
|
|
12194
12633
|
);
|
|
12195
12634
|
if (updatedYaml !== mainYamlContent) {
|
|
12196
|
-
|
|
12197
|
-
console.log(` Updated instructions paths in ${
|
|
12635
|
+
fs15.writeFileSync(mainYamlPath, updatedYaml, "utf-8");
|
|
12636
|
+
console.log(` Updated instructions paths in ${path17.basename(mainYamlPath)}`);
|
|
12198
12637
|
}
|
|
12199
12638
|
}
|
|
12200
12639
|
}
|
|
@@ -12255,7 +12694,7 @@ async function pushSingleHub(client, hubId, hubFolder, autoConfirm, organization
|
|
|
12255
12694
|
function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
|
|
12256
12695
|
if (selector) {
|
|
12257
12696
|
const match = allHubs.find(
|
|
12258
|
-
(h) => h.hubId === selector ||
|
|
12697
|
+
(h) => h.hubId === selector || path17.basename(h.hubFolder) === selector
|
|
12259
12698
|
);
|
|
12260
12699
|
if (!match) {
|
|
12261
12700
|
console.error(`No hub matching --hub ${selector} found in ${wsLabel}/.`);
|
|
@@ -12298,7 +12737,7 @@ New hub: "${newHub.hubName}" (${hubType})`);
|
|
|
12298
12737
|
process.exit(1);
|
|
12299
12738
|
}
|
|
12300
12739
|
console.log(`Hub created: ${createdHub.hub_name} (${hubId})`);
|
|
12301
|
-
const content =
|
|
12740
|
+
const content = fs15.readFileSync(hubYamlPath, "utf-8");
|
|
12302
12741
|
const hasVersion = content.match(/^version:\s/m);
|
|
12303
12742
|
let updated;
|
|
12304
12743
|
if (hasVersion) {
|
|
@@ -12314,7 +12753,7 @@ hub_id: "${hubId}"
|
|
|
12314
12753
|
hub_environment: preview
|
|
12315
12754
|
${content}`;
|
|
12316
12755
|
}
|
|
12317
|
-
|
|
12756
|
+
fs15.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
12318
12757
|
autoBindIfUnbound(hubId);
|
|
12319
12758
|
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
12320
12759
|
}
|
|
@@ -12323,7 +12762,7 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
|
|
|
12323
12762
|
if (existingHubs.length > 0) {
|
|
12324
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\`:`);
|
|
12325
12764
|
for (const h of existingHubs) {
|
|
12326
|
-
console.error(` ${
|
|
12765
|
+
console.error(` ${path17.basename(h.hubFolder)} (${h.hubId}, production mirror)`);
|
|
12327
12766
|
}
|
|
12328
12767
|
} else {
|
|
12329
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\`).`);
|
|
@@ -12336,10 +12775,10 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
|
|
|
12336
12775
|
console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
12337
12776
|
}
|
|
12338
12777
|
for (const h of existingHubs) {
|
|
12339
|
-
console.error(` ${
|
|
12778
|
+
console.error(` ${path17.basename(h.hubFolder)} (${h.hubId})`);
|
|
12340
12779
|
}
|
|
12341
12780
|
for (const h of newHubs) {
|
|
12342
|
-
console.error(` ${
|
|
12781
|
+
console.error(` ${path17.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
12343
12782
|
}
|
|
12344
12783
|
process.exit(1);
|
|
12345
12784
|
}
|
|
@@ -12358,7 +12797,7 @@ async function pushCommand(args2) {
|
|
|
12358
12797
|
console.error(`Created ${file}`);
|
|
12359
12798
|
}
|
|
12360
12799
|
}
|
|
12361
|
-
if (!
|
|
12800
|
+
if (!fs15.existsSync(workspaceDir)) {
|
|
12362
12801
|
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
12363
12802
|
process.exit(1);
|
|
12364
12803
|
}
|
|
@@ -12377,8 +12816,8 @@ async function pushCommand(args2) {
|
|
|
12377
12816
|
if (label) {
|
|
12378
12817
|
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
12379
12818
|
}
|
|
12380
|
-
console.log(`Target hub: ${
|
|
12381
|
-
assertHubMatchesBinding(existing.hubId,
|
|
12819
|
+
console.log(`Target hub: ${path17.basename(existing.hubFolder)} (${existing.hubId})`);
|
|
12820
|
+
assertHubMatchesBinding(existing.hubId, path17.basename(existing.hubFolder));
|
|
12382
12821
|
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
12383
12822
|
return;
|
|
12384
12823
|
}
|
|
@@ -12408,8 +12847,8 @@ var create_exports = {};
|
|
|
12408
12847
|
__export(create_exports, {
|
|
12409
12848
|
createCommand: () => createCommand
|
|
12410
12849
|
});
|
|
12411
|
-
import * as
|
|
12412
|
-
import * as
|
|
12850
|
+
import * as path18 from "path";
|
|
12851
|
+
import * as fs16 from "fs";
|
|
12413
12852
|
function parseArgs6(args2) {
|
|
12414
12853
|
let autoConfirm = false;
|
|
12415
12854
|
let folderSelector;
|
|
@@ -12436,7 +12875,7 @@ async function createCommand(args2) {
|
|
|
12436
12875
|
const gitRoot = findGitRoot();
|
|
12437
12876
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
12438
12877
|
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
12439
|
-
if (!
|
|
12878
|
+
if (!fs16.existsSync(workspaceDir)) {
|
|
12440
12879
|
console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
|
|
12441
12880
|
process.exit(1);
|
|
12442
12881
|
}
|
|
@@ -12445,7 +12884,7 @@ async function createCommand(args2) {
|
|
|
12445
12884
|
const resolution = resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, folderSelector);
|
|
12446
12885
|
if (!resolution.ok) {
|
|
12447
12886
|
if (resolution.reason === "exists") {
|
|
12448
|
-
const folder =
|
|
12887
|
+
const folder = path18.basename(resolution.existing.hubFolder);
|
|
12449
12888
|
console.error(`Hub "${folder}" already exists (${resolution.existing.hubId}). Use \`wayai push --hub ${folder}\` to update it.`);
|
|
12450
12889
|
process.exit(1);
|
|
12451
12890
|
}
|
|
@@ -12459,7 +12898,7 @@ async function createCommand(args2) {
|
|
|
12459
12898
|
}
|
|
12460
12899
|
console.error(`Multiple new hub folders found in ${wsLabel}/. Pass the folder name (\`wayai create <folder>\`) or run from inside one:`);
|
|
12461
12900
|
for (const h of newHubs) {
|
|
12462
|
-
console.error(` ${
|
|
12901
|
+
console.error(` ${path18.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
12463
12902
|
}
|
|
12464
12903
|
process.exit(1);
|
|
12465
12904
|
}
|
|
@@ -12641,12 +13080,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
12641
13080
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
12642
13081
|
return false;
|
|
12643
13082
|
}
|
|
12644
|
-
function validateSchema2(schema,
|
|
13083
|
+
function validateSchema2(schema, path30, errors, opts = {}) {
|
|
12645
13084
|
if (typeof schema === "boolean") return;
|
|
12646
13085
|
const depth = opts.depth ?? 0;
|
|
12647
13086
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
12648
13087
|
errors.push({
|
|
12649
|
-
path:
|
|
13088
|
+
path: path30 || "<root>",
|
|
12650
13089
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
12651
13090
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
12652
13091
|
});
|
|
@@ -12654,7 +13093,7 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12654
13093
|
}
|
|
12655
13094
|
if (!isRecord2(schema)) {
|
|
12656
13095
|
errors.push({
|
|
12657
|
-
path:
|
|
13096
|
+
path: path30,
|
|
12658
13097
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
12659
13098
|
});
|
|
12660
13099
|
return;
|
|
@@ -12662,14 +13101,14 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12662
13101
|
if (opts.isRoot) {
|
|
12663
13102
|
if ("type" in schema && schema.type !== "object") {
|
|
12664
13103
|
errors.push({
|
|
12665
|
-
path:
|
|
13104
|
+
path: path30 ? `${path30}.type` : "type",
|
|
12666
13105
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
12667
13106
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
12668
13107
|
});
|
|
12669
13108
|
}
|
|
12670
13109
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
12671
13110
|
errors.push({
|
|
12672
|
-
path: `${
|
|
13111
|
+
path: `${path30}.type`,
|
|
12673
13112
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
12674
13113
|
});
|
|
12675
13114
|
}
|
|
@@ -12678,25 +13117,25 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12678
13117
|
if (typeof e === "string") {
|
|
12679
13118
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
12680
13119
|
errors.push({
|
|
12681
|
-
path: `${
|
|
13120
|
+
path: `${path30}.enum`,
|
|
12682
13121
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
12683
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"]`.'
|
|
12684
13123
|
});
|
|
12685
13124
|
} else if (!Array.isArray(e)) {
|
|
12686
13125
|
errors.push({
|
|
12687
|
-
path: `${
|
|
13126
|
+
path: `${path30}.enum`,
|
|
12688
13127
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
12689
13128
|
});
|
|
12690
13129
|
} else if (e.length === 0) {
|
|
12691
13130
|
errors.push({
|
|
12692
|
-
path: `${
|
|
13131
|
+
path: `${path30}.enum`,
|
|
12693
13132
|
message: "enum must not be empty"
|
|
12694
13133
|
});
|
|
12695
13134
|
} else {
|
|
12696
13135
|
for (let i = 0; i < e.length; i++) {
|
|
12697
13136
|
if (!isPrimitive2(e[i])) {
|
|
12698
13137
|
errors.push({
|
|
12699
|
-
path: `${
|
|
13138
|
+
path: `${path30}.enum[${i}]`,
|
|
12700
13139
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
12701
13140
|
});
|
|
12702
13141
|
}
|
|
@@ -12706,7 +13145,7 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12706
13145
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
12707
13146
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
12708
13147
|
errors.push({
|
|
12709
|
-
path: `${
|
|
13148
|
+
path: `${path30}.${key}`,
|
|
12710
13149
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
12711
13150
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
12712
13151
|
});
|
|
@@ -12715,45 +13154,45 @@ function validateSchema2(schema, path28, errors, opts = {}) {
|
|
|
12715
13154
|
if ("properties" in schema) {
|
|
12716
13155
|
if (!isRecord2(schema.properties)) {
|
|
12717
13156
|
errors.push({
|
|
12718
|
-
path: `${
|
|
13157
|
+
path: `${path30}.properties`,
|
|
12719
13158
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
12720
13159
|
});
|
|
12721
13160
|
} else {
|
|
12722
13161
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
12723
|
-
validateSchema2(propSchema, `${
|
|
13162
|
+
validateSchema2(propSchema, `${path30}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
12724
13163
|
}
|
|
12725
13164
|
}
|
|
12726
13165
|
}
|
|
12727
13166
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
12728
13167
|
if (Array.isArray(schema.items)) {
|
|
12729
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
13168
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path30}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
12730
13169
|
} else {
|
|
12731
|
-
validateSchema2(schema.items, `${
|
|
13170
|
+
validateSchema2(schema.items, `${path30}.items`, errors, { depth: depth + 1 });
|
|
12732
13171
|
}
|
|
12733
13172
|
}
|
|
12734
13173
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
12735
13174
|
if (key in schema && isRecord2(schema[key])) {
|
|
12736
|
-
validateSchema2(schema[key], `${
|
|
13175
|
+
validateSchema2(schema[key], `${path30}.${key}`, errors, { depth: depth + 1 });
|
|
12737
13176
|
}
|
|
12738
13177
|
}
|
|
12739
13178
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
12740
13179
|
const list = schema[key];
|
|
12741
13180
|
if (Array.isArray(list)) {
|
|
12742
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
13181
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path30}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
12743
13182
|
}
|
|
12744
13183
|
}
|
|
12745
13184
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
12746
13185
|
const map = schema[key];
|
|
12747
13186
|
if (isRecord2(map)) {
|
|
12748
13187
|
for (const [name, sub] of Object.entries(map)) {
|
|
12749
|
-
validateSchema2(sub, `${
|
|
13188
|
+
validateSchema2(sub, `${path30}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
12750
13189
|
}
|
|
12751
13190
|
}
|
|
12752
13191
|
}
|
|
12753
13192
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
12754
13193
|
for (const [k, v] of Object.entries(schema)) {
|
|
12755
13194
|
if (typeof v !== "string") continue;
|
|
12756
|
-
const fieldPath = `${
|
|
13195
|
+
const fieldPath = `${path30}.${k}`;
|
|
12757
13196
|
if (reportedPaths.has(fieldPath)) continue;
|
|
12758
13197
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
12759
13198
|
if (v === token) {
|
|
@@ -12828,15 +13267,17 @@ function describeRole2(role) {
|
|
|
12828
13267
|
return `a ${typeof role}`;
|
|
12829
13268
|
}
|
|
12830
13269
|
function asEvalInputRecord2(input) {
|
|
12831
|
-
const value =
|
|
12832
|
-
try {
|
|
12833
|
-
return JSON.parse(input);
|
|
12834
|
-
} catch {
|
|
12835
|
-
return null;
|
|
12836
|
-
}
|
|
12837
|
-
})() : input;
|
|
13270
|
+
const value = parseMaybeJson2(input);
|
|
12838
13271
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
12839
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
|
+
}
|
|
12840
13281
|
function evalInputRoleError2(input) {
|
|
12841
13282
|
const record = asEvalInputRecord2(input);
|
|
12842
13283
|
if (record === null) return null;
|
|
@@ -12847,6 +13288,32 @@ function evalInputRoleError2(input) {
|
|
|
12847
13288
|
}
|
|
12848
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`;
|
|
12849
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
|
+
}
|
|
12850
13317
|
function refineEvalMessageTextRole2(value, ctx) {
|
|
12851
13318
|
const error = evalInputRoleError2(value.eval.message_text);
|
|
12852
13319
|
if (error) {
|
|
@@ -12857,6 +13324,38 @@ function refineEvalMessageTextRole2(value, ctx) {
|
|
|
12857
13324
|
});
|
|
12858
13325
|
}
|
|
12859
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
|
+
}
|
|
12860
13359
|
function refineHubAsCodeCustomTools2(config, ctx) {
|
|
12861
13360
|
const agents = config.agents;
|
|
12862
13361
|
if (!Array.isArray(agents)) return;
|
|
@@ -12964,10 +13463,84 @@ function refineHubAsCodeEvals2(config, ctx) {
|
|
|
12964
13463
|
}
|
|
12965
13464
|
}
|
|
12966
13465
|
}
|
|
12967
|
-
function
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
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("/");
|
|
12971
13544
|
return segments.every(
|
|
12972
13545
|
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
12973
13546
|
);
|
|
@@ -12995,14 +13568,14 @@ function isPlainObject(value) {
|
|
|
12995
13568
|
const proto = Object.getPrototypeOf(value);
|
|
12996
13569
|
return proto === Object.prototype || proto === null;
|
|
12997
13570
|
}
|
|
12998
|
-
function isSanitizableSliceFile(
|
|
12999
|
-
if (!/\.ya?ml$/i.test(
|
|
13000
|
-
return
|
|
13571
|
+
function isSanitizableSliceFile(path30) {
|
|
13572
|
+
if (!/\.ya?ml$/i.test(path30)) return false;
|
|
13573
|
+
return path30 !== "resources" && !path30.startsWith("resources/");
|
|
13001
13574
|
}
|
|
13002
13575
|
function distinctUsesBackends(uses) {
|
|
13003
13576
|
return [...new Set((uses ?? []).map((u) => u.backend))];
|
|
13004
13577
|
}
|
|
13005
|
-
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;
|
|
13006
13579
|
var init_contracts = __esm({
|
|
13007
13580
|
"../../packages/core/dist/contracts/index.js"() {
|
|
13008
13581
|
"use strict";
|
|
@@ -14174,10 +14747,10 @@ var init_contracts = __esm({
|
|
|
14174
14747
|
ROLE_ECHO_MAX2 = 40;
|
|
14175
14748
|
createEvalBody2 = external_exports.object({
|
|
14176
14749
|
eval: external_exports.record(external_exports.unknown())
|
|
14177
|
-
}).superRefine(refineEvalMessageTextRole2);
|
|
14750
|
+
}).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2);
|
|
14178
14751
|
updateEvalBody2 = external_exports.object({
|
|
14179
14752
|
eval: external_exports.record(external_exports.unknown())
|
|
14180
|
-
}).superRefine(refineEvalMessageTextRole2);
|
|
14753
|
+
}).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2);
|
|
14181
14754
|
getEvalsQuery2 = external_exports.object({
|
|
14182
14755
|
hub_id: external_exports.string().uuid(),
|
|
14183
14756
|
agent_id: external_exports.string().uuid().optional(),
|
|
@@ -14304,6 +14877,15 @@ var init_contracts = __esm({
|
|
|
14304
14877
|
journey_name: external_exports.string().min(1).max(200),
|
|
14305
14878
|
evaluator_instructions: external_exports.string().max(4e3).optional()
|
|
14306
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";
|
|
14307
14889
|
journeyIdParam2 = external_exports.object({ id: external_exports.string().uuid() });
|
|
14308
14890
|
journeyToolCallSchema2 = external_exports.object({
|
|
14309
14891
|
id: external_exports.string(),
|
|
@@ -14315,7 +14897,10 @@ var init_contracts = __esm({
|
|
|
14315
14897
|
content: external_exports.string().nullable().optional(),
|
|
14316
14898
|
tool_calls: external_exports.array(journeyToolCallSchema2).optional(),
|
|
14317
14899
|
tool_call_id: external_exports.string().optional(),
|
|
14318
|
-
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
|
|
14319
14904
|
});
|
|
14320
14905
|
journeyStepOverrideSchema2 = external_exports.object({
|
|
14321
14906
|
number_of_runs: external_exports.number().int().positive().max(100).optional(),
|
|
@@ -14820,6 +15405,10 @@ var init_contracts = __esm({
|
|
|
14820
15405
|
agent_id: external_exports.string().uuid().nullable().optional(),
|
|
14821
15406
|
trigger_message: external_exports.string().nullable().optional()
|
|
14822
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;
|
|
14823
15412
|
uuidPattern2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
14824
15413
|
ciUuidSchema2 = external_exports.string().regex(uuidPattern2, "must be a valid UUID");
|
|
14825
15414
|
hubAsCodeConfigSchema2 = external_exports.object({
|
|
@@ -14832,6 +15421,7 @@ var init_contracts = __esm({
|
|
|
14832
15421
|
refineHubAsCodeKanbanStatuses2(config, ctx);
|
|
14833
15422
|
refineHubAsCodeLanes2(config, ctx);
|
|
14834
15423
|
refineHubAsCodeEvals2(config, ctx);
|
|
15424
|
+
refineHubAsCodeEvalAttachments2(config, ctx);
|
|
14835
15425
|
});
|
|
14836
15426
|
ciPullHubIdParam2 = external_exports.object({
|
|
14837
15427
|
hub_id: ciUuidSchema2
|
|
@@ -15721,8 +16311,8 @@ var replicate_exports = {};
|
|
|
15721
16311
|
__export(replicate_exports, {
|
|
15722
16312
|
replicateCommand: () => replicateCommand
|
|
15723
16313
|
});
|
|
15724
|
-
import * as
|
|
15725
|
-
import * as
|
|
16314
|
+
import * as fs17 from "fs";
|
|
16315
|
+
import * as path19 from "path";
|
|
15726
16316
|
function parseArgs8(args2) {
|
|
15727
16317
|
let label;
|
|
15728
16318
|
let hubSelector;
|
|
@@ -15768,7 +16358,7 @@ async function replicateCommand(args2) {
|
|
|
15768
16358
|
payload.preview_label,
|
|
15769
16359
|
payload.branch_name
|
|
15770
16360
|
);
|
|
15771
|
-
|
|
16361
|
+
fs17.mkdirSync(path19.dirname(hubFolder), { recursive: true });
|
|
15772
16362
|
writeHubFolder(hubFolder, payload);
|
|
15773
16363
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
15774
16364
|
hubFolder = autoRenameHubFolder(
|
|
@@ -15780,8 +16370,8 @@ async function replicateCommand(args2) {
|
|
|
15780
16370
|
payload.branch_name
|
|
15781
16371
|
);
|
|
15782
16372
|
autoBindIfUnbound(previewHubId);
|
|
15783
|
-
console.log(`Preview written to ${
|
|
15784
|
-
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)}`);
|
|
15785
16375
|
}
|
|
15786
16376
|
var init_replicate = __esm({
|
|
15787
16377
|
"src/commands/replicate.ts"() {
|
|
@@ -15803,7 +16393,7 @@ var relabel_exports = {};
|
|
|
15803
16393
|
__export(relabel_exports, {
|
|
15804
16394
|
relabelCommand: () => relabelCommand
|
|
15805
16395
|
});
|
|
15806
|
-
import * as
|
|
16396
|
+
import * as path20 from "path";
|
|
15807
16397
|
function parseArgs9(args2) {
|
|
15808
16398
|
let label;
|
|
15809
16399
|
let clear = false;
|
|
@@ -15847,7 +16437,7 @@ async function relabelCommand(args2) {
|
|
|
15847
16437
|
} else {
|
|
15848
16438
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
15849
16439
|
for (const h of previewHubs) {
|
|
15850
|
-
console.error(` ${
|
|
16440
|
+
console.error(` ${path20.basename(h.hubFolder)} (${h.hubId})`);
|
|
15851
16441
|
}
|
|
15852
16442
|
}
|
|
15853
16443
|
process.exit(1);
|
|
@@ -15856,7 +16446,7 @@ async function relabelCommand(args2) {
|
|
|
15856
16446
|
console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
|
|
15857
16447
|
return;
|
|
15858
16448
|
}
|
|
15859
|
-
assertHubMatchesBinding(target.hubId,
|
|
16449
|
+
assertHubMatchesBinding(target.hubId, path20.basename(target.hubFolder));
|
|
15860
16450
|
console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
|
|
15861
16451
|
const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
|
|
15862
16452
|
const row = data[0];
|
|
@@ -15872,7 +16462,7 @@ async function relabelCommand(args2) {
|
|
|
15872
16462
|
);
|
|
15873
16463
|
console.log(serverLabel ? `Preview label set to "${serverLabel}".` : "Preview label cleared.");
|
|
15874
16464
|
if (finalFolder !== target.hubFolder) {
|
|
15875
|
-
console.log(`Hub folder is now ${
|
|
16465
|
+
console.log(`Hub folder is now ${path20.basename(finalFolder)}`);
|
|
15876
16466
|
}
|
|
15877
16467
|
}
|
|
15878
16468
|
var init_relabel = __esm({
|
|
@@ -15898,7 +16488,7 @@ __export(publish_exports, {
|
|
|
15898
16488
|
renderHubDiff: () => renderHubDiff,
|
|
15899
16489
|
runPublish: () => runPublish
|
|
15900
16490
|
});
|
|
15901
|
-
import * as
|
|
16491
|
+
import * as path21 from "path";
|
|
15902
16492
|
function parseArgs10(args2) {
|
|
15903
16493
|
let autoConfirm = false;
|
|
15904
16494
|
let hubSelector;
|
|
@@ -16004,7 +16594,7 @@ async function publishCommand(args2) {
|
|
|
16004
16594
|
return;
|
|
16005
16595
|
}
|
|
16006
16596
|
}
|
|
16007
|
-
assertHubMatchesBinding(hubId, hubFolder ?
|
|
16597
|
+
assertHubMatchesBinding(hubId, hubFolder ? path21.basename(hubFolder) : void 0);
|
|
16008
16598
|
await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
|
|
16009
16599
|
}
|
|
16010
16600
|
var STATUS_STYLE;
|
|
@@ -16036,7 +16626,7 @@ var use_exports = {};
|
|
|
16036
16626
|
__export(use_exports, {
|
|
16037
16627
|
useCommand: () => useCommand
|
|
16038
16628
|
});
|
|
16039
|
-
import * as
|
|
16629
|
+
import * as path22 from "path";
|
|
16040
16630
|
async function useCommand(args2) {
|
|
16041
16631
|
const target = args2[0];
|
|
16042
16632
|
if (!target || target.startsWith("-")) {
|
|
@@ -16058,7 +16648,7 @@ async function useCommand(args2) {
|
|
|
16058
16648
|
const match = findHubByFolderName(workspaceDir, target);
|
|
16059
16649
|
if (!match) {
|
|
16060
16650
|
const newHubs = scanNewHubs(workspaceDir);
|
|
16061
|
-
const pending = newHubs.find((h) =>
|
|
16651
|
+
const pending = newHubs.find((h) => path22.basename(h.hubFolder) === target);
|
|
16062
16652
|
if (pending) {
|
|
16063
16653
|
console.error(
|
|
16064
16654
|
`"${target}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
|
|
@@ -16069,10 +16659,10 @@ Create it first \u2014 the worktree binds automatically afterward:
|
|
|
16069
16659
|
}
|
|
16070
16660
|
console.error(`No hub matching "${target}" found in ${wsLabel}/. Pass a UUID or a folder name from:`);
|
|
16071
16661
|
for (const h of scanWorkspaceHubs(workspaceDir)) {
|
|
16072
|
-
console.error(` ${
|
|
16662
|
+
console.error(` ${path22.basename(h.hubFolder)} (${h.hubId})`);
|
|
16073
16663
|
}
|
|
16074
16664
|
for (const h of newHubs) {
|
|
16075
|
-
console.error(` ${
|
|
16665
|
+
console.error(` ${path22.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path22.basename(h.hubFolder)}\`)`);
|
|
16076
16666
|
}
|
|
16077
16667
|
process.exit(1);
|
|
16078
16668
|
}
|
|
@@ -16111,11 +16701,11 @@ __export(migrate_exports, {
|
|
|
16111
16701
|
migrateCommand: () => migrateCommand
|
|
16112
16702
|
});
|
|
16113
16703
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
16114
|
-
import * as
|
|
16115
|
-
import * as
|
|
16704
|
+
import * as fs18 from "fs";
|
|
16705
|
+
import * as path23 from "path";
|
|
16116
16706
|
function isTracked(gitRoot, p) {
|
|
16117
16707
|
try {
|
|
16118
|
-
execFileSync3("git", ["ls-files", "--error-unmatch", "--",
|
|
16708
|
+
execFileSync3("git", ["ls-files", "--error-unmatch", "--", path23.relative(gitRoot, p)], {
|
|
16119
16709
|
cwd: gitRoot,
|
|
16120
16710
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16121
16711
|
});
|
|
@@ -16125,10 +16715,10 @@ function isTracked(gitRoot, p) {
|
|
|
16125
16715
|
}
|
|
16126
16716
|
}
|
|
16127
16717
|
function moveDir(gitRoot, from, to) {
|
|
16128
|
-
|
|
16718
|
+
fs18.mkdirSync(path23.dirname(to), { recursive: true });
|
|
16129
16719
|
if (isTracked(gitRoot, from)) {
|
|
16130
16720
|
try {
|
|
16131
|
-
execFileSync3("git", ["mv",
|
|
16721
|
+
execFileSync3("git", ["mv", path23.relative(gitRoot, from), path23.relative(gitRoot, to)], {
|
|
16132
16722
|
cwd: gitRoot,
|
|
16133
16723
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16134
16724
|
});
|
|
@@ -16136,7 +16726,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
16136
16726
|
} catch {
|
|
16137
16727
|
}
|
|
16138
16728
|
}
|
|
16139
|
-
|
|
16729
|
+
fs18.renameSync(from, to);
|
|
16140
16730
|
return "fs";
|
|
16141
16731
|
}
|
|
16142
16732
|
async function migrateCommand(_args) {
|
|
@@ -16145,12 +16735,12 @@ async function migrateCommand(_args) {
|
|
|
16145
16735
|
console.error("Not inside a git repository.");
|
|
16146
16736
|
process.exit(1);
|
|
16147
16737
|
}
|
|
16148
|
-
const rel = (p) =>
|
|
16149
|
-
const newWs =
|
|
16150
|
-
const legacyWs =
|
|
16151
|
-
const legacyOrg =
|
|
16152
|
-
const newHubs =
|
|
16153
|
-
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);
|
|
16154
16744
|
const hasLegacyWs = isDirectory(legacyWs);
|
|
16155
16745
|
const hasLegacyOrg = isDirectory(legacyOrg);
|
|
16156
16746
|
if (!hasLegacyWs && !hasLegacyOrg) {
|
|
@@ -16224,12 +16814,12 @@ var send_message_exports = {};
|
|
|
16224
16814
|
__export(send_message_exports, {
|
|
16225
16815
|
sendMessageCommand: () => sendMessageCommand
|
|
16226
16816
|
});
|
|
16227
|
-
import * as
|
|
16228
|
-
import * as
|
|
16817
|
+
import * as fs19 from "fs";
|
|
16818
|
+
import * as path24 from "path";
|
|
16229
16819
|
function statAttachment(filePath) {
|
|
16230
16820
|
let stat;
|
|
16231
16821
|
try {
|
|
16232
|
-
stat =
|
|
16822
|
+
stat = fs19.statSync(filePath);
|
|
16233
16823
|
} catch {
|
|
16234
16824
|
console.error(`Error: file not found: ${filePath}`);
|
|
16235
16825
|
process.exit(1);
|
|
@@ -16241,11 +16831,11 @@ function statAttachment(filePath) {
|
|
|
16241
16831
|
return { filePath, size: stat.size };
|
|
16242
16832
|
}
|
|
16243
16833
|
function readAttachment(filePath, size) {
|
|
16244
|
-
const fileName =
|
|
16245
|
-
const ext =
|
|
16834
|
+
const fileName = path24.basename(filePath);
|
|
16835
|
+
const ext = path24.extname(fileName).replace(/^\./, "");
|
|
16246
16836
|
return {
|
|
16247
16837
|
file_name: fileName,
|
|
16248
|
-
file_binary:
|
|
16838
|
+
file_binary: fs19.readFileSync(filePath).toString("base64"),
|
|
16249
16839
|
file_size: size,
|
|
16250
16840
|
...ext && { file_extension: ext }
|
|
16251
16841
|
};
|
|
@@ -16292,7 +16882,7 @@ async function sendMessageCommand(args2) {
|
|
|
16292
16882
|
}
|
|
16293
16883
|
const stats = filePaths.map(statAttachment);
|
|
16294
16884
|
const filesTotal = stats.reduce((sum, s) => sum + base64Length(s.size), 0);
|
|
16295
|
-
const fileDetail = () => stats.map((s) => `${
|
|
16885
|
+
const fileDetail = () => stats.map((s) => `${path24.basename(s.filePath)} ${asMb(s.size)} MB`).join(", ");
|
|
16296
16886
|
if (filesTotal > MAX_MESSAGE_BODY_BYTES2) {
|
|
16297
16887
|
console.error(
|
|
16298
16888
|
`Error: ${fileDetail()} encode to ~${asMb(filesTotal)} MB, over the ${asMb(MAX_MESSAGE_BODY_BYTES2)} MB per-request limit.`
|
|
@@ -17527,7 +18117,7 @@ Timeout after ${timeoutSeconds}s. Session is still running.`);
|
|
|
17527
18117
|
console.log(`Check results: wayai eval-results --session ${sessionId}`);
|
|
17528
18118
|
}
|
|
17529
18119
|
function sleep(ms) {
|
|
17530
|
-
return new Promise((
|
|
18120
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
17531
18121
|
}
|
|
17532
18122
|
function parsePacing(raw) {
|
|
17533
18123
|
const NAMED = EVAL_PACING_PRESET_NAMES.filter((p) => p !== "custom");
|
|
@@ -17752,8 +18342,8 @@ var eval_capture_exports = {};
|
|
|
17752
18342
|
__export(eval_capture_exports, {
|
|
17753
18343
|
evalCaptureCommand: () => evalCaptureCommand
|
|
17754
18344
|
});
|
|
17755
|
-
import * as
|
|
17756
|
-
import * as
|
|
18345
|
+
import * as fs20 from "fs";
|
|
18346
|
+
import * as path25 from "path";
|
|
17757
18347
|
import * as yaml7 from "js-yaml";
|
|
17758
18348
|
function isValidSetName(name) {
|
|
17759
18349
|
if (name.length === 0 || name === "." || name === "..") return false;
|
|
@@ -17819,15 +18409,15 @@ async function evalCaptureCommand(args2) {
|
|
|
17819
18409
|
const setFolderName = targetSetName;
|
|
17820
18410
|
const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;
|
|
17821
18411
|
const slug = slugify(scenarioName);
|
|
17822
|
-
const evalsDir =
|
|
17823
|
-
const targetDir =
|
|
17824
|
-
const targetPath =
|
|
17825
|
-
if (!targetPath.startsWith(evalsDir +
|
|
17826
|
-
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.`);
|
|
17827
18417
|
process.exit(1);
|
|
17828
18418
|
}
|
|
17829
|
-
if (
|
|
17830
|
-
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.`);
|
|
17831
18421
|
process.exit(1);
|
|
17832
18422
|
}
|
|
17833
18423
|
console.log("Resolving scenario set...");
|
|
@@ -17859,9 +18449,9 @@ async function evalCaptureCommand(args2) {
|
|
|
17859
18449
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
17860
18450
|
};
|
|
17861
18451
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
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);
|
|
17865
18455
|
console.log(`
|
|
17866
18456
|
Wrote ${relPath}`);
|
|
17867
18457
|
console.log("Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.");
|
|
@@ -19088,23 +19678,23 @@ var init_set_connection_credential = __esm({
|
|
|
19088
19678
|
});
|
|
19089
19679
|
|
|
19090
19680
|
// src/lib/org-workspace.ts
|
|
19091
|
-
import * as
|
|
19092
|
-
import * as
|
|
19681
|
+
import * as fs21 from "fs";
|
|
19682
|
+
import * as path26 from "path";
|
|
19093
19683
|
import * as yaml8 from "js-yaml";
|
|
19094
19684
|
function getOrgDir(gitRoot) {
|
|
19095
19685
|
return resolveLayout(gitRoot).orgDir;
|
|
19096
19686
|
}
|
|
19097
19687
|
function orgManifestExists(orgDir) {
|
|
19098
|
-
return
|
|
19688
|
+
return fs21.existsSync(path26.join(orgDir, ORG_MANIFEST_NAME));
|
|
19099
19689
|
}
|
|
19100
19690
|
function parseOrgResources(orgDir) {
|
|
19101
|
-
const manifestPath =
|
|
19691
|
+
const manifestPath = path26.join(orgDir, ORG_MANIFEST_NAME);
|
|
19102
19692
|
let manifest = {};
|
|
19103
|
-
if (
|
|
19104
|
-
manifest = yaml8.load(
|
|
19693
|
+
if (fs21.existsSync(manifestPath)) {
|
|
19694
|
+
manifest = yaml8.load(fs21.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
19105
19695
|
}
|
|
19106
19696
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
19107
|
-
const resourcesDir =
|
|
19697
|
+
const resourcesDir = path26.join(orgDir, "resources");
|
|
19108
19698
|
const resources = rawResources.map((res) => {
|
|
19109
19699
|
const resource = { name: res.name };
|
|
19110
19700
|
if (res.id) resource.id = res.id;
|
|
@@ -19116,8 +19706,8 @@ function parseOrgResources(orgDir) {
|
|
|
19116
19706
|
if (res.environment) resource.environment = res.environment;
|
|
19117
19707
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
19118
19708
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
19119
|
-
const resDir =
|
|
19120
|
-
if (
|
|
19709
|
+
const resDir = path26.join(resourcesDir, slugify(resource.name));
|
|
19710
|
+
if (fs21.existsSync(resDir)) {
|
|
19121
19711
|
const files = scanResourceFiles(resDir, "");
|
|
19122
19712
|
if (files.length > 0) resource.files = files;
|
|
19123
19713
|
}
|
|
@@ -19126,28 +19716,28 @@ function parseOrgResources(orgDir) {
|
|
|
19126
19716
|
return { version: 1, resources };
|
|
19127
19717
|
}
|
|
19128
19718
|
function writeOrgResources(orgDir, payload) {
|
|
19129
|
-
|
|
19719
|
+
fs21.mkdirSync(orgDir, { recursive: true });
|
|
19130
19720
|
const resources = payload.resources ?? [];
|
|
19131
19721
|
const manifestResources = resources.map((r) => {
|
|
19132
19722
|
const { files: _files, ...rest } = r;
|
|
19133
19723
|
return rest;
|
|
19134
19724
|
});
|
|
19135
|
-
|
|
19136
|
-
|
|
19725
|
+
fs21.writeFileSync(
|
|
19726
|
+
path26.join(orgDir, ORG_MANIFEST_NAME),
|
|
19137
19727
|
yaml8.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
19138
19728
|
"utf-8"
|
|
19139
19729
|
);
|
|
19140
|
-
const resourcesDir =
|
|
19730
|
+
const resourcesDir = path26.join(orgDir, "resources");
|
|
19141
19731
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
19142
19732
|
for (const resource of resources) {
|
|
19143
19733
|
const resSlug = slugify(resource.name);
|
|
19144
19734
|
currentSlugs.add(resSlug);
|
|
19145
|
-
writeResourceFileTree(
|
|
19735
|
+
writeResourceFileTree(path26.join(resourcesDir, resSlug), resource.files || [], orgDir);
|
|
19146
19736
|
}
|
|
19147
|
-
if (
|
|
19148
|
-
for (const entry of
|
|
19737
|
+
if (fs21.existsSync(resourcesDir)) {
|
|
19738
|
+
for (const entry of fs21.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
19149
19739
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
19150
|
-
|
|
19740
|
+
fs21.rmSync(path26.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
19151
19741
|
}
|
|
19152
19742
|
}
|
|
19153
19743
|
}
|
|
@@ -19156,8 +19746,8 @@ async function downloadOrgBinaryFiles(orgDir, payload) {
|
|
|
19156
19746
|
let count = 0;
|
|
19157
19747
|
for (const resource of payload.resources ?? []) {
|
|
19158
19748
|
if (!resource.files) continue;
|
|
19159
|
-
const resDir =
|
|
19160
|
-
count += await downloadBinaryFiles(resDir, resource.files);
|
|
19749
|
+
const resDir = path26.join(orgDir, "resources", slugify(resource.name));
|
|
19750
|
+
count += await downloadBinaryFiles(resDir, resource.files, orgDir);
|
|
19161
19751
|
}
|
|
19162
19752
|
if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);
|
|
19163
19753
|
}
|
|
@@ -19412,20 +20002,20 @@ var init_list = __esm({
|
|
|
19412
20002
|
});
|
|
19413
20003
|
|
|
19414
20004
|
// src/lib/template-files.ts
|
|
19415
|
-
import * as
|
|
19416
|
-
import * as
|
|
20005
|
+
import * as fs22 from "fs";
|
|
20006
|
+
import * as path27 from "path";
|
|
19417
20007
|
function readDirToFileMap(rootDir) {
|
|
19418
20008
|
const out = {};
|
|
19419
20009
|
function walk(dir, prefix) {
|
|
19420
|
-
const entries =
|
|
20010
|
+
const entries = fs22.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
19421
20011
|
for (const entry of entries) {
|
|
19422
|
-
const abs =
|
|
20012
|
+
const abs = path27.join(dir, entry.name);
|
|
19423
20013
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19424
20014
|
if (entry.isDirectory()) walk(abs, rel);
|
|
19425
|
-
else if (entry.isFile()) out[rel] =
|
|
20015
|
+
else if (entry.isFile()) out[rel] = fs22.readFileSync(abs, "utf-8");
|
|
19426
20016
|
}
|
|
19427
20017
|
}
|
|
19428
|
-
if (
|
|
20018
|
+
if (fs22.existsSync(rootDir)) walk(rootDir, "");
|
|
19429
20019
|
return out;
|
|
19430
20020
|
}
|
|
19431
20021
|
function detectCollisions(targetDir, files) {
|
|
@@ -19434,7 +20024,7 @@ function detectCollisions(targetDir, files) {
|
|
|
19434
20024
|
if (!isSafeTemplatePath2(rel)) {
|
|
19435
20025
|
throw new Error(`Refusing to inspect unsafe template path: ${rel}`);
|
|
19436
20026
|
}
|
|
19437
|
-
if (
|
|
20027
|
+
if (fs22.existsSync(path27.join(targetDir, rel))) collisions.push(rel);
|
|
19438
20028
|
}
|
|
19439
20029
|
return collisions.sort((a, b) => a.localeCompare(b));
|
|
19440
20030
|
}
|
|
@@ -19444,9 +20034,9 @@ function writeFileMap(targetDir, files) {
|
|
|
19444
20034
|
if (!isSafeTemplatePath2(rel)) {
|
|
19445
20035
|
throw new Error(`Refusing to write unsafe template path: ${rel}`);
|
|
19446
20036
|
}
|
|
19447
|
-
const abs =
|
|
19448
|
-
|
|
19449
|
-
|
|
20037
|
+
const abs = path27.join(targetDir, rel);
|
|
20038
|
+
fs22.mkdirSync(path27.dirname(abs), { recursive: true });
|
|
20039
|
+
fs22.writeFileSync(abs, body, "utf-8");
|
|
19450
20040
|
written.push(rel);
|
|
19451
20041
|
}
|
|
19452
20042
|
return written;
|
|
@@ -19454,20 +20044,20 @@ function writeFileMap(targetDir, files) {
|
|
|
19454
20044
|
function listDirRelFiles(dir) {
|
|
19455
20045
|
const out = [];
|
|
19456
20046
|
function walk(d, prefix) {
|
|
19457
|
-
for (const entry of
|
|
20047
|
+
for (const entry of fs22.readdirSync(d, { withFileTypes: true })) {
|
|
19458
20048
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
19459
|
-
if (entry.isDirectory()) walk(
|
|
20049
|
+
if (entry.isDirectory()) walk(path27.join(d, entry.name), rel);
|
|
19460
20050
|
else if (entry.isFile()) out.push(rel);
|
|
19461
20051
|
}
|
|
19462
20052
|
}
|
|
19463
|
-
if (
|
|
20053
|
+
if (fs22.existsSync(dir)) walk(dir, "");
|
|
19464
20054
|
return out;
|
|
19465
20055
|
}
|
|
19466
20056
|
function writeSliceSnapshot(targetDir, files) {
|
|
19467
20057
|
const keep = new Set(Object.keys(files));
|
|
19468
20058
|
const removed = listDirRelFiles(targetDir).filter((rel) => !keep.has(rel)).sort((a, b) => a.localeCompare(b));
|
|
19469
20059
|
const written = writeFileMap(targetDir, files).sort((a, b) => a.localeCompare(b));
|
|
19470
|
-
if (
|
|
20060
|
+
if (fs22.existsSync(targetDir)) cleanOrphanFiles(targetDir, "", keep);
|
|
19471
20061
|
return { written, removed };
|
|
19472
20062
|
}
|
|
19473
20063
|
var init_template_files = __esm({
|
|
@@ -19483,7 +20073,7 @@ var templates_exports = {};
|
|
|
19483
20073
|
__export(templates_exports, {
|
|
19484
20074
|
templateCommand: () => templateCommand
|
|
19485
20075
|
});
|
|
19486
|
-
import * as
|
|
20076
|
+
import * as path28 from "path";
|
|
19487
20077
|
async function templateCommand(args2) {
|
|
19488
20078
|
const [sub, ...rest] = args2;
|
|
19489
20079
|
switch (sub) {
|
|
@@ -19599,8 +20189,8 @@ async function runTemplatePull(rest) {
|
|
|
19599
20189
|
console.log(`Template "${slug}" has no WayAI slice${hint}`);
|
|
19600
20190
|
return;
|
|
19601
20191
|
}
|
|
19602
|
-
const targetDir =
|
|
19603
|
-
const relTarget =
|
|
20192
|
+
const targetDir = path28.join(resolveLayout(gitRoot).hubsDir, slug);
|
|
20193
|
+
const relTarget = path28.relative(gitRoot, targetDir);
|
|
19604
20194
|
const collisions = detectCollisions(targetDir, detail.files);
|
|
19605
20195
|
if (dryRun) {
|
|
19606
20196
|
const planned = Object.keys(detail.files).sort((a, b) => a.localeCompare(b));
|
|
@@ -19726,21 +20316,37 @@ import * as yaml9 from "js-yaml";
|
|
|
19726
20316
|
function sanitizeWayaiSliceFiles(files) {
|
|
19727
20317
|
const out = {};
|
|
19728
20318
|
for (const [filePath, body] of Object.entries(files)) {
|
|
19729
|
-
out[filePath] = isSanitizableSliceFile(filePath) ? sanitizeOne(body) : body;
|
|
20319
|
+
out[filePath] = isSanitizableSliceFile(filePath) ? sanitizeOne(filePath, body) : body;
|
|
19730
20320
|
}
|
|
19731
20321
|
return out;
|
|
19732
20322
|
}
|
|
19733
|
-
function sanitizeOne(body) {
|
|
20323
|
+
function sanitizeOne(filePath, body) {
|
|
19734
20324
|
let parsed;
|
|
19735
20325
|
try {
|
|
19736
20326
|
parsed = yaml9.load(body);
|
|
19737
20327
|
} catch {
|
|
19738
20328
|
return body;
|
|
19739
20329
|
}
|
|
19740
|
-
const scrubbed = excludeTemplateAuthorData(stripTemplateInstanceIds(parsed));
|
|
20330
|
+
const scrubbed = stripEvalAttachments(filePath, excludeTemplateAuthorData(stripTemplateInstanceIds(parsed)));
|
|
19741
20331
|
if (JSON.stringify(parsed) === JSON.stringify(scrubbed)) return body;
|
|
19742
20332
|
return yaml9.dump(scrubbed, YAML_DUMP_OPTIONS);
|
|
19743
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
|
+
}
|
|
19744
20350
|
var init_template_sanitize = __esm({
|
|
19745
20351
|
"src/lib/template-sanitize.ts"() {
|
|
19746
20352
|
"use strict";
|
|
@@ -19774,8 +20380,8 @@ var admin_exports = {};
|
|
|
19774
20380
|
__export(admin_exports, {
|
|
19775
20381
|
adminCommand: () => adminCommand
|
|
19776
20382
|
});
|
|
19777
|
-
import * as
|
|
19778
|
-
import * as
|
|
20383
|
+
import * as fs23 from "fs";
|
|
20384
|
+
import * as path29 from "path";
|
|
19779
20385
|
import * as yaml10 from "js-yaml";
|
|
19780
20386
|
async function adminCommand(args2) {
|
|
19781
20387
|
const [group, ...afterGroup] = args2;
|
|
@@ -20097,7 +20703,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
20097
20703
|
exitOnApiError(err);
|
|
20098
20704
|
throw err;
|
|
20099
20705
|
}
|
|
20100
|
-
|
|
20706
|
+
fs23.writeFileSync(outPath, zip);
|
|
20101
20707
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
20102
20708
|
return;
|
|
20103
20709
|
}
|
|
@@ -20229,15 +20835,15 @@ function loadTemplateManifest(slug) {
|
|
|
20229
20835
|
console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
|
|
20230
20836
|
process.exit(1);
|
|
20231
20837
|
}
|
|
20232
|
-
const templateDir =
|
|
20233
|
-
const manifestPath =
|
|
20234
|
-
if (!
|
|
20235
|
-
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)}`);
|
|
20236
20842
|
process.exit(1);
|
|
20237
20843
|
}
|
|
20238
20844
|
let manifest;
|
|
20239
20845
|
try {
|
|
20240
|
-
manifest = templateYamlSchema2.parse(yaml10.load(
|
|
20846
|
+
manifest = templateYamlSchema2.parse(yaml10.load(fs23.readFileSync(manifestPath, "utf-8")));
|
|
20241
20847
|
} catch (err) {
|
|
20242
20848
|
console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
|
|
20243
20849
|
process.exit(1);
|
|
@@ -20267,20 +20873,20 @@ async function runTemplatePush(positional) {
|
|
|
20267
20873
|
const wayaiEntry = manifest.wayai.locales[locale];
|
|
20268
20874
|
let wayaiFiles;
|
|
20269
20875
|
if (wayaiEntry) {
|
|
20270
|
-
const sliceDir =
|
|
20271
|
-
if (!
|
|
20876
|
+
const sliceDir = path29.resolve(templateDir, wayaiEntry.source);
|
|
20877
|
+
if (!fs23.existsSync(sliceDir)) {
|
|
20272
20878
|
console.error(`wayai source not found for ${locale}: ${wayaiEntry.source} (resolved ${sliceDir})`);
|
|
20273
20879
|
process.exit(1);
|
|
20274
20880
|
}
|
|
20275
20881
|
if (!isInsideTemplateDir(sliceDir, templateDir)) {
|
|
20276
20882
|
console.warn(
|
|
20277
|
-
`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.`
|
|
20278
20884
|
);
|
|
20279
20885
|
}
|
|
20280
20886
|
wayaiFiles = readDirToFileMap(sliceDir);
|
|
20281
20887
|
}
|
|
20282
|
-
const readmePath =
|
|
20283
|
-
const readmeMarkdown =
|
|
20888
|
+
const readmePath = path29.join(templateDir, `README.${locale}.md`);
|
|
20889
|
+
const readmeMarkdown = fs23.existsSync(readmePath) ? fs23.readFileSync(readmePath, "utf-8") : "";
|
|
20284
20890
|
locales[locale] = {
|
|
20285
20891
|
readmeMarkdown,
|
|
20286
20892
|
...wayaiFiles && { wayaiFiles },
|
|
@@ -20291,9 +20897,9 @@ async function runTemplatePush(positional) {
|
|
|
20291
20897
|
}
|
|
20292
20898
|
let hero;
|
|
20293
20899
|
if (manifest.hero) {
|
|
20294
|
-
const heroPath =
|
|
20295
|
-
if (
|
|
20296
|
-
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") };
|
|
20297
20903
|
} else {
|
|
20298
20904
|
console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
|
|
20299
20905
|
}
|
|
@@ -20319,7 +20925,7 @@ async function runTemplatePush(positional) {
|
|
|
20319
20925
|
}
|
|
20320
20926
|
}
|
|
20321
20927
|
function isInsideTemplateDir(dest, templateDir) {
|
|
20322
|
-
return dest === templateDir || dest.startsWith(templateDir +
|
|
20928
|
+
return dest === templateDir || dest.startsWith(templateDir + path29.sep);
|
|
20323
20929
|
}
|
|
20324
20930
|
async function runTemplateFreeze(positional, flagArgs) {
|
|
20325
20931
|
const slug = positional[0];
|
|
@@ -20380,7 +20986,7 @@ async function runTemplateFreeze(positional, flagArgs) {
|
|
|
20380
20986
|
process.exit(1);
|
|
20381
20987
|
}
|
|
20382
20988
|
const entry = manifest.wayai.locales[targetLocale];
|
|
20383
|
-
const dest =
|
|
20989
|
+
const dest = path29.resolve(templateDir, entry.source);
|
|
20384
20990
|
if (!isInsideTemplateDir(dest, templateDir) || dest === templateDir) {
|
|
20385
20991
|
console.error(
|
|
20386
20992
|
`source for "${targetLocale}" must be a committed path inside ${slug}/ (e.g. "./${targetLocale}/slice"), but resolved to:
|
|
@@ -20399,7 +21005,7 @@ Set it to a subdir of the template folder and re-run freeze.`
|
|
|
20399
21005
|
const hubs = scanWorkspaceHubs(hubsDir);
|
|
20400
21006
|
if (hubs.length) {
|
|
20401
21007
|
console.error("Available hubs:");
|
|
20402
|
-
for (const h of hubs) console.error(` ${
|
|
21008
|
+
for (const h of hubs) console.error(` ${path29.basename(h.hubFolder)} (${h.hubId})`);
|
|
20403
21009
|
}
|
|
20404
21010
|
console.error(`
|
|
20405
21011
|
Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`);
|
|
@@ -20407,12 +21013,12 @@ Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`
|
|
|
20407
21013
|
}
|
|
20408
21014
|
const liveFiles = readDirToFileMap(hubFolder);
|
|
20409
21015
|
if (Object.keys(liveFiles).length === 0) {
|
|
20410
|
-
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)}`);
|
|
20411
21017
|
process.exit(1);
|
|
20412
21018
|
}
|
|
20413
21019
|
const sanitized = sanitizeWayaiSliceFiles(liveFiles);
|
|
20414
|
-
const relDest =
|
|
20415
|
-
const relSrc =
|
|
21020
|
+
const relDest = path29.relative(gitRoot, dest);
|
|
21021
|
+
const relSrc = path29.relative(gitRoot, hubFolder);
|
|
20416
21022
|
if (dryRun) {
|
|
20417
21023
|
const existing = new Set(listDirRelFiles(dest));
|
|
20418
21024
|
const nextKeys = new Set(Object.keys(sanitized));
|
|
@@ -20472,7 +21078,7 @@ async function runTemplatePull2(positional, flagArgs) {
|
|
|
20472
21078
|
console.log(JSON.stringify(detail, null, 2));
|
|
20473
21079
|
return;
|
|
20474
21080
|
}
|
|
20475
|
-
const target = outDir ?
|
|
21081
|
+
const target = outDir ? path29.resolve(outDir) : path29.join(process.cwd(), "template-store-pull", slug);
|
|
20476
21082
|
const written = writeFileMap(target, detail.files);
|
|
20477
21083
|
console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
20478
21084
|
const uses = detail.uses ?? [];
|
|
@@ -20495,13 +21101,13 @@ async function runSkillInstall(positional) {
|
|
|
20495
21101
|
throw err;
|
|
20496
21102
|
}
|
|
20497
21103
|
const root = findGitRoot() ?? process.cwd();
|
|
20498
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
21104
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs23.existsSync(path29.join(root, dir)));
|
|
20499
21105
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
20500
21106
|
const fileCount = Object.keys(res.files).length;
|
|
20501
21107
|
const relDirs = targets.map((harness) => {
|
|
20502
|
-
const targetDir =
|
|
21108
|
+
const targetDir = path29.join(root, harness, "skills", name);
|
|
20503
21109
|
writeFileMap(targetDir, res.files);
|
|
20504
|
-
return `${
|
|
21110
|
+
return `${path29.relative(root, targetDir)}/`;
|
|
20505
21111
|
});
|
|
20506
21112
|
console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
|
|
20507
21113
|
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
@@ -21843,9 +22449,9 @@ var init_update = __esm({
|
|
|
21843
22449
|
|
|
21844
22450
|
// src/index.ts
|
|
21845
22451
|
init_sentry();
|
|
21846
|
-
import { readFileSync as
|
|
22452
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
21847
22453
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
21848
|
-
import { dirname as dirname9, join as
|
|
22454
|
+
import { dirname as dirname9, join as join27 } from "path";
|
|
21849
22455
|
|
|
21850
22456
|
// src/lib/errors.ts
|
|
21851
22457
|
init_api_client();
|
|
@@ -21877,7 +22483,7 @@ init_skill_version();
|
|
|
21877
22483
|
import { exec } from "child_process";
|
|
21878
22484
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
21879
22485
|
function refreshCliCache() {
|
|
21880
|
-
return new Promise((
|
|
22486
|
+
return new Promise((resolve6) => {
|
|
21881
22487
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
21882
22488
|
if (!err) {
|
|
21883
22489
|
const latest = stdout.trim();
|
|
@@ -21888,7 +22494,7 @@ function refreshCliCache() {
|
|
|
21888
22494
|
}
|
|
21889
22495
|
}
|
|
21890
22496
|
}
|
|
21891
|
-
|
|
22497
|
+
resolve6();
|
|
21892
22498
|
});
|
|
21893
22499
|
});
|
|
21894
22500
|
}
|
|
@@ -21914,8 +22520,8 @@ async function refreshSkillCache() {
|
|
|
21914
22520
|
}
|
|
21915
22521
|
async function refreshAdminSkillCache() {
|
|
21916
22522
|
let timer;
|
|
21917
|
-
const deadline = new Promise((
|
|
21918
|
-
timer = setTimeout(
|
|
22523
|
+
const deadline = new Promise((resolve6) => {
|
|
22524
|
+
timer = setTimeout(resolve6, REFRESH_TIMEOUT_MS);
|
|
21919
22525
|
});
|
|
21920
22526
|
await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
|
|
21921
22527
|
})]);
|
|
@@ -22025,7 +22631,7 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
22025
22631
|
|
|
22026
22632
|
// src/index.ts
|
|
22027
22633
|
var __dirname = dirname9(fileURLToPath2(import.meta.url));
|
|
22028
|
-
var pkg = JSON.parse(
|
|
22634
|
+
var pkg = JSON.parse(readFileSync20(join27(__dirname, "..", "package.json"), "utf-8"));
|
|
22029
22635
|
var [, , command, ...args] = process.argv;
|
|
22030
22636
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
22031
22637
|
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|