@aliyunrds/ctxdb 1.0.11-beta.0 → 1.0.12-beta.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.
- package/README.md +31 -12
- package/dist/{chunk-EWCB3UQS.js → chunk-4GYXLFNU.js} +35 -9
- package/dist/{chunk-7RMETV4M.js → chunk-7CZIQG6Z.js} +1 -1
- package/dist/{chunk-6XK3RDZ6.js → chunk-BRCQTX2M.js} +1 -1
- package/dist/{chunk-XEX5344F.js → chunk-C66FQHNI.js} +5 -5
- package/dist/{chunk-WCVCSOFL.js → chunk-CGA7EITY.js} +2 -2
- package/dist/{chunk-JM7EOAQZ.js → chunk-EX6SM7I3.js} +1 -1
- package/dist/{chunk-HHKQPWYI.js → chunk-HUX2XS5P.js} +1720 -1709
- package/dist/cli/main.js +41 -19
- package/dist/hooks/hermes-post-llm-call.js +19 -33
- package/dist/hooks/hermes-pre-llm-call.js +9 -9
- package/dist/hooks/session-end.js +4 -4
- package/dist/hooks/session-start.js +8 -8
- package/dist/hooks/stop.js +12 -7
- package/dist/hooks/user-prompt-submit.js +8 -8
- package/dist/opencode/index.js +421 -69
- package/package.json +2 -2
package/dist/opencode/index.js
CHANGED
|
@@ -2724,26 +2724,26 @@ var require_directives = __commonJS({
|
|
|
2724
2724
|
this.tags = Object.assign({}, _Directives.defaultTags);
|
|
2725
2725
|
this.atNextDocument = false;
|
|
2726
2726
|
}
|
|
2727
|
-
const
|
|
2728
|
-
const name =
|
|
2727
|
+
const parts2 = line.trim().split(/[ \t]+/);
|
|
2728
|
+
const name = parts2.shift();
|
|
2729
2729
|
switch (name) {
|
|
2730
2730
|
case "%TAG": {
|
|
2731
|
-
if (
|
|
2731
|
+
if (parts2.length !== 2) {
|
|
2732
2732
|
onError(0, "%TAG directive should contain exactly two parts");
|
|
2733
|
-
if (
|
|
2733
|
+
if (parts2.length < 2)
|
|
2734
2734
|
return false;
|
|
2735
2735
|
}
|
|
2736
|
-
const [handle, prefix] =
|
|
2736
|
+
const [handle, prefix] = parts2;
|
|
2737
2737
|
this.tags[handle] = prefix;
|
|
2738
2738
|
return true;
|
|
2739
2739
|
}
|
|
2740
2740
|
case "%YAML": {
|
|
2741
2741
|
this.yaml.explicit = true;
|
|
2742
|
-
if (
|
|
2742
|
+
if (parts2.length !== 1) {
|
|
2743
2743
|
onError(0, "%YAML directive should contain exactly one part");
|
|
2744
2744
|
return false;
|
|
2745
2745
|
}
|
|
2746
|
-
const [version] =
|
|
2746
|
+
const [version] = parts2;
|
|
2747
2747
|
if (version === "1.1" || version === "1.2") {
|
|
2748
2748
|
this.yaml.version = version;
|
|
2749
2749
|
return true;
|
|
@@ -5516,9 +5516,9 @@ var require_timestamp = __commonJS({
|
|
|
5516
5516
|
var stringifyNumber = require_stringifyNumber();
|
|
5517
5517
|
function parseSexagesimal(str, asBigInt) {
|
|
5518
5518
|
const sign = str[0];
|
|
5519
|
-
const
|
|
5519
|
+
const parts2 = sign === "-" || sign === "+" ? str.substring(1) : str;
|
|
5520
5520
|
const num = (n) => asBigInt ? BigInt(n) : Number(n);
|
|
5521
|
-
const res =
|
|
5521
|
+
const res = parts2.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num(60) + num(p), num(0));
|
|
5522
5522
|
return sign === "-" ? num(-1) * res : res;
|
|
5523
5523
|
}
|
|
5524
5524
|
function stringifySexagesimal(node) {
|
|
@@ -5534,18 +5534,18 @@ var require_timestamp = __commonJS({
|
|
|
5534
5534
|
value *= num(-1);
|
|
5535
5535
|
}
|
|
5536
5536
|
const _60 = num(60);
|
|
5537
|
-
const
|
|
5537
|
+
const parts2 = [value % _60];
|
|
5538
5538
|
if (value < 60) {
|
|
5539
|
-
|
|
5539
|
+
parts2.unshift(0);
|
|
5540
5540
|
} else {
|
|
5541
|
-
value = (value -
|
|
5542
|
-
|
|
5541
|
+
value = (value - parts2[0]) / _60;
|
|
5542
|
+
parts2.unshift(value % _60);
|
|
5543
5543
|
if (value >= 60) {
|
|
5544
|
-
value = (value -
|
|
5545
|
-
|
|
5544
|
+
value = (value - parts2[0]) / _60;
|
|
5545
|
+
parts2.unshift(value);
|
|
5546
5546
|
}
|
|
5547
5547
|
}
|
|
5548
|
-
return sign +
|
|
5548
|
+
return sign + parts2.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
|
|
5549
5549
|
}
|
|
5550
5550
|
var intTime = {
|
|
5551
5551
|
identify: (value) => typeof value === "bigint" || Number.isInteger(value),
|
|
@@ -13867,12 +13867,6 @@ function selectTurnMessages(allParsed, opts = {}) {
|
|
|
13867
13867
|
}
|
|
13868
13868
|
}
|
|
13869
13869
|
const candidates = [];
|
|
13870
|
-
const summaryRange = turnStart >= 0 ? turnStart : allParsed.length;
|
|
13871
|
-
for (let ai = 0; ai < summaryRange; ai++) {
|
|
13872
|
-
if (allParsed[ai].isSummary) {
|
|
13873
|
-
candidates.push(allParsed[ai]);
|
|
13874
|
-
}
|
|
13875
|
-
}
|
|
13876
13870
|
const seenIndices = new Set(candidates.map((m) => m.index));
|
|
13877
13871
|
if (turnStart >= 0) {
|
|
13878
13872
|
const total = allParsed.length - turnStart;
|
|
@@ -14099,10 +14093,21 @@ function selectAndFormatRecalledMemories(memories, userId, config2 = {}) {
|
|
|
14099
14093
|
|
|
14100
14094
|
// ../shared/src/debug-policy.ts
|
|
14101
14095
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14096
|
+
|
|
14097
|
+
// ../shared/src/sites.ts
|
|
14098
|
+
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
14099
|
+
var PUBLIC_SITES = {
|
|
14100
|
+
cn: {
|
|
14101
|
+
baseUrl: "https://api.cn-hangzhou.agentcontext.aliyuncs.com",
|
|
14102
|
+
aliases: ["https://context-database.aliyuncs.com"],
|
|
14103
|
+
authorizationUrl: "https://rdsnext.console.aliyun.com/contextDbCliAuthorization/cn-hangzhou"
|
|
14104
|
+
},
|
|
14105
|
+
intl: {
|
|
14106
|
+
baseUrl: "https://context-database.ap-southeast-1.aliyuncs.com",
|
|
14107
|
+
aliases: [],
|
|
14108
|
+
authorizationUrl: "https://rds.console.alibabacloud.com/contextDbCliAuthorization/ap-southeast-1"
|
|
14109
|
+
}
|
|
14110
|
+
};
|
|
14106
14111
|
function normalizeBaseUrl(value) {
|
|
14107
14112
|
try {
|
|
14108
14113
|
const parsed = new URL(value.trim());
|
|
@@ -14114,12 +14119,18 @@ function normalizeBaseUrl(value) {
|
|
|
14114
14119
|
return null;
|
|
14115
14120
|
}
|
|
14116
14121
|
}
|
|
14117
|
-
|
|
14118
|
-
OFFICIAL_PRODUCTION_BASE_URLS.map((url) => normalizeBaseUrl(url))
|
|
14119
|
-
);
|
|
14120
|
-
function isOfficialProductionUrl(value) {
|
|
14122
|
+
function publicSiteForUrl(value) {
|
|
14121
14123
|
const normalized = normalizeBaseUrl(value);
|
|
14122
|
-
return
|
|
14124
|
+
return Object.keys(PUBLIC_SITES).find((site) => {
|
|
14125
|
+
const preset = PUBLIC_SITES[site];
|
|
14126
|
+
return [preset.baseUrl, ...preset.aliases].some((url) => url === normalized);
|
|
14127
|
+
});
|
|
14128
|
+
}
|
|
14129
|
+
|
|
14130
|
+
// ../shared/src/debug-policy.ts
|
|
14131
|
+
var OFFICIAL_PRODUCTION_BASE_URLS = Object.values(PUBLIC_SITES).flatMap((site) => [site.baseUrl, ...site.aliases]);
|
|
14132
|
+
function isOfficialProductionUrl(value) {
|
|
14133
|
+
return publicSiteForUrl(value) !== void 0;
|
|
14123
14134
|
}
|
|
14124
14135
|
function resolveDebugPolicy(configuredDebug, effectiveBaseUrl) {
|
|
14125
14136
|
const debugForced = !isOfficialProductionUrl(effectiveBaseUrl);
|
|
@@ -15335,6 +15346,7 @@ function createRequestAuthorizationProvider(credential, baseUrl) {
|
|
|
15335
15346
|
|
|
15336
15347
|
// ../shared/src/data-endpoint.ts
|
|
15337
15348
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
15349
|
+
var DEFAULT_DATA_BASE_URL = PUBLIC_SITES.cn.baseUrl;
|
|
15338
15350
|
|
|
15339
15351
|
// ../shared/src/login-cleanup.ts
|
|
15340
15352
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
@@ -15349,6 +15361,339 @@ init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
|
15349
15361
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
15350
15362
|
import { dirname as dirname7, join as join6 } from "path";
|
|
15351
15363
|
|
|
15364
|
+
// ../shared/src/memory-cleanup.ts
|
|
15365
|
+
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
15366
|
+
var SHELL_TOOLS = /* @__PURE__ */ new Set([
|
|
15367
|
+
"bash",
|
|
15368
|
+
"exec",
|
|
15369
|
+
"shell",
|
|
15370
|
+
"sh",
|
|
15371
|
+
"terminal",
|
|
15372
|
+
"exec_command",
|
|
15373
|
+
"run_in_terminal",
|
|
15374
|
+
"functions.exec_command",
|
|
15375
|
+
"functions.shell_command",
|
|
15376
|
+
"shell_command"
|
|
15377
|
+
]);
|
|
15378
|
+
var CONTEXTDB_PROVIDERS = /* @__PURE__ */ new Set(["ctxdb", "contextdb", "openclaw_memory_rds_ctxdb"]);
|
|
15379
|
+
var DELETE_TOOLS = /* @__PURE__ */ new Set(["memory_delete", "memory_batch_delete"]);
|
|
15380
|
+
var CLI_NAMES = /* @__PURE__ */ new Set(["ctxdb", "ctxdb-qoder", "ctxdb_qoder", "rds-ctxdb", "rds_ctxdb", "qoder-ctxdb", "qoder_ctxdb"]);
|
|
15381
|
+
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["help", "json", "verbose", "all", "yes"]);
|
|
15382
|
+
function shellTokens(command) {
|
|
15383
|
+
const tokens = [];
|
|
15384
|
+
let value = "", active = false, quote = "";
|
|
15385
|
+
const flush = () => {
|
|
15386
|
+
if (active) tokens.push({ value });
|
|
15387
|
+
value = "";
|
|
15388
|
+
active = false;
|
|
15389
|
+
};
|
|
15390
|
+
for (let i = 0; i < command.length; i++) {
|
|
15391
|
+
const c = command[i];
|
|
15392
|
+
if (quote) {
|
|
15393
|
+
if (c === quote) {
|
|
15394
|
+
quote = "";
|
|
15395
|
+
continue;
|
|
15396
|
+
}
|
|
15397
|
+
if (quote === '"' && c === "\\" && /["\\$`\n]/.test(command[i + 1] ?? "")) {
|
|
15398
|
+
const next = command[++i];
|
|
15399
|
+
if (next !== "\n") value += next;
|
|
15400
|
+
continue;
|
|
15401
|
+
}
|
|
15402
|
+
if (quote === '"' && (c === "`" || c === "$" && command[i + 1] === "(")) return null;
|
|
15403
|
+
value += c;
|
|
15404
|
+
continue;
|
|
15405
|
+
}
|
|
15406
|
+
if (c === "'" || c === '"') {
|
|
15407
|
+
active = true;
|
|
15408
|
+
quote = c;
|
|
15409
|
+
continue;
|
|
15410
|
+
}
|
|
15411
|
+
if (c === "\\") {
|
|
15412
|
+
const next = command[i + 1];
|
|
15413
|
+
if (next === void 0) return null;
|
|
15414
|
+
if (/[\s'"\\;&|<>$`]/.test(next)) {
|
|
15415
|
+
i++;
|
|
15416
|
+
if (next !== "\n") {
|
|
15417
|
+
value += next;
|
|
15418
|
+
active = true;
|
|
15419
|
+
}
|
|
15420
|
+
} else {
|
|
15421
|
+
value += c;
|
|
15422
|
+
active = true;
|
|
15423
|
+
}
|
|
15424
|
+
continue;
|
|
15425
|
+
}
|
|
15426
|
+
if (c === "#" && !active) {
|
|
15427
|
+
while (i < command.length && command[i] !== "\n") i++;
|
|
15428
|
+
flush();
|
|
15429
|
+
tokens.push({ value: ";", operator: true });
|
|
15430
|
+
continue;
|
|
15431
|
+
}
|
|
15432
|
+
if (c === "`" || c === "$" && command[i + 1] === "(") return null;
|
|
15433
|
+
if (c === "<" && command[i + 1] === "<") return null;
|
|
15434
|
+
if (/[;&|\n()<>]/.test(c)) {
|
|
15435
|
+
flush();
|
|
15436
|
+
let op = c;
|
|
15437
|
+
if (command[i + 1] === c && /[&|>]/.test(c)) op += command[++i];
|
|
15438
|
+
tokens.push({ value: op, operator: true });
|
|
15439
|
+
continue;
|
|
15440
|
+
}
|
|
15441
|
+
if (/\s/.test(c)) {
|
|
15442
|
+
flush();
|
|
15443
|
+
continue;
|
|
15444
|
+
}
|
|
15445
|
+
active = true;
|
|
15446
|
+
value += c;
|
|
15447
|
+
}
|
|
15448
|
+
if (quote) return null;
|
|
15449
|
+
flush();
|
|
15450
|
+
return tokens;
|
|
15451
|
+
}
|
|
15452
|
+
function basename(path) {
|
|
15453
|
+
return path.split(/[\\/]/).at(-1).replace(/\.(?:cmd|exe)$/i, "");
|
|
15454
|
+
}
|
|
15455
|
+
function cliOperation(argv) {
|
|
15456
|
+
if (argv.some((a) => a === "--help" || a.startsWith("--help=") || a === "-h")) return;
|
|
15457
|
+
const positional = [];
|
|
15458
|
+
let literal = false;
|
|
15459
|
+
for (let i = 1; i < argv.length; i++) {
|
|
15460
|
+
const arg = argv[i];
|
|
15461
|
+
if (arg === "--") {
|
|
15462
|
+
literal = true;
|
|
15463
|
+
continue;
|
|
15464
|
+
}
|
|
15465
|
+
if (!literal && arg.startsWith("--")) {
|
|
15466
|
+
if (!arg.includes("=") && !BOOLEAN_FLAGS.has(arg.slice(2)) && argv[i + 1] && !argv[i + 1].startsWith("--")) i++;
|
|
15467
|
+
} else positional.push(arg);
|
|
15468
|
+
}
|
|
15469
|
+
if (positional[0] !== "memory") return;
|
|
15470
|
+
if (positional[1] === "delete" || positional[1] === "batch-delete") return positional[1];
|
|
15471
|
+
}
|
|
15472
|
+
function commandOperation(argv, depth) {
|
|
15473
|
+
let i = 0;
|
|
15474
|
+
while (/^[A-Za-z_][\w]*=/.test(argv[i] ?? "")) i++;
|
|
15475
|
+
if (basename(argv[i] ?? "") === "env") {
|
|
15476
|
+
i++;
|
|
15477
|
+
while (i < argv.length) {
|
|
15478
|
+
if (argv[i] === "--") {
|
|
15479
|
+
i++;
|
|
15480
|
+
break;
|
|
15481
|
+
}
|
|
15482
|
+
if (argv[i] === "-u" || argv[i] === "--unset") {
|
|
15483
|
+
i += 2;
|
|
15484
|
+
continue;
|
|
15485
|
+
}
|
|
15486
|
+
if (argv[i] === "-i" || argv[i] === "--ignore-environment" || argv[i].startsWith("--unset=") || /^[A-Za-z_][\w]*=/.test(argv[i])) {
|
|
15487
|
+
i++;
|
|
15488
|
+
continue;
|
|
15489
|
+
}
|
|
15490
|
+
break;
|
|
15491
|
+
}
|
|
15492
|
+
}
|
|
15493
|
+
if (argv[i] === "command") {
|
|
15494
|
+
i++;
|
|
15495
|
+
if (argv[i] === "--") i++;
|
|
15496
|
+
}
|
|
15497
|
+
const name = basename(argv[i] ?? "");
|
|
15498
|
+
if (CLI_NAMES.has(name)) return cliOperation(argv.slice(i));
|
|
15499
|
+
if (depth < 3 && ["bash", "sh", "zsh"].includes(name)) {
|
|
15500
|
+
const flag = argv[i + 1];
|
|
15501
|
+
if (/^-[a-z]*c[a-z]*$/.test(flag ?? "") && argv[i + 2]) return shellOperation(argv[i + 2], depth + 1);
|
|
15502
|
+
}
|
|
15503
|
+
}
|
|
15504
|
+
function shellOperation(command, depth = 0) {
|
|
15505
|
+
const tokens = shellTokens(command);
|
|
15506
|
+
if (!tokens) return;
|
|
15507
|
+
let argv = [];
|
|
15508
|
+
for (let i = 0; i <= tokens.length; i++) {
|
|
15509
|
+
const token = tokens[i];
|
|
15510
|
+
if (token?.operator && ["<", ">", ">>"].includes(token.value)) {
|
|
15511
|
+
if (/^\d+$/.test(argv.at(-1) ?? "")) argv.pop();
|
|
15512
|
+
if (tokens[i + 1]?.value === "&") i++;
|
|
15513
|
+
i++;
|
|
15514
|
+
continue;
|
|
15515
|
+
}
|
|
15516
|
+
if (!token || token.operator) {
|
|
15517
|
+
const operation = commandOperation(argv, depth);
|
|
15518
|
+
if (operation) return operation;
|
|
15519
|
+
argv = [];
|
|
15520
|
+
} else argv.push(token.value);
|
|
15521
|
+
}
|
|
15522
|
+
}
|
|
15523
|
+
function detectMemoryCleanup(calls) {
|
|
15524
|
+
for (const call of calls) {
|
|
15525
|
+
const qualified = /^mcp__(ctxdb|contextdb)__([^_].*)$/.exec(call.name);
|
|
15526
|
+
const provider = call.provider ?? qualified?.[1];
|
|
15527
|
+
const toolName = qualified?.[2] ?? call.name;
|
|
15528
|
+
if (provider && CONTEXTDB_PROVIDERS.has(provider) && DELETE_TOOLS.has(toolName)) {
|
|
15529
|
+
return { detected: true, operation: toolName === "memory_batch_delete" ? "batch-delete" : "delete", source: "tool" };
|
|
15530
|
+
}
|
|
15531
|
+
if (!SHELL_TOOLS.has(call.name.toLowerCase())) continue;
|
|
15532
|
+
const command = call.arguments.command ?? call.arguments.cmd;
|
|
15533
|
+
if (typeof command !== "string") continue;
|
|
15534
|
+
const operation = shellOperation(command);
|
|
15535
|
+
if (operation) return { detected: true, operation, source: "cli" };
|
|
15536
|
+
}
|
|
15537
|
+
return { detected: false };
|
|
15538
|
+
}
|
|
15539
|
+
|
|
15540
|
+
// ../shared/src/capture-events.ts
|
|
15541
|
+
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
15542
|
+
var object4 = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
|
|
15543
|
+
function captureRecord(value) {
|
|
15544
|
+
const row = object4(value);
|
|
15545
|
+
if (row.type === "response_item" || row.type === "event_msg") return object4(row.payload);
|
|
15546
|
+
if (row.type === "message" && row.role) return row;
|
|
15547
|
+
if (row.message) return object4(row.message);
|
|
15548
|
+
return row;
|
|
15549
|
+
}
|
|
15550
|
+
var info = (v) => object4(object4(v).info);
|
|
15551
|
+
var role = (v) => info(v).role ?? captureRecord(v).role ?? object4(v).type;
|
|
15552
|
+
var parts = (v) => object4(v).parts ?? captureRecord(v).content ?? captureRecord(v).text;
|
|
15553
|
+
function hidden(v) {
|
|
15554
|
+
const row = object4(v), body = captureRecord(v);
|
|
15555
|
+
return [row, body, info(v)].some((r) => r.isMeta || r.isSidechain || r.is_synthetic || r.synthetic || r.ignored || r._pre_verify_synthetic || r._verify_on_stop_synthetic);
|
|
15556
|
+
}
|
|
15557
|
+
function captureText(value) {
|
|
15558
|
+
const content = parts(value);
|
|
15559
|
+
if (typeof content === "string") return content;
|
|
15560
|
+
if (!Array.isArray(content)) return "";
|
|
15561
|
+
if (role(value) === "user" && content.some((b) => object4(b).type === "tool_result")) return "";
|
|
15562
|
+
return content.flatMap((b) => {
|
|
15563
|
+
const block2 = object4(b);
|
|
15564
|
+
return !block2.synthetic && !block2.ignored && ["text", "input_text", "output_text"].includes(block2.type) && typeof block2.text === "string" ? [block2.text] : [];
|
|
15565
|
+
}).join("\n");
|
|
15566
|
+
}
|
|
15567
|
+
function human(v) {
|
|
15568
|
+
if (hidden(v) || role(v) !== "user") return false;
|
|
15569
|
+
let text3 = captureText(v).trim();
|
|
15570
|
+
if (text3.includes("<user_query>")) text3 = /<user_query>([\s\S]*?)<\/user_query>/.exec(text3)?.[1] ?? "";
|
|
15571
|
+
if (/^(?:Stop hook feedback:|# AGENTS\.md instructions|<environment_context>|<INSTRUCTIONS>|<permissions instructions>|<collaboration_mode>|<recommended_plugins>|<apps_instructions>|<skills_instructions>|<plugins_instructions>|## Memory\s+You have access to a memory folder|<recalled-memories>|<available-knowledge-bases>|<external_codex_apps_open_page>)/.test(text3)) return false;
|
|
15572
|
+
if (stripNoiseFromContent(text3).trim()) return true;
|
|
15573
|
+
const content = parts(v);
|
|
15574
|
+
return Array.isArray(content) && content.some((b) => ["image", "input_image"].includes(object4(b).type));
|
|
15575
|
+
}
|
|
15576
|
+
function nativeTurn(v) {
|
|
15577
|
+
const row = object4(v), body = captureRecord(v), metadata = info(v);
|
|
15578
|
+
return (row.type === "turn_context" ? row.payload?.turn_id : void 0) ?? row.turn_id ?? row.turnId ?? body.turn_id ?? body.turnId ?? (metadata.role === "user" ? metadata.id : metadata.parentID);
|
|
15579
|
+
}
|
|
15580
|
+
function selectCaptureTurn(records) {
|
|
15581
|
+
let start = -1;
|
|
15582
|
+
for (let i = records.length - 1; i >= 0; i--) if (human(records[i])) {
|
|
15583
|
+
start = i;
|
|
15584
|
+
break;
|
|
15585
|
+
}
|
|
15586
|
+
if (start < 0) return [];
|
|
15587
|
+
let contextIndex = -1;
|
|
15588
|
+
for (let i = records.length - 1; i >= 0; i--) {
|
|
15589
|
+
const row = object4(records[i]);
|
|
15590
|
+
if (row.type === "turn_context" || row.type === "event_msg" && row.payload?.type === "task_started") {
|
|
15591
|
+
contextIndex = i;
|
|
15592
|
+
break;
|
|
15593
|
+
}
|
|
15594
|
+
}
|
|
15595
|
+
if (contextIndex > start) return [];
|
|
15596
|
+
const turn = nativeTurn(records[start]) ?? (contextIndex >= 0 ? nativeTurn(records[contextIndex]) : void 0);
|
|
15597
|
+
while (start > 0 && human(records[start - 1]) && (turn ? nativeTurn(records[start - 1]) === turn : !nativeTurn(records[start - 1]))) start--;
|
|
15598
|
+
const selected = records.slice(start).filter((r) => !hidden(r) && (role(r) !== "user" || human(r) || Array.isArray(parts(r)) && parts(r).some((b) => b?.type === "tool_result")) && (!turn || !nativeTurn(r) || nativeTurn(r) === turn));
|
|
15599
|
+
return contextIndex >= 0 ? [records[contextIndex], ...selected] : selected;
|
|
15600
|
+
}
|
|
15601
|
+
function argumentsObject(v) {
|
|
15602
|
+
if (typeof v !== "string") return object4(v);
|
|
15603
|
+
try {
|
|
15604
|
+
return object4(JSON.parse(v));
|
|
15605
|
+
} catch {
|
|
15606
|
+
return {};
|
|
15607
|
+
}
|
|
15608
|
+
}
|
|
15609
|
+
function captureToolCalls(records, registeredTools = {}) {
|
|
15610
|
+
const calls = [];
|
|
15611
|
+
for (const raw of records) {
|
|
15612
|
+
if (hidden(raw)) continue;
|
|
15613
|
+
const body = captureRecord(raw);
|
|
15614
|
+
const blocks = [];
|
|
15615
|
+
if (body.type === "function_call" || body.type === "custom_tool_call") blocks.push(body);
|
|
15616
|
+
if (role(raw) === "assistant") {
|
|
15617
|
+
if (Array.isArray(parts(raw))) blocks.push(...parts(raw).map(object4).filter((b) => ["tool_use", "toolCall", "tool"].includes(b.type)));
|
|
15618
|
+
if (Array.isArray(body.tool_calls)) blocks.push(...body.tool_calls.map(object4));
|
|
15619
|
+
}
|
|
15620
|
+
for (const block2 of blocks) {
|
|
15621
|
+
const fn = object4(block2.function);
|
|
15622
|
+
const name = fn.name ?? block2.name ?? block2.tool;
|
|
15623
|
+
if (typeof name !== "string") continue;
|
|
15624
|
+
const encodedArguments = fn.arguments ?? block2.arguments;
|
|
15625
|
+
let invalidArguments = false;
|
|
15626
|
+
if (typeof encodedArguments === "string") {
|
|
15627
|
+
try {
|
|
15628
|
+
const parsed = JSON.parse(encodedArguments);
|
|
15629
|
+
invalidArguments = !parsed || typeof parsed !== "object" || Array.isArray(parsed);
|
|
15630
|
+
} catch {
|
|
15631
|
+
invalidArguments = true;
|
|
15632
|
+
}
|
|
15633
|
+
}
|
|
15634
|
+
const args = argumentsObject(encodedArguments ?? block2.input ?? block2.parameters ?? block2.state?.input);
|
|
15635
|
+
const provider = block2.provider ?? block2.server_name ?? registeredTools[name];
|
|
15636
|
+
const id = block2.call_id ?? block2.callID ?? block2.callId ?? block2.id;
|
|
15637
|
+
calls.push({
|
|
15638
|
+
name,
|
|
15639
|
+
arguments: args,
|
|
15640
|
+
...invalidArguments ? { invalidArguments: true } : {},
|
|
15641
|
+
...typeof provider === "string" ? { provider } : {},
|
|
15642
|
+
...typeof id === "string" ? { id } : {}
|
|
15643
|
+
});
|
|
15644
|
+
}
|
|
15645
|
+
}
|
|
15646
|
+
return calls;
|
|
15647
|
+
}
|
|
15648
|
+
function captureCompletionReason(records, signal = {}) {
|
|
15649
|
+
if (!records.length) return "no_user_in_turn";
|
|
15650
|
+
const pending = /* @__PURE__ */ new Set();
|
|
15651
|
+
let lastAssistant, lastAssistantIndex = -1, lastToolIndex = -1;
|
|
15652
|
+
for (let i = 0; i < records.length; i++) {
|
|
15653
|
+
const raw = records[i], body2 = captureRecord(raw), metadata2 = info(raw), row2 = object4(raw);
|
|
15654
|
+
const session = row2.sessionId ?? row2.session_id ?? body2.session_id ?? metadata2.sessionID;
|
|
15655
|
+
if (signal.sessionId && session && session !== signal.sessionId) return "session_mismatch";
|
|
15656
|
+
const turn = nativeTurn(raw);
|
|
15657
|
+
if (signal.turnId && turn && turn !== signal.turnId) return "turn_unverified";
|
|
15658
|
+
if (role(raw) === "assistant") {
|
|
15659
|
+
lastAssistant = raw;
|
|
15660
|
+
lastAssistantIndex = i;
|
|
15661
|
+
}
|
|
15662
|
+
const calls = captureToolCalls([raw]);
|
|
15663
|
+
for (const call of calls) {
|
|
15664
|
+
if (call.invalidArguments) return "capture_input_incomplete";
|
|
15665
|
+
pending.add(call.id ?? `unknown:${i}`);
|
|
15666
|
+
lastToolIndex = i;
|
|
15667
|
+
}
|
|
15668
|
+
const content = Array.isArray(parts(raw)) ? parts(raw) : [];
|
|
15669
|
+
for (const part of content) {
|
|
15670
|
+
if (part?.type === "tool_result" && role(raw) !== "assistant" && typeof part.tool_use_id === "string") {
|
|
15671
|
+
pending.delete(part.tool_use_id);
|
|
15672
|
+
lastToolIndex = i;
|
|
15673
|
+
}
|
|
15674
|
+
if (part?.type === "tool" && ["completed", "error"].includes(part.state?.status)) pending.delete(part.callID ?? part.id);
|
|
15675
|
+
}
|
|
15676
|
+
if (["tool", "toolResult"].includes(String(role(raw))) || ["function_call_output", "function_call_result", "custom_tool_call_output"].includes(body2.type)) {
|
|
15677
|
+
pending.delete(body2.tool_call_id ?? body2.toolCallId ?? body2.call_id ?? body2.callId);
|
|
15678
|
+
lastToolIndex = i;
|
|
15679
|
+
}
|
|
15680
|
+
}
|
|
15681
|
+
if (pending.size) return "awaiting_tools";
|
|
15682
|
+
if (!lastAssistant || !captureText(lastAssistant).trim()) return "awaiting_assistant";
|
|
15683
|
+
const body = captureRecord(lastAssistant), metadata = info(lastAssistant), row = object4(lastAssistant);
|
|
15684
|
+
const phase = body.phase ?? row.phase;
|
|
15685
|
+
const finish = metadata.finish ?? body.stop_reason ?? body.finish_reason ?? row.finish_reason;
|
|
15686
|
+
if (metadata.error || body.error || ["tool_use", "tool_calls", "tool-calls", "length", "max_tokens", "error", "aborted"].includes(finish)) return "awaiting_final";
|
|
15687
|
+
if (phase && phase !== "final" && phase !== "final_answer") return "awaiting_final";
|
|
15688
|
+
const canonical = (s) => stripNoiseFromContent(s).replace(/\r\n/g, "\n").trim();
|
|
15689
|
+
if (signal.lastAssistantMessage && canonical(captureText(lastAssistant)) !== canonical(signal.lastAssistantMessage)) return "awaiting_host_final";
|
|
15690
|
+
const sdkFinal = metadata.time?.completed && metadata.finish === "stop";
|
|
15691
|
+
if (metadata.role === "assistant" && !sdkFinal) return "awaiting_final";
|
|
15692
|
+
if (lastAssistantIndex <= lastToolIndex && !sdkFinal) return "awaiting_final";
|
|
15693
|
+
if (signal.completed || signal.lastAssistantMessage || sdkFinal || ["end_turn", "stop"].includes(finish) || phase === "final" || phase === "final_answer") return;
|
|
15694
|
+
return "awaiting_final";
|
|
15695
|
+
}
|
|
15696
|
+
|
|
15352
15697
|
// ../ctxdb/src/lib/credentials.ts
|
|
15353
15698
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
15354
15699
|
function apiKeyCredential(apiKey) {
|
|
@@ -15818,7 +16163,7 @@ function parseErrorResponse(text3, fallback) {
|
|
|
15818
16163
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
15819
16164
|
import { readFileSync as readFileSync5, existsSync as existsSync6, unlinkSync as unlinkSync4 } from "fs";
|
|
15820
16165
|
import { homedir as homedir5 } from "os";
|
|
15821
|
-
import { basename, dirname as dirname11, join as join10 } from "path";
|
|
16166
|
+
import { basename as basename2, dirname as dirname11, join as join10 } from "path";
|
|
15822
16167
|
|
|
15823
16168
|
// ../ctxdb/src/lib/agents.ts
|
|
15824
16169
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
@@ -15886,7 +16231,7 @@ function configDir(env = process.env) {
|
|
|
15886
16231
|
return dirname11(defaultConfigPath(env));
|
|
15887
16232
|
}
|
|
15888
16233
|
function configFileName(env = process.env) {
|
|
15889
|
-
return
|
|
16234
|
+
return basename2(defaultConfigPath(env));
|
|
15890
16235
|
}
|
|
15891
16236
|
var DEFAULT_BASE_URL = "https://api.cn-hangzhou.agentcontext.aliyuncs.com";
|
|
15892
16237
|
var DEFAULT_USER_ID = "default";
|
|
@@ -17038,8 +17383,8 @@ function isString(obj) {
|
|
|
17038
17383
|
return _class(obj) === "[object String]";
|
|
17039
17384
|
}
|
|
17040
17385
|
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
17041
|
-
function has(
|
|
17042
|
-
return _hasOwnProperty.call(
|
|
17386
|
+
function has(object5, key) {
|
|
17387
|
+
return _hasOwnProperty.call(object5, key);
|
|
17043
17388
|
}
|
|
17044
17389
|
function assign(obj) {
|
|
17045
17390
|
const sources = Array.prototype.slice.call(arguments, 1);
|
|
@@ -17445,11 +17790,11 @@ default_rules.code_block = function(tokens, idx, options2, env, slf) {
|
|
|
17445
17790
|
};
|
|
17446
17791
|
default_rules.fence = function(tokens, idx, options2, env, slf) {
|
|
17447
17792
|
const token = tokens[idx];
|
|
17448
|
-
const
|
|
17793
|
+
const info2 = token.info ? unescapeAll(token.info).trim() : "";
|
|
17449
17794
|
let langName = "";
|
|
17450
17795
|
let langAttrs = "";
|
|
17451
|
-
if (
|
|
17452
|
-
const arr =
|
|
17796
|
+
if (info2) {
|
|
17797
|
+
const arr = info2.split(/(\s+)/g);
|
|
17453
17798
|
langName = arr[0];
|
|
17454
17799
|
langAttrs = arr.slice(2).join("");
|
|
17455
17800
|
}
|
|
@@ -17462,7 +17807,7 @@ default_rules.fence = function(tokens, idx, options2, env, slf) {
|
|
|
17462
17807
|
if (highlighted.indexOf("<pre") === 0) {
|
|
17463
17808
|
return highlighted + "\n";
|
|
17464
17809
|
}
|
|
17465
|
-
if (
|
|
17810
|
+
if (info2) {
|
|
17466
17811
|
const i = token.attrIndex("class");
|
|
17467
17812
|
const tmpAttrs = token.attrs ? token.attrs.slice() : [];
|
|
17468
17813
|
if (i < 0) {
|
|
@@ -21189,11 +21534,11 @@ function map(array, callback) {
|
|
|
21189
21534
|
return result;
|
|
21190
21535
|
}
|
|
21191
21536
|
function mapDomain(domain, callback) {
|
|
21192
|
-
const
|
|
21537
|
+
const parts2 = domain.split("@");
|
|
21193
21538
|
let result = "";
|
|
21194
|
-
if (
|
|
21195
|
-
result =
|
|
21196
|
-
domain =
|
|
21539
|
+
if (parts2.length > 1) {
|
|
21540
|
+
result = parts2[0] + "@";
|
|
21541
|
+
domain = parts2[1];
|
|
21197
21542
|
}
|
|
21198
21543
|
domain = domain.replace(regexSeparators, ".");
|
|
21199
21544
|
const labels = domain.split(".");
|
|
@@ -21760,8 +22105,8 @@ import { dirname as dirname12, resolve as resolve2, sep as sep2, join as join12
|
|
|
21760
22105
|
import { randomUUID } from "crypto";
|
|
21761
22106
|
import { AsyncLocalStorage } from "async_hooks";
|
|
21762
22107
|
var skillRoot = () => configDir();
|
|
21763
|
-
function privatePath(root, ...
|
|
21764
|
-
const base2 = resolve2(root), target = resolve2(base2, ...
|
|
22108
|
+
function privatePath(root, ...parts2) {
|
|
22109
|
+
const base2 = resolve2(root), target = resolve2(base2, ...parts2);
|
|
21765
22110
|
if (target !== base2 && !target.startsWith(base2 + sep2)) throw new Error("invalid_state_path");
|
|
21766
22111
|
let path = base2;
|
|
21767
22112
|
for (const part of ["", ...target.slice(base2.length + 1).split(sep2).filter(Boolean)]) {
|
|
@@ -22045,24 +22390,24 @@ function normalizeSkillRows(agent, rows, sessionId) {
|
|
|
22045
22390
|
if (session && session !== sessionId) return [];
|
|
22046
22391
|
const message = agent === "workbuddy" && row.type === "message" ? row : row.message ?? row.info ?? row;
|
|
22047
22392
|
const workbuddyTool = agent === "workbuddy" && ["function_call", "function_call_result"].includes(row.type);
|
|
22048
|
-
const
|
|
22049
|
-
if (!["user", "assistant", "tool"].includes(
|
|
22393
|
+
const role2 = message.role ?? (workbuddyTool ? "assistant" : row.type);
|
|
22394
|
+
if (!["user", "assistant", "tool"].includes(role2)) return [];
|
|
22050
22395
|
const id = row.uuid ?? message.id ?? row.id ?? `${ordinal}`;
|
|
22051
|
-
const turn = row.turn_id ?? message.turn_id ?? (agent === "opencode" ?
|
|
22396
|
+
const turn = row.turn_id ?? message.turn_id ?? (agent === "opencode" ? role2 === "user" ? message.id : message.parentID : void 0);
|
|
22052
22397
|
const result = [];
|
|
22053
22398
|
const item = (payload) => result.push({ type: "response_item", payload });
|
|
22054
22399
|
const text3 = (value, part) => {
|
|
22055
|
-
if (agent === "workbuddy" && row.type === "message" &&
|
|
22400
|
+
if (agent === "workbuddy" && row.type === "message" && role2 === "user") {
|
|
22056
22401
|
if (value.trimStart().startsWith("Stop hook feedback:")) return;
|
|
22057
22402
|
value = /<user_query>([\s\S]*)<\/user_query>\s*$/.exec(value)?.[1] ?? value;
|
|
22058
22403
|
}
|
|
22059
22404
|
item({
|
|
22060
22405
|
type: "message",
|
|
22061
22406
|
id: `${id}:${part}`,
|
|
22062
|
-
role,
|
|
22063
|
-
...
|
|
22407
|
+
role: role2,
|
|
22408
|
+
...role2 === "assistant" ? { phase: "final" } : {},
|
|
22064
22409
|
...turn ? { internal_chat_message_metadata_passthrough: { turn_id: turn } } : {},
|
|
22065
|
-
content: [{ type:
|
|
22410
|
+
content: [{ type: role2 === "user" ? "input_text" : "output_text", text: value }]
|
|
22066
22411
|
});
|
|
22067
22412
|
};
|
|
22068
22413
|
const call = (callId, name, args) => {
|
|
@@ -22094,21 +22439,21 @@ function normalizeSkillRows(agent, rows, sessionId) {
|
|
|
22094
22439
|
}
|
|
22095
22440
|
return result;
|
|
22096
22441
|
}
|
|
22097
|
-
if (
|
|
22442
|
+
if (role2 === "tool") {
|
|
22098
22443
|
output(message.tool_call_id, message.content);
|
|
22099
22444
|
return result;
|
|
22100
22445
|
}
|
|
22101
22446
|
const content = row.parts ?? message.content;
|
|
22102
22447
|
if (typeof content === "string") text3(content, 0);
|
|
22103
22448
|
if (Array.isArray(content)) {
|
|
22104
|
-
const visible = content.filter((block2) => (block2?.type === "text" || agent === "workbuddy" && block2?.type === (
|
|
22449
|
+
const visible = content.filter((block2) => (block2?.type === "text" || agent === "workbuddy" && block2?.type === (role2 === "user" ? "input_text" : "output_text")) && !block2.synthetic && !block2.ignored && typeof block2.text === "string").map((block2) => block2.text).join("\n");
|
|
22105
22450
|
if (visible) text3(visible, 0);
|
|
22106
22451
|
}
|
|
22107
22452
|
if (Array.isArray(content)) content.forEach((block2) => {
|
|
22108
22453
|
if (!block2 || block2.synthetic || block2.ignored) return;
|
|
22109
22454
|
if (block2.type === "tool_use") call(block2.id, block2.name, block2.input);
|
|
22110
22455
|
if (block2.type === "tool_result") output(block2.tool_use_id, block2.content, block2.is_error);
|
|
22111
|
-
if (block2.type === "tool" &&
|
|
22456
|
+
if (block2.type === "tool" && role2 === "assistant") {
|
|
22112
22457
|
call(block2.callID, block2.tool, block2.state?.input);
|
|
22113
22458
|
if (["completed", "error"].includes(block2.state?.status)) output(block2.callID, block2.state.output ?? block2.state.error, block2.state.status === "error");
|
|
22114
22459
|
}
|
|
@@ -23363,7 +23708,7 @@ async function fetchKbCatalogBlock(client, timeoutMs, agent = "opencode") {
|
|
|
23363
23708
|
// src/warmup.ts
|
|
23364
23709
|
init_define_CTXDB_DISTRIBUTION_MANIFEST();
|
|
23365
23710
|
import { execSync } from "child_process";
|
|
23366
|
-
import { basename as
|
|
23711
|
+
import { basename as basename3 } from "path";
|
|
23367
23712
|
function collectGitSignals(cwd) {
|
|
23368
23713
|
const result = { branch: "", recentCommits: [] };
|
|
23369
23714
|
try {
|
|
@@ -23393,11 +23738,11 @@ function collectGitSignals(cwd) {
|
|
|
23393
23738
|
return result;
|
|
23394
23739
|
}
|
|
23395
23740
|
function buildWarmupQuery(cwd, git) {
|
|
23396
|
-
const project =
|
|
23397
|
-
const
|
|
23398
|
-
if (git.branch)
|
|
23399
|
-
if (git.recentCommits.length > 0)
|
|
23400
|
-
return
|
|
23741
|
+
const project = basename3(cwd) || "unknown";
|
|
23742
|
+
const parts2 = [`project: ${project}`];
|
|
23743
|
+
if (git.branch) parts2.push(`branch: ${git.branch}`);
|
|
23744
|
+
if (git.recentCommits.length > 0) parts2.push(`recent work: ${git.recentCommits.join("; ")}`);
|
|
23745
|
+
return parts2.join(", ");
|
|
23401
23746
|
}
|
|
23402
23747
|
|
|
23403
23748
|
// src/capture.ts
|
|
@@ -23442,9 +23787,9 @@ function toParsedMessage(m, index) {
|
|
|
23442
23787
|
if (!m || typeof m !== "object") return null;
|
|
23443
23788
|
const obj = m;
|
|
23444
23789
|
if (obj.info && typeof obj.info === "object" && Array.isArray(obj.parts)) {
|
|
23445
|
-
const
|
|
23446
|
-
const
|
|
23447
|
-
if (
|
|
23790
|
+
const info2 = obj.info;
|
|
23791
|
+
const role2 = info2.role;
|
|
23792
|
+
if (role2 !== "user" && role2 !== "assistant") return null;
|
|
23448
23793
|
const textChunks = [];
|
|
23449
23794
|
for (const rawPart of obj.parts) {
|
|
23450
23795
|
if (!rawPart || typeof rawPart !== "object") continue;
|
|
@@ -23455,8 +23800,8 @@ function toParsedMessage(m, index) {
|
|
|
23455
23800
|
}
|
|
23456
23801
|
const content = textChunks.join("\n").trim();
|
|
23457
23802
|
if (!content) return null;
|
|
23458
|
-
const isSummary =
|
|
23459
|
-
return { role, content, index, isSummary };
|
|
23803
|
+
const isSummary = role2 === "assistant" && info2.summary === true;
|
|
23804
|
+
return { role: role2, content, index, isSummary };
|
|
23460
23805
|
}
|
|
23461
23806
|
if (obj.type === "user") {
|
|
23462
23807
|
const content = typeof obj.text === "string" ? obj.text.trim() : "";
|
|
@@ -23490,7 +23835,13 @@ async function runCapture(messages, cfg, client, timeoutMs, lastFingerprint, ses
|
|
|
23490
23835
|
if (!cfg.autoCapture) return { ...EMPTY2, reason: "auto_capture_disabled" };
|
|
23491
23836
|
if (!cfg.baseUrl) return { ...EMPTY2, reason: "config_incomplete" };
|
|
23492
23837
|
if (messages.length === 0) return { ...EMPTY2, reason: "empty_transcript" };
|
|
23493
|
-
const
|
|
23838
|
+
const current = selectCaptureTurn(messages);
|
|
23839
|
+
const cleanup = detectMemoryCleanup(captureToolCalls(current));
|
|
23840
|
+
if (cleanup.detected) return { ...EMPTY2, reason: "memory_cleanup_skip" };
|
|
23841
|
+
const completionReason = captureCompletionReason(current, { sessionId });
|
|
23842
|
+
if (!current.length) return { ...EMPTY2, reason: "empty_turn_slice" };
|
|
23843
|
+
if (completionReason && completionReason !== "awaiting_assistant") return { ...EMPTY2, reason: completionReason };
|
|
23844
|
+
const parsed = toParsedMessages(current);
|
|
23494
23845
|
if (parsed.length === 0) return { ...EMPTY2, reason: "transcript_no_text_parts" };
|
|
23495
23846
|
const turn = selectTurnMessages(parsed);
|
|
23496
23847
|
if (turn.length === 0) return { ...EMPTY2, reason: "empty_turn_slice" };
|
|
@@ -23498,6 +23849,7 @@ async function runCapture(messages, cfg, client, timeoutMs, lastFingerprint, ses
|
|
|
23498
23849
|
if (!turn.some((m) => m.role === "assistant")) {
|
|
23499
23850
|
return { ...EMPTY2, reason: "no_assistant_in_turn" };
|
|
23500
23851
|
}
|
|
23852
|
+
if (completionReason) return { ...EMPTY2, reason: completionReason };
|
|
23501
23853
|
const raw = turn.map((m) => ({ role: m.role, content: m.content }));
|
|
23502
23854
|
const filtered = filterMessagesForExtraction(raw);
|
|
23503
23855
|
if (filtered.length === 0) return { ...EMPTY2, reason: "all_filtered" };
|
|
@@ -23582,9 +23934,9 @@ function pruneSessions(state) {
|
|
|
23582
23934
|
for (let i = 0; i < Math.min(overflow, sorted.length); i++) state.delete(sorted[i][0]);
|
|
23583
23935
|
}
|
|
23584
23936
|
}
|
|
23585
|
-
function extractTextPrompt(
|
|
23937
|
+
function extractTextPrompt(parts2) {
|
|
23586
23938
|
const chunks = [];
|
|
23587
|
-
for (const p of
|
|
23939
|
+
for (const p of parts2) {
|
|
23588
23940
|
if (p.type !== "text") continue;
|
|
23589
23941
|
if (p.synthetic === true || p.ignored === true) continue;
|
|
23590
23942
|
if (typeof p.text === "string" && p.text) chunks.push(p.text);
|