@agentsky/sky 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -18978,6 +18978,14 @@ var REASONING_EFFORT_VALUES = [
|
|
|
18978
18978
|
"max",
|
|
18979
18979
|
"ultra"
|
|
18980
18980
|
];
|
|
18981
|
+
var MODEL_REASONING_EFFORTS = {
|
|
18982
|
+
"claude-haiku-4-5": [],
|
|
18983
|
+
"gemini-3.8-flash": ["low", "medium", "high"],
|
|
18984
|
+
"gemini-3.5-flash": ["low", "medium", "high"],
|
|
18985
|
+
"glm-5.3": ["low", "high", "max"],
|
|
18986
|
+
"glm-5.3-flash": ["low", "high", "max"],
|
|
18987
|
+
"grok-4.6": ["low", "medium", "high"]
|
|
18988
|
+
};
|
|
18981
18989
|
var REASONING_EFFORTS = {
|
|
18982
18990
|
agoragentic_acp: null,
|
|
18983
18991
|
amp_acp: null,
|
|
@@ -19032,15 +19040,20 @@ var REASONING_EFFORTS = {
|
|
|
19032
19040
|
};
|
|
19033
19041
|
function reasoningEffortsForModel(agentType, model) {
|
|
19034
19042
|
const normalized = model?.split("/").at(-1);
|
|
19043
|
+
const levels = REASONING_EFFORTS[agentType];
|
|
19044
|
+
if (levels === null) return null;
|
|
19035
19045
|
if (normalized === "gpt-6.1-sol" && (agentType === "codex" || agentType === "hermes")) return ["low", "medium", "high", "xhigh", "max"];
|
|
19036
|
-
return
|
|
19046
|
+
if (agentType === "opencode" && (normalized === "muse-spark-1.1" || normalized === "muse-spark-1.2")) return ["minimal", "low", "medium", "high", "xhigh"];
|
|
19047
|
+
const modelLevels = normalized ? MODEL_REASONING_EFFORTS[normalized] : void 0;
|
|
19048
|
+
return modelLevels ? levels.filter((level) => modelLevels.includes(level)) : levels;
|
|
19037
19049
|
}
|
|
19038
19050
|
function isModelEffortSupported(agentType, model, effort) {
|
|
19039
|
-
|
|
19040
|
-
return allowed !== null && allowed.includes(effort);
|
|
19051
|
+
return reasoningEffortsForModel(agentType, model)?.includes(effort) ?? false;
|
|
19041
19052
|
}
|
|
19042
19053
|
function reasoningEffortDocLine() {
|
|
19043
|
-
|
|
19054
|
+
const harness = Object.entries(REASONING_EFFORTS).map(([type, values]) => values ? `${type}: ${values.join("/")}` : `${type}: not supported`).join("; ");
|
|
19055
|
+
const models = Object.entries(MODEL_REASONING_EFFORTS).map(([model, values]) => `${model}: ${values.length ? values.join("/") : "not supported"}`).join("; ");
|
|
19056
|
+
return `${harness}; models: ${models}; codex/hermes + gpt-6.1-sol: low/medium/high/xhigh/max`;
|
|
19044
19057
|
}
|
|
19045
19058
|
|
|
19046
19059
|
// ../../packages/spec/src/acp-catalog.ts
|
|
@@ -21080,6 +21093,8 @@ var podTurnBodySchema = external_exports.object({
|
|
|
21080
21093
|
// ../../packages/spec/src/resources.ts
|
|
21081
21094
|
var MAX_RESOURCES_PER_CREATE = 100;
|
|
21082
21095
|
var MAX_REPOSITORY_TOKEN_CHARS = 1024;
|
|
21096
|
+
var MAX_SESSION_MEMORY_SNAPSHOT_BYTES = 8 * 1024 * 1024;
|
|
21097
|
+
var MAX_MEMORY_STORE_INSTRUCTIONS_CHARS = 4096;
|
|
21083
21098
|
var mountPathSchema = external_exports.string().min(1).max(4096).nullish();
|
|
21084
21099
|
var fileResourceParamSchema = external_exports.object({
|
|
21085
21100
|
type: external_exports.literal("file"),
|
|
@@ -21097,14 +21112,28 @@ var githubRepositoryResourceParamSchema = external_exports.object({
|
|
|
21097
21112
|
checkout: repositoryCheckoutSchema.nullish(),
|
|
21098
21113
|
mount_path: mountPathSchema
|
|
21099
21114
|
});
|
|
21115
|
+
var memoryStoreResourceParamSchema = external_exports.object({
|
|
21116
|
+
type: external_exports.literal("memory_store"),
|
|
21117
|
+
memory_store_id: external_exports.string().min(1).max(255),
|
|
21118
|
+
/** Write access must be explicitly granted for this session. */
|
|
21119
|
+
access: external_exports.enum(["read_only", "read_write"]),
|
|
21120
|
+
/** Optional per-session instructions passed to the agent about this store (≤ 4096 chars). */
|
|
21121
|
+
instructions: external_exports.string().max(MAX_MEMORY_STORE_INSTRUCTIONS_CHARS).optional(),
|
|
21122
|
+
/** Where the store's memories land; defaults to /mnt/memory/<memory_store_id>. */
|
|
21123
|
+
mount_path: external_exports.string().min(1).max(4096).nullish()
|
|
21124
|
+
});
|
|
21100
21125
|
var sessionResourceParamSchema = external_exports.discriminatedUnion("type", [
|
|
21101
21126
|
fileResourceParamSchema,
|
|
21102
|
-
githubRepositoryResourceParamSchema
|
|
21127
|
+
githubRepositoryResourceParamSchema,
|
|
21128
|
+
memoryStoreResourceParamSchema
|
|
21103
21129
|
]);
|
|
21104
21130
|
var sessionResourcesParamSchema = external_exports.array(sessionResourceParamSchema).max(MAX_RESOURCES_PER_CREATE);
|
|
21105
21131
|
var updateSessionResourceSchema = external_exports.object({
|
|
21106
21132
|
authorization_token: external_exports.string().min(1).max(MAX_REPOSITORY_TOKEN_CHARS)
|
|
21107
21133
|
});
|
|
21134
|
+
var MAX_MEMORY_MOUNT_PATH_BYTES = 4095 - 1024 - 2 * 13;
|
|
21135
|
+
var MAX_FILESYSTEM_COMPONENT_BYTES = 255;
|
|
21136
|
+
var MAX_STAGED_COMPONENT_BYTES = MAX_FILESYSTEM_COMPONENT_BYTES - 13;
|
|
21108
21137
|
|
|
21109
21138
|
// ../../packages/spec/src/usage.ts
|
|
21110
21139
|
var usageReportSchema = external_exports.object({
|
|
@@ -21151,6 +21180,689 @@ var connectionSupportSchema = external_exports.object({
|
|
|
21151
21180
|
connectors: external_exports.enum(["all", "none"])
|
|
21152
21181
|
}).strict();
|
|
21153
21182
|
|
|
21183
|
+
// ../../packages/spec/src/question.ts
|
|
21184
|
+
var QUESTION_REQUEST_KINDS = ["connect_app"];
|
|
21185
|
+
var questionSchema = external_exports.object({
|
|
21186
|
+
requestId: external_exports.string().min(1),
|
|
21187
|
+
question: external_exports.string().trim().min(1),
|
|
21188
|
+
options: external_exports.array(
|
|
21189
|
+
external_exports.object({
|
|
21190
|
+
id: external_exports.string().min(1),
|
|
21191
|
+
label: external_exports.string().trim().min(1),
|
|
21192
|
+
description: external_exports.string().optional()
|
|
21193
|
+
})
|
|
21194
|
+
).default([]),
|
|
21195
|
+
allowFreeText: external_exports.boolean().default(true),
|
|
21196
|
+
allowMultiple: external_exports.boolean().optional(),
|
|
21197
|
+
/** Authenticated platform user id; a share-link visitor cannot impersonate it. */
|
|
21198
|
+
requiredUserId: external_exports.string().trim().min(1).optional(),
|
|
21199
|
+
/** Holds the current Goal until an authenticated answer is admitted. */
|
|
21200
|
+
blocksGoal: external_exports.boolean().optional(),
|
|
21201
|
+
/** Informational deadline. Passing it never approves or answers the question. */
|
|
21202
|
+
dueAt: external_exports.string().datetime({ offset: true }).optional(),
|
|
21203
|
+
/** What the platform is asking for when the question is one of its own
|
|
21204
|
+
* requests rather than an agent's free question. Absent on an ordinary question. */
|
|
21205
|
+
kind: external_exports.enum(QUESTION_REQUEST_KINDS).optional(),
|
|
21206
|
+
/** What the request is about: the app to connect, for `connect_app`. */
|
|
21207
|
+
subject: external_exports.string().trim().min(1).max(200).optional()
|
|
21208
|
+
}).superRefine((value, context) => {
|
|
21209
|
+
if (new Set(value.options.map((option) => option.id)).size !== value.options.length) {
|
|
21210
|
+
context.addIssue({ code: "custom", message: "Option identifiers must be unique." });
|
|
21211
|
+
}
|
|
21212
|
+
if (!value.options.length && !value.allowFreeText) {
|
|
21213
|
+
context.addIssue({ code: "custom", message: "The question must allow an answer." });
|
|
21214
|
+
}
|
|
21215
|
+
});
|
|
21216
|
+
var replySchema = external_exports.object({
|
|
21217
|
+
question: questionSchema,
|
|
21218
|
+
answer: external_exports.union([external_exports.object({ optionId: external_exports.string() }), external_exports.object({ optionIds: external_exports.array(external_exports.string()) }), external_exports.object({ text: external_exports.string() })])
|
|
21219
|
+
});
|
|
21220
|
+
|
|
21221
|
+
// ../../packages/spec/src/import-base64.ts
|
|
21222
|
+
function isCanonicalBase64(value) {
|
|
21223
|
+
if (value.length === 0 || value.length % 4 !== 0) return false;
|
|
21224
|
+
const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
21225
|
+
for (let index = 0; index < value.length - padding; index += 1) {
|
|
21226
|
+
const code = value.charCodeAt(index);
|
|
21227
|
+
const alphabet = code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47;
|
|
21228
|
+
if (!alphabet) return false;
|
|
21229
|
+
}
|
|
21230
|
+
return Buffer.from(value, "base64").toString("base64") === value;
|
|
21231
|
+
}
|
|
21232
|
+
|
|
21233
|
+
// ../../packages/spec/src/import-redact.ts
|
|
21234
|
+
function ci(word) {
|
|
21235
|
+
return word.split("").map((c) => /[a-z]/i.test(c) ? `[${c.toUpperCase()}${c.toLowerCase()}]` : c).join("");
|
|
21236
|
+
}
|
|
21237
|
+
var UnsafeImportError = class extends Error {
|
|
21238
|
+
};
|
|
21239
|
+
var TEXT_ATTACHMENT_MEDIA_TYPES = [
|
|
21240
|
+
"application/json",
|
|
21241
|
+
"application/xml",
|
|
21242
|
+
"application/javascript",
|
|
21243
|
+
"application/ecmascript",
|
|
21244
|
+
"application/x-javascript",
|
|
21245
|
+
"application/yaml",
|
|
21246
|
+
"application/x-yaml",
|
|
21247
|
+
"application/x-www-form-urlencoded",
|
|
21248
|
+
"image/svg+xml",
|
|
21249
|
+
"application/toml",
|
|
21250
|
+
"application/x-toml",
|
|
21251
|
+
"application/sql",
|
|
21252
|
+
"application/x-sql",
|
|
21253
|
+
"application/pem-certificate-chain",
|
|
21254
|
+
"application/x-pem-file",
|
|
21255
|
+
"application/x-pem-key",
|
|
21256
|
+
"application/x-ndjson",
|
|
21257
|
+
"application/ndjson"
|
|
21258
|
+
];
|
|
21259
|
+
var textAttachmentMediaTypes = new Set(TEXT_ATTACHMENT_MEDIA_TYPES);
|
|
21260
|
+
function isTextMediaType(value) {
|
|
21261
|
+
const media = typeof value === "string" ? value.split(";", 1)[0].trim().toLowerCase() : "";
|
|
21262
|
+
return media.startsWith("text/") || textAttachmentMediaTypes.has(media) || /\+(?:json|xml)$/.test(media);
|
|
21263
|
+
}
|
|
21264
|
+
var MASK = "\u25CF\u25CF\u25CF\u25CF\u25CF";
|
|
21265
|
+
var SECRET_PATTERNS = [
|
|
21266
|
+
{ name: "anthropic key", source: "(?<![A-Za-z0-9_])(sk-ant-)[A-Za-z0-9_-]{10,}", replacement: `\\1${MASK}` },
|
|
21267
|
+
{ name: "openai key", source: "(?<![A-Za-z0-9_])(sk-proj-|sk-)[A-Za-z0-9_-]{8,}", replacement: `\\1${MASK}` },
|
|
21268
|
+
{ name: "github token", source: "(?<![A-Za-z0-9_])(gh[pousr]_)[A-Za-z0-9]{16,}", replacement: `\\1${MASK}` },
|
|
21269
|
+
{ name: "github fine-grained token", source: "(?<![A-Za-z0-9_])(github_pat_)[A-Za-z0-9_]{20,}", replacement: `\\1${MASK}` },
|
|
21270
|
+
{ name: "slack token", source: "(?<![A-Za-z0-9_])(xox[abeprs]-|xapp-)[A-Za-z0-9-]{10,}", replacement: `\\1${MASK}` },
|
|
21271
|
+
{ name: "agentsky token", source: "(?<![A-Za-z0-9_])(ast_)[A-Za-z0-9_-]{10,}", replacement: `\\1${MASK}` },
|
|
21272
|
+
{ name: "guild broker token", source: "(?<![A-Za-z0-9_])(gbk_)[A-Za-z0-9_-]{10,}", replacement: `\\1${MASK}` },
|
|
21273
|
+
{ name: "jwt", source: "(?<![A-Za-z0-9_])eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*", replacement: MASK },
|
|
21274
|
+
{ name: "private key", source: "-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\\s\\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY-----|$)", replacement: MASK },
|
|
21275
|
+
{ name: "google oauth token", source: "(ya29\\.)[A-Za-z0-9_-]{20,}", replacement: `\\1${MASK}` },
|
|
21276
|
+
{ name: "google api key", source: "(?<![A-Za-z0-9_])(AIza)[A-Za-z0-9_-]{30,}", replacement: `\\1${MASK}` },
|
|
21277
|
+
{ name: "aws key id", source: "(?<![A-Za-z0-9_])(AKIA)[0-9A-Z]{16}(?![A-Za-z0-9_])", replacement: `\\1${MASK}` },
|
|
21278
|
+
{ name: "import key", source: "(agt_)[A-Za-z0-9_-]{20,}", replacement: `\\1${MASK}` },
|
|
21279
|
+
{
|
|
21280
|
+
name: "database url",
|
|
21281
|
+
source: "(postgres://|postgresql://|mysql://|mongodb\\+srv://|mongodb://|redis://)([^:@/ ]+):[^@ ]+@",
|
|
21282
|
+
replacement: `\\1\\2:${MASK}@`
|
|
21283
|
+
},
|
|
21284
|
+
{ name: "bearer header", source: `(?<![A-Za-z0-9_])(${ci("bearer")}\\s+)[A-Za-z0-9._~+/=-]{16,}`, replacement: `\\1${MASK}` },
|
|
21285
|
+
{ name: "api key header", source: `(${ci("x-api-key")}: )[A-Za-z0-9_.=-]{16,}`, replacement: `\\1${MASK}` }
|
|
21286
|
+
];
|
|
21287
|
+
var compiled = SECRET_PATTERNS.map((p) => ({
|
|
21288
|
+
name: p.name,
|
|
21289
|
+
re: new RegExp(p.source, "g"),
|
|
21290
|
+
replacement: p.replacement.replace(/\\(\d)/g, "$$$1")
|
|
21291
|
+
}));
|
|
21292
|
+
function asPlainDecimal(token) {
|
|
21293
|
+
const m = /^([+-]?)(\d+)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$/.exec(token);
|
|
21294
|
+
if (!m) return null;
|
|
21295
|
+
const [, sign, whole, fraction = "", exponent = "0"] = m;
|
|
21296
|
+
const digits = whole + fraction;
|
|
21297
|
+
if (Math.abs(Number(exponent)) > 400) return /[1-9]/.test(digits) ? null : "0";
|
|
21298
|
+
let pointAt = whole.length + Number(exponent);
|
|
21299
|
+
let padded = digits;
|
|
21300
|
+
if (pointAt <= 0) {
|
|
21301
|
+
padded = "0".repeat(1 - pointAt) + digits;
|
|
21302
|
+
pointAt += 1 - pointAt;
|
|
21303
|
+
}
|
|
21304
|
+
if (pointAt >= padded.length) padded += "0".repeat(pointAt - padded.length + 1);
|
|
21305
|
+
const intPart = padded.slice(0, pointAt).replace(/^0+(?=\d)/, "");
|
|
21306
|
+
const fracPart = padded.slice(pointAt).replace(/0+$/, "");
|
|
21307
|
+
const value = fracPart ? `${intPart}.${fracPart}` : intPart;
|
|
21308
|
+
return (sign === "-" && /[1-9]/.test(digits) ? "-" : "") + value;
|
|
21309
|
+
}
|
|
21310
|
+
function changesWhenRead(token) {
|
|
21311
|
+
const value = Number(token);
|
|
21312
|
+
if (!Number.isFinite(value)) return true;
|
|
21313
|
+
const mine = asPlainDecimal(token);
|
|
21314
|
+
const theirs = asPlainDecimal(String(value));
|
|
21315
|
+
if (mine === null) return /[1-9]/.test(token);
|
|
21316
|
+
if (theirs === null) return true;
|
|
21317
|
+
return mine !== theirs;
|
|
21318
|
+
}
|
|
21319
|
+
function unsafeNumberSpans(line) {
|
|
21320
|
+
const spans = [];
|
|
21321
|
+
let inString = false;
|
|
21322
|
+
for (let i = 0; i < line.length; i += 1) {
|
|
21323
|
+
const c = line[i];
|
|
21324
|
+
if (inString) {
|
|
21325
|
+
if (c === "\\") i += 1;
|
|
21326
|
+
else if (c === '"') inString = false;
|
|
21327
|
+
continue;
|
|
21328
|
+
}
|
|
21329
|
+
if (c === '"') {
|
|
21330
|
+
inString = true;
|
|
21331
|
+
continue;
|
|
21332
|
+
}
|
|
21333
|
+
if (c !== "-" && (c < "0" || c > "9")) continue;
|
|
21334
|
+
const start = i;
|
|
21335
|
+
if (c === "-") i += 1;
|
|
21336
|
+
while (i < line.length && line[i] >= "0" && line[i] <= "9") i += 1;
|
|
21337
|
+
if (line[i] === ".") {
|
|
21338
|
+
i += 1;
|
|
21339
|
+
while (i < line.length && line[i] >= "0" && line[i] <= "9") i += 1;
|
|
21340
|
+
}
|
|
21341
|
+
if (line[i] === "e" || line[i] === "E") {
|
|
21342
|
+
i += 1;
|
|
21343
|
+
if (line[i] === "+" || line[i] === "-") i += 1;
|
|
21344
|
+
while (i < line.length && line[i] >= "0" && line[i] <= "9") i += 1;
|
|
21345
|
+
}
|
|
21346
|
+
const token = line.slice(start, i);
|
|
21347
|
+
if (changesWhenRead(token)) spans.push([start, i]);
|
|
21348
|
+
i -= 1;
|
|
21349
|
+
}
|
|
21350
|
+
return spans;
|
|
21351
|
+
}
|
|
21352
|
+
function withPreservedNumbers(line) {
|
|
21353
|
+
const spans = unsafeNumberSpans(line);
|
|
21354
|
+
if (spans.length === 0) return { parse: () => JSON.parse(line), serialize: (v) => JSON.stringify(v) };
|
|
21355
|
+
let sentinel = "n";
|
|
21356
|
+
while (line.includes(`@@${sentinel}`)) sentinel += "n";
|
|
21357
|
+
const token = (index) => `@@${sentinel}${index}@@`;
|
|
21358
|
+
let out = "";
|
|
21359
|
+
let cursor = 0;
|
|
21360
|
+
const originals = [];
|
|
21361
|
+
spans.forEach(([start, end], index) => {
|
|
21362
|
+
out += line.slice(cursor, start) + JSON.stringify(token(index));
|
|
21363
|
+
originals.push(line.slice(start, end));
|
|
21364
|
+
cursor = end;
|
|
21365
|
+
});
|
|
21366
|
+
out += line.slice(cursor);
|
|
21367
|
+
return {
|
|
21368
|
+
parse: () => JSON.parse(out),
|
|
21369
|
+
serialize: (value) => {
|
|
21370
|
+
let text = JSON.stringify(value);
|
|
21371
|
+
originals.forEach((original, index) => {
|
|
21372
|
+
text = text.split(JSON.stringify(token(index))).join(original);
|
|
21373
|
+
});
|
|
21374
|
+
return text;
|
|
21375
|
+
}
|
|
21376
|
+
};
|
|
21377
|
+
}
|
|
21378
|
+
function hasDuplicateJsonKeys(line) {
|
|
21379
|
+
const stack = [];
|
|
21380
|
+
const skipSpace = (at) => {
|
|
21381
|
+
while (at < line.length && /\s/.test(line[at])) at += 1;
|
|
21382
|
+
return at;
|
|
21383
|
+
};
|
|
21384
|
+
for (let i = 0; i < line.length; i += 1) {
|
|
21385
|
+
const c = line[i];
|
|
21386
|
+
if (c === '"') {
|
|
21387
|
+
const start = i;
|
|
21388
|
+
i += 1;
|
|
21389
|
+
while (i < line.length) {
|
|
21390
|
+
if (line[i] === "\\") {
|
|
21391
|
+
i += 2;
|
|
21392
|
+
continue;
|
|
21393
|
+
}
|
|
21394
|
+
if (line[i] === '"') break;
|
|
21395
|
+
i += 1;
|
|
21396
|
+
}
|
|
21397
|
+
const frame = stack[stack.length - 1];
|
|
21398
|
+
const colon = skipSpace(i + 1);
|
|
21399
|
+
if (frame?.kind === "object" && frame.expectingKey && line[colon] === ":") {
|
|
21400
|
+
try {
|
|
21401
|
+
const key = JSON.parse(line.slice(start, i + 1));
|
|
21402
|
+
if (frame.keys.has(key)) return true;
|
|
21403
|
+
frame.keys.add(key);
|
|
21404
|
+
frame.expectingKey = false;
|
|
21405
|
+
} catch {
|
|
21406
|
+
}
|
|
21407
|
+
}
|
|
21408
|
+
continue;
|
|
21409
|
+
}
|
|
21410
|
+
if (c === "{") stack.push({ kind: "object", expectingKey: true, keys: /* @__PURE__ */ new Set() });
|
|
21411
|
+
else if (c === "[") stack.push({ kind: "array", expectingKey: false });
|
|
21412
|
+
else if (c === "}" || c === "]") stack.pop();
|
|
21413
|
+
else if (c === "," && stack.at(-1)?.kind === "object") stack.at(-1).expectingKey = true;
|
|
21414
|
+
}
|
|
21415
|
+
return false;
|
|
21416
|
+
}
|
|
21417
|
+
var FIELD_ASSIGNMENTS = new RegExp(
|
|
21418
|
+
String.raw`(?<![A-Za-z0-9_.])(\\{0,8}["']?([A-Za-z_][A-Za-z0-9_.-]{0,255})\\{0,8}["']?\s{0,8}\\{0,8}[:=]\\{0,8}\s{0,8}\\{0,8}(["']?))`,
|
|
21419
|
+
"g"
|
|
21420
|
+
);
|
|
21421
|
+
var JSON_NUMBER = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
21422
|
+
var COMPLETE_MASKED_VALUE = new RegExp(`^(?:${MASK}|${ci("bearer")} ${MASK})$`);
|
|
21423
|
+
function codeIdentifierEnd(value, at) {
|
|
21424
|
+
if (!/[A-Za-z_$]/.test(value[at] ?? "")) return -1;
|
|
21425
|
+
at += 1;
|
|
21426
|
+
while (/[A-Za-z0-9_$]/.test(value[at] ?? "")) at += 1;
|
|
21427
|
+
return at;
|
|
21428
|
+
}
|
|
21429
|
+
function codeGroupEnd(value, at) {
|
|
21430
|
+
const pairs = { "(": ")", "[": "]", "{": "}" };
|
|
21431
|
+
const stack = [pairs[value[at]]];
|
|
21432
|
+
for (let i = at + 1; i < value.length; i += 1) {
|
|
21433
|
+
const c = value[i];
|
|
21434
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
21435
|
+
for (i += 1; i < value.length; i += 1) {
|
|
21436
|
+
if (value[i] === "\\") i += 1;
|
|
21437
|
+
else if (value[i] === c) break;
|
|
21438
|
+
}
|
|
21439
|
+
if (i >= value.length) return -1;
|
|
21440
|
+
continue;
|
|
21441
|
+
}
|
|
21442
|
+
if (pairs[c]) stack.push(pairs[c]);
|
|
21443
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
21444
|
+
if (stack.pop() !== c) return -1;
|
|
21445
|
+
if (stack.length === 0) return i + 1;
|
|
21446
|
+
}
|
|
21447
|
+
}
|
|
21448
|
+
return -1;
|
|
21449
|
+
}
|
|
21450
|
+
function credentialRhsBoundary(value, start, lineEnd) {
|
|
21451
|
+
const pairs = { "(": ")", "[": "]", "{": "}" };
|
|
21452
|
+
const stack = [];
|
|
21453
|
+
for (let i = start; i < lineEnd; i += 1) {
|
|
21454
|
+
const c = value[i];
|
|
21455
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
21456
|
+
for (i += 1; i < lineEnd; i += 1) {
|
|
21457
|
+
if (value[i] === "\\") i += 1;
|
|
21458
|
+
else if (value[i] === c) break;
|
|
21459
|
+
}
|
|
21460
|
+
if (i >= lineEnd) return { end: lineEnd, unsafe: true };
|
|
21461
|
+
continue;
|
|
21462
|
+
}
|
|
21463
|
+
if (c === "/") return { end: lineEnd, unsafe: true };
|
|
21464
|
+
if (pairs[c]) stack.push(pairs[c]);
|
|
21465
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
21466
|
+
if (stack.pop() !== c) return { end: lineEnd, unsafe: true };
|
|
21467
|
+
}
|
|
21468
|
+
}
|
|
21469
|
+
return { end: lineEnd, unsafe: stack.length > 0 };
|
|
21470
|
+
}
|
|
21471
|
+
function maskExpressionLiterals(value) {
|
|
21472
|
+
let out = "";
|
|
21473
|
+
const groups = [];
|
|
21474
|
+
let previousNonWhitespace = "";
|
|
21475
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
21476
|
+
const c = value[i];
|
|
21477
|
+
if (c === "(" || c === "{") {
|
|
21478
|
+
groups.push(c);
|
|
21479
|
+
out += c;
|
|
21480
|
+
previousNonWhitespace = c;
|
|
21481
|
+
continue;
|
|
21482
|
+
}
|
|
21483
|
+
if (c === "[") {
|
|
21484
|
+
let kind = /[A-Za-z0-9_$.)\]}]/.test(previousNonWhitespace) ? "index" : "array";
|
|
21485
|
+
if (kind === "index") {
|
|
21486
|
+
const end = codeGroupEnd(value, i);
|
|
21487
|
+
if (end < 0) return null;
|
|
21488
|
+
const content = value.slice(i + 1, end - 1).trim();
|
|
21489
|
+
if (/^[-+.0-9]/.test(content) && !/^(?:0|[1-9][0-9]*)$/.test(content)) return null;
|
|
21490
|
+
if (/^(?:0|[1-9][0-9]*)$/.test(content)) kind = "index-number";
|
|
21491
|
+
}
|
|
21492
|
+
groups.push(kind);
|
|
21493
|
+
out += c;
|
|
21494
|
+
previousNonWhitespace = c;
|
|
21495
|
+
continue;
|
|
21496
|
+
}
|
|
21497
|
+
if (c === ")" || c === "]" || c === "}") {
|
|
21498
|
+
groups.pop();
|
|
21499
|
+
out += c;
|
|
21500
|
+
previousNonWhitespace = c;
|
|
21501
|
+
continue;
|
|
21502
|
+
}
|
|
21503
|
+
const previousIsIdentifier = i > 0 && /[A-Za-z0-9_$]/.test(value[i - 1]);
|
|
21504
|
+
const numberLooking = !previousIsIdentifier && (/[0-9]/.test(c) || c === "." && /[0-9]/.test(value[i + 1] ?? "") || (c === "+" || c === "-") && (/[0-9]/.test(value[i + 1] ?? "") || value[i + 1] === "." && /[0-9]/.test(value[i + 2] ?? "")));
|
|
21505
|
+
if (numberLooking && groups.at(-1) !== "index-number") return null;
|
|
21506
|
+
if (c !== '"' && c !== "'" && c !== "`") {
|
|
21507
|
+
out += c;
|
|
21508
|
+
if (!/\s/.test(c)) previousNonWhitespace = c;
|
|
21509
|
+
continue;
|
|
21510
|
+
}
|
|
21511
|
+
const start = i;
|
|
21512
|
+
for (i += 1; i < value.length; i += 1) {
|
|
21513
|
+
if (value[i] === "\\") i += 1;
|
|
21514
|
+
else if (value[i] === c) break;
|
|
21515
|
+
}
|
|
21516
|
+
const literal2 = value.slice(start, i + 1);
|
|
21517
|
+
out += groups.at(-1)?.startsWith("index") ? literal2 : `${c}${MASK}${c}`;
|
|
21518
|
+
previousNonWhitespace = c;
|
|
21519
|
+
}
|
|
21520
|
+
return out;
|
|
21521
|
+
}
|
|
21522
|
+
function rewriteCodeExpression(value, declaration) {
|
|
21523
|
+
let source = value.trim();
|
|
21524
|
+
const semicolon = source.endsWith(";");
|
|
21525
|
+
if (semicolon) source = source.slice(0, -1).trimEnd();
|
|
21526
|
+
if (/^(?:null|undefined)$/.test(source)) return value;
|
|
21527
|
+
if (source.startsWith("`")) {
|
|
21528
|
+
if (codeGroupEnd(`(${source})`, 0) !== source.length + 2) return null;
|
|
21529
|
+
return value.replace(source, `\`${MASK}\``);
|
|
21530
|
+
}
|
|
21531
|
+
const awaitPrefix = /^await\s+/.exec(source)?.[0] ?? "";
|
|
21532
|
+
if (awaitPrefix) source = source.slice(awaitPrefix.length);
|
|
21533
|
+
if (source.startsWith("[") || source.startsWith("{")) {
|
|
21534
|
+
if (codeGroupEnd(source, 0) !== source.length) return null;
|
|
21535
|
+
const full2 = semicolon ? `${MASK};` : MASK;
|
|
21536
|
+
return value.replace(value.trim(), full2);
|
|
21537
|
+
}
|
|
21538
|
+
let at = codeIdentifierEnd(source, 0);
|
|
21539
|
+
if (at < 0) return null;
|
|
21540
|
+
let syntax = false;
|
|
21541
|
+
while (at < source.length) {
|
|
21542
|
+
if (source.startsWith("?.", at)) {
|
|
21543
|
+
at += 2;
|
|
21544
|
+
if (source[at] === "[" || source[at] === "(") {
|
|
21545
|
+
const end2 = codeGroupEnd(source, at);
|
|
21546
|
+
if (end2 < 0) return null;
|
|
21547
|
+
syntax = true;
|
|
21548
|
+
at = end2;
|
|
21549
|
+
continue;
|
|
21550
|
+
}
|
|
21551
|
+
} else if (source[at] === ".") at += 1;
|
|
21552
|
+
else if (source[at] === "[" || source[at] === "(") {
|
|
21553
|
+
const end2 = codeGroupEnd(source, at);
|
|
21554
|
+
if (end2 < 0) return null;
|
|
21555
|
+
syntax = true;
|
|
21556
|
+
at = end2;
|
|
21557
|
+
continue;
|
|
21558
|
+
} else return null;
|
|
21559
|
+
const end = codeIdentifierEnd(source, at);
|
|
21560
|
+
if (end < 0) return null;
|
|
21561
|
+
syntax = true;
|
|
21562
|
+
at = end;
|
|
21563
|
+
}
|
|
21564
|
+
if (!syntax && !declaration) return null;
|
|
21565
|
+
const rewritten = maskExpressionLiterals(source);
|
|
21566
|
+
if (rewritten === null) return null;
|
|
21567
|
+
const full = semicolon ? `${awaitPrefix}${rewritten};` : `${awaitPrefix}${rewritten}`;
|
|
21568
|
+
return value.replace(value.trim(), full);
|
|
21569
|
+
}
|
|
21570
|
+
function redactPlainText(text) {
|
|
21571
|
+
const hits = {};
|
|
21572
|
+
let out = redactFieldAssignments(text, () => {
|
|
21573
|
+
hits["secret field"] = (hits["secret field"] ?? 0) + 1;
|
|
21574
|
+
});
|
|
21575
|
+
for (const p of compiled) {
|
|
21576
|
+
p.re.lastIndex = 0;
|
|
21577
|
+
out = out.replace(p.re, (...m) => {
|
|
21578
|
+
hits[p.name] = (hits[p.name] ?? 0) + 1;
|
|
21579
|
+
return p.replacement.replace(/\$(\d)/g, (_, i) => String(m[Number(i)] ?? ""));
|
|
21580
|
+
});
|
|
21581
|
+
}
|
|
21582
|
+
return { text: out, hits };
|
|
21583
|
+
}
|
|
21584
|
+
function nameSegments(name) {
|
|
21585
|
+
return name.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.toLowerCase());
|
|
21586
|
+
}
|
|
21587
|
+
var CREDENTIAL_WORDS = /* @__PURE__ */ new Set([
|
|
21588
|
+
"token",
|
|
21589
|
+
"secret",
|
|
21590
|
+
"secrets",
|
|
21591
|
+
"password",
|
|
21592
|
+
"passwords",
|
|
21593
|
+
"passwd",
|
|
21594
|
+
"credential",
|
|
21595
|
+
"credentials",
|
|
21596
|
+
"authorization",
|
|
21597
|
+
"cookie",
|
|
21598
|
+
"cookies"
|
|
21599
|
+
]);
|
|
21600
|
+
var KEY_OWNERS = /* @__PURE__ */ new Set(["api", "access", "private", "secret", "signing", "encryption"]);
|
|
21601
|
+
var COUNT_QUALIFIERS = /* @__PURE__ */ new Set(["max", "min", "num", "total", "input", "output", "cache", "prompt", "completion", "reasoning", "thinking", "used", "remaining", "limit", "budget"]);
|
|
21602
|
+
var COUNT_SUFFIXES = /* @__PURE__ */ new Set(["count", "counts", "used", "usage", "remaining", "limit", "limits", "budget", "price", "cost", "total", "size", "length"]);
|
|
21603
|
+
function ownsKey(segment) {
|
|
21604
|
+
if (!segment) return false;
|
|
21605
|
+
for (const owner of KEY_OWNERS) if (segment === owner || segment.endsWith(owner)) return true;
|
|
21606
|
+
return false;
|
|
21607
|
+
}
|
|
21608
|
+
function isCredentialField(name) {
|
|
21609
|
+
const segments = nameSegments(name);
|
|
21610
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
21611
|
+
const segment = segments[i];
|
|
21612
|
+
if (segment === "token") {
|
|
21613
|
+
if (!COUNT_QUALIFIERS.has(segments[i - 1] ?? "") && !COUNT_SUFFIXES.has(segments[i + 1] ?? "")) return true;
|
|
21614
|
+
continue;
|
|
21615
|
+
}
|
|
21616
|
+
if (CREDENTIAL_WORDS.has(segment)) return true;
|
|
21617
|
+
if ((segment === "key" || segment === "keys") && i > 0 && ownsKey(segments[i - 1])) return true;
|
|
21618
|
+
if (segment === "id" && i > 0 && segments[i - 1] === "session") return true;
|
|
21619
|
+
if (segment === "sessionid" || segment === "apikey" || segment === "accesskey" || segment === "privatekey") return true;
|
|
21620
|
+
}
|
|
21621
|
+
return false;
|
|
21622
|
+
}
|
|
21623
|
+
function redactFieldAssignments(value, onHit) {
|
|
21624
|
+
FIELD_ASSIGNMENTS.lastIndex = 0;
|
|
21625
|
+
let out = "";
|
|
21626
|
+
let copiedThrough = 0;
|
|
21627
|
+
for (let match = FIELD_ASSIGNMENTS.exec(value); match; match = FIELD_ASSIGNMENTS.exec(value)) {
|
|
21628
|
+
const name = match[2];
|
|
21629
|
+
if (!isCredentialField(name)) continue;
|
|
21630
|
+
const valueStart = FIELD_ASSIGNMENTS.lastIndex;
|
|
21631
|
+
const quote = match[3];
|
|
21632
|
+
const limit = value.length;
|
|
21633
|
+
const lineEnd = value.slice(valueStart, limit).search(/[\r\n]/);
|
|
21634
|
+
const boundedLineEnd = lineEnd < 0 ? limit : valueStart + lineEnd;
|
|
21635
|
+
const boundary = quote ? { end: boundedLineEnd, unsafe: false } : credentialRhsBoundary(value, valueStart, boundedLineEnd);
|
|
21636
|
+
const expressionEnd = boundary.end;
|
|
21637
|
+
const lineStart = value.lastIndexOf("\n", match.index - 1) + 1;
|
|
21638
|
+
const declaration = /(?:^|[;{}]\s*)(?:const|let|var)\s+$/.test(value.slice(lineStart, match.index));
|
|
21639
|
+
const expression = quote || boundary.unsafe ? null : rewriteCodeExpression(value.slice(valueStart, expressionEnd), declaration);
|
|
21640
|
+
if (expression !== null) {
|
|
21641
|
+
if (expression !== value.slice(valueStart, expressionEnd)) {
|
|
21642
|
+
out += value.slice(copiedThrough, valueStart) + expression;
|
|
21643
|
+
copiedThrough = expressionEnd;
|
|
21644
|
+
onHit(value.slice(valueStart, expressionEnd));
|
|
21645
|
+
}
|
|
21646
|
+
FIELD_ASSIGNMENTS.lastIndex = expressionEnd;
|
|
21647
|
+
continue;
|
|
21648
|
+
}
|
|
21649
|
+
if (!quote) {
|
|
21650
|
+
const fieldValue2 = value.slice(valueStart, expressionEnd);
|
|
21651
|
+
const trimmed2 = fieldValue2.trim();
|
|
21652
|
+
if (!COMPLETE_MASKED_VALUE.test(trimmed2)) {
|
|
21653
|
+
out += value.slice(copiedThrough, valueStart) + (JSON_NUMBER.test(trimmed2) ? `"${MASK}"` : MASK);
|
|
21654
|
+
copiedThrough = expressionEnd;
|
|
21655
|
+
onHit(fieldValue2);
|
|
21656
|
+
}
|
|
21657
|
+
FIELD_ASSIGNMENTS.lastIndex = expressionEnd;
|
|
21658
|
+
continue;
|
|
21659
|
+
}
|
|
21660
|
+
let valueEnd = valueStart;
|
|
21661
|
+
if (quote) {
|
|
21662
|
+
let openingSlashes = 0;
|
|
21663
|
+
for (let i = match[1].length - 2; i >= 0 && match[1][i] === "\\"; i -= 1) openingSlashes += 1;
|
|
21664
|
+
while (valueEnd < limit && value[valueEnd] !== "\r" && value[valueEnd] !== "\n") {
|
|
21665
|
+
if (value[valueEnd] === quote) {
|
|
21666
|
+
let syntaxStart = valueEnd;
|
|
21667
|
+
while (syntaxStart > valueStart && value[syntaxStart - 1] === "\\") syntaxStart -= 1;
|
|
21668
|
+
if (valueEnd - syntaxStart === openingSlashes) {
|
|
21669
|
+
valueEnd = syntaxStart;
|
|
21670
|
+
break;
|
|
21671
|
+
}
|
|
21672
|
+
}
|
|
21673
|
+
valueEnd += 1;
|
|
21674
|
+
}
|
|
21675
|
+
} else {
|
|
21676
|
+
while (valueEnd < limit && !/["'\r\n,}]/.test(value[valueEnd])) valueEnd += 1;
|
|
21677
|
+
}
|
|
21678
|
+
if (valueEnd === valueStart) continue;
|
|
21679
|
+
const fieldValue = value.slice(valueStart, valueEnd);
|
|
21680
|
+
const trimmed = fieldValue.trim();
|
|
21681
|
+
if (COMPLETE_MASKED_VALUE.test(trimmed)) continue;
|
|
21682
|
+
out += value.slice(copiedThrough, valueStart) + (!match[3] && JSON_NUMBER.test(trimmed) ? `"${MASK}"` : MASK);
|
|
21683
|
+
copiedThrough = valueEnd;
|
|
21684
|
+
onHit(fieldValue);
|
|
21685
|
+
FIELD_ASSIGNMENTS.lastIndex = valueEnd;
|
|
21686
|
+
}
|
|
21687
|
+
return copiedThrough ? out + value.slice(copiedThrough) : value;
|
|
21688
|
+
}
|
|
21689
|
+
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
21690
|
+
function base64Bytes(value) {
|
|
21691
|
+
const clean = value.endsWith("==") ? value.slice(0, -2) : value.endsWith("=") ? value.slice(0, -1) : value;
|
|
21692
|
+
const out = [];
|
|
21693
|
+
let bits = 0;
|
|
21694
|
+
let acc = 0;
|
|
21695
|
+
for (const ch of clean) {
|
|
21696
|
+
const index = B64.indexOf(ch);
|
|
21697
|
+
if (index < 0) throw new Error("not base64");
|
|
21698
|
+
acc = acc << 6 | index;
|
|
21699
|
+
bits += 6;
|
|
21700
|
+
if (bits >= 8) {
|
|
21701
|
+
bits -= 8;
|
|
21702
|
+
out.push(acc >> bits & 255);
|
|
21703
|
+
}
|
|
21704
|
+
}
|
|
21705
|
+
return Uint8Array.from(out);
|
|
21706
|
+
}
|
|
21707
|
+
function bytesBase64(bytes) {
|
|
21708
|
+
let out = "";
|
|
21709
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
21710
|
+
const a = bytes[i], b = bytes[i + 1], c = bytes[i + 2];
|
|
21711
|
+
out += B64[a >> 2] + B64[(a & 3) << 4 | (b ?? 0) >> 4] + (b === void 0 ? "=" : B64[(b & 15) << 2 | (c ?? 0) >> 6]) + (c === void 0 ? "=" : B64[c & 63]);
|
|
21712
|
+
}
|
|
21713
|
+
return out;
|
|
21714
|
+
}
|
|
21715
|
+
function redactLine(line, options = {}) {
|
|
21716
|
+
const hits = {};
|
|
21717
|
+
function fieldCredentials(value) {
|
|
21718
|
+
return redactFieldAssignments(value, (fieldValue) => {
|
|
21719
|
+
const kind = /^[A-Za-z0-9_/+.=-]{12,}$/.test(fieldValue) ? "env assignment" : "secret field";
|
|
21720
|
+
hits[kind] = (hits[kind] ?? 0) + 1;
|
|
21721
|
+
});
|
|
21722
|
+
}
|
|
21723
|
+
function redactPatterns(value) {
|
|
21724
|
+
let out = value;
|
|
21725
|
+
for (const p of compiled) {
|
|
21726
|
+
p.re.lastIndex = 0;
|
|
21727
|
+
out = out.replace(p.re, (...m) => {
|
|
21728
|
+
hits[p.name] = (hits[p.name] ?? 0) + 1;
|
|
21729
|
+
return p.replacement.replace(/\$(\d)/g, (_, i) => String(m[Number(i)] ?? ""));
|
|
21730
|
+
});
|
|
21731
|
+
}
|
|
21732
|
+
return fieldCredentials(out);
|
|
21733
|
+
}
|
|
21734
|
+
function redactDuplicateRecord(value) {
|
|
21735
|
+
let out = value;
|
|
21736
|
+
for (const p of compiled) {
|
|
21737
|
+
p.re.lastIndex = 0;
|
|
21738
|
+
out = out.replace(p.re, (...m) => {
|
|
21739
|
+
hits[p.name] = (hits[p.name] ?? 0) + 1;
|
|
21740
|
+
return p.replacement.replace(/\$(\d)/g, (_, i) => String(m[Number(i)] ?? ""));
|
|
21741
|
+
});
|
|
21742
|
+
}
|
|
21743
|
+
return out.replace(/("(?:\\.|[^"\\])*"\s*:\s*")((?:\\.|[^"\\])*)(")/g, (whole, prefix, fieldValue, suffix) => {
|
|
21744
|
+
const rawKey = prefix.slice(0, prefix.indexOf(":")).trim();
|
|
21745
|
+
let key;
|
|
21746
|
+
try {
|
|
21747
|
+
key = JSON.parse(rawKey);
|
|
21748
|
+
} catch {
|
|
21749
|
+
return whole;
|
|
21750
|
+
}
|
|
21751
|
+
if (!isCredentialField(key) || fieldValue === MASK) return whole;
|
|
21752
|
+
hits["secret field"] = (hits["secret field"] ?? 0) + 1;
|
|
21753
|
+
return prefix + MASK + suffix;
|
|
21754
|
+
});
|
|
21755
|
+
}
|
|
21756
|
+
function restoreHits(snapshot) {
|
|
21757
|
+
for (const key of Object.keys(hits)) delete hits[key];
|
|
21758
|
+
Object.assign(hits, snapshot);
|
|
21759
|
+
}
|
|
21760
|
+
function redactText(value) {
|
|
21761
|
+
const uri = BASE64_DATA_URI_PREFIX.exec(value);
|
|
21762
|
+
if (uri && isCanonicalBase64(uri[2])) {
|
|
21763
|
+
const prefix = uri[1];
|
|
21764
|
+
const metadata = redactPlainText(prefix.slice(0, -8));
|
|
21765
|
+
for (const [kind, n] of Object.entries(metadata.hits)) hits[kind] = (hits[kind] ?? 0) + n;
|
|
21766
|
+
const mediaType = /^data:([^;,]*)/i.exec(prefix)?.[1] || "text/plain";
|
|
21767
|
+
return metadata.text + prefix.slice(-8) + recodePayload(uri[2], mediaType);
|
|
21768
|
+
}
|
|
21769
|
+
const trimmed = value.trim();
|
|
21770
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
21771
|
+
if (hasDuplicateJsonKeys(value)) throw new UnsafeImportError("Duplicate keys in serialized JSON are not safe to import.");
|
|
21772
|
+
const snapshot = { ...hits };
|
|
21773
|
+
try {
|
|
21774
|
+
const json3 = withPreservedNumbers(value);
|
|
21775
|
+
if (json3) {
|
|
21776
|
+
const parsed = json3.parse();
|
|
21777
|
+
const walked = walk(parsed);
|
|
21778
|
+
if (JSON.stringify(walked) !== JSON.stringify(parsed)) return json3.serialize(walked);
|
|
21779
|
+
restoreHits(snapshot);
|
|
21780
|
+
return value;
|
|
21781
|
+
}
|
|
21782
|
+
} catch (error61) {
|
|
21783
|
+
if (error61 instanceof UnsafeImportError) throw error61;
|
|
21784
|
+
restoreHits(snapshot);
|
|
21785
|
+
}
|
|
21786
|
+
}
|
|
21787
|
+
return redactPatterns(value);
|
|
21788
|
+
}
|
|
21789
|
+
function recodePayload(data, mediaType) {
|
|
21790
|
+
const bytes = base64Bytes(data);
|
|
21791
|
+
if (!isTextMediaType(mediaType)) return data;
|
|
21792
|
+
let content;
|
|
21793
|
+
try {
|
|
21794
|
+
content = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
21795
|
+
} catch {
|
|
21796
|
+
throw new UnsafeImportError("A declared text attachment is not valid UTF-8.");
|
|
21797
|
+
}
|
|
21798
|
+
const cleaned = redactText(content);
|
|
21799
|
+
return cleaned === content ? data : bytesBase64(new TextEncoder().encode(cleaned));
|
|
21800
|
+
}
|
|
21801
|
+
function maskDescendants(value) {
|
|
21802
|
+
if (typeof value === "string") return value === MASK ? value : MASK;
|
|
21803
|
+
if (typeof value === "number" || typeof value === "boolean") return MASK;
|
|
21804
|
+
if (Array.isArray(value)) return value.map(maskDescendants);
|
|
21805
|
+
if (value && typeof value === "object") {
|
|
21806
|
+
const result = {};
|
|
21807
|
+
for (const [key, item] of Object.entries(value)) {
|
|
21808
|
+
const name = redactText(key);
|
|
21809
|
+
let at = name;
|
|
21810
|
+
for (let n = 2; at in result; n += 1) at = `${name} (${n})`;
|
|
21811
|
+
result[at] = maskDescendants(item);
|
|
21812
|
+
}
|
|
21813
|
+
return result;
|
|
21814
|
+
}
|
|
21815
|
+
return value;
|
|
21816
|
+
}
|
|
21817
|
+
function walk(value) {
|
|
21818
|
+
if (typeof value === "string") return redactText(value);
|
|
21819
|
+
if (Array.isArray(value)) return value.map(walk);
|
|
21820
|
+
if (!value || typeof value !== "object") return value;
|
|
21821
|
+
const node2 = value;
|
|
21822
|
+
const payload = isFilePayload(node2);
|
|
21823
|
+
const out = {};
|
|
21824
|
+
const place = (name, item) => {
|
|
21825
|
+
let at = name;
|
|
21826
|
+
for (let n = 2; at in out; n += 1) at = `${name} (${n})`;
|
|
21827
|
+
out[at] = item;
|
|
21828
|
+
};
|
|
21829
|
+
for (const [key, item] of Object.entries(node2)) {
|
|
21830
|
+
const name = redactText(key);
|
|
21831
|
+
if (payload && key === "data") {
|
|
21832
|
+
place(name, recodePayload(item, node2.media_type ?? node2.mime_type));
|
|
21833
|
+
continue;
|
|
21834
|
+
}
|
|
21835
|
+
if (isCredentialField(key) && item !== null && item !== void 0) {
|
|
21836
|
+
const masked = maskDescendants(item);
|
|
21837
|
+
if (JSON.stringify(masked) !== JSON.stringify(item)) {
|
|
21838
|
+
hits["secret field"] = (hits["secret field"] ?? 0) + 1;
|
|
21839
|
+
}
|
|
21840
|
+
place(name, masked);
|
|
21841
|
+
continue;
|
|
21842
|
+
}
|
|
21843
|
+
place(name, walk(item));
|
|
21844
|
+
}
|
|
21845
|
+
return out;
|
|
21846
|
+
}
|
|
21847
|
+
if (hasDuplicateJsonKeys(line)) return { line: redactDuplicateRecord(line), hits };
|
|
21848
|
+
const json2 = withPreservedNumbers(line);
|
|
21849
|
+
if (!json2) {
|
|
21850
|
+
if (options.requireStructured) throw new Error("Could not preserve JSON numbers during redaction.");
|
|
21851
|
+
return { line: redactPatterns(line), hits };
|
|
21852
|
+
}
|
|
21853
|
+
try {
|
|
21854
|
+
const walked = json2.serialize(walk(json2.parse()));
|
|
21855
|
+
return { line: Object.keys(hits).length ? walked : line, hits };
|
|
21856
|
+
} catch (error61) {
|
|
21857
|
+
if (options.requireStructured || error61 instanceof UnsafeImportError) throw error61;
|
|
21858
|
+
return { line: redactPatterns(line), hits };
|
|
21859
|
+
}
|
|
21860
|
+
}
|
|
21861
|
+
var BASE64_DATA_URI_PREFIX = /^(data:[^,]*;base64,)([\s\S]*)(?![\s\S])/i;
|
|
21862
|
+
function isFilePayload(node2) {
|
|
21863
|
+
return typeof node2.data === "string" && node2.data !== "" && (typeof node2.media_type === "string" || typeof node2.mime_type === "string" || node2.type === "import.resource" || node2.type === "base64");
|
|
21864
|
+
}
|
|
21865
|
+
|
|
21154
21866
|
// ../../packages/spec/src/index.ts
|
|
21155
21867
|
var NATIVE_AGENT_TYPES = [
|
|
21156
21868
|
"hermes",
|
|
@@ -21174,6 +21886,7 @@ var LEGACY_CAPABILITY_IDS = [
|
|
|
21174
21886
|
"exa.contents",
|
|
21175
21887
|
"tinyfish.fetch",
|
|
21176
21888
|
"tinyfish.browser",
|
|
21889
|
+
"tinyfish.agent",
|
|
21177
21890
|
"dataforseo.serp",
|
|
21178
21891
|
"dataforseo.ai-keywords",
|
|
21179
21892
|
"dataforseo.llm-responses",
|
|
@@ -21344,6 +22057,8 @@ var allowedLlms = {
|
|
|
21344
22057
|
"kimi-k3",
|
|
21345
22058
|
"kimi-k2.7-code",
|
|
21346
22059
|
"grok-4.6",
|
|
22060
|
+
"muse-spark-1.1",
|
|
22061
|
+
"muse-spark-1.2",
|
|
21347
22062
|
"claude-opus-5-5",
|
|
21348
22063
|
"claude-opus-5",
|
|
21349
22064
|
"claude-fable-5-1",
|
|
@@ -21397,6 +22112,8 @@ var allowedLlms = {
|
|
|
21397
22112
|
"kimi-k3",
|
|
21398
22113
|
"kimi-k2.7-code",
|
|
21399
22114
|
"grok-4.6",
|
|
22115
|
+
"muse-spark-1.1",
|
|
22116
|
+
"muse-spark-1.2",
|
|
21400
22117
|
"claude-opus-5-5",
|
|
21401
22118
|
"claude-opus-5",
|
|
21402
22119
|
"claude-fable-5-1",
|
|
@@ -21491,6 +22208,10 @@ function canonicalCapabilityId(value) {
|
|
|
21491
22208
|
}
|
|
21492
22209
|
var capabilityIdInputSchema = external_exports.preprocess(canonicalCapabilityId, external_exports.enum(CAPABILITY_IDS));
|
|
21493
22210
|
var capabilitiesSchema = external_exports.array(capabilityIdInputSchema).default([]);
|
|
22211
|
+
var CAPABILITY_PERMISSION_POLICIES = ["always_allow", "always_ask", "auto"];
|
|
22212
|
+
var capabilityPermissionPolicySchema = external_exports.enum(
|
|
22213
|
+
CAPABILITY_PERMISSION_POLICIES
|
|
22214
|
+
);
|
|
21494
22215
|
var basicsSchema = external_exports.object({
|
|
21495
22216
|
name: external_exports.string().trim().min(1, "Give your agent a name."),
|
|
21496
22217
|
description: external_exports.string().default("")
|
|
@@ -21567,6 +22288,30 @@ var mcpServerSchema = external_exports.object({
|
|
|
21567
22288
|
tools: mcpToolFilterSchema.optional()
|
|
21568
22289
|
});
|
|
21569
22290
|
var mcpServersSchema = external_exports.array(mcpServerSchema).max(20);
|
|
22291
|
+
var HOOK_EVENTS = [
|
|
22292
|
+
"pre_session_start",
|
|
22293
|
+
"session_start",
|
|
22294
|
+
"user_prompt_submit",
|
|
22295
|
+
"pre_tool_use",
|
|
22296
|
+
"post_tool_use",
|
|
22297
|
+
"stop",
|
|
22298
|
+
"session_end"
|
|
22299
|
+
];
|
|
22300
|
+
var HOOK_MATCHER = /^(?:[A-Za-z0-9_-]|\.\*)+(?:\|(?:[A-Za-z0-9_-]|\.\*)+)*$/;
|
|
22301
|
+
var hookSchema = external_exports.object({
|
|
22302
|
+
event: external_exports.enum(HOOK_EVENTS),
|
|
22303
|
+
command: external_exports.string().min(1).max(4e3).refine((value) => !/[\u0000\uD800-\uDFFF]/u.test(value), {
|
|
22304
|
+
message: "command must be plain text without a NUL character"
|
|
22305
|
+
}),
|
|
22306
|
+
matcher: external_exports.string().min(1).max(255).refine((value) => HOOK_MATCHER.test(value), {
|
|
22307
|
+
message: "matcher must be tool names separated by |, with .* as the only wildcard"
|
|
22308
|
+
}).optional(),
|
|
22309
|
+
timeout_s: external_exports.number().int().min(1).max(600).optional()
|
|
22310
|
+
}).strict().refine((hook) => hook.matcher === void 0 || hook.event === "pre_tool_use" || hook.event === "post_tool_use", {
|
|
22311
|
+
message: "matcher applies only to pre_tool_use and post_tool_use hooks",
|
|
22312
|
+
path: ["matcher"]
|
|
22313
|
+
});
|
|
22314
|
+
var hooksSchema = external_exports.array(hookSchema).max(20);
|
|
21570
22315
|
var packagesSchema = external_exports.object({
|
|
21571
22316
|
apt: external_exports.array(packageNameSchema).max(32).default([]),
|
|
21572
22317
|
pip: external_exports.array(packageNameSchema).max(32).default([]),
|
|
@@ -21602,6 +22347,10 @@ var dataSchema = external_exports.object({
|
|
|
21602
22347
|
}
|
|
21603
22348
|
})
|
|
21604
22349
|
});
|
|
22350
|
+
var capabilityPoliciesSchema = external_exports.record(
|
|
22351
|
+
capabilityIdInputSchema,
|
|
22352
|
+
capabilityPermissionPolicySchema
|
|
22353
|
+
);
|
|
21605
22354
|
var publishSchema = external_exports.object({
|
|
21606
22355
|
name: external_exports.string().trim().min(1, "Give your agent a name."),
|
|
21607
22356
|
description: external_exports.string().default(""),
|
|
@@ -21610,7 +22359,9 @@ var publishSchema = external_exports.object({
|
|
|
21610
22359
|
instructions: external_exports.array(instructionFileSchema),
|
|
21611
22360
|
skills: external_exports.array(skillRefSchema),
|
|
21612
22361
|
customData: external_exports.array(customDataSchema),
|
|
21613
|
-
capabilities: capabilitiesSchema
|
|
22362
|
+
capabilities: capabilitiesSchema,
|
|
22363
|
+
/** Platform-owned capability permission-policy map. Absent keys default to always_allow. */
|
|
22364
|
+
capabilityPolicies: capabilityPoliciesSchema.optional()
|
|
21614
22365
|
}).refine((v) => isCompatible(v.agentType, v.llm), {
|
|
21615
22366
|
path: ["llm"],
|
|
21616
22367
|
message: "This model isn't available for the selected agent type."
|
|
@@ -21624,6 +22375,11 @@ var specPatchSchema = external_exports.object({
|
|
|
21624
22375
|
skills: external_exports.array(skillRefSchema).optional(),
|
|
21625
22376
|
customData: external_exports.array(customDataSchema).optional(),
|
|
21626
22377
|
capabilities: capabilitiesSchema.optional()
|
|
22378
|
+
// capabilityPolicies is intentionally absent: the chat update_spec tool cannot
|
|
22379
|
+
// set it because Guild's applySpecPatch does not persist it (the policy map
|
|
22380
|
+
// lives in a separate AgentSpecPolicyMap table on the asteroids side and is
|
|
22381
|
+
// written exclusively via PATCH /api/v1/agents/:id). Including it here would
|
|
22382
|
+
// create an accept-and-drop field.
|
|
21627
22383
|
}).partial();
|
|
21628
22384
|
|
|
21629
22385
|
export {
|
|
@@ -21637,6 +22393,7 @@ export {
|
|
|
21637
22393
|
isModelEffortSupported,
|
|
21638
22394
|
reasoningEffortDocLine,
|
|
21639
22395
|
sessionResourcesParamSchema,
|
|
22396
|
+
redactLine,
|
|
21640
22397
|
AGENT_TYPES,
|
|
21641
22398
|
supersededBy,
|
|
21642
22399
|
defaultLlm,
|