@autorag/librarian 2.9.0 → 2.10.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 +57 -2
- package/dist/agent/agent.d.ts +27 -21
- package/dist/agent/answer-citations.d.ts +22 -0
- package/dist/agent/answer-guidelines.d.ts +9 -9
- package/dist/agent/citations.d.ts +35 -23
- package/dist/agent/evidence-ledger.d.ts +7 -12
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/{emit-results-tool.d.ts → results.d.ts} +5 -40
- package/dist/agent/search-documents.d.ts +14 -19
- package/dist/agent/self-config.d.ts +1 -1
- package/dist/cli/commands/report.d.ts +1 -1
- package/dist/cli/commands/tui.d.ts +3 -2
- package/dist/cli/index.js +1466 -984
- package/dist/cloud/authorize.d.ts +12 -0
- package/dist/cloud/callback-server.d.ts +33 -0
- package/dist/cloud/callback.d.ts +23 -0
- package/dist/cloud/config.d.ts +23 -0
- package/dist/cloud/errors.d.ts +46 -0
- package/dist/cloud/index.d.ts +12 -0
- package/dist/cloud/models.d.ts +32 -0
- package/dist/cloud/oauth-login.d.ts +22 -0
- package/dist/cloud/pkce.d.ts +20 -0
- package/dist/cloud/provider.d.ts +40 -0
- package/dist/cloud/token.d.ts +22 -0
- package/dist/core.d.ts +2 -5
- package/dist/core.js +1341 -918
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1463 -928
- package/dist/mcp/index.js +1404 -925
- package/dist/minsync/client.d.ts +1 -1
- package/dist/minsync/installer.d.ts +1 -1
- package/dist/observability/run-log.d.ts +1 -1
- package/dist/retrieval/index.d.ts +1 -1
- package/dist/retrieval/types.d.ts +0 -23
- package/package.json +1 -1
- package/skills/autorag-lite-setup/SKILL.md +1 -1
- package/skills/autorag-setup/SKILL.md +2 -2
- package/dist/agent/fast-answer-tool.d.ts +0 -56
package/dist/index.js
CHANGED
|
@@ -5606,7 +5606,7 @@ function isGitHubAsset(value) {
|
|
|
5606
5606
|
function isRecord5(value) {
|
|
5607
5607
|
return typeof value === "object" && value !== null;
|
|
5608
5608
|
}
|
|
5609
|
-
var LATEST_RELEASE_URL = "https://api.github.com/repos/NomaDamas/MinSync/releases/latest", SHA256_HEX_PATTERN, MINSYNC_VERSION = "0.4.
|
|
5609
|
+
var LATEST_RELEASE_URL = "https://api.github.com/repos/NomaDamas/MinSync/releases/latest", SHA256_HEX_PATTERN, MINSYNC_VERSION = "0.4.6", MINSYNC_CARGO_INSTALL_TIMEOUT_MS, CARGO_PROBE_TIMEOUT_MS = 5000, MinSyncReleaseError;
|
|
5610
5610
|
var init_installer2 = __esm(() => {
|
|
5611
5611
|
init_process();
|
|
5612
5612
|
SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/;
|
|
@@ -8040,8 +8040,398 @@ var init_model_auth = __esm(() => {
|
|
|
8040
8040
|
};
|
|
8041
8041
|
});
|
|
8042
8042
|
|
|
8043
|
+
// src/agent/citations.ts
|
|
8044
|
+
function isAsciiDigit(code) {
|
|
8045
|
+
return code >= 48 && code <= 57;
|
|
8046
|
+
}
|
|
8047
|
+
function digitsEndAt(text, from) {
|
|
8048
|
+
let end = from;
|
|
8049
|
+
while (end < text.length && isAsciiDigit(text.charCodeAt(end)))
|
|
8050
|
+
end += 1;
|
|
8051
|
+
return end;
|
|
8052
|
+
}
|
|
8053
|
+
function continuesAsProse(answer, from) {
|
|
8054
|
+
if (answer[from] !== " " && answer[from] !== " ")
|
|
8055
|
+
return false;
|
|
8056
|
+
const next = answer.codePointAt(from + 1);
|
|
8057
|
+
return next !== undefined && /[\p{L}\p{N}]/u.test(String.fromCodePoint(next));
|
|
8058
|
+
}
|
|
8059
|
+
function evidenceMarkerAt(answer, index) {
|
|
8060
|
+
const ids = [];
|
|
8061
|
+
let cursor = index + 1;
|
|
8062
|
+
for (;; ) {
|
|
8063
|
+
if (answer[cursor] !== "e")
|
|
8064
|
+
return;
|
|
8065
|
+
const digitsEnd = digitsEndAt(answer, cursor + 1);
|
|
8066
|
+
if (digitsEnd === cursor + 1)
|
|
8067
|
+
return;
|
|
8068
|
+
ids.push(answer.slice(cursor, digitsEnd));
|
|
8069
|
+
cursor = digitsEnd;
|
|
8070
|
+
if (answer[cursor] === "]")
|
|
8071
|
+
return { ids, end: cursor + 1 };
|
|
8072
|
+
if (answer[cursor] !== ",")
|
|
8073
|
+
return;
|
|
8074
|
+
cursor += 1;
|
|
8075
|
+
while (answer[cursor] === " " || answer[cursor] === "\t")
|
|
8076
|
+
cursor += 1;
|
|
8077
|
+
}
|
|
8078
|
+
}
|
|
8079
|
+
function filePathFrom(raw) {
|
|
8080
|
+
const trimmed = raw.trim();
|
|
8081
|
+
return trimmed.startsWith("<") && trimmed.endsWith(">") ? trimmed.slice(1, -1).trim() : trimmed;
|
|
8082
|
+
}
|
|
8083
|
+
function fileMarkerAt(answer, index, isFile) {
|
|
8084
|
+
if (!answer.startsWith(FILE_MARKER_PREFIX, index))
|
|
8085
|
+
return;
|
|
8086
|
+
const bodyStart = index + FILE_MARKER_PREFIX.length;
|
|
8087
|
+
let closer = answer.indexOf("]", bodyStart);
|
|
8088
|
+
for (let attempt = 0;closer !== -1 && attempt < MAX_FILE_MARKER_CLOSERS; attempt++) {
|
|
8089
|
+
const path = filePathFrom(answer.slice(bodyStart, closer));
|
|
8090
|
+
if (path.length > 0 && isFile(path))
|
|
8091
|
+
return { path, end: closer + 1 };
|
|
8092
|
+
closer = answer.indexOf("]", closer + 1);
|
|
8093
|
+
}
|
|
8094
|
+
return;
|
|
8095
|
+
}
|
|
8096
|
+
function answerMarkers(answer, isFile = () => false) {
|
|
8097
|
+
const markers = [];
|
|
8098
|
+
let floor = 0;
|
|
8099
|
+
let closeIndex = -1;
|
|
8100
|
+
let index = 0;
|
|
8101
|
+
const leadingStart = (from) => {
|
|
8102
|
+
let start = from;
|
|
8103
|
+
while (start > floor && (answer[start - 1] === " " || answer[start - 1] === "\t"))
|
|
8104
|
+
start -= 1;
|
|
8105
|
+
return start;
|
|
8106
|
+
};
|
|
8107
|
+
while (index < answer.length) {
|
|
8108
|
+
const char = answer[index];
|
|
8109
|
+
if (char === "(" && answer[index + 1] === "<") {
|
|
8110
|
+
if (closeIndex < index + 2) {
|
|
8111
|
+
const found = answer.indexOf(">", index + 2);
|
|
8112
|
+
closeIndex = found === -1 ? answer.length : found;
|
|
8113
|
+
}
|
|
8114
|
+
if (answer[closeIndex + 1] === ")") {
|
|
8115
|
+
index = closeIndex + 2;
|
|
8116
|
+
floor = index;
|
|
8117
|
+
continue;
|
|
8118
|
+
}
|
|
8119
|
+
index += 1;
|
|
8120
|
+
continue;
|
|
8121
|
+
}
|
|
8122
|
+
if (char === "[") {
|
|
8123
|
+
const digitsEnd = digitsEndAt(answer, index + 1);
|
|
8124
|
+
if (digitsEnd > index + 1 && answer[digitsEnd] === "]" && answer[digitsEnd + 1] !== "(" && !continuesAsProse(answer, digitsEnd + 1)) {
|
|
8125
|
+
markers.push({
|
|
8126
|
+
kind: "number",
|
|
8127
|
+
start: leadingStart(index),
|
|
8128
|
+
end: digitsEnd + 1,
|
|
8129
|
+
number: Number(answer.slice(index + 1, digitsEnd))
|
|
8130
|
+
});
|
|
8131
|
+
index = digitsEnd + 1;
|
|
8132
|
+
floor = index;
|
|
8133
|
+
continue;
|
|
8134
|
+
}
|
|
8135
|
+
const evidence = evidenceMarkerAt(answer, index);
|
|
8136
|
+
if (evidence !== undefined && answer[evidence.end] !== "(") {
|
|
8137
|
+
markers.push({ kind: "evidence", start: leadingStart(index), end: evidence.end, ids: evidence.ids });
|
|
8138
|
+
index = evidence.end;
|
|
8139
|
+
floor = index;
|
|
8140
|
+
continue;
|
|
8141
|
+
}
|
|
8142
|
+
const file = fileMarkerAt(answer, index, isFile);
|
|
8143
|
+
if (file !== undefined && answer[file.end] !== "(") {
|
|
8144
|
+
markers.push({ kind: "file", start: leadingStart(index), end: file.end, path: file.path });
|
|
8145
|
+
index = file.end;
|
|
8146
|
+
floor = index;
|
|
8147
|
+
continue;
|
|
8148
|
+
}
|
|
8149
|
+
}
|
|
8150
|
+
index += 1;
|
|
8151
|
+
}
|
|
8152
|
+
return markers;
|
|
8153
|
+
}
|
|
8154
|
+
function stripUnresolvedCitations(answer, results) {
|
|
8155
|
+
const known = new Set(results.map((result) => result.number));
|
|
8156
|
+
const unresolved = new Set;
|
|
8157
|
+
let stripped = "";
|
|
8158
|
+
let cursor = 0;
|
|
8159
|
+
for (const marker of answerMarkers(answer)) {
|
|
8160
|
+
if (marker.kind !== "number" || known.has(marker.number))
|
|
8161
|
+
continue;
|
|
8162
|
+
unresolved.add(marker.number);
|
|
8163
|
+
stripped += answer.slice(cursor, marker.start);
|
|
8164
|
+
cursor = marker.end;
|
|
8165
|
+
}
|
|
8166
|
+
if (unresolved.size === 0)
|
|
8167
|
+
return { answer, unresolved: [] };
|
|
8168
|
+
return { answer: stripped + answer.slice(cursor), unresolved: [...unresolved].sort((a, b) => a - b) };
|
|
8169
|
+
}
|
|
8170
|
+
function formatCitationList(numbers) {
|
|
8171
|
+
return numbers.length === 0 ? "none" : numbers.map((number) => `[${number}]`).join(", ");
|
|
8172
|
+
}
|
|
8173
|
+
function duplicateNumbers(sortedNumbers) {
|
|
8174
|
+
const duplicates = [];
|
|
8175
|
+
for (let index = 1;index < sortedNumbers.length; index++) {
|
|
8176
|
+
const number = sortedNumbers[index];
|
|
8177
|
+
if (number === sortedNumbers[index - 1] && duplicates[duplicates.length - 1] !== number)
|
|
8178
|
+
duplicates.push(number);
|
|
8179
|
+
}
|
|
8180
|
+
return duplicates;
|
|
8181
|
+
}
|
|
8182
|
+
function assertResultsMappingOneToOne(label, results, mapping) {
|
|
8183
|
+
const resultNumbers = results.map((result) => result.number).sort((a, b) => a - b);
|
|
8184
|
+
const mappingNumbers = mapping.map((entry) => entry.number).sort((a, b) => a - b);
|
|
8185
|
+
const resultDuplicates = duplicateNumbers(resultNumbers);
|
|
8186
|
+
const mappingDuplicates = duplicateNumbers(mappingNumbers);
|
|
8187
|
+
const sameNumbers = resultNumbers.length === mappingNumbers.length && resultNumbers.every((number, index) => number === mappingNumbers[index]);
|
|
8188
|
+
if (sameNumbers && resultDuplicates.length === 0 && mappingDuplicates.length === 0)
|
|
8189
|
+
return;
|
|
8190
|
+
const duplicateNotes = [
|
|
8191
|
+
resultDuplicates.length > 0 ? `results repeat ${formatCitationList(resultDuplicates)}` : undefined,
|
|
8192
|
+
mappingDuplicates.length > 0 ? `mapping repeats ${formatCitationList(mappingDuplicates)}` : undefined
|
|
8193
|
+
].filter((note) => note !== undefined);
|
|
8194
|
+
throw new Error(`${label}: result numbers and mapping numbers must be one-to-one, but results contain ${formatCitationList(resultNumbers)} ` + `and mapping contains ${formatCitationList(mappingNumbers)}` + (duplicateNotes.length > 0 ? ` (${duplicateNotes.join("; ")})` : "") + ". Give every result a unique number with exactly one mapping entry carrying the same number and no mapping entry without a result.");
|
|
8195
|
+
}
|
|
8196
|
+
var MAX_FILE_MARKER_CLOSERS = 8, FILE_MARKER_PREFIX = "[file:";
|
|
8197
|
+
|
|
8198
|
+
// src/agent/evidence-ledger.ts
|
|
8199
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
8200
|
+
import { closeSync as closeSync2, openSync as openSync2, readSync, statSync } from "node:fs";
|
|
8201
|
+
import { isAbsolute as isAbsolute6 } from "node:path";
|
|
8202
|
+
function metadataString(metadata, key) {
|
|
8203
|
+
const value = metadata[key];
|
|
8204
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
8205
|
+
}
|
|
8206
|
+
function metadataNumber(metadata, key) {
|
|
8207
|
+
const value = metadata[key];
|
|
8208
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
8209
|
+
}
|
|
8210
|
+
function isRegularFile2(path) {
|
|
8211
|
+
try {
|
|
8212
|
+
return statSync(path).isFile();
|
|
8213
|
+
} catch {
|
|
8214
|
+
return false;
|
|
8215
|
+
}
|
|
8216
|
+
}
|
|
8217
|
+
function readFileExcerpt(path) {
|
|
8218
|
+
let descriptor;
|
|
8219
|
+
try {
|
|
8220
|
+
descriptor = openSync2(path, "r");
|
|
8221
|
+
const buffer = Buffer.alloc(MAX_CONTENT_CHARS * 4);
|
|
8222
|
+
const bytes = readSync(descriptor, buffer, 0, buffer.length, 0);
|
|
8223
|
+
const head = buffer.subarray(0, bytes);
|
|
8224
|
+
return head.includes(0) ? path : head.toString("utf8").slice(0, MAX_CONTENT_CHARS);
|
|
8225
|
+
} catch {
|
|
8226
|
+
return path;
|
|
8227
|
+
} finally {
|
|
8228
|
+
if (descriptor !== undefined)
|
|
8229
|
+
closeSync2(descriptor);
|
|
8230
|
+
}
|
|
8231
|
+
}
|
|
8232
|
+
function toEvidenceRef(entry) {
|
|
8233
|
+
return {
|
|
8234
|
+
method: entry.method,
|
|
8235
|
+
source: entry.source,
|
|
8236
|
+
content: entry.content,
|
|
8237
|
+
retrieverMix: [...entry.retrieverMix],
|
|
8238
|
+
...entry.retrievalResultId !== undefined ? { retrievalResultId: entry.retrievalResultId } : {},
|
|
8239
|
+
...entry.chunkIndex !== undefined ? { chunkIndex: entry.chunkIndex } : {},
|
|
8240
|
+
...entry.lineNumber !== undefined ? { lineNumber: entry.lineNumber } : {},
|
|
8241
|
+
...entry.parserType !== undefined ? { parserType: entry.parserType } : {},
|
|
8242
|
+
...entry.documentType !== undefined ? { documentType: entry.documentType } : {},
|
|
8243
|
+
...entry.documentArea !== undefined ? { documentArea: entry.documentArea } : {},
|
|
8244
|
+
...entry.evidenceType !== undefined ? { evidenceType: entry.evidenceType } : {},
|
|
8245
|
+
...entry.evidenceLocation !== undefined ? { evidenceLocation: entry.evidenceLocation } : {}
|
|
8246
|
+
};
|
|
8247
|
+
}
|
|
8248
|
+
|
|
8249
|
+
class EvidenceLedger {
|
|
8250
|
+
entries = [];
|
|
8251
|
+
byKey = new Map;
|
|
8252
|
+
byId = new Map;
|
|
8253
|
+
lastOrdinal = 0;
|
|
8254
|
+
register(input) {
|
|
8255
|
+
const content = input.content.slice(0, MAX_CONTENT_CHARS);
|
|
8256
|
+
const digest = createHash10("sha256").update(input.content.replace(/\s+/gu, " ").trim()).digest("hex");
|
|
8257
|
+
const key = `${input.source}\x00${digest}`;
|
|
8258
|
+
const existing = this.byKey.get(key);
|
|
8259
|
+
if (existing !== undefined) {
|
|
8260
|
+
if (!existing.retrieverMix.includes(input.method))
|
|
8261
|
+
existing.retrieverMix.push(input.method);
|
|
8262
|
+
return existing.id;
|
|
8263
|
+
}
|
|
8264
|
+
const entry = {
|
|
8265
|
+
...input,
|
|
8266
|
+
content,
|
|
8267
|
+
id: `e${++this.lastOrdinal}`,
|
|
8268
|
+
retrieverMix: [input.method]
|
|
8269
|
+
};
|
|
8270
|
+
this.entries.push(entry);
|
|
8271
|
+
this.byKey.set(key, entry);
|
|
8272
|
+
this.byId.set(entry.id, entry);
|
|
8273
|
+
return entry.id;
|
|
8274
|
+
}
|
|
8275
|
+
registerResult(tool, result) {
|
|
8276
|
+
const metadata = result.metadata;
|
|
8277
|
+
const chunkIndex = metadataNumber(metadata, "chunkIndex");
|
|
8278
|
+
const lineNumber = metadataNumber(metadata, "lineNumber");
|
|
8279
|
+
const parserType = metadataString(metadata, "parserType");
|
|
8280
|
+
const documentType = metadataString(metadata, "documentType");
|
|
8281
|
+
const documentArea = metadataString(metadata, "documentArea");
|
|
8282
|
+
const evidenceType = metadataString(metadata, "evidenceType");
|
|
8283
|
+
const evidenceLocation = metadataString(metadata, "evidenceLocation");
|
|
8284
|
+
return this.register({
|
|
8285
|
+
method: metadataString(metadata, "method") ?? tool,
|
|
8286
|
+
source: result.source,
|
|
8287
|
+
content: result.content,
|
|
8288
|
+
retrievalResultId: result.id,
|
|
8289
|
+
...chunkIndex !== undefined ? { chunkIndex } : {},
|
|
8290
|
+
...lineNumber !== undefined ? { lineNumber } : {},
|
|
8291
|
+
...parserType !== undefined ? { parserType } : {},
|
|
8292
|
+
...documentType !== undefined ? { documentType } : {},
|
|
8293
|
+
...documentArea !== undefined ? { documentArea } : {},
|
|
8294
|
+
...evidenceType !== undefined ? { evidenceType } : {},
|
|
8295
|
+
...evidenceLocation !== undefined ? { evidenceLocation } : {}
|
|
8296
|
+
});
|
|
8297
|
+
}
|
|
8298
|
+
lookup(raw, options) {
|
|
8299
|
+
const trimmed = raw.trim();
|
|
8300
|
+
const ref = trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1).trim() : trimmed;
|
|
8301
|
+
const byId = this.byId.get(ref);
|
|
8302
|
+
if (byId !== undefined)
|
|
8303
|
+
return [toEvidenceRef(byId)];
|
|
8304
|
+
const bySource = this.entries.filter((entry) => entry.source === ref);
|
|
8305
|
+
if (bySource.length > 0)
|
|
8306
|
+
return bySource.map(toEvidenceRef);
|
|
8307
|
+
if (options.allowLocalFiles && isAbsolute6(ref) && isRegularFile2(ref)) {
|
|
8308
|
+
return [{ method: "bash", source: ref, content: readFileExcerpt(ref) }];
|
|
8309
|
+
}
|
|
8310
|
+
return [];
|
|
8311
|
+
}
|
|
8312
|
+
clear() {
|
|
8313
|
+
this.entries = [];
|
|
8314
|
+
this.byKey.clear();
|
|
8315
|
+
this.byId.clear();
|
|
8316
|
+
}
|
|
8317
|
+
}
|
|
8318
|
+
var MAX_CONTENT_CHARS = 2000;
|
|
8319
|
+
var init_evidence_ledger = () => {};
|
|
8320
|
+
|
|
8321
|
+
// src/agent/answer-citations.ts
|
|
8322
|
+
import { isAbsolute as isAbsolute7 } from "node:path";
|
|
8323
|
+
function claimBefore(text, end) {
|
|
8324
|
+
const window = text.slice(Math.max(0, end - CLAIM_LOOKBACK_CHARS), end);
|
|
8325
|
+
const lineStart = window.lastIndexOf(`
|
|
8326
|
+
`) + 1;
|
|
8327
|
+
const line = window.slice(lineStart).replace(EVIDENCE_MARKER_TEXT, "");
|
|
8328
|
+
let start = 0;
|
|
8329
|
+
for (let index = line.length - 2;index >= 0; index--) {
|
|
8330
|
+
if (SENTENCE_END.test(line.charAt(index)) && /\s/u.test(line.charAt(index + 1))) {
|
|
8331
|
+
start = index + 2;
|
|
8332
|
+
break;
|
|
8333
|
+
}
|
|
8334
|
+
}
|
|
8335
|
+
const claim = line.slice(start).replace(LEADING_LIST_MARK, "").replace(/\s+/gu, " ").trim();
|
|
8336
|
+
return claim.length > MAX_CLAIM_CHARS ? `${claim.slice(0, MAX_CLAIM_CHARS)}…` : claim;
|
|
8337
|
+
}
|
|
8338
|
+
function deriveResultsFromAnswer(text, ledger, options) {
|
|
8339
|
+
const isFile = (path) => options.allowLocalFiles && isAbsolute7(path) && isRegularFile2(path);
|
|
8340
|
+
const sources = new Map;
|
|
8341
|
+
const dropped = new Set;
|
|
8342
|
+
let answer = "";
|
|
8343
|
+
let cursor = 0;
|
|
8344
|
+
let lastEmitted;
|
|
8345
|
+
const cite = (reference, claimEnd) => {
|
|
8346
|
+
const refs = ledger.lookup(reference, options);
|
|
8347
|
+
const [primary] = refs;
|
|
8348
|
+
if (primary === undefined) {
|
|
8349
|
+
dropped.add(reference);
|
|
8350
|
+
return;
|
|
8351
|
+
}
|
|
8352
|
+
let cited = sources.get(primary.source);
|
|
8353
|
+
if (cited === undefined) {
|
|
8354
|
+
cited = { number: sources.size + 1, refs: [], chunkKeys: new Set, claim: claimBefore(text, claimEnd) };
|
|
8355
|
+
sources.set(primary.source, cited);
|
|
8356
|
+
}
|
|
8357
|
+
for (const ref of refs) {
|
|
8358
|
+
const chunkKey = `${ref.source}\x00${ref.content ?? ""}`;
|
|
8359
|
+
if (cited.chunkKeys.has(chunkKey))
|
|
8360
|
+
continue;
|
|
8361
|
+
cited.chunkKeys.add(chunkKey);
|
|
8362
|
+
cited.refs.push(ref);
|
|
8363
|
+
}
|
|
8364
|
+
return cited.number;
|
|
8365
|
+
};
|
|
8366
|
+
for (const marker of answerMarkers(text, isFile)) {
|
|
8367
|
+
answer += text.slice(cursor, marker.start);
|
|
8368
|
+
cursor = marker.end;
|
|
8369
|
+
if (marker.kind === "number") {
|
|
8370
|
+
dropped.add(`[${marker.number}]`);
|
|
8371
|
+
continue;
|
|
8372
|
+
}
|
|
8373
|
+
const references = marker.kind === "evidence" ? marker.ids : [`file:${marker.path}`];
|
|
8374
|
+
const numbers = [];
|
|
8375
|
+
for (const reference of references) {
|
|
8376
|
+
const number = cite(marker.kind === "file" ? marker.path : reference, marker.start);
|
|
8377
|
+
if (number !== undefined && !numbers.includes(number))
|
|
8378
|
+
numbers.push(number);
|
|
8379
|
+
}
|
|
8380
|
+
if (numbers.length === 0)
|
|
8381
|
+
continue;
|
|
8382
|
+
const adjacent = lastEmitted !== undefined && text.slice(lastEmitted.end, marker.start).trim() === "";
|
|
8383
|
+
const fresh = numbers.filter((number) => !(adjacent && lastEmitted?.number === number));
|
|
8384
|
+
lastEmitted = { number: numbers[numbers.length - 1], end: marker.end };
|
|
8385
|
+
if (fresh.length === 0)
|
|
8386
|
+
continue;
|
|
8387
|
+
const leading = LEADING_BLANK.exec(text.slice(marker.start, marker.end))?.[0] ?? "";
|
|
8388
|
+
answer += leading + fresh.map((number) => `[${number}]`).join("");
|
|
8389
|
+
}
|
|
8390
|
+
answer += text.slice(cursor);
|
|
8391
|
+
const results = [];
|
|
8392
|
+
const mapping = [];
|
|
8393
|
+
for (const [source, cited] of sources) {
|
|
8394
|
+
const [primary] = cited.refs;
|
|
8395
|
+
if (primary === undefined)
|
|
8396
|
+
continue;
|
|
8397
|
+
results.push({
|
|
8398
|
+
number: cited.number,
|
|
8399
|
+
title: source.split(/[\\/]/u).filter((part) => part.length > 0).pop() ?? source,
|
|
8400
|
+
summary: cited.claim,
|
|
8401
|
+
evidence: cited.refs.map((ref) => {
|
|
8402
|
+
const excerpt = (ref.content ?? "").replace(/\s+/gu, " ").trim().slice(0, MAX_EXCERPT_CHARS);
|
|
8403
|
+
return ref.lineNumber !== undefined ? { excerpt, lineNumber: ref.lineNumber } : { excerpt };
|
|
8404
|
+
})
|
|
8405
|
+
});
|
|
8406
|
+
mapping.push({
|
|
8407
|
+
number: cited.number,
|
|
8408
|
+
source,
|
|
8409
|
+
method: primary.method,
|
|
8410
|
+
content: primary.content ?? "",
|
|
8411
|
+
evidenceRefs: cited.refs
|
|
8412
|
+
});
|
|
8413
|
+
}
|
|
8414
|
+
const diagnostics = dropped.size === 0 ? [] : [
|
|
8415
|
+
{
|
|
8416
|
+
code: "citation-without-result",
|
|
8417
|
+
severity: "warning",
|
|
8418
|
+
message: `Dropped ${dropped.size} answer citation(s) that matched no evidence retrieved in this run: ${[...dropped].join(", ")}. Every remaining citation resolves to a recorded source.`,
|
|
8419
|
+
source: "agent"
|
|
8420
|
+
}
|
|
8421
|
+
];
|
|
8422
|
+
return { details: { answer: answer.trim(), results, mapping, warnings: [] }, diagnostics };
|
|
8423
|
+
}
|
|
8424
|
+
var MAX_EXCERPT_CHARS = 400, MAX_CLAIM_CHARS = 280, CLAIM_LOOKBACK_CHARS = 600, SENTENCE_END, LEADING_LIST_MARK, EVIDENCE_MARKER_TEXT, LEADING_BLANK;
|
|
8425
|
+
var init_answer_citations = __esm(() => {
|
|
8426
|
+
init_evidence_ledger();
|
|
8427
|
+
SENTENCE_END = /[.!?。!?]/u;
|
|
8428
|
+
LEADING_LIST_MARK = /^[\s\-*•>]+/u;
|
|
8429
|
+
EVIDENCE_MARKER_TEXT = /\[(?:e\d+(?:,\s*)?)+\]|\[file:[^\]]*\]/gu;
|
|
8430
|
+
LEADING_BLANK = /^[ \t]*/u;
|
|
8431
|
+
});
|
|
8432
|
+
|
|
8043
8433
|
// src/agent/answer-guidelines.ts
|
|
8044
|
-
var ANSWER_IMAGE_EMBED_RULE = "**Images**: when a retrieved result is itself an image file (png, jpg, jpeg, gif, webp, svg, bmp, avif, heic, tiff) and showing it answers the question, embed it in
|
|
8434
|
+
var ANSWER_IMAGE_EMBED_RULE = "**Images**: when a retrieved result is itself an image file (png, jpg, jpeg, gif, webp, svg, bmp, avif, heic, tiff) and showing it answers the question, embed it in the answer as a markdown image on its own line: ``, followed by its citation, e.g. ` [e2]`. Use only the real source path of retrieved evidence. Never invent a path, use relative paths, or embed remote URLs. Apart from these image embeds, the no-file-paths rule stands.", ANSWER_IMAGE_DELTA_RULE = "An image already embedded in the first answer must not be embedded again.", ANSWER_CITATION_RULE = "**Citations**: cite supporting evidence inline with the evidence id shown next to each retrieved result, in square brackets (e.g. [e3], or [e3][e7] for two). Copy ids exactly; never invent one. For a local file you opened yourself with `bash`, cite `[file:<absolute path>]`. Cite the evidence that backs a sentence at the end of that sentence. Do not cite numbers, paths, or anything else.";
|
|
8045
8435
|
|
|
8046
8436
|
// src/agent/datasource-skill.ts
|
|
8047
8437
|
import { Type as Type2 } from "typebox";
|
|
@@ -8242,230 +8632,8 @@ var init_dupey_tool = __esm(() => {
|
|
|
8242
8632
|
scanDuplicateDocumentsSchema = Type3.Object({});
|
|
8243
8633
|
});
|
|
8244
8634
|
|
|
8245
|
-
// src/agent/citations.ts
|
|
8246
|
-
function isAsciiDigit(code) {
|
|
8247
|
-
return code >= 48 && code <= 57;
|
|
8248
|
-
}
|
|
8249
|
-
function citationMarkers(answer) {
|
|
8250
|
-
const markers = [];
|
|
8251
|
-
let floor = 0;
|
|
8252
|
-
let closeIndex = -1;
|
|
8253
|
-
let index = 0;
|
|
8254
|
-
while (index < answer.length) {
|
|
8255
|
-
const char = answer[index];
|
|
8256
|
-
if (char === "(" && answer[index + 1] === "<") {
|
|
8257
|
-
if (closeIndex < index + 2) {
|
|
8258
|
-
const found = answer.indexOf(">", index + 2);
|
|
8259
|
-
closeIndex = found === -1 ? answer.length : found;
|
|
8260
|
-
}
|
|
8261
|
-
if (answer[closeIndex + 1] === ")") {
|
|
8262
|
-
index = closeIndex + 2;
|
|
8263
|
-
floor = index;
|
|
8264
|
-
continue;
|
|
8265
|
-
}
|
|
8266
|
-
index += 1;
|
|
8267
|
-
continue;
|
|
8268
|
-
}
|
|
8269
|
-
if (char === "[") {
|
|
8270
|
-
let digitsEnd = index + 1;
|
|
8271
|
-
while (digitsEnd < answer.length && isAsciiDigit(answer.charCodeAt(digitsEnd)))
|
|
8272
|
-
digitsEnd += 1;
|
|
8273
|
-
if (digitsEnd > index + 1 && answer[digitsEnd] === "]" && answer[digitsEnd + 1] !== "(") {
|
|
8274
|
-
let start = index;
|
|
8275
|
-
while (start > floor && (answer[start - 1] === " " || answer[start - 1] === "\t"))
|
|
8276
|
-
start -= 1;
|
|
8277
|
-
markers.push({ start, end: digitsEnd + 1, number: Number(answer.slice(index + 1, digitsEnd)) });
|
|
8278
|
-
index = digitsEnd + 1;
|
|
8279
|
-
floor = index;
|
|
8280
|
-
continue;
|
|
8281
|
-
}
|
|
8282
|
-
}
|
|
8283
|
-
index += 1;
|
|
8284
|
-
}
|
|
8285
|
-
return markers;
|
|
8286
|
-
}
|
|
8287
|
-
function unresolvedCitations(answer, results) {
|
|
8288
|
-
const known = new Set(results.map((result) => result.number));
|
|
8289
|
-
const unresolved = new Set;
|
|
8290
|
-
for (const marker of citationMarkers(answer)) {
|
|
8291
|
-
if (!known.has(marker.number))
|
|
8292
|
-
unresolved.add(marker.number);
|
|
8293
|
-
}
|
|
8294
|
-
return [...unresolved].sort((a, b) => a - b);
|
|
8295
|
-
}
|
|
8296
|
-
function stripUnresolvedCitations(answer, results) {
|
|
8297
|
-
const known = new Set(results.map((result) => result.number));
|
|
8298
|
-
const unresolved = new Set;
|
|
8299
|
-
let stripped = "";
|
|
8300
|
-
let cursor = 0;
|
|
8301
|
-
for (const marker of citationMarkers(answer)) {
|
|
8302
|
-
if (known.has(marker.number))
|
|
8303
|
-
continue;
|
|
8304
|
-
unresolved.add(marker.number);
|
|
8305
|
-
stripped += answer.slice(cursor, marker.start);
|
|
8306
|
-
cursor = marker.end;
|
|
8307
|
-
}
|
|
8308
|
-
if (unresolved.size === 0)
|
|
8309
|
-
return { answer, unresolved: [] };
|
|
8310
|
-
return { answer: stripped + answer.slice(cursor), unresolved: [...unresolved].sort((a, b) => a - b) };
|
|
8311
|
-
}
|
|
8312
|
-
function formatCitationList(numbers) {
|
|
8313
|
-
return numbers.length === 0 ? "none" : numbers.map((number) => `[${number}]`).join(", ");
|
|
8314
|
-
}
|
|
8315
|
-
function duplicateNumbers(sortedNumbers) {
|
|
8316
|
-
const duplicates = [];
|
|
8317
|
-
for (let index = 1;index < sortedNumbers.length; index++) {
|
|
8318
|
-
const number = sortedNumbers[index];
|
|
8319
|
-
if (number === sortedNumbers[index - 1] && duplicates[duplicates.length - 1] !== number)
|
|
8320
|
-
duplicates.push(number);
|
|
8321
|
-
}
|
|
8322
|
-
return duplicates;
|
|
8323
|
-
}
|
|
8324
|
-
function assertUniqueResultNumbers(label, results) {
|
|
8325
|
-
const duplicates = duplicateNumbers(results.map((result) => result.number).sort((a, b) => a - b));
|
|
8326
|
-
if (duplicates.length === 0)
|
|
8327
|
-
return;
|
|
8328
|
-
throw new Error(`${label}: result numbers must be unique, but results repeat ${formatCitationList(duplicates)}. Give every result its own number and re-emit.`);
|
|
8329
|
-
}
|
|
8330
|
-
function assertResultsMappingOneToOne(label, results, mapping) {
|
|
8331
|
-
const resultNumbers = results.map((result) => result.number).sort((a, b) => a - b);
|
|
8332
|
-
const mappingNumbers = mapping.map((entry) => entry.number).sort((a, b) => a - b);
|
|
8333
|
-
const resultDuplicates = duplicateNumbers(resultNumbers);
|
|
8334
|
-
const mappingDuplicates = duplicateNumbers(mappingNumbers);
|
|
8335
|
-
const sameNumbers = resultNumbers.length === mappingNumbers.length && resultNumbers.every((number, index) => number === mappingNumbers[index]);
|
|
8336
|
-
if (sameNumbers && resultDuplicates.length === 0 && mappingDuplicates.length === 0)
|
|
8337
|
-
return;
|
|
8338
|
-
const duplicateNotes = [
|
|
8339
|
-
resultDuplicates.length > 0 ? `results repeat ${formatCitationList(resultDuplicates)}` : undefined,
|
|
8340
|
-
mappingDuplicates.length > 0 ? `mapping repeats ${formatCitationList(mappingDuplicates)}` : undefined
|
|
8341
|
-
].filter((note) => note !== undefined);
|
|
8342
|
-
throw new Error(`${label}: result numbers and mapping numbers must be one-to-one, but results contain ${formatCitationList(resultNumbers)} ` + `and mapping contains ${formatCitationList(mappingNumbers)}` + (duplicateNotes.length > 0 ? ` (${duplicateNotes.join("; ")})` : "") + ". Give every result a unique number with exactly one mapping entry carrying the same number and no mapping entry without a result. Re-emit with consistent numbering.");
|
|
8343
|
-
}
|
|
8344
|
-
function assertCitationsResolve(label, answer, results) {
|
|
8345
|
-
const unresolved = unresolvedCitations(answer, results);
|
|
8346
|
-
if (unresolved.length === 0)
|
|
8347
|
-
return;
|
|
8348
|
-
const emitted = [...new Set(results.map((result) => result.number))].sort((a, b) => a - b);
|
|
8349
|
-
throw new Error(`${label}: answer cites ${formatCitationList(unresolved)} but results only contain ${formatCitationList(emitted)}. ` + "Every bracketed citation in answer must be the number of a result in results of this same call; " + "candidate numbers from retrieval context or an earlier answer are not citation numbers. Re-emit with consistent numbering.");
|
|
8350
|
-
}
|
|
8351
|
-
|
|
8352
|
-
// src/agent/emit-results-tool.ts
|
|
8353
|
-
import { Type as Type4 } from "typebox";
|
|
8354
|
-
function createEmitResultsTool(capture, options) {
|
|
8355
|
-
return {
|
|
8356
|
-
name: EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
8357
|
-
label: "Emit AutoRAG Results",
|
|
8358
|
-
description: "Return the final structured AutoRAG answer. Call this exactly once as your last action after searching, reading, and curating. Cite each result's supporting evidence in its refs, using the evidence ids shown next to retrieved results (e.g. e3); the source paths are attached for you. A call whose answer cites a number missing from results, whose result numbers repeat, or whose refs name evidence no tool returned is rejected; fix it and call again.",
|
|
8359
|
-
parameters: emitResultsSchema,
|
|
8360
|
-
async execute(_toolCallId, params) {
|
|
8361
|
-
assertCitationsResolve(EMIT_AUTORAG_RESULTS_TOOL_NAME, params.answer, params.results);
|
|
8362
|
-
assertUniqueResultNumbers(EMIT_AUTORAG_RESULTS_TOOL_NAME, params.results);
|
|
8363
|
-
const mapping = params.results.map((result) => {
|
|
8364
|
-
const evidenceRefs = options.ledger.resolve(result.refs, {
|
|
8365
|
-
label: EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
8366
|
-
number: result.number,
|
|
8367
|
-
fallbackContent: result.evidence.map((evidence) => evidence.excerpt).join(`
|
|
8368
|
-
`) || result.summary,
|
|
8369
|
-
allowLocalFiles: options.allowLocalFiles
|
|
8370
|
-
});
|
|
8371
|
-
const primary = evidenceRefs[0];
|
|
8372
|
-
if (primary === undefined) {
|
|
8373
|
-
throw new Error(`${EMIT_AUTORAG_RESULTS_TOOL_NAME}: result ${result.number} resolved no evidence. Give it at least one valid ref.`);
|
|
8374
|
-
}
|
|
8375
|
-
return {
|
|
8376
|
-
number: result.number,
|
|
8377
|
-
source: primary.source,
|
|
8378
|
-
method: primary.method,
|
|
8379
|
-
content: primary.content ?? "",
|
|
8380
|
-
evidenceRefs
|
|
8381
|
-
};
|
|
8382
|
-
});
|
|
8383
|
-
const details = {
|
|
8384
|
-
answer: params.answer,
|
|
8385
|
-
results: params.results.map((result) => ({
|
|
8386
|
-
number: result.number,
|
|
8387
|
-
title: result.title,
|
|
8388
|
-
summary: result.summary,
|
|
8389
|
-
evidence: result.evidence.map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
8390
|
-
confidence: result.confidence
|
|
8391
|
-
})),
|
|
8392
|
-
mapping,
|
|
8393
|
-
warnings: params.warnings ?? []
|
|
8394
|
-
};
|
|
8395
|
-
capture(details);
|
|
8396
|
-
return {
|
|
8397
|
-
content: [{ type: "text", text: "AutoRAG results emitted." }],
|
|
8398
|
-
details,
|
|
8399
|
-
terminate: true
|
|
8400
|
-
};
|
|
8401
|
-
}
|
|
8402
|
-
};
|
|
8403
|
-
}
|
|
8404
|
-
var EMIT_AUTORAG_RESULTS_TOOL_NAME = "emit_autorag_results", evidenceRefSchema, answerSchema, warningsSchema, curatedResultFields, emitResultsSchema, reportSchema;
|
|
8405
|
-
var init_emit_results_tool = __esm(() => {
|
|
8406
|
-
evidenceRefSchema = Type4.Object({
|
|
8407
|
-
method: Type4.String({ description: "Retrieval method namespace for this evidence chunk" }),
|
|
8408
|
-
source: Type4.String({ description: "Internal opaque source identifier for this evidence chunk" }),
|
|
8409
|
-
excerpt: Type4.Optional(Type4.String({ description: "Evidence excerpt used for stable ID normalization" })),
|
|
8410
|
-
content: Type4.Optional(Type4.String({ description: "Evidence content used for stable ID normalization" })),
|
|
8411
|
-
retrievalResultId: Type4.Optional(Type4.String({ description: "Backend retrieval ID when path-opaque and stable" })),
|
|
8412
|
-
chunkIndex: Type4.Optional(Type4.Integer({ description: "Chunk index, if available" })),
|
|
8413
|
-
lineNumber: Type4.Optional(Type4.Integer({ description: "Line number, if available" })),
|
|
8414
|
-
stableEvidenceId: Type4.Optional(Type4.String({ description: "Stable evidence ID, if already normalized" })),
|
|
8415
|
-
retrieverMix: Type4.Optional(Type4.Array(Type4.String({ maxLength: 64 }), {
|
|
8416
|
-
description: "Retrievers that contributed to this result",
|
|
8417
|
-
maxItems: 8
|
|
8418
|
-
})),
|
|
8419
|
-
parserType: Type4.Optional(Type4.String({ description: "Parser that produced this evidence", maxLength: 120 })),
|
|
8420
|
-
documentType: Type4.Optional(Type4.String({ description: "Document type, if known", maxLength: 120 })),
|
|
8421
|
-
documentArea: Type4.Optional(Type4.String({ description: "Document collection area, if known", maxLength: 120 })),
|
|
8422
|
-
evidenceType: Type4.Optional(Type4.String({ description: "Evidence type, if known", maxLength: 120 })),
|
|
8423
|
-
evidenceLocation: Type4.Optional(Type4.String({ description: "Human-readable evidence location", maxLength: 120 })),
|
|
8424
|
-
confidence: Type4.Optional(Type4.Number({ description: "Evidence confidence, 0..1", minimum: 0, maximum: 1 }))
|
|
8425
|
-
});
|
|
8426
|
-
answerSchema = Type4.String({
|
|
8427
|
-
description: `Answer for the caller. When a first answer was already delivered to the caller during this run, this MUST contain only the corrections and newly verified findings relative to it — never restate the first answer; otherwise it is the complete answer. At most 5 bullet points (plus optional explanation); reference results by bracketed number (e.g. [1], [2]) without file paths or raw chunk text, except the image-embed exception below. ${ANSWER_CITATION_RULE} ${ANSWER_IMAGE_EMBED_RULE} ${ANSWER_IMAGE_DELTA_RULE}`
|
|
8428
|
-
});
|
|
8429
|
-
warningsSchema = Type4.Optional(Type4.Array(Type4.String(), { description: "Optional warnings about this result set" }));
|
|
8430
|
-
curatedResultFields = {
|
|
8431
|
-
number: Type4.Integer({ description: "1-based result number" }),
|
|
8432
|
-
title: Type4.String({ description: "Short name of the curated knowledge unit" }),
|
|
8433
|
-
summary: Type4.String({ description: "Key insight: purpose, details, and line range" }),
|
|
8434
|
-
evidence: Type4.Array(Type4.Object({
|
|
8435
|
-
excerpt: Type4.String({ description: "Supporting excerpt" }),
|
|
8436
|
-
lineNumber: Type4.Optional(Type4.Integer({ description: "Line number of the excerpt, if known" }))
|
|
8437
|
-
})),
|
|
8438
|
-
confidence: Type4.Number({ description: "Confidence in this result, 0..1", minimum: 0, maximum: 1 })
|
|
8439
|
-
};
|
|
8440
|
-
emitResultsSchema = Type4.Object({
|
|
8441
|
-
answer: answerSchema,
|
|
8442
|
-
results: Type4.Array(Type4.Object({
|
|
8443
|
-
...curatedResultFields,
|
|
8444
|
-
refs: Type4.Array(Type4.String(), {
|
|
8445
|
-
minItems: 1,
|
|
8446
|
-
description: "Evidence ids supporting this result, copied from the ids shown next to retrieved results (e.g. e3). For a local file you opened yourself with bash, give its absolute path instead."
|
|
8447
|
-
})
|
|
8448
|
-
}), { description: "Numbered curated knowledge units." }),
|
|
8449
|
-
warnings: warningsSchema
|
|
8450
|
-
});
|
|
8451
|
-
reportSchema = Type4.Object({
|
|
8452
|
-
answer: answerSchema,
|
|
8453
|
-
results: Type4.Array(Type4.Object(curatedResultFields), { description: "Numbered curated knowledge units." }),
|
|
8454
|
-
mapping: Type4.Array(Type4.Object({
|
|
8455
|
-
number: Type4.Integer({ description: "Matches the result number this entry maps" }),
|
|
8456
|
-
source: Type4.String({ description: "Source identifier — a real file path or a datasource id" }),
|
|
8457
|
-
method: Type4.String({ description: "Retrieval method or tool that produced the source" }),
|
|
8458
|
-
content: Type4.String({ description: "Raw content snippet of the evidence behind this result" }),
|
|
8459
|
-
evidenceRefs: Type4.Optional(Type4.Array(evidenceRefSchema, {
|
|
8460
|
-
description: "Hidden evidence chunk references supporting this curated result"
|
|
8461
|
-
}))
|
|
8462
|
-
}), { description: "Internal number -> source/method mapping. One entry per result number." }),
|
|
8463
|
-
warnings: warningsSchema
|
|
8464
|
-
});
|
|
8465
|
-
});
|
|
8466
|
-
|
|
8467
8635
|
// src/agent/everything-search-tool.ts
|
|
8468
|
-
import { Type as
|
|
8636
|
+
import { Type as Type4 } from "typebox";
|
|
8469
8637
|
function createEverythingSearchTool(provider) {
|
|
8470
8638
|
return {
|
|
8471
8639
|
name: EVERYTHING_SEARCH_TOOL_NAME,
|
|
@@ -8517,28 +8685,28 @@ ${lines.join(`
|
|
|
8517
8685
|
}
|
|
8518
8686
|
var EVERYTHING_SEARCH_TOOL_NAME = "everything_search", MAX_RESULTS_CAP2 = 1000, DEFAULT_MAX_RESULTS3 = 100, everythingSearchSchema;
|
|
8519
8687
|
var init_everything_search_tool = __esm(() => {
|
|
8520
|
-
everythingSearchSchema =
|
|
8521
|
-
query:
|
|
8688
|
+
everythingSearchSchema = Type4.Object({
|
|
8689
|
+
query: Type4.String({
|
|
8522
8690
|
description: 'Everything search syntax over file and folder names: space = AND, | = OR, ! = NOT, "quoted phrase", wildcards (*.pdf), ext:pdf;docx, dm:thisweek, size:>10mb, parent:<folder>, path fragments like \\reports\\ when matchPath is true.'
|
|
8523
8691
|
}),
|
|
8524
|
-
regex:
|
|
8525
|
-
matchCase:
|
|
8526
|
-
matchPath:
|
|
8527
|
-
wholeWord:
|
|
8528
|
-
kind:
|
|
8529
|
-
path:
|
|
8530
|
-
sort:
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8692
|
+
regex: Type4.Optional(Type4.Boolean({ description: "Treat query as a regular expression." })),
|
|
8693
|
+
matchCase: Type4.Optional(Type4.Boolean()),
|
|
8694
|
+
matchPath: Type4.Optional(Type4.Boolean({ description: "Match against the full path instead of the name." })),
|
|
8695
|
+
wholeWord: Type4.Optional(Type4.Boolean()),
|
|
8696
|
+
kind: Type4.Optional(Type4.Union([Type4.Literal("files"), Type4.Literal("folders")])),
|
|
8697
|
+
path: Type4.Optional(Type4.String({ description: "Absolute folder to search within." })),
|
|
8698
|
+
sort: Type4.Optional(Type4.Union([
|
|
8699
|
+
Type4.Literal("name-ascending"),
|
|
8700
|
+
Type4.Literal("name-descending"),
|
|
8701
|
+
Type4.Literal("path-ascending"),
|
|
8702
|
+
Type4.Literal("path-descending"),
|
|
8703
|
+
Type4.Literal("size-ascending"),
|
|
8704
|
+
Type4.Literal("size-descending"),
|
|
8705
|
+
Type4.Literal("date-modified-ascending"),
|
|
8706
|
+
Type4.Literal("date-modified-descending")
|
|
8539
8707
|
])),
|
|
8540
|
-
offset:
|
|
8541
|
-
maxResults:
|
|
8708
|
+
offset: Type4.Optional(Type4.Integer({ minimum: 0, description: "Skip this many results (pagination)." })),
|
|
8709
|
+
maxResults: Type4.Optional(Type4.Integer({
|
|
8542
8710
|
minimum: 1,
|
|
8543
8711
|
description: `Maximum results (default ${DEFAULT_MAX_RESULTS3}, cap ${MAX_RESULTS_CAP2}).`
|
|
8544
8712
|
}))
|
|
@@ -8670,146 +8838,6 @@ var init_evidence_judgment = __esm(() => {
|
|
|
8670
8838
|
};
|
|
8671
8839
|
});
|
|
8672
8840
|
|
|
8673
|
-
// src/agent/evidence-ledger.ts
|
|
8674
|
-
import { createHash as createHash10 } from "node:crypto";
|
|
8675
|
-
import { statSync } from "node:fs";
|
|
8676
|
-
import { isAbsolute as isAbsolute6 } from "node:path";
|
|
8677
|
-
function metadataString(metadata, key) {
|
|
8678
|
-
const value = metadata[key];
|
|
8679
|
-
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
8680
|
-
}
|
|
8681
|
-
function metadataNumber(metadata, key) {
|
|
8682
|
-
const value = metadata[key];
|
|
8683
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
8684
|
-
}
|
|
8685
|
-
function isRegularFile2(path) {
|
|
8686
|
-
try {
|
|
8687
|
-
return statSync(path).isFile();
|
|
8688
|
-
} catch {
|
|
8689
|
-
return false;
|
|
8690
|
-
}
|
|
8691
|
-
}
|
|
8692
|
-
function toEvidenceRef(entry) {
|
|
8693
|
-
return {
|
|
8694
|
-
method: entry.method,
|
|
8695
|
-
source: entry.source,
|
|
8696
|
-
content: entry.content,
|
|
8697
|
-
retrieverMix: [...entry.retrieverMix],
|
|
8698
|
-
...entry.retrievalResultId !== undefined ? { retrievalResultId: entry.retrievalResultId } : {},
|
|
8699
|
-
...entry.chunkIndex !== undefined ? { chunkIndex: entry.chunkIndex } : {},
|
|
8700
|
-
...entry.lineNumber !== undefined ? { lineNumber: entry.lineNumber } : {},
|
|
8701
|
-
...entry.parserType !== undefined ? { parserType: entry.parserType } : {},
|
|
8702
|
-
...entry.documentType !== undefined ? { documentType: entry.documentType } : {},
|
|
8703
|
-
...entry.documentArea !== undefined ? { documentArea: entry.documentArea } : {},
|
|
8704
|
-
...entry.evidenceType !== undefined ? { evidenceType: entry.evidenceType } : {},
|
|
8705
|
-
...entry.evidenceLocation !== undefined ? { evidenceLocation: entry.evidenceLocation } : {}
|
|
8706
|
-
};
|
|
8707
|
-
}
|
|
8708
|
-
|
|
8709
|
-
class EvidenceLedger {
|
|
8710
|
-
entries = [];
|
|
8711
|
-
byKey = new Map;
|
|
8712
|
-
byId = new Map;
|
|
8713
|
-
lastOrdinal = 0;
|
|
8714
|
-
register(input) {
|
|
8715
|
-
const content = input.content.slice(0, MAX_CONTENT_CHARS);
|
|
8716
|
-
const digest = createHash10("sha256").update(input.content.replace(/\s+/gu, " ").trim()).digest("hex");
|
|
8717
|
-
const key = `${input.source}\x00${digest}`;
|
|
8718
|
-
const existing = this.byKey.get(key);
|
|
8719
|
-
if (existing !== undefined) {
|
|
8720
|
-
if (!existing.retrieverMix.includes(input.method))
|
|
8721
|
-
existing.retrieverMix.push(input.method);
|
|
8722
|
-
return existing.id;
|
|
8723
|
-
}
|
|
8724
|
-
const entry = {
|
|
8725
|
-
...input,
|
|
8726
|
-
content,
|
|
8727
|
-
id: `e${++this.lastOrdinal}`,
|
|
8728
|
-
retrieverMix: [input.method]
|
|
8729
|
-
};
|
|
8730
|
-
this.entries.push(entry);
|
|
8731
|
-
this.byKey.set(key, entry);
|
|
8732
|
-
this.byId.set(entry.id, entry);
|
|
8733
|
-
return entry.id;
|
|
8734
|
-
}
|
|
8735
|
-
registerResult(tool, result) {
|
|
8736
|
-
const metadata = result.metadata;
|
|
8737
|
-
const chunkIndex = metadataNumber(metadata, "chunkIndex");
|
|
8738
|
-
const lineNumber = metadataNumber(metadata, "lineNumber");
|
|
8739
|
-
const parserType = metadataString(metadata, "parserType");
|
|
8740
|
-
const documentType = metadataString(metadata, "documentType");
|
|
8741
|
-
const documentArea = metadataString(metadata, "documentArea");
|
|
8742
|
-
const evidenceType = metadataString(metadata, "evidenceType");
|
|
8743
|
-
const evidenceLocation = metadataString(metadata, "evidenceLocation");
|
|
8744
|
-
return this.register({
|
|
8745
|
-
method: metadataString(metadata, "method") ?? tool,
|
|
8746
|
-
source: result.source,
|
|
8747
|
-
content: result.content,
|
|
8748
|
-
retrievalResultId: result.id,
|
|
8749
|
-
...chunkIndex !== undefined ? { chunkIndex } : {},
|
|
8750
|
-
...lineNumber !== undefined ? { lineNumber } : {},
|
|
8751
|
-
...parserType !== undefined ? { parserType } : {},
|
|
8752
|
-
...documentType !== undefined ? { documentType } : {},
|
|
8753
|
-
...documentArea !== undefined ? { documentArea } : {},
|
|
8754
|
-
...evidenceType !== undefined ? { evidenceType } : {},
|
|
8755
|
-
...evidenceLocation !== undefined ? { evidenceLocation } : {}
|
|
8756
|
-
});
|
|
8757
|
-
}
|
|
8758
|
-
resolve(refs, options) {
|
|
8759
|
-
const resolved = [];
|
|
8760
|
-
const seen = new Set;
|
|
8761
|
-
const push = (entry) => {
|
|
8762
|
-
if (seen.has(entry.id))
|
|
8763
|
-
return;
|
|
8764
|
-
seen.add(entry.id);
|
|
8765
|
-
resolved.push(toEvidenceRef(entry));
|
|
8766
|
-
};
|
|
8767
|
-
for (const raw of refs) {
|
|
8768
|
-
const trimmed = raw.trim();
|
|
8769
|
-
const ref = trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1).trim() : trimmed;
|
|
8770
|
-
const byId = this.byId.get(ref);
|
|
8771
|
-
if (byId !== undefined) {
|
|
8772
|
-
push(byId);
|
|
8773
|
-
continue;
|
|
8774
|
-
}
|
|
8775
|
-
const bySource = this.entries.filter((entry) => entry.source === ref);
|
|
8776
|
-
if (bySource.length > 0) {
|
|
8777
|
-
for (const entry of bySource)
|
|
8778
|
-
push(entry);
|
|
8779
|
-
continue;
|
|
8780
|
-
}
|
|
8781
|
-
if (options.allowLocalFiles && isAbsolute6(ref) && isRegularFile2(ref)) {
|
|
8782
|
-
const key = `file\x00${ref}`;
|
|
8783
|
-
if (seen.has(key))
|
|
8784
|
-
continue;
|
|
8785
|
-
seen.add(key);
|
|
8786
|
-
resolved.push({
|
|
8787
|
-
method: "bash",
|
|
8788
|
-
source: ref,
|
|
8789
|
-
content: (options.fallbackContent.trim() || ref).slice(0, MAX_CONTENT_CHARS)
|
|
8790
|
-
});
|
|
8791
|
-
continue;
|
|
8792
|
-
}
|
|
8793
|
-
throw new Error(this.unresolvedMessage(ref, EVIDENCE_ID_PATTERN.test(ref), options));
|
|
8794
|
-
}
|
|
8795
|
-
return resolved;
|
|
8796
|
-
}
|
|
8797
|
-
clear() {
|
|
8798
|
-
this.entries = [];
|
|
8799
|
-
this.byKey.clear();
|
|
8800
|
-
this.byId.clear();
|
|
8801
|
-
}
|
|
8802
|
-
unresolvedMessage(ref, looksLikeId, options) {
|
|
8803
|
-
const known = this.entries.length === 0 ? "No search or fetch has returned evidence in this run yet." : `Evidence ids issued in this run: ${this.entries[0]?.id}${this.entries.length > 1 ? `..${this.entries[this.entries.length - 1]?.id}` : ""}.`;
|
|
8804
|
-
const local = options.allowLocalFiles ? " For a file you opened yourself with bash, pass its absolute path." : "";
|
|
8805
|
-
return `${options.label}: result ${options.number} cites evidence "${ref}" that no tool returned in this run` + `${looksLikeId ? " (unknown evidence id)" : ""}. ${known} ` + `Cite only the evidence ids shown next to retrieved results (e.g. e3).${local} Re-emit with valid refs.`;
|
|
8806
|
-
}
|
|
8807
|
-
}
|
|
8808
|
-
var MAX_CONTENT_CHARS = 2000, EVIDENCE_ID_PATTERN;
|
|
8809
|
-
var init_evidence_ledger = __esm(() => {
|
|
8810
|
-
EVIDENCE_ID_PATTERN = /^e\d+$/u;
|
|
8811
|
-
});
|
|
8812
|
-
|
|
8813
8841
|
// src/agent/evidence-origins.ts
|
|
8814
8842
|
function normalize3(text) {
|
|
8815
8843
|
return text.normalize("NFC").toLowerCase().replace(/\s+/g, " ").trim();
|
|
@@ -8910,168 +8938,688 @@ class EvidenceOriginIndex {
|
|
|
8910
8938
|
}
|
|
8911
8939
|
return;
|
|
8912
8940
|
}
|
|
8913
|
-
clear() {
|
|
8914
|
-
this.candidates.length = 0;
|
|
8915
|
-
this.seen.clear();
|
|
8941
|
+
clear() {
|
|
8942
|
+
this.candidates.length = 0;
|
|
8943
|
+
this.seen.clear();
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
var MAX_CANDIDATES = 2000, MAX_CONTENT_LENGTH = 4000, MIN_MATCH_LENGTH = 12;
|
|
8947
|
+
|
|
8948
|
+
// src/agent/fsearch-search-tool.ts
|
|
8949
|
+
import { Type as Type5 } from "typebox";
|
|
8950
|
+
function createFSearchSearchTool(provider) {
|
|
8951
|
+
return {
|
|
8952
|
+
name: FSEARCH_SEARCH_TOOL_NAME,
|
|
8953
|
+
label: "FSearch Search",
|
|
8954
|
+
description: "Instantly find files and folders by name, extension, path, size, or modified date across the configured search folders using fsearch-cli/FSearch (macOS/Linux), falling back to a slow filesystem walk when fsearch-cli is not installed. Returns absolute paths; read file contents with bash.",
|
|
8955
|
+
parameters: fsearchSearchSchema,
|
|
8956
|
+
async execute(_toolCallId, params) {
|
|
8957
|
+
const query = params.query.trim();
|
|
8958
|
+
if (query.length === 0) {
|
|
8959
|
+
return {
|
|
8960
|
+
content: [{ type: "text", text: "FSearch query was empty; nothing searched." }],
|
|
8961
|
+
details: { method: FSEARCH_SEARCH_TOOL_NAME, resultCount: 0, sources: [], results: [] }
|
|
8962
|
+
};
|
|
8963
|
+
}
|
|
8964
|
+
const request = {
|
|
8965
|
+
...params,
|
|
8966
|
+
query,
|
|
8967
|
+
maxResults: Math.min(params.maxResults ?? DEFAULT_MAX_RESULTS4, MAX_RESULTS_CAP3)
|
|
8968
|
+
};
|
|
8969
|
+
const result = await provider.searchFsearch(request);
|
|
8970
|
+
if (!result.ok) {
|
|
8971
|
+
return {
|
|
8972
|
+
content: [{ type: "text", text: `FSearch ${result.reason}: ${result.message}` }],
|
|
8973
|
+
details: { method: FSEARCH_SEARCH_TOOL_NAME, resultCount: 0, sources: [], results: [] }
|
|
8974
|
+
};
|
|
8975
|
+
}
|
|
8976
|
+
const lines = result.results.map((entry, index) => {
|
|
8977
|
+
const parts = [`[${index + 1}] ${entry.type} ${entry.path}`];
|
|
8978
|
+
if (entry.size !== undefined)
|
|
8979
|
+
parts.push(`size=${entry.size}`);
|
|
8980
|
+
if (entry.dateModified !== undefined)
|
|
8981
|
+
parts.push(`modified=${entry.dateModified}`);
|
|
8982
|
+
return parts.join(" ");
|
|
8983
|
+
});
|
|
8984
|
+
const backendLabel = result.backend === "walk" ? "FSearch slow filesystem walk (fsearch-cli unavailable)" : "FSearch";
|
|
8985
|
+
const limitNote = result.backend === "fsearch-cli" && (result.total ?? 0) > lines.length && lines.length === request.maxResults ? ` of ${result.total} total (limit reached; narrow the query or page with offset)` : "";
|
|
8986
|
+
const noteSuffix = result.note !== undefined ? `
|
|
8987
|
+
${result.note}` : "";
|
|
8988
|
+
const text = lines.length === 0 ? `${backendLabel} found no files or folders matching: ${query}${noteSuffix}` : `${backendLabel} found ${lines.length} item(s)${limitNote}:
|
|
8989
|
+
${lines.join(`
|
|
8990
|
+
`)}${noteSuffix}`;
|
|
8991
|
+
return {
|
|
8992
|
+
content: [{ type: "text", text }],
|
|
8993
|
+
details: {
|
|
8994
|
+
method: FSEARCH_SEARCH_TOOL_NAME,
|
|
8995
|
+
resultCount: result.results.length,
|
|
8996
|
+
sources: result.results.map((entry) => entry.path),
|
|
8997
|
+
results: result.results.map((entry, index) => ({ source: entry.path, excerpt: lines[index] }))
|
|
8998
|
+
}
|
|
8999
|
+
};
|
|
9000
|
+
}
|
|
9001
|
+
};
|
|
9002
|
+
}
|
|
9003
|
+
var FSEARCH_SEARCH_TOOL_NAME = "fsearch_search", MAX_RESULTS_CAP3 = 1000, DEFAULT_MAX_RESULTS4 = 100, fsearchSearchSchema;
|
|
9004
|
+
var init_fsearch_search_tool = __esm(() => {
|
|
9005
|
+
fsearchSearchSchema = Type5.Object({
|
|
9006
|
+
query: Type5.String({
|
|
9007
|
+
description: 'FSearch query syntax over file and folder names: space = AND, OR keyword = OR (never the pipe |), ! = NOT, "quoted phrase", wildcards (*.pdf), ext:pdf;docx, size:>10mb, path:<fragment>, case:, regex:. When the slow-walk fallback answers (fsearch-cli not installed), only substring/regex name matching applies.'
|
|
9008
|
+
}),
|
|
9009
|
+
regex: Type5.Optional(Type5.Boolean({ description: "Treat query as a regular expression." })),
|
|
9010
|
+
matchCase: Type5.Optional(Type5.Boolean()),
|
|
9011
|
+
matchPath: Type5.Optional(Type5.Boolean({ description: "Match against the full path instead of the name." })),
|
|
9012
|
+
kind: Type5.Optional(Type5.Union([Type5.Literal("files"), Type5.Literal("folders")])),
|
|
9013
|
+
path: Type5.Optional(Type5.String({ description: "Absolute folder to search within." })),
|
|
9014
|
+
sort: Type5.Optional(Type5.Union([
|
|
9015
|
+
Type5.Literal("name-ascending"),
|
|
9016
|
+
Type5.Literal("name-descending"),
|
|
9017
|
+
Type5.Literal("path-ascending"),
|
|
9018
|
+
Type5.Literal("path-descending"),
|
|
9019
|
+
Type5.Literal("size-ascending"),
|
|
9020
|
+
Type5.Literal("size-descending"),
|
|
9021
|
+
Type5.Literal("date-modified-ascending"),
|
|
9022
|
+
Type5.Literal("date-modified-descending")
|
|
9023
|
+
])),
|
|
9024
|
+
offset: Type5.Optional(Type5.Integer({ minimum: 0, description: "Skip this many results (pagination)." })),
|
|
9025
|
+
maxResults: Type5.Optional(Type5.Integer({
|
|
9026
|
+
minimum: 1,
|
|
9027
|
+
description: `Maximum results (default ${DEFAULT_MAX_RESULTS4}, cap ${MAX_RESULTS_CAP3}).`
|
|
9028
|
+
}))
|
|
9029
|
+
});
|
|
9030
|
+
});
|
|
9031
|
+
|
|
9032
|
+
// src/cloud/config.ts
|
|
9033
|
+
function normalizeBaseUrl(value) {
|
|
9034
|
+
const trimmed = value.trim();
|
|
9035
|
+
let end = trimmed.length;
|
|
9036
|
+
while (end > 0 && trimmed.charCodeAt(end - 1) === 47)
|
|
9037
|
+
end--;
|
|
9038
|
+
return trimmed.slice(0, end);
|
|
9039
|
+
}
|
|
9040
|
+
function resolveBaseUrl(env) {
|
|
9041
|
+
const configured = env[AUTORAG_BASE_URL_ENV];
|
|
9042
|
+
const value = typeof configured === "string" && configured.trim() !== "" ? configured : DEFAULT_BASE_URL;
|
|
9043
|
+
return normalizeBaseUrl(value);
|
|
9044
|
+
}
|
|
9045
|
+
var PROVIDER_ID = "autorag", PROVIDER_NAME = "AutoRAG", DEFAULT_BASE_URL = "https://api.dazziapp.com", AUTORAG_BASE_URL_ENV = "AUTORAG_BASE_URL", AUTORAG_API_KEY_ENV = "AUTORAG_API_KEY", API_PATH = "/v1", MODELS_PATH = "/v1/models", AUTHORIZE_PATH = "/desktop/authorize", TOKEN_PATH = "/api/desktop/token", OAUTH_CLIENT_ID = "agent", API_KEY_CONFIG_VALUE;
|
|
9046
|
+
var init_config = __esm(() => {
|
|
9047
|
+
API_KEY_CONFIG_VALUE = `$${AUTORAG_API_KEY_ENV}`;
|
|
9048
|
+
});
|
|
9049
|
+
|
|
9050
|
+
// src/cloud/errors.ts
|
|
9051
|
+
function extractErrorPayload(body) {
|
|
9052
|
+
if (typeof body !== "object" || body === null)
|
|
9053
|
+
return {};
|
|
9054
|
+
const record = body;
|
|
9055
|
+
const error = record.error;
|
|
9056
|
+
if (typeof error === "string")
|
|
9057
|
+
return error.length > 0 ? { message: error } : {};
|
|
9058
|
+
if (typeof error === "object" && error !== null) {
|
|
9059
|
+
const inner = error;
|
|
9060
|
+
const payload = {};
|
|
9061
|
+
if (typeof inner.message === "string")
|
|
9062
|
+
payload.message = inner.message;
|
|
9063
|
+
if (typeof inner.code === "string")
|
|
9064
|
+
payload.code = inner.code;
|
|
9065
|
+
if (typeof inner.type === "string")
|
|
9066
|
+
payload.type = inner.type;
|
|
9067
|
+
return payload;
|
|
9068
|
+
}
|
|
9069
|
+
return typeof record.message === "string" ? { message: record.message } : {};
|
|
9070
|
+
}
|
|
9071
|
+
var AutoragError, AutoragOAuthError, AutoragHttpError;
|
|
9072
|
+
var init_errors3 = __esm(() => {
|
|
9073
|
+
AutoragError = class AutoragError extends Error {
|
|
9074
|
+
constructor(message, options) {
|
|
9075
|
+
super(message, options);
|
|
9076
|
+
this.name = "AutoragError";
|
|
9077
|
+
}
|
|
9078
|
+
};
|
|
9079
|
+
AutoragOAuthError = class AutoragOAuthError extends AutoragError {
|
|
9080
|
+
constructor(message, options) {
|
|
9081
|
+
super(message, options);
|
|
9082
|
+
this.name = "AutoragOAuthError";
|
|
9083
|
+
}
|
|
9084
|
+
};
|
|
9085
|
+
AutoragHttpError = class AutoragHttpError extends AutoragError {
|
|
9086
|
+
status;
|
|
9087
|
+
code;
|
|
9088
|
+
type;
|
|
9089
|
+
constructor(message, options) {
|
|
9090
|
+
super(message, { cause: options.cause });
|
|
9091
|
+
this.name = "AutoragHttpError";
|
|
9092
|
+
this.status = options.status;
|
|
9093
|
+
if (options.code !== undefined)
|
|
9094
|
+
this.code = options.code;
|
|
9095
|
+
if (options.type !== undefined)
|
|
9096
|
+
this.type = options.type;
|
|
9097
|
+
}
|
|
9098
|
+
};
|
|
9099
|
+
});
|
|
9100
|
+
|
|
9101
|
+
// src/cloud/models.ts
|
|
9102
|
+
function resolveCredentialKey(credential) {
|
|
9103
|
+
if (credential === undefined)
|
|
9104
|
+
return;
|
|
9105
|
+
const value = credential.type === "oauth" ? credential.access : credential.key;
|
|
9106
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
9107
|
+
}
|
|
9108
|
+
async function fetchModels(options) {
|
|
9109
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
9110
|
+
let response;
|
|
9111
|
+
try {
|
|
9112
|
+
response = await doFetch(`${normalizeBaseUrl(options.baseUrl)}${MODELS_PATH}`, {
|
|
9113
|
+
headers: { authorization: `Bearer ${options.apiKey}`, accept: "application/json" },
|
|
9114
|
+
signal: options.signal
|
|
9115
|
+
});
|
|
9116
|
+
} catch (cause) {
|
|
9117
|
+
if (options.signal?.aborted) {
|
|
9118
|
+
throw new AutoragOAuthError("AutoRAG model refresh was cancelled.", { cause });
|
|
9119
|
+
}
|
|
9120
|
+
throw new AutoragOAuthError(`AutoRAG model listing could not reach ${normalizeBaseUrl(options.baseUrl)}.`, {
|
|
9121
|
+
cause
|
|
9122
|
+
});
|
|
9123
|
+
}
|
|
9124
|
+
let body;
|
|
9125
|
+
try {
|
|
9126
|
+
body = await response.json();
|
|
9127
|
+
} catch {
|
|
9128
|
+
body = undefined;
|
|
9129
|
+
}
|
|
9130
|
+
if (!response.ok)
|
|
9131
|
+
throw mapModelsError(response.status, body);
|
|
9132
|
+
return mapServerModels(body);
|
|
9133
|
+
}
|
|
9134
|
+
function mapModelsError(status, body) {
|
|
9135
|
+
const payload = extractErrorPayload(body);
|
|
9136
|
+
if (status === 401) {
|
|
9137
|
+
return new AutoragHttpError("AutoRAG rejected the API key (HTTP 401). Run /login again or set AUTORAG_API_KEY.", {
|
|
9138
|
+
status,
|
|
9139
|
+
code: payload.code ?? "unauthorized",
|
|
9140
|
+
type: payload.type
|
|
9141
|
+
});
|
|
9142
|
+
}
|
|
9143
|
+
const reason = payload.message ?? "the server returned no error message";
|
|
9144
|
+
return new AutoragHttpError(`AutoRAG model listing failed (HTTP ${status}): ${reason}`, {
|
|
9145
|
+
status,
|
|
9146
|
+
code: payload.code,
|
|
9147
|
+
type: payload.type
|
|
9148
|
+
});
|
|
9149
|
+
}
|
|
9150
|
+
function mapServerModels(payload) {
|
|
9151
|
+
if (typeof payload !== "object" || payload === null)
|
|
9152
|
+
return [];
|
|
9153
|
+
const data = payload.data;
|
|
9154
|
+
if (!Array.isArray(data))
|
|
9155
|
+
return [];
|
|
9156
|
+
const models = [];
|
|
9157
|
+
for (const entry of data) {
|
|
9158
|
+
if (typeof entry !== "object" || entry === null)
|
|
9159
|
+
continue;
|
|
9160
|
+
const model = mapServerModel(entry);
|
|
9161
|
+
if (model !== undefined)
|
|
9162
|
+
models.push(model);
|
|
9163
|
+
}
|
|
9164
|
+
return models;
|
|
9165
|
+
}
|
|
9166
|
+
function mapServerModel(entry) {
|
|
9167
|
+
const id = readString2(entry.id);
|
|
9168
|
+
if (id === undefined)
|
|
9169
|
+
return;
|
|
9170
|
+
return {
|
|
9171
|
+
type: "chat",
|
|
9172
|
+
id,
|
|
9173
|
+
name: readString2(entry.name) ?? id,
|
|
9174
|
+
input: readInputModalities(entry.input_modalities),
|
|
9175
|
+
cost: readPricing(entry.pricing),
|
|
9176
|
+
reasoning: entry.reasoning === true,
|
|
9177
|
+
contextWindow: readPositiveNumber(entry.context_window) ?? DEFAULT_CONTEXT_WINDOW,
|
|
9178
|
+
maxTokens: readPositiveNumber(entry.max_output_tokens) ?? DEFAULT_MAX_TOKENS
|
|
9179
|
+
};
|
|
9180
|
+
}
|
|
9181
|
+
function buildStoreEntry(models, providerId, baseUrl) {
|
|
9182
|
+
const stored = [];
|
|
9183
|
+
for (const model of models) {
|
|
9184
|
+
if (model.type === "image" || model.type === "classifier")
|
|
9185
|
+
continue;
|
|
9186
|
+
stored.push({
|
|
9187
|
+
type: "chat",
|
|
9188
|
+
id: model.id,
|
|
9189
|
+
name: model.name,
|
|
9190
|
+
api: model.api ?? "openai-responses",
|
|
9191
|
+
provider: providerId,
|
|
9192
|
+
baseUrl: model.baseUrl ?? baseUrl,
|
|
9193
|
+
input: model.input,
|
|
9194
|
+
cost: model.cost,
|
|
9195
|
+
reasoning: model.reasoning,
|
|
9196
|
+
contextWindow: model.contextWindow,
|
|
9197
|
+
maxTokens: model.maxTokens
|
|
9198
|
+
});
|
|
9199
|
+
}
|
|
9200
|
+
return { models: stored, checkedAt: Date.now() };
|
|
9201
|
+
}
|
|
9202
|
+
function modelsFromStore(stored) {
|
|
9203
|
+
if (stored === undefined)
|
|
9204
|
+
return [];
|
|
9205
|
+
const models = [];
|
|
9206
|
+
for (const entry of stored.models) {
|
|
9207
|
+
if (entry.type === "image" || entry.type === "classifier")
|
|
9208
|
+
continue;
|
|
9209
|
+
models.push({
|
|
9210
|
+
type: "chat",
|
|
9211
|
+
id: entry.id,
|
|
9212
|
+
name: entry.name,
|
|
9213
|
+
input: entry.input,
|
|
9214
|
+
cost: entry.cost,
|
|
9215
|
+
reasoning: entry.reasoning,
|
|
9216
|
+
contextWindow: entry.contextWindow,
|
|
9217
|
+
maxTokens: entry.maxTokens
|
|
9218
|
+
});
|
|
9219
|
+
}
|
|
9220
|
+
return models;
|
|
9221
|
+
}
|
|
9222
|
+
function readString2(value) {
|
|
9223
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : undefined;
|
|
9224
|
+
}
|
|
9225
|
+
function readPositiveNumber(value) {
|
|
9226
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
|
|
9227
|
+
}
|
|
9228
|
+
function readInputModalities(value) {
|
|
9229
|
+
if (!Array.isArray(value))
|
|
9230
|
+
return ["text"];
|
|
9231
|
+
const modalities = value.filter((item) => item === "text" || item === "image");
|
|
9232
|
+
const unique = Array.from(new Set(modalities));
|
|
9233
|
+
return unique.length > 0 ? unique : ["text"];
|
|
9234
|
+
}
|
|
9235
|
+
function readPricing(value) {
|
|
9236
|
+
const pricing = typeof value === "object" && value !== null ? value : {};
|
|
9237
|
+
return {
|
|
9238
|
+
input: readPositiveNumber(pricing.input) ?? 0,
|
|
9239
|
+
output: readPositiveNumber(pricing.output) ?? 0,
|
|
9240
|
+
cacheRead: readPositiveNumber(pricing.cache_read) ?? 0,
|
|
9241
|
+
cacheWrite: readPositiveNumber(pricing.cache_write) ?? 0
|
|
9242
|
+
};
|
|
9243
|
+
}
|
|
9244
|
+
var DEFAULT_CONTEXT_WINDOW = 128000, DEFAULT_MAX_TOKENS = 16384;
|
|
9245
|
+
var init_models = __esm(() => {
|
|
9246
|
+
init_config();
|
|
9247
|
+
init_errors3();
|
|
9248
|
+
});
|
|
9249
|
+
|
|
9250
|
+
// src/cloud/authorize.ts
|
|
9251
|
+
function buildAuthorizeUrl(params) {
|
|
9252
|
+
const url = new URL(`${normalizeBaseUrl(params.baseUrl)}${AUTHORIZE_PATH}`);
|
|
9253
|
+
url.searchParams.set("client", OAUTH_CLIENT_ID);
|
|
9254
|
+
url.searchParams.set("redirect_uri", params.redirectUri);
|
|
9255
|
+
url.searchParams.set("state", params.state);
|
|
9256
|
+
url.searchParams.set("code_challenge", params.codeChallenge);
|
|
9257
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
9258
|
+
return url.toString();
|
|
9259
|
+
}
|
|
9260
|
+
var init_authorize = __esm(() => {
|
|
9261
|
+
init_config();
|
|
9262
|
+
});
|
|
9263
|
+
|
|
9264
|
+
// src/cloud/callback.ts
|
|
9265
|
+
function parseCallbackQuery(params) {
|
|
9266
|
+
const result = {};
|
|
9267
|
+
const code = params.get("code");
|
|
9268
|
+
const error = params.get("error");
|
|
9269
|
+
const state = params.get("state");
|
|
9270
|
+
if (code !== null && code !== "")
|
|
9271
|
+
result.code = code;
|
|
9272
|
+
if (error !== null && error !== "")
|
|
9273
|
+
result.error = error;
|
|
9274
|
+
if (state !== null && state !== "")
|
|
9275
|
+
result.state = state;
|
|
9276
|
+
return result;
|
|
9277
|
+
}
|
|
9278
|
+
function parseCallbackInput(input) {
|
|
9279
|
+
const trimmed = input.trim();
|
|
9280
|
+
if (trimmed === "") {
|
|
9281
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: nothing was pasted.");
|
|
9282
|
+
}
|
|
9283
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
9284
|
+
try {
|
|
9285
|
+
return parseCallbackQuery(new URL(trimmed).searchParams);
|
|
9286
|
+
} catch {
|
|
9287
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: the pasted URL is not valid.");
|
|
9288
|
+
}
|
|
9289
|
+
}
|
|
9290
|
+
const query = trimmed.startsWith("?") ? trimmed.slice(1) : trimmed;
|
|
9291
|
+
if (!query.includes(" ")) {
|
|
9292
|
+
const params = new URLSearchParams(query);
|
|
9293
|
+
if (params.has("code") || params.has("error") || params.has("state")) {
|
|
9294
|
+
return parseCallbackQuery(params);
|
|
9295
|
+
}
|
|
9296
|
+
}
|
|
9297
|
+
return { code: trimmed };
|
|
9298
|
+
}
|
|
9299
|
+
function requireAuthorizationCode(result, expectedState) {
|
|
9300
|
+
if (result.state !== undefined && result.state !== expectedState) {
|
|
9301
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: state mismatch (the callback did not originate from this login attempt).");
|
|
9302
|
+
}
|
|
9303
|
+
if (result.error !== undefined) {
|
|
9304
|
+
throw new AutoragOAuthError(result.error === "access_denied" ? "AutoRAG sign-in was cancelled in the browser." : `AutoRAG sign-in failed: ${result.error}.`);
|
|
9305
|
+
}
|
|
9306
|
+
if (result.code === undefined) {
|
|
9307
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: the callback carried no authorization code.");
|
|
9308
|
+
}
|
|
9309
|
+
return { code: result.code };
|
|
9310
|
+
}
|
|
9311
|
+
var init_callback = __esm(() => {
|
|
9312
|
+
init_errors3();
|
|
9313
|
+
});
|
|
9314
|
+
|
|
9315
|
+
// src/cloud/callback-server.ts
|
|
9316
|
+
import { createServer as createServer3 } from "node:http";
|
|
9317
|
+
function createDeferred() {
|
|
9318
|
+
let resolve;
|
|
9319
|
+
let reject;
|
|
9320
|
+
const promise = new Promise((res, rej) => {
|
|
9321
|
+
resolve = res;
|
|
9322
|
+
reject = rej;
|
|
9323
|
+
});
|
|
9324
|
+
return { promise, resolve, reject };
|
|
9325
|
+
}
|
|
9326
|
+
function renderCallbackPage(failed) {
|
|
9327
|
+
const message = failed ? "AutoRAG sign-in did not complete. You can close this tab and try again." : "Signed in to AutoRAG. You can close this tab.";
|
|
9328
|
+
return [
|
|
9329
|
+
"<!doctype html>",
|
|
9330
|
+
'<html lang="en">',
|
|
9331
|
+
"<head>",
|
|
9332
|
+
'<meta charset="utf-8">',
|
|
9333
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
9334
|
+
"<title>AutoRAG</title>",
|
|
9335
|
+
"</head>",
|
|
9336
|
+
'<body style="font-family: system-ui, sans-serif; margin: 4rem auto; max-width: 32rem; text-align: center;">',
|
|
9337
|
+
`<p>${message}</p>`,
|
|
9338
|
+
"</body>",
|
|
9339
|
+
"</html>"
|
|
9340
|
+
].join(`
|
|
9341
|
+
`);
|
|
9342
|
+
}
|
|
9343
|
+
function startCallbackServer(options) {
|
|
9344
|
+
const host = options.host ?? "127.0.0.1";
|
|
9345
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS;
|
|
9346
|
+
const server = createServer3();
|
|
9347
|
+
const started = createDeferred();
|
|
9348
|
+
const callback = createDeferred();
|
|
9349
|
+
callback.promise.catch(() => {});
|
|
9350
|
+
let finished = false;
|
|
9351
|
+
let startSettled = false;
|
|
9352
|
+
let timer;
|
|
9353
|
+
function cleanup() {
|
|
9354
|
+
clearTimeout(timer);
|
|
9355
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
9356
|
+
if (server.listening) {
|
|
9357
|
+
server.closeAllConnections();
|
|
9358
|
+
server.close();
|
|
9359
|
+
}
|
|
9360
|
+
}
|
|
9361
|
+
function fail(error) {
|
|
9362
|
+
if (finished)
|
|
9363
|
+
return;
|
|
9364
|
+
finished = true;
|
|
9365
|
+
cleanup();
|
|
9366
|
+
callback.reject(error);
|
|
9367
|
+
}
|
|
9368
|
+
function onAbort() {
|
|
9369
|
+
fail(new AutoragOAuthError("AutoRAG sign-in was cancelled."));
|
|
9370
|
+
}
|
|
9371
|
+
server.on("request", (req, res) => {
|
|
9372
|
+
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
9373
|
+
if (req.method !== "GET" || url.pathname !== CALLBACK_PATH) {
|
|
9374
|
+
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
9375
|
+
res.end("Not found");
|
|
9376
|
+
return;
|
|
9377
|
+
}
|
|
9378
|
+
if (finished) {
|
|
9379
|
+
res.writeHead(410, { "content-type": "text/plain; charset=utf-8" });
|
|
9380
|
+
res.end("Callback already handled");
|
|
9381
|
+
return;
|
|
9382
|
+
}
|
|
9383
|
+
const params = url.searchParams;
|
|
9384
|
+
const code = params.get("code");
|
|
9385
|
+
const oauthError = params.get("error");
|
|
9386
|
+
const hasResponse = code !== null && code !== "" || oauthError !== null && oauthError !== "";
|
|
9387
|
+
if (params.get("state") !== options.state || !hasResponse) {
|
|
9388
|
+
res.writeHead(400, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" });
|
|
9389
|
+
res.end(renderCallbackPage(true));
|
|
9390
|
+
return;
|
|
9391
|
+
}
|
|
9392
|
+
finished = true;
|
|
9393
|
+
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" });
|
|
9394
|
+
res.end(renderCallbackPage(params.has("error")));
|
|
9395
|
+
cleanup();
|
|
9396
|
+
callback.resolve(params);
|
|
9397
|
+
});
|
|
9398
|
+
server.on("error", (error) => {
|
|
9399
|
+
const wrapped = error instanceof Error ? error : new Error(String(error));
|
|
9400
|
+
if (!startSettled) {
|
|
9401
|
+
startSettled = true;
|
|
9402
|
+
cleanup();
|
|
9403
|
+
started.reject(wrapped);
|
|
9404
|
+
return;
|
|
9405
|
+
}
|
|
9406
|
+
fail(wrapped);
|
|
9407
|
+
});
|
|
9408
|
+
server.listen(0, host, () => {
|
|
9409
|
+
const address = server.address();
|
|
9410
|
+
const port = typeof address === "object" && address !== null ? address.port : 0;
|
|
9411
|
+
const redirectUri = `http://${host}:${port}${CALLBACK_PATH}`;
|
|
9412
|
+
timer = setTimeout(() => fail(new AutoragOAuthError("AutoRAG sign-in timed out waiting for the browser callback.")), timeoutMs);
|
|
9413
|
+
if (options.signal?.aborted)
|
|
9414
|
+
onAbort();
|
|
9415
|
+
else
|
|
9416
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
9417
|
+
startSettled = true;
|
|
9418
|
+
options.onListening?.(redirectUri);
|
|
9419
|
+
started.resolve({
|
|
9420
|
+
redirectUri,
|
|
9421
|
+
waitForCallback: () => callback.promise,
|
|
9422
|
+
close: () => {
|
|
9423
|
+
if (!finished)
|
|
9424
|
+
fail(new AutoragOAuthError("AutoRAG sign-in was cancelled."));
|
|
9425
|
+
}
|
|
9426
|
+
});
|
|
9427
|
+
});
|
|
9428
|
+
return started.promise;
|
|
9429
|
+
}
|
|
9430
|
+
var CALLBACK_PATH = "/callback", DEFAULT_LOGIN_TIMEOUT_MS;
|
|
9431
|
+
var init_callback_server = __esm(() => {
|
|
9432
|
+
init_errors3();
|
|
9433
|
+
DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
9434
|
+
});
|
|
9435
|
+
|
|
9436
|
+
// src/cloud/pkce.ts
|
|
9437
|
+
import { createHash as createHash11, randomBytes } from "node:crypto";
|
|
9438
|
+
function base64UrlEncode(bytes) {
|
|
9439
|
+
return Buffer.from(bytes).toString("base64url");
|
|
9440
|
+
}
|
|
9441
|
+
function createCodeChallenge(verifier) {
|
|
9442
|
+
return base64UrlEncode(createHash11("sha256").update(verifier, "ascii").digest());
|
|
9443
|
+
}
|
|
9444
|
+
function createCodeVerifier(byteLength = 32) {
|
|
9445
|
+
return base64UrlEncode(randomBytes(byteLength));
|
|
9446
|
+
}
|
|
9447
|
+
function createState(byteLength = 24) {
|
|
9448
|
+
return base64UrlEncode(randomBytes(byteLength));
|
|
9449
|
+
}
|
|
9450
|
+
function createPkcePair(byteLength = 32) {
|
|
9451
|
+
const verifier = createCodeVerifier(byteLength);
|
|
9452
|
+
return { verifier, challenge: createCodeChallenge(verifier) };
|
|
9453
|
+
}
|
|
9454
|
+
var init_pkce = () => {};
|
|
9455
|
+
|
|
9456
|
+
// src/cloud/token.ts
|
|
9457
|
+
function mapTokenExchangeError(status, body) {
|
|
9458
|
+
const payload = extractErrorPayload(body);
|
|
9459
|
+
const reason = payload.message ?? "the server returned no error message";
|
|
9460
|
+
return new AutoragHttpError(`AutoRAG token exchange failed (HTTP ${status}): ${reason}`, {
|
|
9461
|
+
status,
|
|
9462
|
+
code: payload.code,
|
|
9463
|
+
type: payload.type
|
|
9464
|
+
});
|
|
9465
|
+
}
|
|
9466
|
+
async function exchangeCodeForToken(options) {
|
|
9467
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
9468
|
+
let response;
|
|
9469
|
+
try {
|
|
9470
|
+
response = await doFetch(`${normalizeBaseUrl(options.baseUrl)}${TOKEN_PATH}`, {
|
|
9471
|
+
method: "POST",
|
|
9472
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
9473
|
+
body: JSON.stringify({
|
|
9474
|
+
code: options.code,
|
|
9475
|
+
code_verifier: options.codeVerifier,
|
|
9476
|
+
redirect_uri: options.redirectUri
|
|
9477
|
+
}),
|
|
9478
|
+
signal: options.signal
|
|
9479
|
+
});
|
|
9480
|
+
} catch (cause) {
|
|
9481
|
+
if (options.signal?.aborted) {
|
|
9482
|
+
throw new AutoragOAuthError("AutoRAG sign-in was cancelled.", { cause });
|
|
9483
|
+
}
|
|
9484
|
+
throw new AutoragOAuthError(`AutoRAG token exchange could not reach ${normalizeBaseUrl(options.baseUrl)}.`, {
|
|
9485
|
+
cause
|
|
9486
|
+
});
|
|
9487
|
+
}
|
|
9488
|
+
let body;
|
|
9489
|
+
try {
|
|
9490
|
+
body = await response.json();
|
|
9491
|
+
} catch {
|
|
9492
|
+
body = undefined;
|
|
9493
|
+
}
|
|
9494
|
+
if (!response.ok)
|
|
9495
|
+
throw mapTokenExchangeError(response.status, body);
|
|
9496
|
+
const accessToken = readAccessToken(body);
|
|
9497
|
+
if (accessToken === undefined) {
|
|
9498
|
+
throw new AutoragOAuthError("AutoRAG token exchange succeeded but returned no access token.");
|
|
8916
9499
|
}
|
|
9500
|
+
const email = readEmail(body);
|
|
9501
|
+
return email === undefined ? { accessToken } : { accessToken, email };
|
|
8917
9502
|
}
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
8923
|
-
return {
|
|
8924
|
-
name: EMIT_FAST_ANSWER_TOOL_NAME,
|
|
8925
|
-
label: "Emit Fast Answer",
|
|
8926
|
-
description: "Deliver the immediate first answer to the user. Call this exactly once during the fast phase with a complete, self-contained answer built only from the baseline retrieval evidence. Do not call any other tool before this one. The run continues afterwards for verification. A call whose answer cites a number missing from results, or whose refs name evidence that was not provided, is rejected; fix it and call again.",
|
|
8927
|
-
parameters: fastAnswerSchema,
|
|
8928
|
-
async execute(_toolCallId, params) {
|
|
8929
|
-
assertCitationsResolve(EMIT_FAST_ANSWER_TOOL_NAME, params.answer, params.results);
|
|
8930
|
-
const evidenceRefs = [];
|
|
8931
|
-
for (const result of params.results) {
|
|
8932
|
-
if (result.refs === undefined || result.refs.length === 0)
|
|
8933
|
-
continue;
|
|
8934
|
-
const refs = options.ledger.resolve(result.refs, {
|
|
8935
|
-
label: EMIT_FAST_ANSWER_TOOL_NAME,
|
|
8936
|
-
number: result.number,
|
|
8937
|
-
fallbackContent: result.summary,
|
|
8938
|
-
allowLocalFiles: false
|
|
8939
|
-
});
|
|
8940
|
-
if (refs.length > 0)
|
|
8941
|
-
evidenceRefs.push({ number: result.number, refs });
|
|
8942
|
-
}
|
|
8943
|
-
const details = {
|
|
8944
|
-
answer: params.answer,
|
|
8945
|
-
results: params.results.map((result) => ({
|
|
8946
|
-
number: result.number,
|
|
8947
|
-
title: result.title,
|
|
8948
|
-
summary: result.summary,
|
|
8949
|
-
evidence: (result.evidence ?? []).map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
8950
|
-
...result.confidence !== undefined ? { confidence: result.confidence } : {}
|
|
8951
|
-
})),
|
|
8952
|
-
sources: evidenceRefs.flatMap((entry) => {
|
|
8953
|
-
const [primary] = entry.refs;
|
|
8954
|
-
return primary === undefined ? [] : [{ number: entry.number, source: primary.source }];
|
|
8955
|
-
}),
|
|
8956
|
-
evidenceRefs
|
|
8957
|
-
};
|
|
8958
|
-
capture(details);
|
|
8959
|
-
return {
|
|
8960
|
-
content: [
|
|
8961
|
-
{
|
|
8962
|
-
type: "text",
|
|
8963
|
-
text: "Fast answer delivered to the user. Stop now; a deeper verification pass follows separately."
|
|
8964
|
-
}
|
|
8965
|
-
],
|
|
8966
|
-
details
|
|
8967
|
-
};
|
|
8968
|
-
}
|
|
8969
|
-
};
|
|
9503
|
+
function readAccessToken(body) {
|
|
9504
|
+
if (typeof body !== "object" || body === null)
|
|
9505
|
+
return;
|
|
9506
|
+
const value = body.access_token;
|
|
9507
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
8970
9508
|
}
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
9509
|
+
function readEmail(body) {
|
|
9510
|
+
if (typeof body !== "object" || body === null)
|
|
9511
|
+
return;
|
|
9512
|
+
const value = body.email;
|
|
9513
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
9514
|
+
}
|
|
9515
|
+
var init_token = __esm(() => {
|
|
9516
|
+
init_config();
|
|
9517
|
+
init_errors3();
|
|
9518
|
+
});
|
|
9519
|
+
|
|
9520
|
+
// src/cloud/oauth-login.ts
|
|
9521
|
+
function refreshAutoragCredentials(credentials) {
|
|
9522
|
+
return credentials;
|
|
9523
|
+
}
|
|
9524
|
+
async function loginAutorag(callbacks, options) {
|
|
9525
|
+
const { verifier, challenge } = createPkcePair();
|
|
9526
|
+
const state = createState();
|
|
9527
|
+
const server = await startCallbackServer({
|
|
9528
|
+
state,
|
|
9529
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS,
|
|
9530
|
+
signal: callbacks.signal
|
|
8990
9531
|
});
|
|
9532
|
+
try {
|
|
9533
|
+
callbacks.onAuth({
|
|
9534
|
+
url: buildAuthorizeUrl({
|
|
9535
|
+
baseUrl: options.baseUrl,
|
|
9536
|
+
redirectUri: server.redirectUri,
|
|
9537
|
+
state,
|
|
9538
|
+
codeChallenge: challenge
|
|
9539
|
+
}),
|
|
9540
|
+
instructions: `Waiting for the AutoRAG sign-in callback on ${server.redirectUri}. If the browser cannot reach this machine, paste the final redirect URL or the code instead.`
|
|
9541
|
+
});
|
|
9542
|
+
callbacks.onProgress?.(`Listening for the AutoRAG sign-in callback on ${server.redirectUri}`);
|
|
9543
|
+
const outcome = await Promise.race([
|
|
9544
|
+
server.waitForCallback().then((params) => ({ params })),
|
|
9545
|
+
callbacks.onPrompt({
|
|
9546
|
+
message: "Complete the AutoRAG sign-in in your browser, or paste the final redirect URL / authorization code here:",
|
|
9547
|
+
placeholder: server.redirectUri,
|
|
9548
|
+
allowEmpty: true
|
|
9549
|
+
}).then((value) => ({ value }))
|
|
9550
|
+
]);
|
|
9551
|
+
const parsed = "params" in outcome ? parseCallbackQuery(outcome.params) : parseCallbackInput(outcome.value);
|
|
9552
|
+
const { code } = requireAuthorizationCode(parsed, state);
|
|
9553
|
+
const token = await exchangeCodeForToken({
|
|
9554
|
+
baseUrl: options.baseUrl,
|
|
9555
|
+
code,
|
|
9556
|
+
codeVerifier: verifier,
|
|
9557
|
+
redirectUri: server.redirectUri,
|
|
9558
|
+
signal: callbacks.signal,
|
|
9559
|
+
fetchImpl: options.fetchImpl
|
|
9560
|
+
});
|
|
9561
|
+
return {
|
|
9562
|
+
access: token.accessToken,
|
|
9563
|
+
refresh: "",
|
|
9564
|
+
expires: Number.MAX_SAFE_INTEGER,
|
|
9565
|
+
...token.email !== undefined ? { email: token.email } : {}
|
|
9566
|
+
};
|
|
9567
|
+
} finally {
|
|
9568
|
+
server.close();
|
|
9569
|
+
}
|
|
9570
|
+
}
|
|
9571
|
+
var init_oauth_login = __esm(() => {
|
|
9572
|
+
init_authorize();
|
|
9573
|
+
init_callback();
|
|
9574
|
+
init_callback_server();
|
|
9575
|
+
init_pkce();
|
|
9576
|
+
init_token();
|
|
8991
9577
|
});
|
|
8992
9578
|
|
|
8993
|
-
// src/
|
|
8994
|
-
|
|
8995
|
-
|
|
9579
|
+
// src/cloud/provider.ts
|
|
9580
|
+
async function refreshAutoragModels(context, endpoints) {
|
|
9581
|
+
const stored = modelsFromStore(context.stored);
|
|
9582
|
+
const apiKey = resolveCredentialKey(context.credential);
|
|
9583
|
+
if (!context.allowNetwork || apiKey === undefined)
|
|
9584
|
+
return stored;
|
|
9585
|
+
let models;
|
|
9586
|
+
try {
|
|
9587
|
+
models = await fetchModels({ baseUrl: endpoints.baseUrl, apiKey, signal: context.signal });
|
|
9588
|
+
} catch {
|
|
9589
|
+
return stored;
|
|
9590
|
+
}
|
|
9591
|
+
if (models.length === 0)
|
|
9592
|
+
return stored;
|
|
9593
|
+
try {
|
|
9594
|
+
await context.publish({ persist: buildStoreEntry(models, PROVIDER_ID, endpoints.apiBaseUrl) });
|
|
9595
|
+
} catch {}
|
|
9596
|
+
return models;
|
|
9597
|
+
}
|
|
9598
|
+
function createAutoRAGProviderConfig(env = process.env) {
|
|
9599
|
+
const baseUrl = resolveBaseUrl(env);
|
|
9600
|
+
const endpoints = { baseUrl, apiBaseUrl: `${baseUrl}${API_PATH}` };
|
|
8996
9601
|
return {
|
|
8997
|
-
name:
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
}
|
|
9009
|
-
const request = {
|
|
9010
|
-
...params,
|
|
9011
|
-
query,
|
|
9012
|
-
maxResults: Math.min(params.maxResults ?? DEFAULT_MAX_RESULTS4, MAX_RESULTS_CAP3)
|
|
9013
|
-
};
|
|
9014
|
-
const result = await provider.searchFsearch(request);
|
|
9015
|
-
if (!result.ok) {
|
|
9016
|
-
return {
|
|
9017
|
-
content: [{ type: "text", text: `FSearch ${result.reason}: ${result.message}` }],
|
|
9018
|
-
details: { method: FSEARCH_SEARCH_TOOL_NAME, resultCount: 0, sources: [], results: [] }
|
|
9019
|
-
};
|
|
9020
|
-
}
|
|
9021
|
-
const lines = result.results.map((entry, index) => {
|
|
9022
|
-
const parts = [`[${index + 1}] ${entry.type} ${entry.path}`];
|
|
9023
|
-
if (entry.size !== undefined)
|
|
9024
|
-
parts.push(`size=${entry.size}`);
|
|
9025
|
-
if (entry.dateModified !== undefined)
|
|
9026
|
-
parts.push(`modified=${entry.dateModified}`);
|
|
9027
|
-
return parts.join(" ");
|
|
9028
|
-
});
|
|
9029
|
-
const backendLabel = result.backend === "walk" ? "FSearch slow filesystem walk (fsearch-cli unavailable)" : "FSearch";
|
|
9030
|
-
const limitNote = result.backend === "fsearch-cli" && (result.total ?? 0) > lines.length && lines.length === request.maxResults ? ` of ${result.total} total (limit reached; narrow the query or page with offset)` : "";
|
|
9031
|
-
const noteSuffix = result.note !== undefined ? `
|
|
9032
|
-
${result.note}` : "";
|
|
9033
|
-
const text = lines.length === 0 ? `${backendLabel} found no files or folders matching: ${query}${noteSuffix}` : `${backendLabel} found ${lines.length} item(s)${limitNote}:
|
|
9034
|
-
${lines.join(`
|
|
9035
|
-
`)}${noteSuffix}`;
|
|
9036
|
-
return {
|
|
9037
|
-
content: [{ type: "text", text }],
|
|
9038
|
-
details: {
|
|
9039
|
-
method: FSEARCH_SEARCH_TOOL_NAME,
|
|
9040
|
-
resultCount: result.results.length,
|
|
9041
|
-
sources: result.results.map((entry) => entry.path),
|
|
9042
|
-
results: result.results.map((entry, index) => ({ source: entry.path, excerpt: lines[index] }))
|
|
9043
|
-
}
|
|
9044
|
-
};
|
|
9045
|
-
}
|
|
9602
|
+
name: PROVIDER_NAME,
|
|
9603
|
+
baseUrl: endpoints.apiBaseUrl,
|
|
9604
|
+
api: "openai-responses",
|
|
9605
|
+
apiKey: API_KEY_CONFIG_VALUE,
|
|
9606
|
+
oauth: {
|
|
9607
|
+
name: PROVIDER_NAME,
|
|
9608
|
+
login: (callbacks) => loginAutorag(callbacks, { baseUrl }),
|
|
9609
|
+
refreshToken: async (credentials) => refreshAutoragCredentials(credentials),
|
|
9610
|
+
getApiKey: (credentials) => credentials.access
|
|
9611
|
+
},
|
|
9612
|
+
refreshModels: (context) => refreshAutoragModels(context, endpoints)
|
|
9046
9613
|
};
|
|
9047
9614
|
}
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
matchPath: Type7.Optional(Type7.Boolean({ description: "Match against the full path instead of the name." })),
|
|
9057
|
-
kind: Type7.Optional(Type7.Union([Type7.Literal("files"), Type7.Literal("folders")])),
|
|
9058
|
-
path: Type7.Optional(Type7.String({ description: "Absolute folder to search within." })),
|
|
9059
|
-
sort: Type7.Optional(Type7.Union([
|
|
9060
|
-
Type7.Literal("name-ascending"),
|
|
9061
|
-
Type7.Literal("name-descending"),
|
|
9062
|
-
Type7.Literal("path-ascending"),
|
|
9063
|
-
Type7.Literal("path-descending"),
|
|
9064
|
-
Type7.Literal("size-ascending"),
|
|
9065
|
-
Type7.Literal("size-descending"),
|
|
9066
|
-
Type7.Literal("date-modified-ascending"),
|
|
9067
|
-
Type7.Literal("date-modified-descending")
|
|
9068
|
-
])),
|
|
9069
|
-
offset: Type7.Optional(Type7.Integer({ minimum: 0, description: "Skip this many results (pagination)." })),
|
|
9070
|
-
maxResults: Type7.Optional(Type7.Integer({
|
|
9071
|
-
minimum: 1,
|
|
9072
|
-
description: `Maximum results (default ${DEFAULT_MAX_RESULTS4}, cap ${MAX_RESULTS_CAP3}).`
|
|
9073
|
-
}))
|
|
9074
|
-
});
|
|
9615
|
+
async function registerAutoRAGProvider(runtime, env = process.env) {
|
|
9616
|
+
runtime.registerProvider(PROVIDER_ID, createAutoRAGProviderConfig(env));
|
|
9617
|
+
await runtime.refresh({ allowNetwork: false, providers: [PROVIDER_ID] });
|
|
9618
|
+
}
|
|
9619
|
+
var init_provider = __esm(() => {
|
|
9620
|
+
init_config();
|
|
9621
|
+
init_models();
|
|
9622
|
+
init_oauth_login();
|
|
9075
9623
|
});
|
|
9076
9624
|
|
|
9077
9625
|
// src/agent/pi-session.ts
|
|
@@ -9200,6 +9748,7 @@ async function createAutoRAGPiSession(options) {
|
|
|
9200
9748
|
authPath: join21(agentDir, "auth.json"),
|
|
9201
9749
|
modelsPath: join21(agentDir, "models.json")
|
|
9202
9750
|
});
|
|
9751
|
+
await registerAutoRAGProvider(modelRuntime);
|
|
9203
9752
|
await configureModelRuntime(modelRuntime, options.model, options.apiKey, options.providerApiKeys);
|
|
9204
9753
|
const customTools = [...options.customTools];
|
|
9205
9754
|
const extensionToolNames = [...options.extensionToolNames ?? []];
|
|
@@ -9249,6 +9798,7 @@ async function createAutoRAGPiInteractiveRuntime(options) {
|
|
|
9249
9798
|
authPath: join21(agentDir, "auth.json"),
|
|
9250
9799
|
modelsPath: join21(agentDir, "models.json")
|
|
9251
9800
|
});
|
|
9801
|
+
await registerAutoRAGProvider(modelRuntime);
|
|
9252
9802
|
await configureModelRuntime(modelRuntime, options.model, options.apiKey, options.providerApiKeys);
|
|
9253
9803
|
const sessionManager = options.sessionPath ? SessionManager.open(options.sessionPath, options.sessionDir, options.cwd) : SessionManager.create(options.cwd, options.sessionDir);
|
|
9254
9804
|
const createRuntime = async ({
|
|
@@ -9298,12 +9848,13 @@ async function createAutoRAGPiInteractiveRuntime(options) {
|
|
|
9298
9848
|
}
|
|
9299
9849
|
var PI_BUILTIN_TOOL_NAMES, EMBEDDED_AUTH_MARKER = "<autorag-embedded-model>";
|
|
9300
9850
|
var init_pi_session = __esm(() => {
|
|
9851
|
+
init_provider();
|
|
9301
9852
|
PI_BUILTIN_TOOL_NAMES = ["read", "bash", "edit", "write", "grep", "find", "ls"];
|
|
9302
9853
|
});
|
|
9303
9854
|
|
|
9304
9855
|
// src/agent/jev-extension.ts
|
|
9305
9856
|
import { Jev } from "jev-use";
|
|
9306
|
-
import { Type as
|
|
9857
|
+
import { Type as Type6 } from "typebox";
|
|
9307
9858
|
function createJevJudge(options = {}) {
|
|
9308
9859
|
let client;
|
|
9309
9860
|
return async (state, questions, callOptions = {}) => {
|
|
@@ -9356,32 +9907,32 @@ var JEV_TOOL_NAME = "jev", OPENROUTER_DEFAULT_MODEL = "typesafe/jev-1.13", BACKE
|
|
|
9356
9907
|
var init_jev_extension = __esm(() => {
|
|
9357
9908
|
init_pi_session();
|
|
9358
9909
|
BACKEND_DEFAULT_MODEL = { openrouter: OPENROUTER_DEFAULT_MODEL };
|
|
9359
|
-
jevQuestionSchema =
|
|
9360
|
-
id:
|
|
9361
|
-
type:
|
|
9910
|
+
jevQuestionSchema = Type6.Object({
|
|
9911
|
+
id: Type6.Optional(Type6.String({ description: "Caller-assigned id, echoed back in the verdict" })),
|
|
9912
|
+
type: Type6.Union([Type6.Literal("noul"), Type6.Literal("choice"), Type6.Literal("score")], {
|
|
9362
9913
|
description: "noul = P(yes), choice = pick one option, score = ordered level index"
|
|
9363
9914
|
}),
|
|
9364
|
-
question:
|
|
9915
|
+
question: Type6.String({
|
|
9365
9916
|
minLength: 1,
|
|
9366
9917
|
description: "One narrow question about the state. Jev answers exactly this."
|
|
9367
9918
|
}),
|
|
9368
|
-
options:
|
|
9919
|
+
options: Type6.Optional(Type6.Union([Type6.Array(Type6.String()), Type6.Record(Type6.String(), Type6.String())], {
|
|
9369
9920
|
description: "choice only: at least two option labels (or label -> meaning)"
|
|
9370
9921
|
})),
|
|
9371
|
-
levels:
|
|
9922
|
+
levels: Type6.Optional(Type6.Array(Type6.String(), {
|
|
9372
9923
|
description: "score only: at least two ordered level descriptions; the answer indexes into them"
|
|
9373
9924
|
})),
|
|
9374
|
-
criteria:
|
|
9925
|
+
criteria: Type6.Optional(Type6.Object({ true: Type6.String(), false: Type6.String() }, { description: "noul only: what yes and no mean, to sharpen calibration" }))
|
|
9375
9926
|
});
|
|
9376
|
-
jevParameters =
|
|
9377
|
-
state:
|
|
9927
|
+
jevParameters = Type6.Object({
|
|
9928
|
+
state: Type6.Unknown({
|
|
9378
9929
|
description: "Text, JSON object, or JSON array Jev should judge. Keep it small and self-contained."
|
|
9379
9930
|
}),
|
|
9380
|
-
questions:
|
|
9931
|
+
questions: Type6.Array(jevQuestionSchema, {
|
|
9381
9932
|
minItems: 1,
|
|
9382
9933
|
description: "Named questions, all evaluated against the same state in one batched request."
|
|
9383
9934
|
}),
|
|
9384
|
-
confidence_threshold:
|
|
9935
|
+
confidence_threshold: Type6.Optional(Type6.Number({
|
|
9385
9936
|
minimum: 0,
|
|
9386
9937
|
maximum: 1,
|
|
9387
9938
|
description: "Escalate any verdict below this confidence; omitted uses jev-use's per-source defaults"
|
|
@@ -9390,7 +9941,7 @@ var init_jev_extension = __esm(() => {
|
|
|
9390
9941
|
});
|
|
9391
9942
|
|
|
9392
9943
|
// src/agent/jikji-find-tool.ts
|
|
9393
|
-
import { Type as
|
|
9944
|
+
import { Type as Type7 } from "typebox";
|
|
9394
9945
|
function createJikjiFindTool(provider, ledger = new EvidenceLedger) {
|
|
9395
9946
|
return {
|
|
9396
9947
|
name: JIKJI_FIND_TOOL_NAME,
|
|
@@ -9521,10 +10072,10 @@ function formatDirective(policy) {
|
|
|
9521
10072
|
var JIKJI_FIND_TOOL_NAME = "jikji_find", jikjiFindSchema;
|
|
9522
10073
|
var init_jikji_find_tool = __esm(() => {
|
|
9523
10074
|
init_evidence_ledger();
|
|
9524
|
-
jikjiFindSchema =
|
|
9525
|
-
query:
|
|
9526
|
-
topK:
|
|
9527
|
-
first:
|
|
10075
|
+
jikjiFindSchema = Type7.Object({
|
|
10076
|
+
query: Type7.String({ description: "Query for Jikji local file discovery." }),
|
|
10077
|
+
topK: Type7.Optional(Type7.Integer({ description: "Maximum number of answer paths / candidates to return." })),
|
|
10078
|
+
first: Type7.Optional(Type7.Boolean({ description: "Return only the first/best answer." }))
|
|
9528
10079
|
});
|
|
9529
10080
|
});
|
|
9530
10081
|
|
|
@@ -10493,57 +11044,57 @@ var init_policy = __esm(() => {
|
|
|
10493
11044
|
});
|
|
10494
11045
|
|
|
10495
11046
|
// src/p2p/wire.ts
|
|
10496
|
-
import { Type as
|
|
11047
|
+
import { Type as Type8 } from "typebox";
|
|
10497
11048
|
var PeerRefusalCodeSchema, PeerDiagnosticSchema, PeerFileEntrySchema, PeerResultEntrySchema, PeerQueryRequestSchema, PeerQueryResponseSchema;
|
|
10498
11049
|
var init_wire = __esm(() => {
|
|
10499
|
-
PeerRefusalCodeSchema =
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
10504
|
-
|
|
10505
|
-
|
|
10506
|
-
|
|
11050
|
+
PeerRefusalCodeSchema = Type8.Union([
|
|
11051
|
+
Type8.Literal("auth-error"),
|
|
11052
|
+
Type8.Literal("replay-rejected"),
|
|
11053
|
+
Type8.Literal("rate-limited"),
|
|
11054
|
+
Type8.Literal("injection-detected"),
|
|
11055
|
+
Type8.Literal("policy-denied"),
|
|
11056
|
+
Type8.Literal("queue-full"),
|
|
11057
|
+
Type8.Literal("internal-error")
|
|
10507
11058
|
]);
|
|
10508
|
-
PeerDiagnosticSchema =
|
|
10509
|
-
code:
|
|
10510
|
-
message:
|
|
11059
|
+
PeerDiagnosticSchema = Type8.Object({
|
|
11060
|
+
code: Type8.String({ minLength: 1, description: "Diagnostic or refusal code" }),
|
|
11061
|
+
message: Type8.String({ description: "Human-readable diagnostic message" })
|
|
10511
11062
|
});
|
|
10512
|
-
PeerFileEntrySchema =
|
|
10513
|
-
source:
|
|
11063
|
+
PeerFileEntrySchema = Type8.Object({
|
|
11064
|
+
source: Type8.String({
|
|
10514
11065
|
description: "Canonical retrieval source identifier"
|
|
10515
11066
|
}),
|
|
10516
|
-
contentBase64:
|
|
10517
|
-
redacted:
|
|
11067
|
+
contentBase64: Type8.String({ description: "Base64-encoded file content" }),
|
|
11068
|
+
redacted: Type8.Boolean({ description: "Whether the content was PII-redacted" })
|
|
10518
11069
|
});
|
|
10519
|
-
PeerResultEntrySchema =
|
|
10520
|
-
number:
|
|
10521
|
-
title:
|
|
10522
|
-
summary:
|
|
10523
|
-
source:
|
|
11070
|
+
PeerResultEntrySchema = Type8.Object({
|
|
11071
|
+
number: Type8.Integer({ minimum: 1, description: "1-based result number" }),
|
|
11072
|
+
title: Type8.String({ minLength: 1, description: "Short title of the result" }),
|
|
11073
|
+
summary: Type8.String({ description: "Key insight summary" }),
|
|
11074
|
+
source: Type8.String({
|
|
10524
11075
|
description: "Canonical retrieval source identifier"
|
|
10525
11076
|
}),
|
|
10526
|
-
excerpt:
|
|
11077
|
+
excerpt: Type8.String({ description: "Supporting excerpt" })
|
|
10527
11078
|
});
|
|
10528
|
-
PeerQueryRequestSchema =
|
|
10529
|
-
v:
|
|
10530
|
-
query:
|
|
10531
|
-
topK:
|
|
10532
|
-
scope:
|
|
11079
|
+
PeerQueryRequestSchema = Type8.Object({
|
|
11080
|
+
v: Type8.Literal(1, { description: "Protocol version" }),
|
|
11081
|
+
query: Type8.String({ minLength: 1, maxLength: 4096, description: "Search query (max 4096 chars)" }),
|
|
11082
|
+
topK: Type8.Optional(Type8.Integer({ minimum: 1, maximum: 20, description: "Max results to return (max 20)" })),
|
|
11083
|
+
scope: Type8.Optional(Type8.String({ description: "Optional search scope hint" }))
|
|
10533
11084
|
});
|
|
10534
|
-
PeerQueryResponseSchema =
|
|
10535
|
-
v:
|
|
10536
|
-
status:
|
|
11085
|
+
PeerQueryResponseSchema = Type8.Object({
|
|
11086
|
+
v: Type8.Literal(1, { description: "Protocol version" }),
|
|
11087
|
+
status: Type8.Union([Type8.Literal("ok"), Type8.Literal("rejected")], {
|
|
10537
11088
|
description: "Response status"
|
|
10538
11089
|
}),
|
|
10539
|
-
answer:
|
|
10540
|
-
results:
|
|
11090
|
+
answer: Type8.String({ description: "Curated answer text" }),
|
|
11091
|
+
results: Type8.Array(PeerResultEntrySchema, {
|
|
10541
11092
|
description: "Curated result entries with opaque source ids"
|
|
10542
11093
|
}),
|
|
10543
|
-
files:
|
|
11094
|
+
files: Type8.Array(PeerFileEntrySchema, {
|
|
10544
11095
|
description: "Attached original files with opaque source ids"
|
|
10545
11096
|
}),
|
|
10546
|
-
diagnostics:
|
|
11097
|
+
diagnostics: Type8.Array(PeerDiagnosticSchema, {
|
|
10547
11098
|
description: "Diagnostic messages (degraded-mode, rejection reasons, etc.)"
|
|
10548
11099
|
})
|
|
10549
11100
|
});
|
|
@@ -10790,7 +11341,7 @@ var init_simplex_query_store = __esm(() => {
|
|
|
10790
11341
|
// src/p2p/simplex-server.ts
|
|
10791
11342
|
import { existsSync as existsSync19, mkdirSync as mkdirSync15, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "node:fs";
|
|
10792
11343
|
import { join as join26 } from "node:path";
|
|
10793
|
-
import { Type as
|
|
11344
|
+
import { Type as Type9 } from "typebox";
|
|
10794
11345
|
import { Value as Value2 } from "typebox/value";
|
|
10795
11346
|
function targetTokens(value) {
|
|
10796
11347
|
return new Set((value.toLocaleLowerCase().match(TARGET_TOKEN_PATTERN) ?? []).filter((token) => token.length > 1));
|
|
@@ -11104,11 +11655,11 @@ var init_simplex_server = __esm(() => {
|
|
|
11104
11655
|
shareBytes: false,
|
|
11105
11656
|
redact: true
|
|
11106
11657
|
};
|
|
11107
|
-
SimplexWireEnvelopeSchema =
|
|
11108
|
-
v:
|
|
11109
|
-
kind:
|
|
11110
|
-
id:
|
|
11111
|
-
payload:
|
|
11658
|
+
SimplexWireEnvelopeSchema = Type9.Object({
|
|
11659
|
+
v: Type9.Literal(1, { description: "Envelope version" }),
|
|
11660
|
+
kind: Type9.Union([Type9.Literal("query"), Type9.Literal("response")], { description: "Payload kind" }),
|
|
11661
|
+
id: Type9.String({ minLength: 1, maxLength: 128, description: "Correlation id" }),
|
|
11662
|
+
payload: Type9.Unknown({ description: "PeerQueryRequest or PeerQueryResponse" })
|
|
11112
11663
|
});
|
|
11113
11664
|
TARGET_TOKEN_PATTERN = /[\p{L}\p{N}]+/gu;
|
|
11114
11665
|
PEERS_DIR = join26(".autorag", "p2p");
|
|
@@ -11121,7 +11672,7 @@ var init_simplex_server = __esm(() => {
|
|
|
11121
11672
|
});
|
|
11122
11673
|
|
|
11123
11674
|
// src/agent/peer-target-tool.ts
|
|
11124
|
-
import { Type as
|
|
11675
|
+
import { Type as Type10 } from "typebox";
|
|
11125
11676
|
function createRecommendPeerTargetsTool(workspacePath) {
|
|
11126
11677
|
return {
|
|
11127
11678
|
name: RECOMMEND_PEER_TARGETS_TOOL_NAME,
|
|
@@ -11154,8 +11705,8 @@ function createRecommendPeerTargetsTool(workspacePath) {
|
|
|
11154
11705
|
var RECOMMEND_PEER_TARGETS_TOOL_NAME = "recommend_peer_targets", recommendPeerTargetsSchema;
|
|
11155
11706
|
var init_peer_target_tool = __esm(() => {
|
|
11156
11707
|
init_simplex_server();
|
|
11157
|
-
recommendPeerTargetsSchema =
|
|
11158
|
-
query:
|
|
11708
|
+
recommendPeerTargetsSchema = Type10.Object({
|
|
11709
|
+
query: Type10.String({ description: "Question or topic to match against local peer personas." })
|
|
11159
11710
|
});
|
|
11160
11711
|
});
|
|
11161
11712
|
|
|
@@ -11231,7 +11782,7 @@ var MAX_DECOMPOSED_QUERIES = 5;
|
|
|
11231
11782
|
var init_query_decomposition = () => {};
|
|
11232
11783
|
|
|
11233
11784
|
// src/agent/query-peer-tool.ts
|
|
11234
|
-
import { Type as
|
|
11785
|
+
import { Type as Type11 } from "typebox";
|
|
11235
11786
|
function failure(alias, message) {
|
|
11236
11787
|
const details = { method: "query_peer_agent", ok: false, alias, message };
|
|
11237
11788
|
return { content: [{ type: "text", text: message }], details };
|
|
@@ -11346,11 +11897,11 @@ var init_query_peer_tool = __esm(() => {
|
|
|
11346
11897
|
init_simplex_query_store();
|
|
11347
11898
|
init_simplex_server();
|
|
11348
11899
|
init_evidence_ledger();
|
|
11349
|
-
queryPeerAgentSchema =
|
|
11350
|
-
alias:
|
|
11351
|
-
query:
|
|
11352
|
-
topK:
|
|
11353
|
-
scope:
|
|
11900
|
+
queryPeerAgentSchema = Type11.Object({
|
|
11901
|
+
alias: Type11.String({ minLength: 1 }),
|
|
11902
|
+
query: Type11.String({ minLength: 1, maxLength: 4096 }),
|
|
11903
|
+
topK: Type11.Optional(Type11.Integer({ minimum: 1, maximum: 20 })),
|
|
11904
|
+
scope: Type11.Optional(Type11.String())
|
|
11354
11905
|
});
|
|
11355
11906
|
});
|
|
11356
11907
|
|
|
@@ -11617,29 +12168,29 @@ function reconcileCitations(answer, results) {
|
|
|
11617
12168
|
]
|
|
11618
12169
|
};
|
|
11619
12170
|
}
|
|
11620
|
-
function
|
|
11621
|
-
|
|
11622
|
-
const results = details.results.map((result) => ({
|
|
12171
|
+
function toSearchResults(details, sourceByNumber) {
|
|
12172
|
+
return details.results.map((result) => ({
|
|
11623
12173
|
number: result.number,
|
|
11624
12174
|
title: result.title,
|
|
11625
12175
|
summary: result.summary,
|
|
11626
12176
|
evidence: result.evidence.map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
11627
|
-
confidence: confidenceFrom(result.confidence
|
|
12177
|
+
...result.confidence !== undefined ? { confidence: confidenceFrom(result.confidence) } : {},
|
|
11628
12178
|
source: sourceByNumber.get(result.number)
|
|
11629
12179
|
}));
|
|
11630
|
-
|
|
12180
|
+
}
|
|
12181
|
+
function createPreliminarySearchDocumentsResponse(sessionId, query, details, diagnostics = []) {
|
|
12182
|
+
const sourceByNumber = new Map(details.mapping.map((entry) => [entry.number, entry.source]));
|
|
11631
12183
|
return {
|
|
11632
12184
|
sessionId,
|
|
11633
12185
|
query,
|
|
11634
|
-
results,
|
|
11635
|
-
answer:
|
|
12186
|
+
results: toSearchResults(details, sourceByNumber),
|
|
12187
|
+
answer: details.answer,
|
|
11636
12188
|
searched: details.results.length,
|
|
11637
12189
|
warnings: [],
|
|
11638
|
-
diagnostics: [...
|
|
12190
|
+
diagnostics: [...diagnostics]
|
|
11639
12191
|
};
|
|
11640
12192
|
}
|
|
11641
|
-
function createEmptySearchDocumentsResponse(sessionId, query,
|
|
11642
|
-
sessions.set(sessionId, { query, registry: new Map });
|
|
12193
|
+
function createEmptySearchDocumentsResponse(sessionId, query, diagnostics = []) {
|
|
11643
12194
|
return {
|
|
11644
12195
|
sessionId,
|
|
11645
12196
|
query,
|
|
@@ -11655,7 +12206,7 @@ function normalizeEntryEvidenceRefs(entry) {
|
|
|
11655
12206
|
const derivedRetrieverMix = Array.from(new Set(rawRefs.map((ref) => ref.method)));
|
|
11656
12207
|
return rawRefs.map((ref) => {
|
|
11657
12208
|
if (ref.excerpt === undefined && ref.content === undefined) {
|
|
11658
|
-
throw new Error("
|
|
12209
|
+
throw new Error("results: every evidenceRef must include excerpt or content");
|
|
11659
12210
|
}
|
|
11660
12211
|
return normalizeSessionEvidenceRef({
|
|
11661
12212
|
method: ref.method,
|
|
@@ -11676,19 +12227,11 @@ function normalizeEntryEvidenceRefs(entry) {
|
|
|
11676
12227
|
});
|
|
11677
12228
|
});
|
|
11678
12229
|
}
|
|
11679
|
-
function recordStructuredResultsSession(sessionId, query, details,
|
|
11680
|
-
assertResultsMappingOneToOne("
|
|
11681
|
-
const registry = new Map;
|
|
12230
|
+
function recordStructuredResultsSession(sessionId, query, details, memory, componentDiagnostics = [], options = {}) {
|
|
12231
|
+
assertResultsMappingOneToOne("results", details.results, details.mapping);
|
|
11682
12232
|
const memoryResults = [];
|
|
11683
12233
|
for (const entry of details.mapping) {
|
|
11684
12234
|
const evidenceRefs = normalizeEntryEvidenceRefs(entry);
|
|
11685
|
-
registry.set(entry.number, {
|
|
11686
|
-
index: entry.number,
|
|
11687
|
-
content: entry.content,
|
|
11688
|
-
source: entry.source,
|
|
11689
|
-
method: entry.method,
|
|
11690
|
-
evidenceRefs
|
|
11691
|
-
});
|
|
11692
12235
|
const emittedResult = details.results.find((result) => result.number === entry.number);
|
|
11693
12236
|
memoryResults.push({
|
|
11694
12237
|
number: entry.number,
|
|
@@ -11697,23 +12240,15 @@ function recordStructuredResultsSession(sessionId, query, details, sessions, mem
|
|
|
11697
12240
|
content: entry.content,
|
|
11698
12241
|
method: entry.method,
|
|
11699
12242
|
source: entry.source,
|
|
11700
|
-
...emittedResult !== undefined ? { confidence: confidenceFrom(emittedResult.confidence) } : {},
|
|
12243
|
+
...emittedResult?.confidence !== undefined ? { confidence: confidenceFrom(emittedResult.confidence) } : {},
|
|
11701
12244
|
evidenceRefs
|
|
11702
12245
|
});
|
|
11703
12246
|
}
|
|
11704
|
-
sessions.set(sessionId, { query, registry });
|
|
11705
12247
|
if (!options.isolateMemory) {
|
|
11706
12248
|
memory.recordCuratedResultsSession({ sessionId, query, results: memoryResults });
|
|
11707
12249
|
memory.save();
|
|
11708
12250
|
}
|
|
11709
|
-
const results = details.
|
|
11710
|
-
number: result.number,
|
|
11711
|
-
title: result.title,
|
|
11712
|
-
summary: result.summary,
|
|
11713
|
-
evidence: result.evidence.map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
11714
|
-
confidence: confidenceFrom(result.confidence),
|
|
11715
|
-
source: registry.get(result.number)?.source || undefined
|
|
11716
|
-
}));
|
|
12251
|
+
const results = toSearchResults(details, new Map(details.mapping.map((entry) => [entry.number, entry.source || undefined])));
|
|
11717
12252
|
const citations = reconcileCitations(details.answer, results);
|
|
11718
12253
|
const answer = citations.answer;
|
|
11719
12254
|
const diagnostics = [...citations.diagnostics];
|
|
@@ -11743,7 +12278,7 @@ var init_search_documents = __esm(() => {
|
|
|
11743
12278
|
});
|
|
11744
12279
|
|
|
11745
12280
|
// src/agent/search-all-tool.ts
|
|
11746
|
-
import { Type as
|
|
12281
|
+
import { Type as Type12 } from "typebox";
|
|
11747
12282
|
function createSearchAllDocumentsTool(provider, ledger = new EvidenceLedger) {
|
|
11748
12283
|
return {
|
|
11749
12284
|
name: SEARCH_ALL_DOCUMENTS_TOOL_NAME,
|
|
@@ -11798,17 +12333,17 @@ var SEARCH_ALL_DOCUMENTS_TOOL_NAME = "search_all_documents", searchAllSchema;
|
|
|
11798
12333
|
var init_search_all_tool = __esm(() => {
|
|
11799
12334
|
init_evidence_ledger();
|
|
11800
12335
|
init_search_documents();
|
|
11801
|
-
searchAllSchema =
|
|
11802
|
-
query:
|
|
11803
|
-
topK:
|
|
12336
|
+
searchAllSchema = Type12.Object({
|
|
12337
|
+
query: Type12.String({ description: "Query to search across all configured retrieval methods." }),
|
|
12338
|
+
topK: Type12.Optional(Type12.Integer({
|
|
11804
12339
|
description: "Upper bound on returned evidence. Omit it to receive every distinct chunk the methods found; set it only when you deliberately want a shorter list."
|
|
11805
12340
|
})),
|
|
11806
|
-
scope:
|
|
12341
|
+
scope: Type12.Optional(Type12.String({ description: "Optional opaque virtual-path scope, e.g. /docs or /docs/**." }))
|
|
11807
12342
|
});
|
|
11808
12343
|
});
|
|
11809
12344
|
|
|
11810
12345
|
// src/agent/search-minsync-tool.ts
|
|
11811
|
-
import { Type as
|
|
12346
|
+
import { Type as Type13 } from "typebox";
|
|
11812
12347
|
function createSearchMinSyncDocumentsTool(getMethod, resolveScope = (scope) => scope, ledger = new EvidenceLedger) {
|
|
11813
12348
|
return {
|
|
11814
12349
|
name: SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME,
|
|
@@ -11858,12 +12393,12 @@ var SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME = "semantic_search_local_docs", searchMin
|
|
|
11858
12393
|
var init_search_minsync_tool = __esm(() => {
|
|
11859
12394
|
init_evidence_ledger();
|
|
11860
12395
|
init_search_documents();
|
|
11861
|
-
searchMinSyncSchema =
|
|
11862
|
-
query:
|
|
12396
|
+
searchMinSyncSchema = Type13.Object({
|
|
12397
|
+
query: Type13.String({
|
|
11863
12398
|
description: "Semantic query to search parsed document mirrors with MinSync vector retrieval."
|
|
11864
12399
|
}),
|
|
11865
|
-
topK:
|
|
11866
|
-
scope:
|
|
12400
|
+
topK: Type13.Optional(Type13.Integer({ description: "Maximum number of MinSync semantic chunks to return. Defaults to 50." })),
|
|
12401
|
+
scope: Type13.Optional(Type13.String({ description: "Optional opaque virtual-path scope, e.g. /docs or /docs/**." }))
|
|
11867
12402
|
});
|
|
11868
12403
|
});
|
|
11869
12404
|
|
|
@@ -11881,7 +12416,7 @@ function datasourceSearchToolName(datasourceId) {
|
|
|
11881
12416
|
}
|
|
11882
12417
|
|
|
11883
12418
|
// src/agent/search-single-datasource-tool.ts
|
|
11884
|
-
import { Type as
|
|
12419
|
+
import { Type as Type14 } from "typebox";
|
|
11885
12420
|
function createSingleDatasourceSearchTools(provider, specs, ledger = new EvidenceLedger) {
|
|
11886
12421
|
return specs.map((spec) => createTool(provider, spec, ledger));
|
|
11887
12422
|
}
|
|
@@ -11947,10 +12482,10 @@ var init_search_single_datasource_tool = __esm(() => {
|
|
|
11947
12482
|
init_evidence_ledger();
|
|
11948
12483
|
init_search_documents();
|
|
11949
12484
|
singleDatasourceToolName = datasourceSearchToolName;
|
|
11950
|
-
searchSingleDatasourceSchema =
|
|
11951
|
-
query:
|
|
11952
|
-
topK:
|
|
11953
|
-
scope:
|
|
12485
|
+
searchSingleDatasourceSchema = Type14.Object({
|
|
12486
|
+
query: Type14.String({ description: "Query to search within this datasource connection." }),
|
|
12487
|
+
topK: Type14.Optional(Type14.Integer({ description: "Maximum number of chunks to return. Defaults to 20." })),
|
|
12488
|
+
scope: Type14.Optional(Type14.String({ description: "Optional scope narrowing inside this datasource, e.g. one instance root." }))
|
|
11954
12489
|
});
|
|
11955
12490
|
});
|
|
11956
12491
|
|
|
@@ -12035,7 +12570,7 @@ ${input.skill}
|
|
|
12035
12570
|
|
|
12036
12571
|
${input.query}
|
|
12037
12572
|
|
|
12038
|
-
` + `When done,
|
|
12573
|
+
` + `When done, reply with a short report as your final message, with no tool call: what you changed (field: old → new), what you verified and how, ` + `and anything that still needs the user (for example an unset API-key environment variable, by name only). ` + `If you changed nothing, say why.`;
|
|
12039
12574
|
}
|
|
12040
12575
|
var SETUP_SKILL_RELATIVE_PATH;
|
|
12041
12576
|
var init_self_config = __esm(() => {
|
|
@@ -12066,7 +12601,6 @@ function buildSystemPrompt(config) {
|
|
|
12066
12601
|
toolLine(config, "check_memory", "inspect evidence earlier searches found for similar questions"),
|
|
12067
12602
|
toolLine(config, "recommend_peer_targets", "recommend local peer personas to ask about a topic without contacting them"),
|
|
12068
12603
|
toolLine(config, "query_peer_agent", "ask one trusted peer agent over SimpleX"),
|
|
12069
|
-
toolLine(config, "emit_autorag_results", "return the final structured answer with evidence ids for each result"),
|
|
12070
12604
|
...config.toolNames.filter((name) => name.startsWith("search_datasource_")).map((name) => `- **${name}**: search only the ${name.slice("search_datasource_".length).replace(/_/g, "-")} datasource connection, spawning no other datasource CLIs`),
|
|
12071
12605
|
...config.toolNames.filter((name) => ![
|
|
12072
12606
|
"bash",
|
|
@@ -12082,8 +12616,7 @@ function buildSystemPrompt(config) {
|
|
|
12082
12616
|
"jev",
|
|
12083
12617
|
"check_memory",
|
|
12084
12618
|
"recommend_peer_targets",
|
|
12085
|
-
"query_peer_agent"
|
|
12086
|
-
"emit_autorag_results"
|
|
12619
|
+
"query_peer_agent"
|
|
12087
12620
|
].includes(name) && !name.startsWith("search_datasource_")).map((name) => `- **${name}**: caller-provided tool`)
|
|
12088
12621
|
].filter((line) => line !== undefined);
|
|
12089
12622
|
const manifests = config.manifests.length === 0 ? "" : `
|
|
@@ -12147,12 +12680,12 @@ Your job is to retrieve candidates, read the relevant source material directly,
|
|
|
12147
12680
|
## Workflow
|
|
12148
12681
|
|
|
12149
12682
|
Searches follow a progressive, two-phase loop:
|
|
12150
|
-
1. **PLAN & FAST ANSWER** — Decide whether the query is answerable from general knowledge or memory. When baseline retrieval evidence is provided,
|
|
12683
|
+
1. **PLAN & FAST ANSWER** — Decide whether the query is answerable from general knowledge or memory. When baseline retrieval evidence is provided, write a complete, self-contained immediate first answer from that evidence as your reply, right away, without calling tools or waiting.
|
|
12151
12684
|
2. **EXPLORE & RETRIEVE** — Immediately following the fast answer, begin deeper exploration: ${discovery ? `use ${discovery} actively to locate relevant files and folders, and ` : ""}fan out across MinSync lexical/vector/hybrid retrieval, combined retrieval, and datasource search to expand candidates and fill evidence gaps.
|
|
12152
12685
|
3. **READ & VERIFY** — Use \`bash\` to open and verify relevant local files directly when needed, and in local sessions to organize files when the user asks (see File Organization); rely on Jikji and retrieval rather than blind directory browsing.
|
|
12153
12686
|
4. **JUDGE & RESOLVE** — Evaluate relevance, sufficiency, conflicts, and temporal context. When search results or evidence contain conflicting information, treat the freshest (most recent) information as authoritative and correct.
|
|
12154
12687
|
5. **CURATE** — Produce concise numbered knowledge units grounded in source evidence.
|
|
12155
|
-
6. **FINALIZE** —
|
|
12688
|
+
6. **FINALIZE** — End with the final answer as a plain reply, with no tool call. Earlier replies that are followed by a tool call are progress notes; only the last reply is the answer.
|
|
12156
12689
|
|
|
12157
12690
|
## Available Tools
|
|
12158
12691
|
|
|
@@ -12197,17 +12730,17 @@ ${fsearch}
|
|
|
12197
12730
|
${manifests}
|
|
12198
12731
|
## Output Format
|
|
12199
12732
|
|
|
12200
|
-
|
|
12201
|
-
-
|
|
12202
|
-
-
|
|
12203
|
-
-
|
|
12733
|
+
Your answer is your final reply, written as plain text, never as a tool call. Cite evidence inline with the ids the retrieval tools print next to each result:
|
|
12734
|
+
- Put the id in square brackets at the end of the sentence it supports, e.g. \`The cap is 28% [e3].\` Use \`[e3][e7]\` or \`[e3, e7]\` for several. Copy ids exactly as printed; never invent one.
|
|
12735
|
+
- For a local file you opened yourself with \`bash\`, cite \`[file:<absolute path>]\`.
|
|
12736
|
+
- The harness resolves every id to its recorded source, number the citations \`[1]\`, \`[2]\`, … in order of first appearance, and attaches the sources for you. Never type a source path, a chunk, or a citation number yourself.
|
|
12737
|
+
- A citation whose id no tool returned in this run is dropped, so cite only ids you saw.
|
|
12204
12738
|
|
|
12205
12739
|
## Answer Guidelines
|
|
12206
12740
|
|
|
12207
12741
|
- **Complete vs. delta answer**: When no first answer reached the caller, give the complete core answer. When a first answer was already delivered, return only the delta against it — corrections and newly verified findings — and never repeat its unchanged content; if nothing changed, confirm the first answer in one short line.
|
|
12208
12742
|
- **Bullet-point core answer**: Provide the core answer to the user's question in at most 5 bullet points. If additional explanation or context is necessary, append it after the bullet points.
|
|
12209
|
-
- **Direct answer only**: The caller only needs the answer to their question. Never include specific file paths, datasource descriptions, or retrieval mechanics/principles in
|
|
12210
|
-
- **Citation style**: Cite supporting evidence chunks using bracketed numbers only (e.g. [1], [2]). Do not quote raw chunk text or mention source paths directly in \`answer\`.
|
|
12743
|
+
- **Direct answer only**: The caller only needs the answer to their question. Never include specific file paths, datasource descriptions, or retrieval mechanics/principles in the answer (source paths are attached to each citation from the evidence ids you cite). Do not quote raw chunk text.
|
|
12211
12744
|
- ${ANSWER_CITATION_RULE}
|
|
12212
12745
|
- ${ANSWER_IMAGE_EMBED_RULE} ${ANSWER_IMAGE_DELTA_RULE}
|
|
12213
12746
|
- **No per-source negative reports**: Never report individual negative findings per source (e.g. "no information found in Slack" or "checked Drive but found nothing"). Simply omit unproductive sources from the answer and focus on what was found or provide a concise overall conclusion.
|
|
@@ -12220,7 +12753,7 @@ Call \`emit_autorag_results\` exactly once with:
|
|
|
12220
12753
|
- **Curate, don't dump**: return useful knowledge units, not raw search output.
|
|
12221
12754
|
- **Address intent**: answer the caller's actual need.
|
|
12222
12755
|
- **Preserve traceability**: cite evidence by the ids retrieval tools show, so source paths and excerpts are attached for you.
|
|
12223
|
-
- **Finalize once**: the
|
|
12756
|
+
- **Finalize once**: the last reply, with no tool call, is the final answer.
|
|
12224
12757
|
`;
|
|
12225
12758
|
}
|
|
12226
12759
|
var init_system_prompt = __esm(() => {
|
|
@@ -14207,7 +14740,7 @@ var init_render = __esm(() => {
|
|
|
14207
14740
|
});
|
|
14208
14741
|
|
|
14209
14742
|
// src/agent/web-fetch-tool.ts
|
|
14210
|
-
import { Type as
|
|
14743
|
+
import { Type as Type15 } from "typebox";
|
|
14211
14744
|
function truncateHead(output, maxBytes, maxLines) {
|
|
14212
14745
|
const lines = output.split(`
|
|
14213
14746
|
`);
|
|
@@ -14311,9 +14844,9 @@ var init_web_fetch_tool = __esm(() => {
|
|
|
14311
14844
|
init_render();
|
|
14312
14845
|
init_evidence_ledger();
|
|
14313
14846
|
FETCH_MAX_OUTPUT_BYTES = 50 * 1024;
|
|
14314
|
-
webFetchSchema =
|
|
14315
|
-
url:
|
|
14316
|
-
raw:
|
|
14847
|
+
webFetchSchema = Type15.Object({
|
|
14848
|
+
url: Type15.String({ description: "The http(s) URL to fetch and read." }),
|
|
14849
|
+
raw: Type15.Optional(Type15.Boolean({ description: "Return the raw response body without markdown rendering or formatting." }))
|
|
14317
14850
|
});
|
|
14318
14851
|
});
|
|
14319
14852
|
|
|
@@ -15272,7 +15805,7 @@ function parseResponse(data) {
|
|
|
15272
15805
|
} : {}
|
|
15273
15806
|
};
|
|
15274
15807
|
}
|
|
15275
|
-
var
|
|
15808
|
+
var DEFAULT_BASE_URL2 = "https://generativelanguage.googleapis.com", API_VERSION = "v1beta", DEFAULT_MODEL = "gemini-3.8-flash", MAX_RESPONSE_BYTES, MAX_ERROR_BYTES, GeminiProvider;
|
|
15276
15809
|
var init_gemini = __esm(() => {
|
|
15277
15810
|
init_model_auth();
|
|
15278
15811
|
init_query();
|
|
@@ -15294,7 +15827,7 @@ var init_gemini = __esm(() => {
|
|
|
15294
15827
|
const model = envCredential("GEMINI_SEARCH_MODEL") ?? (credential.source === "injected" ? credential.modelId : undefined) ?? DEFAULT_MODEL;
|
|
15295
15828
|
const parsed = params.parsedQuery ?? parseSearchQuery(params.query);
|
|
15296
15829
|
const query = parsed.hasDirectives ? formatQuery(parsed, GOOGLE_QUERY_SYNTAX) : params.query;
|
|
15297
|
-
const baseUrl = (credential.baseUrl ??
|
|
15830
|
+
const baseUrl = (credential.baseUrl ?? DEFAULT_BASE_URL2).replace(/\/+$/, "");
|
|
15298
15831
|
const fetchImpl = params.fetch ?? fetch;
|
|
15299
15832
|
const response = await fetchImpl(`${baseUrl}/${API_VERSION}/models/${model}:generateContent`, {
|
|
15300
15833
|
method: "POST",
|
|
@@ -15439,7 +15972,7 @@ function parseResponse2(response) {
|
|
|
15439
15972
|
...response.id !== undefined ? { requestId: response.id } : {}
|
|
15440
15973
|
};
|
|
15441
15974
|
}
|
|
15442
|
-
var
|
|
15975
|
+
var DEFAULT_BASE_URL3 = "https://api.anthropic.com", DEFAULT_MODEL2 = "claude-haiku-5-5", DEFAULT_MAX_TOKENS2 = 4096, MAX_RESPONSE_BYTES2, MAX_ERROR_BYTES2, WEB_SEARCH_TOOL_TYPE = "web_search_20250305", ANTHROPIC_QUERY_SYNTAX, AnthropicProvider;
|
|
15443
15976
|
var init_anthropic = __esm(() => {
|
|
15444
15977
|
init_model_auth();
|
|
15445
15978
|
init_query();
|
|
@@ -15470,7 +16003,7 @@ var init_anthropic = __esm(() => {
|
|
|
15470
16003
|
const model = envCredential("ANTHROPIC_SEARCH_MODEL") ?? (credential.source === "injected" ? credential.modelId : undefined) ?? DEFAULT_MODEL2;
|
|
15471
16004
|
const parsed = params.parsedQuery ?? parseSearchQuery(params.query);
|
|
15472
16005
|
const plan = planQuery(params.query, parsed);
|
|
15473
|
-
const baseUrl = (credential.baseUrl ??
|
|
16006
|
+
const baseUrl = (credential.baseUrl ?? DEFAULT_BASE_URL3).replace(/\/+$/, "");
|
|
15474
16007
|
const fetchImpl = params.fetch ?? fetch;
|
|
15475
16008
|
const response = await fetchImpl(`${baseUrl}/v1/messages?beta=true`, {
|
|
15476
16009
|
method: "POST",
|
|
@@ -15482,7 +16015,7 @@ var init_anthropic = __esm(() => {
|
|
|
15482
16015
|
},
|
|
15483
16016
|
body: JSON.stringify({
|
|
15484
16017
|
model,
|
|
15485
|
-
max_tokens: params.maxOutputTokens ??
|
|
16018
|
+
max_tokens: params.maxOutputTokens ?? DEFAULT_MAX_TOKENS2,
|
|
15486
16019
|
...params.systemPrompt ? { system: params.systemPrompt } : {},
|
|
15487
16020
|
messages: [{ role: "user", content: plan.query }],
|
|
15488
16021
|
tools: [
|
|
@@ -17565,7 +18098,7 @@ async function searchPublicWeb(params, deadlines = {}) {
|
|
|
17565
18098
|
}
|
|
17566
18099
|
var PUBLIC_ENGINE_IDS, DEFAULT_NUM_RESULTS8 = 15, MAX_NUM_RESULTS8 = 30, SOFT_DEADLINE_MS = 5000, HARD_DEADLINE_MS = 30000, PublicWebProvider;
|
|
17567
18100
|
var init_public = __esm(() => {
|
|
17568
|
-
|
|
18101
|
+
init_provider2();
|
|
17569
18102
|
init_types3();
|
|
17570
18103
|
init_utils();
|
|
17571
18104
|
PUBLIC_ENGINE_IDS = [
|
|
@@ -17639,7 +18172,7 @@ function resolveProviderCandidates(routing = {}) {
|
|
|
17639
18172
|
return candidates;
|
|
17640
18173
|
}
|
|
17641
18174
|
var PROVIDER_META, instanceCache;
|
|
17642
|
-
var
|
|
18175
|
+
var init_provider2 = __esm(() => {
|
|
17643
18176
|
init_types3();
|
|
17644
18177
|
init_types3();
|
|
17645
18178
|
PROVIDER_META = {
|
|
@@ -17825,15 +18358,15 @@ async function executeWebSearch(params, options = {}) {
|
|
|
17825
18358
|
}
|
|
17826
18359
|
var TOTAL_TIMEOUT_MULTIPLIER = 2;
|
|
17827
18360
|
var init_search = __esm(() => {
|
|
17828
|
-
|
|
18361
|
+
init_provider2();
|
|
17829
18362
|
init_query();
|
|
17830
18363
|
init_types3();
|
|
17831
|
-
|
|
18364
|
+
init_provider2();
|
|
17832
18365
|
init_types3();
|
|
17833
18366
|
});
|
|
17834
18367
|
|
|
17835
18368
|
// src/agent/web-search-tool.ts
|
|
17836
|
-
import { Type as
|
|
18369
|
+
import { Type as Type16 } from "typebox";
|
|
17837
18370
|
function createWebSearchTool(options = {}, ledger = new EvidenceLedger) {
|
|
17838
18371
|
return {
|
|
17839
18372
|
name: WEB_SEARCH_TOOL_NAME,
|
|
@@ -17909,15 +18442,15 @@ var WEB_SEARCH_TOOL_NAME = "web_search", webSearchSchema;
|
|
|
17909
18442
|
var init_web_search_tool = __esm(() => {
|
|
17910
18443
|
init_search();
|
|
17911
18444
|
init_evidence_ledger();
|
|
17912
|
-
webSearchSchema =
|
|
17913
|
-
query:
|
|
18445
|
+
webSearchSchema = Type16.Object({
|
|
18446
|
+
query: Type16.String({
|
|
17914
18447
|
description: 'Search query. Supports Google-style directives: site:/-site:, after:/before: (YYYY-MM-DD), inurl:, intitle:, filetype:, "exact phrase", -term, OR.'
|
|
17915
18448
|
}),
|
|
17916
|
-
recency:
|
|
18449
|
+
recency: Type16.Optional(Type16.Union([Type16.Literal("day"), Type16.Literal("week"), Type16.Literal("month"), Type16.Literal("year")], {
|
|
17917
18450
|
description: "Optional recency window for results (pure time filter)."
|
|
17918
18451
|
})),
|
|
17919
|
-
limit:
|
|
17920
|
-
num_search_results:
|
|
18452
|
+
limit: Type16.Optional(Type16.Integer({ description: "Maximum number of results to return." })),
|
|
18453
|
+
num_search_results: Type16.Optional(Type16.Integer({ description: "Alias for limit (result count hint)." }))
|
|
17921
18454
|
});
|
|
17922
18455
|
});
|
|
17923
18456
|
|
|
@@ -17964,10 +18497,7 @@ class AutoRAGAgent {
|
|
|
17964
18497
|
runLogger;
|
|
17965
18498
|
lastQuery;
|
|
17966
18499
|
lastSessionId;
|
|
17967
|
-
sessions = new Map;
|
|
17968
18500
|
activeRun = false;
|
|
17969
|
-
resultCapture;
|
|
17970
|
-
interactiveFastAnswerCallback;
|
|
17971
18501
|
modelNativeSearchAuth;
|
|
17972
18502
|
retrievalTrace = [];
|
|
17973
18503
|
evidenceLedger = new EvidenceLedger;
|
|
@@ -18129,10 +18659,6 @@ class AutoRAGAgent {
|
|
|
18129
18659
|
const searchMinSyncTool = createSearchMinSyncDocumentsTool(() => this.remoteFilteredRetrievalMethod(this.minSyncMethod), (scope) => this.resolveRetrievalScope(scope), this.evidenceLedger);
|
|
18130
18660
|
const searchAllTool = createSearchAllDocumentsTool(this, this.evidenceLedger);
|
|
18131
18661
|
const loadDatasourceSkillTool = createLoadDatasourceSkillTool(this);
|
|
18132
|
-
const emitResultsTool = createEmitResultsTool((details) => this.resultCapture?.(details), {
|
|
18133
|
-
ledger: this.evidenceLedger,
|
|
18134
|
-
allowLocalFiles: !this.remoteSession
|
|
18135
|
-
});
|
|
18136
18662
|
const scanDuplicateDocumentsTool = this.dupeyOptions === false ? undefined : createScanDuplicateDocumentsTool(this);
|
|
18137
18663
|
this.jevJudge = options.jev === undefined || options.jev === false || this.remoteSession ? undefined : createJevJudge(options.jev);
|
|
18138
18664
|
this.jevExtension = this.jevJudge === undefined ? undefined : createJevExtension(this.jevJudge);
|
|
@@ -18167,8 +18693,6 @@ class AutoRAGAgent {
|
|
|
18167
18693
|
"check_memory",
|
|
18168
18694
|
...singleDatasourceTools.map((tool) => tool.name),
|
|
18169
18695
|
LOAD_DATASOURCE_SKILL_TOOL_NAME,
|
|
18170
|
-
EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
18171
|
-
EMIT_FAST_ANSWER_TOOL_NAME,
|
|
18172
18696
|
SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME,
|
|
18173
18697
|
SEARCH_ALL_DOCUMENTS_TOOL_NAME,
|
|
18174
18698
|
JIKJI_FIND_TOOL_NAME,
|
|
@@ -18199,7 +18723,6 @@ class AutoRAGAgent {
|
|
|
18199
18723
|
loadDatasourceSkillTool,
|
|
18200
18724
|
...webSearchTool !== undefined ? [webSearchTool] : [],
|
|
18201
18725
|
...webFetchTool !== undefined ? [webFetchTool] : [],
|
|
18202
|
-
emitResultsTool,
|
|
18203
18726
|
...scanDuplicateDocumentsTool !== undefined ? [scanDuplicateDocumentsTool] : [],
|
|
18204
18727
|
...jikjiFindTool !== undefined ? [jikjiFindTool] : [],
|
|
18205
18728
|
...everythingSearchTool !== undefined ? [everythingSearchTool] : [],
|
|
@@ -18346,12 +18869,11 @@ ${context.text}
|
|
|
18346
18869
|
source: "memory"
|
|
18347
18870
|
};
|
|
18348
18871
|
}
|
|
18349
|
-
const registry = this.sessions.get(sessionId)?.registry;
|
|
18350
18872
|
const resultByNumber = new Map(details.results.map((result) => [result.number, result]));
|
|
18351
18873
|
const units = [];
|
|
18352
18874
|
for (const entry of details.mapping) {
|
|
18353
18875
|
const result = resultByNumber.get(entry.number);
|
|
18354
|
-
const refs =
|
|
18876
|
+
const refs = normalizeEntryEvidenceRefs(entry);
|
|
18355
18877
|
if (result === undefined || refs.length === 0)
|
|
18356
18878
|
continue;
|
|
18357
18879
|
for (const ref of refs) {
|
|
@@ -18432,7 +18954,7 @@ ${context.text}
|
|
|
18432
18954
|
providerApiKeys: { [local.provider]: local.apiKey }
|
|
18433
18955
|
};
|
|
18434
18956
|
}
|
|
18435
|
-
async createSearchSession(resolved, systemPrompt
|
|
18957
|
+
async createSearchSession(resolved, systemPrompt) {
|
|
18436
18958
|
if (this.boundPiRuntime !== undefined) {
|
|
18437
18959
|
const session = this.boundPiRuntime.session;
|
|
18438
18960
|
return {
|
|
@@ -18452,10 +18974,7 @@ ${context.text}
|
|
|
18452
18974
|
apiKey: resolved.apiKey,
|
|
18453
18975
|
providerApiKeys: resolved.providerApiKeys,
|
|
18454
18976
|
getSystemPrompt: () => systemPrompt,
|
|
18455
|
-
customTools:
|
|
18456
|
-
...this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
18457
|
-
...extraTools
|
|
18458
|
-
],
|
|
18977
|
+
customTools: this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
18459
18978
|
remoteSession: this.remoteSession,
|
|
18460
18979
|
contextTransform: (messages) => this.withMemoryContext(messages),
|
|
18461
18980
|
...this.jevExtension !== undefined ? { extensionFactories: [this.jevExtension], extensionToolNames: [JEV_TOOL_NAME] } : {}
|
|
@@ -18536,19 +19055,12 @@ ${context.text}
|
|
|
18536
19055
|
modelId: this.boundPiRuntime?.session.model?.id ?? resolved?.model.id
|
|
18537
19056
|
})),
|
|
18538
19057
|
contextTransform: (messages) => this.withMemoryContext(messages),
|
|
18539
|
-
customTools:
|
|
18540
|
-
...this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
18541
|
-
createEmitFastAnswerTool((details) => this.interactiveFastAnswerCallback?.(details), {
|
|
18542
|
-
ledger: this.evidenceLedger
|
|
18543
|
-
})
|
|
18544
|
-
],
|
|
19058
|
+
customTools: this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
18545
19059
|
onQuery: (query, pi) => this.runInteractivePiQuery(query, pi),
|
|
18546
|
-
inactiveToolNames: [EMIT_FAST_ANSWER_TOOL_NAME],
|
|
18547
19060
|
...this.jevExtension !== undefined ? { extensionFactories: [this.jevExtension], extensionToolNames: [JEV_TOOL_NAME] } : {},
|
|
18548
19061
|
...this.updateNotice === undefined ? {} : { updateNotice: this.updateNotice }
|
|
18549
19062
|
});
|
|
18550
19063
|
this.boundPiRuntime = runtime.runtime;
|
|
18551
|
-
runtime.runtime.session.setActiveToolsByName(runtime.runtime.session.getActiveToolNames().filter((name) => name !== EMIT_FAST_ANSWER_TOOL_NAME));
|
|
18552
19064
|
const dispose = runtime.dispose;
|
|
18553
19065
|
return {
|
|
18554
19066
|
...runtime,
|
|
@@ -18559,17 +19071,14 @@ ${context.text}
|
|
|
18559
19071
|
}
|
|
18560
19072
|
};
|
|
18561
19073
|
}
|
|
19074
|
+
deriveAnswer(text) {
|
|
19075
|
+
const derived = deriveResultsFromAnswer(text, this.evidenceLedger, { allowLocalFiles: !this.remoteSession });
|
|
19076
|
+
this.routingDiagnostics.push(...derived.diagnostics);
|
|
19077
|
+
return derived.details;
|
|
19078
|
+
}
|
|
18562
19079
|
async runInteractivePiQuery(query, pi) {
|
|
18563
19080
|
pi.setSessionName(query.slice(0, 80));
|
|
18564
|
-
for await (const
|
|
18565
|
-
const text = event.type === "progress" ? event.text : event.response.answer;
|
|
18566
|
-
pi.sendMessage({
|
|
18567
|
-
customType: `autorag.${event.type}`,
|
|
18568
|
-
content: [{ type: "text", text }],
|
|
18569
|
-
display: true,
|
|
18570
|
-
details: event
|
|
18571
|
-
}, { triggerTurn: false });
|
|
18572
|
-
}
|
|
19081
|
+
for await (const _event of this.searchDocumentsStream(query)) {}
|
|
18573
19082
|
}
|
|
18574
19083
|
abort() {
|
|
18575
19084
|
this.activeSession?.abort();
|
|
@@ -18600,11 +19109,6 @@ ${context.text}
|
|
|
18600
19109
|
this.refreshing = false;
|
|
18601
19110
|
}
|
|
18602
19111
|
}
|
|
18603
|
-
getResultRegistry(sessionId) {
|
|
18604
|
-
const sid = sessionId ?? this.lastSessionId;
|
|
18605
|
-
const session = sid ? this.sessions.get(sid) : undefined;
|
|
18606
|
-
return session?.registry ?? new Map;
|
|
18607
|
-
}
|
|
18608
19112
|
async searchDocuments(query, options = {}) {
|
|
18609
19113
|
if (this.activeRun) {
|
|
18610
19114
|
throw new Error("AutoRAG agent is busy; await the in-flight searchDocuments() call before starting another");
|
|
@@ -18616,7 +19120,7 @@ ${context.text}
|
|
|
18616
19120
|
if (trimmedQuery.length === 0) {
|
|
18617
19121
|
this.lastQuery = trimmedQuery;
|
|
18618
19122
|
this.lastSessionId = sessionId;
|
|
18619
|
-
return createEmptySearchDocumentsResponse(sessionId, trimmedQuery, this.
|
|
19123
|
+
return createEmptySearchDocumentsResponse(sessionId, trimmedQuery, this.startupDiagnostics);
|
|
18620
19124
|
}
|
|
18621
19125
|
options = this.normalizeRetrievalOptions(options);
|
|
18622
19126
|
if (this.remoteSession && options.observedSources !== undefined)
|
|
@@ -18652,11 +19156,7 @@ ${context.text}
|
|
|
18652
19156
|
publishPreliminary(details);
|
|
18653
19157
|
};
|
|
18654
19158
|
let session;
|
|
18655
|
-
this.interactiveFastAnswerCallback = emitPreliminary;
|
|
18656
19159
|
let unsubscribers = [];
|
|
18657
|
-
this.resultCapture = (details) => {
|
|
18658
|
-
captured = details;
|
|
18659
|
-
};
|
|
18660
19160
|
let searchStarted = false;
|
|
18661
19161
|
try {
|
|
18662
19162
|
const resolved = await this.resolveSessionModel();
|
|
@@ -18674,7 +19174,7 @@ ${context.text}
|
|
|
18674
19174
|
model: resolved.model.id
|
|
18675
19175
|
});
|
|
18676
19176
|
searchStarted = true;
|
|
18677
|
-
session = await this.createSearchSession(resolved, buildSystemPrompt(this.currentSystemPromptConfig({ modelId: resolved.model.id }))
|
|
19177
|
+
session = await this.createSearchSession(resolved, buildSystemPrompt(this.currentSystemPromptConfig({ modelId: resolved.model.id })));
|
|
18678
19178
|
this.activeSession = session;
|
|
18679
19179
|
unsubscribers = this.configureSearchSession(session);
|
|
18680
19180
|
let timeout;
|
|
@@ -18683,45 +19183,36 @@ ${context.text}
|
|
|
18683
19183
|
await Promise.race([
|
|
18684
19184
|
(async () => {
|
|
18685
19185
|
const plan = await this.planQuery(trimmedQuery, resolved, planAbort.signal);
|
|
18686
|
-
const sessionAgent = session.piSession;
|
|
18687
19186
|
const activeSession = session;
|
|
18688
|
-
const
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
activeSession.agent.state.thinkingLevel = clampThinkingLevel(resolved.model, this.fastThinkingLevel);
|
|
18697
|
-
activeSession.agent.state.tools = [
|
|
18698
|
-
...this.tools,
|
|
18699
|
-
{ name: EMIT_FAST_ANSWER_TOOL_NAME }
|
|
18700
|
-
];
|
|
18701
|
-
}
|
|
19187
|
+
const sessionAgent = activeSession.piSession;
|
|
19188
|
+
const transcript = () => sessionAgent?.messages ?? activeSession.agent.state.messages;
|
|
19189
|
+
const setThinking = (level) => {
|
|
19190
|
+
const clamped = clampThinkingLevel(resolved.model, level);
|
|
19191
|
+
if (sessionAgent !== undefined)
|
|
19192
|
+
sessionAgent.setThinkingLevel(clamped);
|
|
19193
|
+
else
|
|
19194
|
+
activeSession.agent.state.thinkingLevel = clamped;
|
|
18702
19195
|
};
|
|
18703
19196
|
if (plan.route === "config" && plan.selfConfigSkill !== undefined && this.selfConfig !== undefined) {
|
|
18704
19197
|
selfConfigRun = true;
|
|
18705
19198
|
mkdirSync17(this.workspaceProjectRoot, { recursive: true });
|
|
18706
19199
|
const previousTools = sessionAgent?.getActiveToolNames();
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
sessionAgent.setActiveToolsByName([...PI_BUILTIN_TOOL_NAMES
|
|
18710
|
-
|
|
18711
|
-
activeSession.agent.state.
|
|
18712
|
-
activeSession.agent.state.tools = this.tools.filter((tool) => tool.name === EMIT_AUTORAG_RESULTS_TOOL_NAME);
|
|
18713
|
-
}
|
|
19200
|
+
setThinking(this.finalThinkingLevel);
|
|
19201
|
+
if (sessionAgent !== undefined)
|
|
19202
|
+
sessionAgent.setActiveToolsByName([...PI_BUILTIN_TOOL_NAMES]);
|
|
19203
|
+
else
|
|
19204
|
+
activeSession.agent.state.tools = [];
|
|
18714
19205
|
const configBefore = snapshotConfigFile(this.selfConfig.configPath);
|
|
18715
19206
|
try {
|
|
18716
|
-
await
|
|
19207
|
+
await activeSession.prompt(buildSelfConfigPrompt({
|
|
18717
19208
|
query: trimmedQuery,
|
|
18718
19209
|
configPath: this.selfConfig.configPath,
|
|
18719
19210
|
agentDir: this.piAgentDir ?? getAgentDir2(),
|
|
18720
19211
|
skill: plan.selfConfigSkill
|
|
18721
19212
|
}));
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
19213
|
+
const report = finalAnswerText(transcript());
|
|
19214
|
+
if (report !== undefined)
|
|
19215
|
+
captured = this.deriveAnswer(report);
|
|
18725
19216
|
const rolledBack = await rollbackIfBroken(this.selfConfig, configBefore);
|
|
18726
19217
|
if (rolledBack !== undefined) {
|
|
18727
19218
|
this.routingDiagnostics.push({
|
|
@@ -18730,11 +19221,10 @@ ${context.text}
|
|
|
18730
19221
|
message: `The edited config did not validate, so the previous config was restored. ${rolledBack}`,
|
|
18731
19222
|
source: "self-config"
|
|
18732
19223
|
});
|
|
18733
|
-
|
|
18734
|
-
if (emitted !== undefined) {
|
|
19224
|
+
if (captured !== undefined) {
|
|
18735
19225
|
captured = {
|
|
18736
|
-
...
|
|
18737
|
-
answer: `${
|
|
19226
|
+
...captured,
|
|
19227
|
+
answer: `${captured.answer}
|
|
18738
19228
|
|
|
18739
19229
|
Warning: the edited config did not validate, so the previous config was restored (nothing was changed). Problem: ${rolledBack}`
|
|
18740
19230
|
};
|
|
@@ -18748,49 +19238,35 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
18748
19238
|
return;
|
|
18749
19239
|
}
|
|
18750
19240
|
if (plan.route === "direct") {
|
|
18751
|
-
|
|
18752
|
-
await
|
|
18753
|
-
const answer =
|
|
19241
|
+
setThinking(this.fastThinkingLevel);
|
|
19242
|
+
await activeSession.prompt(this.buildDirectAnswerPrompt(trimmedQuery));
|
|
19243
|
+
const answer = finalAnswerText(transcript());
|
|
18754
19244
|
if (answer !== undefined)
|
|
18755
|
-
captured =
|
|
19245
|
+
captured = this.deriveAnswer(answer);
|
|
18756
19246
|
return;
|
|
18757
19247
|
}
|
|
18758
19248
|
const baseline = await this.prefetchInitialRetrievalContext(trimmedQuery, plan.queries, options, plan.datasources);
|
|
18759
|
-
|
|
18760
|
-
await
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
const text = lastAssistantText(session.piSession?.messages ?? session.agent.state.messages);
|
|
18764
|
-
if (text !== undefined)
|
|
18765
|
-
preliminary = { answer: text, results: [], sources: [], evidenceRefs: [] };
|
|
18766
|
-
}
|
|
18767
|
-
if (preliminary !== undefined)
|
|
18768
|
-
emitPreliminary(preliminary);
|
|
18769
|
-
if (captured !== undefined)
|
|
18770
|
-
return;
|
|
19249
|
+
setThinking(this.fastThinkingLevel);
|
|
19250
|
+
await activeSession.prompt(this.buildFastAnswerPrompt(trimmedQuery, options, baseline));
|
|
19251
|
+
const fastText = finalAnswerText(transcript());
|
|
19252
|
+
const preliminary = fastText === undefined ? undefined : this.deriveAnswer(fastText);
|
|
18771
19253
|
if (preliminary !== undefined) {
|
|
19254
|
+
emitPreliminary(preliminary);
|
|
18772
19255
|
const followUp = await this.shouldFollowUp(trimmedQuery, preliminary);
|
|
18773
19256
|
if (planAbort.signal.aborted)
|
|
18774
19257
|
return;
|
|
18775
19258
|
if (!followUp) {
|
|
18776
|
-
captured =
|
|
19259
|
+
captured = preliminary;
|
|
18777
19260
|
return;
|
|
18778
19261
|
}
|
|
18779
|
-
}
|
|
18780
|
-
if (preliminary !== undefined)
|
|
18781
19262
|
publishPreliminary(preliminary);
|
|
18782
|
-
if (sessionAgent !== undefined) {
|
|
18783
|
-
sessionAgent.setThinkingLevel(clampThinkingLevel(resolved.model, this.finalThinkingLevel));
|
|
18784
|
-
sessionAgent.setActiveToolsByName(sessionAgent.getActiveToolNames().filter((name) => name !== EMIT_FAST_ANSWER_TOOL_NAME));
|
|
18785
|
-
} else {
|
|
18786
|
-
session.agent.state.thinkingLevel = clampThinkingLevel(resolved.model, this.finalThinkingLevel);
|
|
18787
|
-
session.agent.state.tools = [...this.tools];
|
|
18788
19263
|
}
|
|
19264
|
+
setThinking(this.finalThinkingLevel);
|
|
18789
19265
|
const fastAnswerDelivered = preliminary !== undefined && this.preliminaryCallback !== undefined;
|
|
18790
|
-
await
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
19266
|
+
await activeSession.prompt(this.buildRefinementPrompt(trimmedQuery, options, fastText, fastAnswerDelivered));
|
|
19267
|
+
const finalText = finalAnswerText(transcript());
|
|
19268
|
+
if (finalText !== undefined)
|
|
19269
|
+
captured = this.deriveAnswer(finalText);
|
|
18794
19270
|
})(),
|
|
18795
19271
|
new Promise((resolve, reject) => {
|
|
18796
19272
|
timeout = setTimeout(() => {
|
|
@@ -18810,7 +19286,7 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
18810
19286
|
clearTimeout(timeout);
|
|
18811
19287
|
}
|
|
18812
19288
|
if (captured === undefined && timedOutAfterFastAnswer && fastCaptured !== undefined) {
|
|
18813
|
-
const response = recordStructuredResultsSession(sessionId, trimmedQuery,
|
|
19289
|
+
const response = recordStructuredResultsSession(sessionId, trimmedQuery, fastCaptured, this.memory, [
|
|
18814
19290
|
...this.collectComponentDiagnostics(),
|
|
18815
19291
|
{
|
|
18816
19292
|
code: "search-timeout",
|
|
@@ -18844,15 +19320,15 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
18844
19320
|
sessionId,
|
|
18845
19321
|
query: trimmedQuery,
|
|
18846
19322
|
results: [],
|
|
18847
|
-
answer:
|
|
19323
|
+
answer: buildMissingFinalAnswer(trimmedQuery, reason, this.retrievalTrace, modelError),
|
|
18848
19324
|
searched: this.retrievalTrace.reduce((total, entry) => total + entry.resultCount, 0),
|
|
18849
19325
|
warnings: [],
|
|
18850
19326
|
diagnostics: [
|
|
18851
19327
|
...this.collectComponentDiagnostics(),
|
|
18852
19328
|
{
|
|
18853
|
-
code: "
|
|
19329
|
+
code: "no-final-answer",
|
|
18854
19330
|
severity: "warning",
|
|
18855
|
-
message: "The agent ended its run without
|
|
19331
|
+
message: "The agent ended its run without a final answer message; returning a degraded response that carries the run's retrieval trace."
|
|
18856
19332
|
},
|
|
18857
19333
|
...modelError === undefined ? [] : [
|
|
18858
19334
|
{
|
|
@@ -18898,7 +19374,7 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
18898
19374
|
source: "agent"
|
|
18899
19375
|
});
|
|
18900
19376
|
}
|
|
18901
|
-
const recorded = recordStructuredResultsSession(sessionId, trimmedQuery, captured, this.
|
|
19377
|
+
const recorded = recordStructuredResultsSession(sessionId, trimmedQuery, captured, this.memory, componentDiagnostics, { isolateMemory: this.remoteSession || selfConfigRun });
|
|
18902
19378
|
const memoryDiagnostic = selfConfigRun ? undefined : await this.recordJudgedEvidence(sessionId, trimmedQuery, captured);
|
|
18903
19379
|
const response = memoryDiagnostic === undefined ? recorded : { ...recorded, diagnostics: [...recorded.diagnostics ?? [], memoryDiagnostic] };
|
|
18904
19380
|
this.runLogger.write({
|
|
@@ -18939,36 +19415,25 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
18939
19415
|
});
|
|
18940
19416
|
}
|
|
18941
19417
|
this.activeSession = undefined;
|
|
18942
|
-
this.resultCapture = undefined;
|
|
18943
19418
|
this.activeRetrievalOptions = undefined;
|
|
18944
19419
|
this.preliminaryCallback = undefined;
|
|
18945
|
-
if (this.interactiveFastAnswerCallback === emitPreliminary)
|
|
18946
|
-
this.interactiveFastAnswerCallback = undefined;
|
|
18947
19420
|
this.activeRun = false;
|
|
18948
19421
|
this.memoryContextCache = undefined;
|
|
18949
19422
|
}
|
|
18950
19423
|
}
|
|
18951
19424
|
async* searchDocumentsStream(query, options = {}) {
|
|
18952
19425
|
const queue = [];
|
|
18953
|
-
let progressBuffer = "";
|
|
18954
19426
|
let wake;
|
|
18955
19427
|
let settled = false;
|
|
18956
19428
|
const unsubscribe = this.subscribe((event) => {
|
|
18957
|
-
if (event.type !== "
|
|
19429
|
+
if (event.type !== "message_end" || event.message.role !== "assistant")
|
|
18958
19430
|
return;
|
|
18959
|
-
|
|
18960
|
-
if (text.trim().length === 0)
|
|
19431
|
+
if (event.message.stopReason !== "toolUse")
|
|
18961
19432
|
return;
|
|
18962
|
-
|
|
18963
|
-
if (
|
|
19433
|
+
const text = event.message.content.filter((block) => block.type === "text").map((block) => block.text).join("").trim();
|
|
19434
|
+
if (text === "")
|
|
18964
19435
|
return;
|
|
18965
|
-
queue.push({
|
|
18966
|
-
type: "progress",
|
|
18967
|
-
sessionId: this.lastSessionId ?? "",
|
|
18968
|
-
query: query.trim(),
|
|
18969
|
-
text: progressBuffer
|
|
18970
|
-
});
|
|
18971
|
-
progressBuffer = "";
|
|
19436
|
+
queue.push({ type: "progress", sessionId: this.lastSessionId ?? "", query: query.trim(), text });
|
|
18972
19437
|
wake?.();
|
|
18973
19438
|
wake = undefined;
|
|
18974
19439
|
});
|
|
@@ -18984,15 +19449,6 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
18984
19449
|
wake = undefined;
|
|
18985
19450
|
};
|
|
18986
19451
|
const run = this.searchDocuments(query, options).then((response) => {
|
|
18987
|
-
if (progressBuffer.trim() !== "") {
|
|
18988
|
-
queue.push({
|
|
18989
|
-
type: "progress",
|
|
18990
|
-
sessionId: this.lastSessionId ?? "",
|
|
18991
|
-
query: query.trim(),
|
|
18992
|
-
text: progressBuffer
|
|
18993
|
-
});
|
|
18994
|
-
progressBuffer = "";
|
|
18995
|
-
}
|
|
18996
19452
|
queue.push({ type: "complete", response });
|
|
18997
19453
|
}).catch((error) => {
|
|
18998
19454
|
settled = true;
|
|
@@ -19383,7 +19839,7 @@ ${result.content.replace(/\s+/gu, " ")}`).join(`
|
|
|
19383
19839
|
}
|
|
19384
19840
|
}
|
|
19385
19841
|
buildFastAnswerPrompt(query, options, baseline) {
|
|
19386
|
-
const limit = typeof options.topK === "number" ? `
|
|
19842
|
+
const limit = typeof options.topK === "number" ? ` Cite at most ${options.topK} sources.` : "";
|
|
19387
19843
|
const scope = options.scope ? ` Restrict search to virtual path scope ${options.scope}.` : "";
|
|
19388
19844
|
return `Answer this original query immediately: ${query}${limit}${scope}
|
|
19389
19845
|
|
|
@@ -19395,21 +19851,18 @@ ${baseline}
|
|
|
19395
19851
|
` + `Formatting and content rules for the answer:
|
|
19396
19852
|
` + `- Provide the core answer to the user's question in at most 5 bullet points. If additional explanation is necessary, append it after the bullet points.
|
|
19397
19853
|
` + `- Answer the question directly. Do not include specific file paths, datasource descriptions, or retrieval mechanics in the answer text.
|
|
19398
|
-
` + `- Cite evidence with bracketed numbers only (e.g. [1], [2]); do not quote raw chunks or mention source paths directly in the answer.
|
|
19399
19854
|
` + `- ${ANSWER_CITATION_RULE}
|
|
19400
19855
|
` + `- ${ANSWER_IMAGE_EMBED_RULE}
|
|
19401
19856
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack" or "checked Drive but found nothing").
|
|
19402
19857
|
` + `- When evidence conflicts, treat the freshest (most recent) information as the correct source of truth.
|
|
19403
19858
|
` + `- If information is incomplete or uncertain, acknowledge it briefly without lengthy explanations, stating that it is difficult to answer fully with the given information and searching continues. If there are partial clues or leads (even if not the exact answer), mention those clues concisely.
|
|
19404
19859
|
|
|
19405
|
-
` + `
|
|
19860
|
+
` + `Write the answer as your reply, then stop.`;
|
|
19406
19861
|
}
|
|
19407
19862
|
buildDirectAnswerPrompt(query) {
|
|
19408
19863
|
return `Answer this query directly from your own general knowledge: ${query}
|
|
19409
19864
|
|
|
19410
|
-
` + `It needs no search: it is general knowledge, simple reasoning, or conversation. Do NOT call any search, retrieval, web, or file-reading tools. ` + `Reply naturally and concisely; for small talk, just respond conversationally. Do not cite sources or mention retrieval
|
|
19411
|
-
|
|
19412
|
-
` + `Call emit_fast_answer exactly once with the answer and an empty results list, then stop.`;
|
|
19865
|
+
` + `It needs no search: it is general knowledge, simple reasoning, or conversation. Do NOT call any search, retrieval, web, or file-reading tools. ` + `Reply naturally and concisely; for small talk, just respond conversationally. Do not cite sources or mention retrieval.`;
|
|
19413
19866
|
}
|
|
19414
19867
|
discoveryHint(sentence) {
|
|
19415
19868
|
const names = this.tools.map((tool) => tool.name).filter((name) => name === JIKJI_FIND_TOOL_NAME || name === EVERYTHING_SEARCH_TOOL_NAME);
|
|
@@ -19423,22 +19876,20 @@ ${baseline}
|
|
|
19423
19876
|
return `When local evidence is missing, thin, or possibly outdated — or the question concerns current events, recent releases, prices, or other public facts — use ${WEB_SEARCH_TOOL_NAME}${fetch2} to confirm or correct claims and fill gaps; use URLs as result sources for web-derived evidence. `;
|
|
19424
19877
|
}
|
|
19425
19878
|
buildRefinementPrompt(query, options, fastAnswer, fastAnswerDelivered) {
|
|
19426
|
-
const limit = typeof options.topK === "number" ? `
|
|
19879
|
+
const limit = typeof options.topK === "number" ? ` Cite at most ${options.topK} sources.` : "";
|
|
19427
19880
|
const scope = options.scope ? ` Restrict search to virtual path scope ${options.scope}.` : "";
|
|
19428
19881
|
const firstAnswer = formatFirstAnswerContext(fastAnswer, fastAnswerDelivered);
|
|
19429
|
-
const answerRules = fastAnswerDelivered ? `Formatting and content rules for
|
|
19430
|
-
` + `- The user already has the first answer above.
|
|
19882
|
+
const answerRules = fastAnswerDelivered ? `Formatting and content rules for your final answer (DELTA ONLY):
|
|
19883
|
+
` + `- The user already has the first answer above. Your final answer MUST contain only the delta against it: (a) corrections to anything in the first answer that is wrong, unsupported, or outdated, and (b) newly verified findings that were not present in the first answer.
|
|
19431
19884
|
` + `- NEVER restate or re-list first-answer facts that remain correct, and never repeat its bullet list.
|
|
19432
19885
|
` + `- Mark each item clearly as a correction or as a new finding.
|
|
19433
19886
|
` + `- If verification changed nothing and found nothing new, say so in one short line (the first answer is confirmed as-is) instead of restating it.
|
|
19434
|
-
` + `-
|
|
19435
|
-
` + `- ${ANSWER_CITATION_RULE} A correction or new finding that relies on a first-answer unit must re-emit that evidence as a result of this call and cite its new number.
|
|
19887
|
+
` + `- ${ANSWER_CITATION_RULE} A correction or new finding that relies on evidence the first answer cited must cite that evidence's id again.
|
|
19436
19888
|
` + `- ${ANSWER_IMAGE_EMBED_RULE} ${ANSWER_IMAGE_DELTA_RULE}
|
|
19437
19889
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack").
|
|
19438
19890
|
` + `- When evidence conflicts, treat the freshest (most recent) information as the correct source of truth.` : `Formatting and content rules for the final answer (COMPLETE — no first answer reached the caller):
|
|
19439
19891
|
` + `- Provide the core answer to the user's question in at most 5 bullet points. If additional explanation is necessary, append it after the bullet points.
|
|
19440
19892
|
` + `- Answer the question directly. Do not include specific file paths, datasource descriptions, or retrieval mechanics in the answer text.
|
|
19441
|
-
` + `- Cite evidence with bracketed numbers only (e.g. [1], [2]); do not quote raw chunks or mention source paths directly in the answer.
|
|
19442
19893
|
` + `- ${ANSWER_CITATION_RULE}
|
|
19443
19894
|
` + `- ${ANSWER_IMAGE_EMBED_RULE}
|
|
19444
19895
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack").
|
|
@@ -19447,35 +19898,34 @@ ${baseline}
|
|
|
19447
19898
|
|
|
19448
19899
|
` + `${firstAnswer}
|
|
19449
19900
|
|
|
19450
|
-
` + `Now verify it rigorously. ${this.discoveryHint((tools) => `Actively use ${tools} when discovering or exploring local files and folders. `)}Check important claims against source files with bash when needed, correct anything wrong or unsupported, fill gaps with retrieval tools, and resolve conflicts and freshness. ${this.webFallbackHint()}
|
|
19901
|
+
` + `Now verify it rigorously. ${this.discoveryHint((tools) => `Actively use ${tools} when discovering or exploring local files and folders. `)}Check important claims against source files with bash when needed, correct anything wrong or unsupported, fill gaps with retrieval tools, and resolve conflicts and freshness. ${this.webFallbackHint()}
|
|
19451
19902
|
|
|
19452
19903
|
` + `${answerRules}
|
|
19453
19904
|
|
|
19454
|
-
` + `Do not use broad grep/find or recursive filesystem scans: only inspect a path or narrow neighborhood surfaced by retrieval, and only when evidence clearly points there. ` + `Avoid spinning repeated near-identical queries against the same datasource; once additional attempts stop surfacing new evidence, conclude from the evidence available. ` + `If more search is needed, first write a brief 1–2 line progress update stating the best current hypothesis and what you are checking next, then call retrieval tools. ` + `When finished,
|
|
19905
|
+
` + `Do not use broad grep/find or recursive filesystem scans: only inspect a path or narrow neighborhood surfaced by retrieval, and only when evidence clearly points there. ` + `Avoid spinning repeated near-identical queries against the same datasource; once additional attempts stop surfacing new evidence, conclude from the evidence available. ` + `If more search is needed, first write a brief 1–2 line progress update stating the best current hypothesis and what you are checking next, then call retrieval tools. ` + `When finished, reply with the final answer and no tool call: that last reply is what the user receives, so keep progress notes out of it.`;
|
|
19455
19906
|
}
|
|
19456
19907
|
buildSearchPrompt(query, options, initialRetrievalContext) {
|
|
19457
|
-
const limit = typeof options.topK === "number" ? `
|
|
19908
|
+
const limit = typeof options.topK === "number" ? ` Cite at most ${options.topK} sources.` : "";
|
|
19458
19909
|
const scope = options.scope ? ` Restrict search to virtual path scope ${options.scope}.` : "";
|
|
19459
19910
|
return `Find and curate information for this original query: ${query}${limit}${scope}
|
|
19460
19911
|
|
|
19461
|
-
` + `Start by deciding whether this is answerable from general knowledge or memory. If it is a generic, stable question, answer it immediately without retrieval
|
|
19912
|
+
` + `Start by deciding whether this is answerable from general knowledge or memory. If it is a generic, stable question, answer it immediately without retrieval. ` + `Otherwise, baseline MinSync and Jikji retrieval is already running in parallel; do not give the final answer until its next message arrives.
|
|
19462
19913
|
|
|
19463
19914
|
` + `Baseline retrieval context:
|
|
19464
19915
|
${initialRetrievalContext ?? "Pending; continue only with a brief progress statement."}
|
|
19465
19916
|
|
|
19466
|
-
` + `Treat candidates as unverified evidence, verify important claims against source files when needed, and use additional tools when needed. ` + `Judge relevance, conflicts, freshness, and sufficiency in this agent loop.
|
|
19917
|
+
` + `Treat candidates as unverified evidence, verify important claims against source files when needed, and use additional tools when needed. ` + `Judge relevance, conflicts, freshness, and sufficiency in this agent loop.
|
|
19467
19918
|
|
|
19468
19919
|
` + `Formatting and content rules for the answer:
|
|
19469
19920
|
` + `- Provide the core answer to the user's question in at most 5 bullet points. If additional explanation is necessary, append it after the bullet points.
|
|
19470
19921
|
` + `- Answer the question directly. Do not include specific file paths, datasource descriptions, or retrieval mechanics in the answer text.
|
|
19471
|
-
` + `- Cite evidence with bracketed numbers only (e.g. [1], [2]); do not quote raw chunks or mention source paths directly in the answer.
|
|
19472
19922
|
` + `- ${ANSWER_CITATION_RULE}
|
|
19473
19923
|
` + `- ${ANSWER_IMAGE_EMBED_RULE}
|
|
19474
19924
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack").
|
|
19475
19925
|
` + `- When evidence conflicts, treat the freshest (most recent) information as the correct source of truth.
|
|
19476
19926
|
` + `- If information is incomplete or uncertain, acknowledge it briefly without lengthy explanations. If there are partial clues or leads, mention them concisely.
|
|
19477
19927
|
|
|
19478
|
-
` + `${this.discoveryHint((tools) => `When exploring local files and folders, actively use ${tools} rather than exploratory bash commands. `)}If more search is needed, first write a brief 1–2 line progress update stating the best current hypothesis and what you are checking next, then call retrieval tools. ` + `Never repeat a generic status message. Do not use broad grep/find or recursive filesystem scans: only inspect a path or narrow neighborhood surfaced by retrieval, and only when evidence clearly points there. ` + `Avoid spinning repeated near-identical queries against the same datasource; once additional attempts stop surfacing new evidence, conclude from the evidence available. ` + `When finished,
|
|
19928
|
+
` + `${this.discoveryHint((tools) => `When exploring local files and folders, actively use ${tools} rather than exploratory bash commands. `)}If more search is needed, first write a brief 1–2 line progress update stating the best current hypothesis and what you are checking next, then call retrieval tools. ` + `Never repeat a generic status message. Do not use broad grep/find or recursive filesystem scans: only inspect a path or narrow neighborhood surfaced by retrieval, and only when evidence clearly points there. ` + `Avoid spinning repeated near-identical queries against the same datasource; once additional attempts stop surfacing new evidence, conclude from the evidence available. ` + `When finished, reply with the final answer and no tool call: that last reply is what the user receives, so keep progress notes out of it.`;
|
|
19479
19929
|
}
|
|
19480
19930
|
async refresh(force = false, opts) {
|
|
19481
19931
|
const methods = opts?.methods;
|
|
@@ -20107,57 +20557,21 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
20107
20557
|
function formatRerankedBaseline(results, evidenceIds) {
|
|
20108
20558
|
const lines = results.map((result, index) => `[${evidenceIds[index]}] ${result.source}
|
|
20109
20559
|
${result.content.replace(/\s+/gu, " ")}`);
|
|
20110
|
-
return `Reranked initial candidates (ordered by relevance to the query; cite evidence by its [eN] id
|
|
20560
|
+
return `Reranked initial candidates (ordered by relevance to the query; cite evidence by its [eN] id):
|
|
20111
20561
|
${lines.join(`
|
|
20112
20562
|
`)}`;
|
|
20113
20563
|
}
|
|
20114
|
-
function fastAnswerAsFinal(fastAnswer) {
|
|
20115
|
-
const refsByNumber = new Map(fastAnswer.evidenceRefs.map((entry) => [entry.number, entry.refs]));
|
|
20116
|
-
return {
|
|
20117
|
-
answer: fastAnswer.answer,
|
|
20118
|
-
results: fastAnswer.results.map((result) => ({
|
|
20119
|
-
number: result.number,
|
|
20120
|
-
title: result.title,
|
|
20121
|
-
summary: result.summary,
|
|
20122
|
-
evidence: result.evidence,
|
|
20123
|
-
confidence: result.confidence ?? 0.5
|
|
20124
|
-
})),
|
|
20125
|
-
mapping: fastAnswer.results.map((result) => {
|
|
20126
|
-
const refs = refsByNumber.get(result.number) ?? [];
|
|
20127
|
-
const primary = refs[0];
|
|
20128
|
-
return {
|
|
20129
|
-
number: result.number,
|
|
20130
|
-
source: primary?.source ?? "",
|
|
20131
|
-
method: primary?.method ?? EMIT_FAST_ANSWER_TOOL_NAME,
|
|
20132
|
-
content: primary?.content ?? (result.evidence.map((evidence) => evidence.excerpt).join(`
|
|
20133
|
-
`) || result.summary),
|
|
20134
|
-
evidenceRefs: refs
|
|
20135
|
-
};
|
|
20136
|
-
}),
|
|
20137
|
-
warnings: []
|
|
20138
|
-
};
|
|
20139
|
-
}
|
|
20140
20564
|
function formatFirstAnswerContext(fastAnswer, delivered) {
|
|
20141
20565
|
if (fastAnswer === undefined) {
|
|
20142
20566
|
return "(the fast phase produced no answer — write the complete answer)";
|
|
20143
20567
|
}
|
|
20144
|
-
const header = delivered ? "The user has ALREADY received this immediate first answer:" : "An internal first-pass draft was produced but was NOT shown to the caller; write the complete answer:";
|
|
20145
|
-
const units = fastAnswer.results.length === 0 ? "" : `
|
|
20146
|
-
|
|
20147
|
-
Numbered units of that first answer (its own numbering — NOT citation numbers for your final answer; cite only the results you emit):
|
|
20148
|
-
${fastAnswer.results.map((result) => `[${result.number}] ${result.title} — ${result.summary}`).join(`
|
|
20149
|
-
`)}`;
|
|
20150
|
-
const sources = fastAnswer.sources.length === 0 ? "" : `
|
|
20151
|
-
|
|
20152
|
-
Sources of that first answer:
|
|
20153
|
-
${fastAnswer.sources.map((entry) => `[${entry.number}] -> ${entry.source}`).join(`
|
|
20154
|
-
`)}`;
|
|
20568
|
+
const header = delivered ? "The user has ALREADY received this immediate first answer (its citations were renumbered for the user; the [eN] ids below are still valid for you):" : "An internal first-pass draft was produced but was NOT shown to the caller; write the complete answer:";
|
|
20155
20569
|
return `${header}
|
|
20156
|
-
${fastAnswer
|
|
20570
|
+
${fastAnswer}`;
|
|
20157
20571
|
}
|
|
20158
|
-
function
|
|
20572
|
+
function buildMissingFinalAnswer(query, reason, trace, modelError) {
|
|
20159
20573
|
const lines = [
|
|
20160
|
-
`The search run for "${query}" ended without
|
|
20574
|
+
`The search run for "${query}" ended without a final answer: the agent stopped before writing one, so no curated answer is available within the configured search range.`,
|
|
20161
20575
|
...modelError === undefined ? [] : [`The model request failed: ${modelError}`],
|
|
20162
20576
|
...reason === undefined ? modelError === undefined ? ["The agent did not record why it stopped."] : [] : [`The agent's last note before stopping: "${reason.length > 500 ? `${reason.slice(0, 500)}…` : reason}"`],
|
|
20163
20577
|
modelError === undefined ? "Next steps: broaden the configured searchPaths, connect additional datasources via the datasources configuration, or retry with a narrower or different query." : "Next steps: fix the model provider error above (rate limit, quota, credentials, or model id) and retry the same query.",
|
|
@@ -20178,8 +20592,17 @@ function lastModelRequestError(messages) {
|
|
|
20178
20592
|
}
|
|
20179
20593
|
return;
|
|
20180
20594
|
}
|
|
20181
|
-
function
|
|
20182
|
-
|
|
20595
|
+
function finalAnswerText(messages) {
|
|
20596
|
+
for (let index = messages.length - 1;index >= 0; index--) {
|
|
20597
|
+
const message = messages[index];
|
|
20598
|
+
if (message.role !== "assistant")
|
|
20599
|
+
continue;
|
|
20600
|
+
if (message.stopReason !== "stop")
|
|
20601
|
+
return;
|
|
20602
|
+
const text = message.content.filter((block) => block.type === "text").map((block) => block.text).join("").trim();
|
|
20603
|
+
return text === "" ? undefined : text;
|
|
20604
|
+
}
|
|
20605
|
+
return;
|
|
20183
20606
|
}
|
|
20184
20607
|
function lastAssistantText(messages) {
|
|
20185
20608
|
for (let index = messages.length - 1;index >= 0; index--) {
|
|
@@ -20341,13 +20764,12 @@ var init_agent = __esm(() => {
|
|
|
20341
20764
|
init_rerank();
|
|
20342
20765
|
init_scope();
|
|
20343
20766
|
init_model_auth();
|
|
20767
|
+
init_answer_citations();
|
|
20344
20768
|
init_datasource_skill();
|
|
20345
20769
|
init_dupey_tool();
|
|
20346
|
-
init_emit_results_tool();
|
|
20347
20770
|
init_everything_search_tool();
|
|
20348
20771
|
init_evidence_judgment();
|
|
20349
20772
|
init_evidence_ledger();
|
|
20350
|
-
init_fast_answer_tool();
|
|
20351
20773
|
init_fsearch_search_tool();
|
|
20352
20774
|
init_jev_extension();
|
|
20353
20775
|
init_jikji_find_tool();
|
|
@@ -20392,6 +20814,60 @@ var init_agent = __esm(() => {
|
|
|
20392
20814
|
};
|
|
20393
20815
|
});
|
|
20394
20816
|
|
|
20817
|
+
// src/agent/results.ts
|
|
20818
|
+
import { Type as Type17 } from "typebox";
|
|
20819
|
+
var evidenceRefSchema, answerSchema, warningsSchema, curatedResultFields, reportSchema;
|
|
20820
|
+
var init_results = __esm(() => {
|
|
20821
|
+
evidenceRefSchema = Type17.Object({
|
|
20822
|
+
method: Type17.String({ description: "Retrieval method namespace for this evidence chunk" }),
|
|
20823
|
+
source: Type17.String({ description: "Internal opaque source identifier for this evidence chunk" }),
|
|
20824
|
+
excerpt: Type17.Optional(Type17.String({ description: "Evidence excerpt used for stable ID normalization" })),
|
|
20825
|
+
content: Type17.Optional(Type17.String({ description: "Evidence content used for stable ID normalization" })),
|
|
20826
|
+
retrievalResultId: Type17.Optional(Type17.String({ description: "Backend retrieval ID when path-opaque and stable" })),
|
|
20827
|
+
chunkIndex: Type17.Optional(Type17.Integer({ description: "Chunk index, if available" })),
|
|
20828
|
+
lineNumber: Type17.Optional(Type17.Integer({ description: "Line number, if available" })),
|
|
20829
|
+
stableEvidenceId: Type17.Optional(Type17.String({ description: "Stable evidence ID, if already normalized" })),
|
|
20830
|
+
retrieverMix: Type17.Optional(Type17.Array(Type17.String({ maxLength: 64 }), {
|
|
20831
|
+
description: "Retrievers that contributed to this result",
|
|
20832
|
+
maxItems: 8
|
|
20833
|
+
})),
|
|
20834
|
+
parserType: Type17.Optional(Type17.String({ description: "Parser that produced this evidence", maxLength: 120 })),
|
|
20835
|
+
documentType: Type17.Optional(Type17.String({ description: "Document type, if known", maxLength: 120 })),
|
|
20836
|
+
documentArea: Type17.Optional(Type17.String({ description: "Document collection area, if known", maxLength: 120 })),
|
|
20837
|
+
evidenceType: Type17.Optional(Type17.String({ description: "Evidence type, if known", maxLength: 120 })),
|
|
20838
|
+
evidenceLocation: Type17.Optional(Type17.String({ description: "Human-readable evidence location", maxLength: 120 })),
|
|
20839
|
+
confidence: Type17.Optional(Type17.Number({ description: "Evidence confidence, 0..1", minimum: 0, maximum: 1 }))
|
|
20840
|
+
});
|
|
20841
|
+
answerSchema = Type17.String({
|
|
20842
|
+
description: `Answer for the caller. At most 5 bullet points (plus optional explanation); reference results by bracketed number (e.g. [1], [2]) without file paths or raw chunk text, except the image-embed exception below. ${ANSWER_CITATION_RULE} ${ANSWER_IMAGE_EMBED_RULE}`
|
|
20843
|
+
});
|
|
20844
|
+
warningsSchema = Type17.Optional(Type17.Array(Type17.String(), { description: "Optional warnings about this result set" }));
|
|
20845
|
+
curatedResultFields = {
|
|
20846
|
+
number: Type17.Integer({ description: "1-based result number" }),
|
|
20847
|
+
title: Type17.String({ description: "Short name of the curated knowledge unit" }),
|
|
20848
|
+
summary: Type17.String({ description: "Key insight: purpose, details, and line range" }),
|
|
20849
|
+
evidence: Type17.Array(Type17.Object({
|
|
20850
|
+
excerpt: Type17.String({ description: "Supporting excerpt" }),
|
|
20851
|
+
lineNumber: Type17.Optional(Type17.Integer({ description: "Line number of the excerpt, if known" }))
|
|
20852
|
+
})),
|
|
20853
|
+
confidence: Type17.Number({ description: "Confidence in this result, 0..1", minimum: 0, maximum: 1 })
|
|
20854
|
+
};
|
|
20855
|
+
reportSchema = Type17.Object({
|
|
20856
|
+
answer: answerSchema,
|
|
20857
|
+
results: Type17.Array(Type17.Object(curatedResultFields), { description: "Numbered curated knowledge units." }),
|
|
20858
|
+
mapping: Type17.Array(Type17.Object({
|
|
20859
|
+
number: Type17.Integer({ description: "Matches the result number this entry maps" }),
|
|
20860
|
+
source: Type17.String({ description: "Source identifier — a real file path or a datasource id" }),
|
|
20861
|
+
method: Type17.String({ description: "Retrieval method or tool that produced the source" }),
|
|
20862
|
+
content: Type17.String({ description: "Raw content snippet of the evidence behind this result" }),
|
|
20863
|
+
evidenceRefs: Type17.Optional(Type17.Array(evidenceRefSchema, {
|
|
20864
|
+
description: "Hidden evidence chunk references supporting this curated result"
|
|
20865
|
+
}))
|
|
20866
|
+
}), { description: "Internal number -> source/method mapping. One entry per result number." }),
|
|
20867
|
+
warnings: warningsSchema
|
|
20868
|
+
});
|
|
20869
|
+
});
|
|
20870
|
+
|
|
20395
20871
|
// src/datasource/aliased-skill.ts
|
|
20396
20872
|
class AliasedDatasourceSkill {
|
|
20397
20873
|
skill;
|
|
@@ -20789,7 +21265,7 @@ function datasourceCliError(datasourceId, command, failure) {
|
|
|
20789
21265
|
return new DatasourceCliError(datasourceId, command, failure);
|
|
20790
21266
|
}
|
|
20791
21267
|
var DatasourceCliError;
|
|
20792
|
-
var
|
|
21268
|
+
var init_errors4 = __esm(() => {
|
|
20793
21269
|
DatasourceCliError = class DatasourceCliError extends Error {
|
|
20794
21270
|
datasourceId;
|
|
20795
21271
|
command;
|
|
@@ -20881,7 +21357,7 @@ function toResult(hit, source, mode, instanceId) {
|
|
|
20881
21357
|
};
|
|
20882
21358
|
}
|
|
20883
21359
|
var init_methods = __esm(() => {
|
|
20884
|
-
|
|
21360
|
+
init_errors4();
|
|
20885
21361
|
init_scope2();
|
|
20886
21362
|
});
|
|
20887
21363
|
|
|
@@ -21475,7 +21951,7 @@ var init_rclone_connector = __esm(() => {
|
|
|
21475
21951
|
});
|
|
21476
21952
|
|
|
21477
21953
|
// src/datasource/connector.ts
|
|
21478
|
-
import { createHash as
|
|
21954
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
21479
21955
|
function connectorFailureToDiagnosticCode(reason) {
|
|
21480
21956
|
switch (reason) {
|
|
21481
21957
|
case "auth":
|
|
@@ -21509,7 +21985,7 @@ function sanitizeIdSegment(value) {
|
|
|
21509
21985
|
const cleaned = normalized.slice(start, end);
|
|
21510
21986
|
if (cleaned === value && cleaned.length > 0 && cleaned.length <= 80)
|
|
21511
21987
|
return cleaned;
|
|
21512
|
-
const hash =
|
|
21988
|
+
const hash = createHash12("sha256").update(value).digest("hex").slice(0, 8);
|
|
21513
21989
|
const stem = cleaned.slice(0, 60);
|
|
21514
21990
|
return stem.length > 0 ? `${stem}-${hash}` : hash;
|
|
21515
21991
|
}
|
|
@@ -22708,7 +23184,7 @@ function toRetrievalResult(hit, source, methodName, instanceId, mode, diagnostic
|
|
|
22708
23184
|
}
|
|
22709
23185
|
var DISCORD_DATASOURCE_ID = "discord", DEFAULT_DISCORD_TAGS, DEFAULT_TOP_K2 = 20;
|
|
22710
23186
|
var init_methods2 = __esm(() => {
|
|
22711
|
-
|
|
23187
|
+
init_errors4();
|
|
22712
23188
|
init_scope2();
|
|
22713
23189
|
init_paths3();
|
|
22714
23190
|
DEFAULT_DISCORD_TAGS = ["discord", "chat", "pii"];
|
|
@@ -23006,7 +23482,7 @@ class GitHubConnector {
|
|
|
23006
23482
|
if (repos.length === 0)
|
|
23007
23483
|
return { ok: false, reason: "not-configured", message: "no repositories configured" };
|
|
23008
23484
|
const token = resolveToken(this.options.token, this.options.tokenEnv ?? DEFAULT_TOKEN_ENV);
|
|
23009
|
-
const baseUrl = this.options.baseUrl ??
|
|
23485
|
+
const baseUrl = this.options.baseUrl ?? DEFAULT_BASE_URL4;
|
|
23010
23486
|
const request = {
|
|
23011
23487
|
headers: {
|
|
23012
23488
|
Accept: "application/vnd.github+json",
|
|
@@ -23079,7 +23555,7 @@ ${body}` : title,
|
|
|
23079
23555
|
return { ok: true, documents, ...warnings.length > 0 ? { warnings } : {} };
|
|
23080
23556
|
}
|
|
23081
23557
|
}
|
|
23082
|
-
var
|
|
23558
|
+
var DEFAULT_BASE_URL4 = "https://api.github.com", DEFAULT_TOKEN_ENV = "GITHUB_TOKEN", DEFAULT_MAX_PAGES = 10, DEFAULT_MAX_DOCUMENTS2 = 500;
|
|
23083
23559
|
var init_connector2 = () => {};
|
|
23084
23560
|
|
|
23085
23561
|
// src/datasource/skills/github/skill.ts
|
|
@@ -23146,7 +23622,7 @@ class GitHubGistConnector {
|
|
|
23146
23622
|
message: "no GitHub token: set GITHUB_TOKEN (or connector.tokenEnv) or authenticate the gh CLI"
|
|
23147
23623
|
};
|
|
23148
23624
|
}
|
|
23149
|
-
const baseUrl = this.options.baseUrl ??
|
|
23625
|
+
const baseUrl = this.options.baseUrl ?? DEFAULT_BASE_URL5;
|
|
23150
23626
|
const request = {
|
|
23151
23627
|
headers: {
|
|
23152
23628
|
Accept: "application/vnd.github+json",
|
|
@@ -23295,15 +23771,15 @@ ${content}`);
|
|
|
23295
23771
|
}
|
|
23296
23772
|
};
|
|
23297
23773
|
}
|
|
23298
|
-
var
|
|
23774
|
+
var DEFAULT_BASE_URL5 = "https://api.github.com", DEFAULT_TOKEN_ENV2 = "GITHUB_TOKEN", DEFAULT_MAX_PAGES2 = 10, DEFAULT_MAX_GISTS = 500, GH_TOKEN_TIMEOUT_MS = 5000, STATE_VERSION = 1;
|
|
23299
23775
|
var init_connector3 = () => {};
|
|
23300
23776
|
|
|
23301
23777
|
// src/datasource/skills/github-gist/semantic.ts
|
|
23302
|
-
import { createHash as
|
|
23778
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
23303
23779
|
import { existsSync as existsSync26, mkdirSync as mkdirSync22, readFileSync as readFileSync23, writeFileSync as writeFileSync21 } from "node:fs";
|
|
23304
23780
|
import { dirname as dirname21 } from "node:path";
|
|
23305
23781
|
function contentHash(chunk) {
|
|
23306
|
-
return
|
|
23782
|
+
return createHash13("sha256").update(`${chunk.title ?? ""}
|
|
23307
23783
|
${chunk.content}`).digest("hex");
|
|
23308
23784
|
}
|
|
23309
23785
|
function sameIdentity(a, b) {
|
|
@@ -24233,7 +24709,7 @@ function isRemoteEmbedder(value) {
|
|
|
24233
24709
|
}
|
|
24234
24710
|
var CHAT_TAG = "lark:chat", DOCS_TAG = "lark:docs", DEFAULT_TAGS2, REMOTE_NOTE = "remote-search datasource: no local mirror";
|
|
24235
24711
|
var init_skill6 = __esm(() => {
|
|
24236
|
-
|
|
24712
|
+
init_errors4();
|
|
24237
24713
|
init_scope2();
|
|
24238
24714
|
init_client7();
|
|
24239
24715
|
DEFAULT_TAGS2 = [CHAT_TAG, DOCS_TAG];
|
|
@@ -24761,7 +25237,7 @@ function toRetrievalResult2(hit, source, methodName, instanceId, mode) {
|
|
|
24761
25237
|
}
|
|
24762
25238
|
var KAKAO_DATASOURCE_ID = "kakao", DEFAULT_KAKAO_TAGS, DEFAULT_TOP_K4 = 20;
|
|
24763
25239
|
var init_methods3 = __esm(() => {
|
|
24764
|
-
|
|
25240
|
+
init_errors4();
|
|
24765
25241
|
init_paths4();
|
|
24766
25242
|
DEFAULT_KAKAO_TAGS = ["kakaotalk", "personal", "pii"];
|
|
24767
25243
|
});
|
|
@@ -25115,7 +25591,7 @@ function ensurePrivateMailcrawlDataDir(path) {
|
|
|
25115
25591
|
if (process.platform !== "win32")
|
|
25116
25592
|
chmodSync(path, 448);
|
|
25117
25593
|
}
|
|
25118
|
-
var
|
|
25594
|
+
var init_config2 = () => {};
|
|
25119
25595
|
|
|
25120
25596
|
// src/datasource/skills/mailcrawl/client.ts
|
|
25121
25597
|
import { spawn as spawn15 } from "node:child_process";
|
|
@@ -25441,7 +25917,7 @@ function truncateUtf8(value, maxBytes) {
|
|
|
25441
25917
|
var DEFAULT_BINARY4 = "mailcrawl", DEFAULT_SEARCH_TIMEOUT_MS3 = 60000, DEFAULT_INDEX_TIMEOUT_MS3 = 1800000, DEFAULT_MAX_BUFFER_BYTES4 = 1048576, LOOPBACK_HOSTS2, SAFE_ENV_KEYS2, SAFE_MAILCRAWL_ENV_KEYS, REMOTE_EMBEDDING_ENV_KEYS;
|
|
25442
25918
|
var init_client9 = __esm(() => {
|
|
25443
25919
|
init_portable_spawn();
|
|
25444
|
-
|
|
25920
|
+
init_config2();
|
|
25445
25921
|
LOOPBACK_HOSTS2 = new Set(["127.0.0.1", "localhost", "[::1]", "::1"]);
|
|
25446
25922
|
SAFE_ENV_KEYS2 = new Set(["HOME", "LANG", "LC_ALL", "PATH", "TMPDIR", "TMP", "TEMP", "NO_COLOR"]);
|
|
25447
25923
|
SAFE_MAILCRAWL_ENV_KEYS = new Set([
|
|
@@ -25540,7 +26016,7 @@ class MailcrawlMethod {
|
|
|
25540
26016
|
}
|
|
25541
26017
|
var modes, MAILCRAWL_MODES;
|
|
25542
26018
|
var init_methods4 = __esm(() => {
|
|
25543
|
-
|
|
26019
|
+
init_errors4();
|
|
25544
26020
|
init_scope2();
|
|
25545
26021
|
modes = ["bm25", "semantic", "hybrid"];
|
|
25546
26022
|
MAILCRAWL_MODES = modes;
|
|
@@ -25688,7 +26164,7 @@ var TAGS;
|
|
|
25688
26164
|
var init_skill9 = __esm(() => {
|
|
25689
26165
|
init_scope2();
|
|
25690
26166
|
init_client9();
|
|
25691
|
-
|
|
26167
|
+
init_config2();
|
|
25692
26168
|
init_methods4();
|
|
25693
26169
|
TAGS = ["mailcrawl", "email", "pii"];
|
|
25694
26170
|
});
|
|
@@ -25908,7 +26384,7 @@ function failureCode2(reason) {
|
|
|
25908
26384
|
}
|
|
25909
26385
|
var DEFAULT_INSTANCE_ID5 = "default", DEFAULT_POLLING_INTERVAL_MS4;
|
|
25910
26386
|
var init_crawler_skill = __esm(() => {
|
|
25911
|
-
|
|
26387
|
+
init_errors4();
|
|
25912
26388
|
init_scope2();
|
|
25913
26389
|
DEFAULT_POLLING_INTERVAL_MS4 = 15 * 60 * 1000;
|
|
25914
26390
|
});
|
|
@@ -26094,7 +26570,7 @@ var DEFAULT_QMD_BINARY = "qmd", DEFAULT_QMD_TIMEOUT_MS = 60000, DEFAULT_QMD_MAX_
|
|
|
26094
26570
|
// src/datasource/skills/obsidian/client.ts
|
|
26095
26571
|
import { spawn as spawn16 } from "node:child_process";
|
|
26096
26572
|
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync22 } from "node:fs";
|
|
26097
|
-
import { isAbsolute as
|
|
26573
|
+
import { isAbsolute as isAbsolute8, resolve as resolve14 } from "node:path";
|
|
26098
26574
|
|
|
26099
26575
|
class QmdClient {
|
|
26100
26576
|
options;
|
|
@@ -26190,7 +26666,7 @@ function resolveVaultPath(vaultPath) {
|
|
|
26190
26666
|
if (vaultPath === undefined || vaultPath.trim().length === 0)
|
|
26191
26667
|
return;
|
|
26192
26668
|
const trimmed = vaultPath.trim();
|
|
26193
|
-
return
|
|
26669
|
+
return isAbsolute8(trimmed) ? trimmed : resolve14(trimmed);
|
|
26194
26670
|
}
|
|
26195
26671
|
function controlledEnv5(options) {
|
|
26196
26672
|
const instanceId = options.instanceId ?? "default";
|
|
@@ -26546,7 +27022,7 @@ function toRetrievalResult3(hit, source, methodName, instanceId, mode) {
|
|
|
26546
27022
|
}
|
|
26547
27023
|
var OBSIDIAN_DATASOURCE_ID = "obsidian", DEFAULT_OBSIDIAN_TAGS, DEFAULT_TOP_K5 = 20;
|
|
26548
27024
|
var init_methods5 = __esm(() => {
|
|
26549
|
-
|
|
27025
|
+
init_errors4();
|
|
26550
27026
|
init_scope2();
|
|
26551
27027
|
DEFAULT_OBSIDIAN_TAGS = ["obsidian", "notes"];
|
|
26552
27028
|
});
|
|
@@ -27084,7 +27560,7 @@ var init_slack = __esm(() => {
|
|
|
27084
27560
|
|
|
27085
27561
|
// src/datasource/skills/spotlight/connector.ts
|
|
27086
27562
|
import { spawn as spawn17 } from "node:child_process";
|
|
27087
|
-
import { createHash as
|
|
27563
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
27088
27564
|
import { readFile as fsReadFile, stat as stat7 } from "node:fs/promises";
|
|
27089
27565
|
import { basename as basename13, extname as extname8 } from "node:path";
|
|
27090
27566
|
|
|
@@ -27169,7 +27645,7 @@ class SpotlightConnector {
|
|
|
27169
27645
|
if (content.length === 0)
|
|
27170
27646
|
continue;
|
|
27171
27647
|
documents.push({
|
|
27172
|
-
docId:
|
|
27648
|
+
docId: createHash14("sha256").update(path).digest("hex").slice(0, 16),
|
|
27173
27649
|
hierarchy: ["files"],
|
|
27174
27650
|
title: basename13(path),
|
|
27175
27651
|
content,
|
|
@@ -27764,7 +28240,7 @@ var init_factory = __esm(() => {
|
|
|
27764
28240
|
// src/cli/config.ts
|
|
27765
28241
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
27766
28242
|
import { existsSync as existsSync28, mkdirSync as mkdirSync25, readFileSync as readFileSync24, renameSync as renameSync11, unlinkSync as unlinkSync5, writeFileSync as writeFileSync23 } from "node:fs";
|
|
27767
|
-
import { basename as basename14, dirname as dirname23, isAbsolute as
|
|
28243
|
+
import { basename as basename14, dirname as dirname23, isAbsolute as isAbsolute9, join as join36, resolve as resolve15 } from "node:path";
|
|
27768
28244
|
import { findEnvKeys, getEnvApiKey } from "@earendil-works/pi-ai/compat";
|
|
27769
28245
|
import { getAgentDir as getAgentDir3, ModelRuntime as ModelRuntime2, SettingsManager as SettingsManager2 } from "@earendil-works/pi-coding-agent";
|
|
27770
28246
|
function resolveConfigPath(input) {
|
|
@@ -27892,7 +28368,7 @@ function resolveSearchPaths(searchPaths, origin) {
|
|
|
27892
28368
|
return searchPaths.map((searchPath) => resolvePersistedPath(searchPath, origin));
|
|
27893
28369
|
}
|
|
27894
28370
|
function resolvePersistedPath(path, origin) {
|
|
27895
|
-
return
|
|
28371
|
+
return isAbsolute9(path) ? path : resolve15(origin, path);
|
|
27896
28372
|
}
|
|
27897
28373
|
function normalizeLegacyConfigPaths(partial, origin) {
|
|
27898
28374
|
const workspacePath = resolvePersistedPath(partial.workspacePath ?? ".", origin);
|
|
@@ -28732,11 +29208,15 @@ function getModelRuntime(agentDir) {
|
|
|
28732
29208
|
const cached = modelRuntimeCache.get(agentDir);
|
|
28733
29209
|
if (cached !== undefined)
|
|
28734
29210
|
return cached;
|
|
28735
|
-
const created =
|
|
28736
|
-
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
|
|
29211
|
+
const created = (async () => {
|
|
29212
|
+
const runtime = await ModelRuntime2.create({
|
|
29213
|
+
authPath: join36(agentDir, "auth.json"),
|
|
29214
|
+
modelsPath: join36(agentDir, "models.json"),
|
|
29215
|
+
allowModelNetwork: false
|
|
29216
|
+
});
|
|
29217
|
+
await registerAutoRAGProvider(runtime);
|
|
29218
|
+
return runtime;
|
|
29219
|
+
})();
|
|
28740
29220
|
modelRuntimeCache.set(agentDir, created);
|
|
28741
29221
|
created.catch(() => {
|
|
28742
29222
|
modelRuntimeCache.delete(agentDir);
|
|
@@ -29065,8 +29545,9 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
29065
29545
|
}
|
|
29066
29546
|
}
|
|
29067
29547
|
var DEFAULT_CONFIG_FILENAME = "config.json", LEGACY_CONFIG_FILENAME = "autorag.config.json", CONFIG_LOCK_RETRY_MS = 10, CONFIG_LOCK_TIMEOUT_MS = 1e4, CONFIG_LOCK_STALE_MS = 30000, ConfigError, MINSYNC_REQUIRED_MESSAGE = "MinSync is required and cannot be disabled; remove `minSync: false` / `minSync.enabled: false` from the config.", AGENT_MODEL_APIS, AGENT_MODEL_INPUTS, API_KEY_ENV_PATTERN2, POSITIVE_INT_FIELDS, EMBEDDER_ALLOWLIST, MINSYNC_ALLOWLIST, MINSYNC_LEGACY_IGNORED, P2P_ALLOWLIST, P2P_QUOTA_ALLOWLIST, LIMITS_ALLOWLIST, LIMITS_PREFETCH_ALLOWLIST, JEV_CONFIG_FIELDS, JEV_BACKEND_NAMES, DEFAULT_JEV_BACKEND = "openrouter", DEFAULT_QUERY_DECOMPOSITION_MODEL, RERANK_ALLOWLIST, UNKNOWN_MODEL_HINT = "Add baseUrl (and optional api/apiKeyEnv) for an OpenAI-compatible endpoint outside the pi-ai catalog, or use a pi-ai catalog model id.", modelRuntimeCache;
|
|
29068
|
-
var
|
|
29548
|
+
var init_config3 = __esm(() => {
|
|
29069
29549
|
init_local_model();
|
|
29550
|
+
init_provider();
|
|
29070
29551
|
init_home();
|
|
29071
29552
|
init_factory();
|
|
29072
29553
|
init_file_lock();
|
|
@@ -29161,7 +29642,6 @@ class AutoRAGLite {
|
|
|
29161
29642
|
agent;
|
|
29162
29643
|
retrievalEngine;
|
|
29163
29644
|
memory;
|
|
29164
|
-
sessions = new Map;
|
|
29165
29645
|
constructor(config) {
|
|
29166
29646
|
this.config = config;
|
|
29167
29647
|
const agentOptions = buildAgentOptions(config);
|
|
@@ -29216,14 +29696,11 @@ class AutoRAGLite {
|
|
|
29216
29696
|
return this.retrievalEngine.retrieveByMethod(query, options);
|
|
29217
29697
|
}
|
|
29218
29698
|
recordStructuredResultsSession(sessionId, query, details) {
|
|
29219
|
-
return recordStructuredResultsSession(sessionId, query, details, this.
|
|
29699
|
+
return recordStructuredResultsSession(sessionId, query, details, this.memory);
|
|
29220
29700
|
}
|
|
29221
29701
|
recordReport(query, details) {
|
|
29222
29702
|
return this.recordStructuredResultsSession(randomUUID10(), query, details);
|
|
29223
29703
|
}
|
|
29224
|
-
getResultRegistry(sessionId) {
|
|
29225
|
-
return this.sessions.get(sessionId)?.registry ?? new Map;
|
|
29226
|
-
}
|
|
29227
29704
|
getMemorySchema() {
|
|
29228
29705
|
return structuredClone(this.memory.getSchema());
|
|
29229
29706
|
}
|
|
@@ -29241,9 +29718,9 @@ function createAutoRAGLite(options = {}) {
|
|
|
29241
29718
|
var init_core = __esm(() => {
|
|
29242
29719
|
init_agent();
|
|
29243
29720
|
init_search_documents();
|
|
29244
|
-
|
|
29721
|
+
init_config3();
|
|
29245
29722
|
init_memory();
|
|
29246
|
-
|
|
29723
|
+
init_config3();
|
|
29247
29724
|
});
|
|
29248
29725
|
|
|
29249
29726
|
// src/cli/output.ts
|
|
@@ -29417,7 +29894,8 @@ function searchEnvelope(resp, debug) {
|
|
|
29417
29894
|
if (r.source !== undefined)
|
|
29418
29895
|
base.source = r.source;
|
|
29419
29896
|
if (debug) {
|
|
29420
|
-
|
|
29897
|
+
if (r.confidence !== undefined)
|
|
29898
|
+
base.confidence = r.confidence;
|
|
29421
29899
|
base.evidence = r.evidence.map((e) => {
|
|
29422
29900
|
const ev = { excerpt: e.excerpt };
|
|
29423
29901
|
if (e.lineNumber !== undefined)
|
|
@@ -29454,7 +29932,8 @@ function renderSearchHuman(resp, debug) {
|
|
|
29454
29932
|
if (r.summary)
|
|
29455
29933
|
lines.push(` ${r.summary}`);
|
|
29456
29934
|
if (debug) {
|
|
29457
|
-
|
|
29935
|
+
if (r.confidence !== undefined)
|
|
29936
|
+
lines.push(` confidence: ${r.confidence}`);
|
|
29458
29937
|
for (const ev of r.evidence) {
|
|
29459
29938
|
const ln = ev.lineNumber !== undefined ? ` (line ${ev.lineNumber})` : "";
|
|
29460
29939
|
lines.push(` evidence${ln}: ${ev.excerpt}`);
|
|
@@ -29686,7 +30165,7 @@ async function runEvidence(ctx) {
|
|
|
29686
30165
|
}
|
|
29687
30166
|
var init_evidence = __esm(() => {
|
|
29688
30167
|
init_memory();
|
|
29689
|
-
|
|
30168
|
+
init_config3();
|
|
29690
30169
|
});
|
|
29691
30170
|
|
|
29692
30171
|
// src/cli/commands/report.ts
|
|
@@ -29784,9 +30263,9 @@ async function runReport(ctx) {
|
|
|
29784
30263
|
}
|
|
29785
30264
|
var MAX_REPORTED_SCHEMA_ERRORS = 8;
|
|
29786
30265
|
var init_report = __esm(() => {
|
|
29787
|
-
|
|
30266
|
+
init_results();
|
|
29788
30267
|
init_core();
|
|
29789
|
-
|
|
30268
|
+
init_config3();
|
|
29790
30269
|
});
|
|
29791
30270
|
|
|
29792
30271
|
// src/mirror/index.ts
|
|
@@ -29803,10 +30282,10 @@ init_agent();
|
|
|
29803
30282
|
init_agent();
|
|
29804
30283
|
init_datasource_skill();
|
|
29805
30284
|
init_dupey_tool();
|
|
29806
|
-
init_emit_results_tool();
|
|
29807
30285
|
init_jev_extension();
|
|
29808
30286
|
init_jikji_find_tool();
|
|
29809
30287
|
init_query_peer_tool();
|
|
30288
|
+
init_results();
|
|
29810
30289
|
init_search_all_tool();
|
|
29811
30290
|
init_search_minsync_tool();
|
|
29812
30291
|
init_search_single_datasource_tool();
|
|
@@ -29814,6 +30293,20 @@ init_system_prompt();
|
|
|
29814
30293
|
|
|
29815
30294
|
// src/index.ts
|
|
29816
30295
|
init_system_prompt();
|
|
30296
|
+
|
|
30297
|
+
// src/cloud/index.ts
|
|
30298
|
+
init_authorize();
|
|
30299
|
+
init_callback();
|
|
30300
|
+
init_callback_server();
|
|
30301
|
+
init_config();
|
|
30302
|
+
init_errors3();
|
|
30303
|
+
init_models();
|
|
30304
|
+
init_oauth_login();
|
|
30305
|
+
init_pkce();
|
|
30306
|
+
init_provider();
|
|
30307
|
+
init_token();
|
|
30308
|
+
|
|
30309
|
+
// src/index.ts
|
|
29817
30310
|
init_core();
|
|
29818
30311
|
|
|
29819
30312
|
// src/datasource/index.ts
|
|
@@ -30020,7 +30513,7 @@ import { z as z2 } from "zod";
|
|
|
30020
30513
|
// src/filesystem/name-search.ts
|
|
30021
30514
|
import { realpathSync as realpathSync6 } from "node:fs";
|
|
30022
30515
|
import { lstat, readdir as readdir4 } from "node:fs/promises";
|
|
30023
|
-
import { basename as basename15, dirname as dirname24, isAbsolute as
|
|
30516
|
+
import { basename as basename15, dirname as dirname24, isAbsolute as isAbsolute10, join as join37, relative as relative6, resolve as resolve16, sep as sep7 } from "node:path";
|
|
30024
30517
|
var SKIP_DIR_NAMES2 = {
|
|
30025
30518
|
".git": true,
|
|
30026
30519
|
".autorag": true,
|
|
@@ -30167,7 +30660,7 @@ async function pinConfiguredRoots(roots, diagnostics) {
|
|
|
30167
30660
|
return outermost;
|
|
30168
30661
|
}
|
|
30169
30662
|
async function resolveRequestRoots(requestRoot, pinnedRoots) {
|
|
30170
|
-
const candidates =
|
|
30663
|
+
const candidates = isAbsolute10(requestRoot) ? [requestRoot] : pinnedRoots.map((root) => resolve16(root, requestRoot));
|
|
30171
30664
|
const allowed = [];
|
|
30172
30665
|
for (const candidate of candidates) {
|
|
30173
30666
|
let real;
|
|
@@ -30720,20 +31213,33 @@ init_minsync();
|
|
|
30720
31213
|
init_mirror();
|
|
30721
31214
|
init_parser();
|
|
30722
31215
|
export {
|
|
31216
|
+
API_KEY_CONFIG_VALUE,
|
|
31217
|
+
API_PATH,
|
|
31218
|
+
AUTHORIZE_PATH,
|
|
31219
|
+
AUTORAG_API_KEY_ENV,
|
|
31220
|
+
AUTORAG_BASE_URL_ENV,
|
|
30723
31221
|
AliasedDatasourceSkill,
|
|
30724
31222
|
AutoRAGAgent,
|
|
30725
31223
|
AutoRAGLite,
|
|
31224
|
+
AutoragError,
|
|
31225
|
+
AutoragHttpError,
|
|
31226
|
+
AutoragOAuthError,
|
|
30726
31227
|
BUILTIN_DATASOURCE_SKILL_NAMES,
|
|
30727
31228
|
BUILTIN_OCR_LANGUAGES,
|
|
31229
|
+
CALLBACK_PATH,
|
|
30728
31230
|
CLOUD_DRIVE_SKILL_DEFINITION,
|
|
30729
31231
|
CloudDriveSkill,
|
|
30730
31232
|
ConnectorDatasourceSkill,
|
|
30731
31233
|
ConnectorLexicalMethod,
|
|
30732
31234
|
DATASOURCE_CHUNKS_SEGMENT,
|
|
31235
|
+
DEFAULT_BASE_URL,
|
|
31236
|
+
DEFAULT_CONTEXT_WINDOW,
|
|
30733
31237
|
DEFAULT_DISCRAWL_EMBEDDING_MODEL,
|
|
30734
31238
|
DEFAULT_DISCRAWL_MODE,
|
|
30735
31239
|
DEFAULT_JIKJI_OPTIONS,
|
|
31240
|
+
DEFAULT_LOGIN_TIMEOUT_MS,
|
|
30736
31241
|
DEFAULT_MAX_SOURCE_BYTES,
|
|
31242
|
+
DEFAULT_MAX_TOKENS,
|
|
30737
31243
|
DEFAULT_MINSYNC_EMBEDDER_CONFIG,
|
|
30738
31244
|
DEFAULT_MINSYNC_EMBEDDER_DIMENSION,
|
|
30739
31245
|
DEFAULT_MINSYNC_EMBEDDER_ID,
|
|
@@ -30749,7 +31255,6 @@ export {
|
|
|
30749
31255
|
DiscrawlSemanticMethod,
|
|
30750
31256
|
DiscrawlSkill,
|
|
30751
31257
|
DupeyCliError,
|
|
30752
|
-
EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
30753
31258
|
ENGLISH_ONLY_EMBEDDING_MODELS,
|
|
30754
31259
|
EVIDENCE_SUPPORT_THRESHOLD,
|
|
30755
31260
|
EmlParser,
|
|
@@ -30777,6 +31282,7 @@ export {
|
|
|
30777
31282
|
MINSYNC_SUBDIR,
|
|
30778
31283
|
MINSYNC_SURFACE,
|
|
30779
31284
|
MINSYNC_VERSION,
|
|
31285
|
+
MODELS_PATH,
|
|
30780
31286
|
MailExportConnector,
|
|
30781
31287
|
MailExportSkill,
|
|
30782
31288
|
MailcrawlClient,
|
|
@@ -30790,10 +31296,13 @@ export {
|
|
|
30790
31296
|
MinSyncVectorMethod,
|
|
30791
31297
|
NotcrawlClient,
|
|
30792
31298
|
NotionSkill,
|
|
31299
|
+
OAUTH_CLIENT_ID,
|
|
30793
31300
|
ObsidianBm25Method,
|
|
30794
31301
|
ObsidianSemanticMethod,
|
|
30795
31302
|
ObsidianSkill,
|
|
30796
31303
|
OpenRouterReranker,
|
|
31304
|
+
PROVIDER_ID,
|
|
31305
|
+
PROVIDER_NAME,
|
|
30797
31306
|
ParallelRetriever,
|
|
30798
31307
|
ParseError,
|
|
30799
31308
|
Parser,
|
|
@@ -30815,13 +31324,16 @@ export {
|
|
|
30815
31324
|
SlacrawlClient,
|
|
30816
31325
|
SpotlightConnector,
|
|
30817
31326
|
SpotlightSkill,
|
|
31327
|
+
TOKEN_PATH,
|
|
30818
31328
|
TelecrawlClient,
|
|
30819
31329
|
TelecrawlSkill,
|
|
30820
31330
|
WacrawlClient,
|
|
30821
31331
|
WacrawlSkill,
|
|
31332
|
+
base64UrlEncode,
|
|
30822
31333
|
bm25Scores,
|
|
30823
31334
|
boundDiagnosticText2 as boundDiagnosticText,
|
|
30824
31335
|
buildAgentOptions,
|
|
31336
|
+
buildAuthorizeUrl,
|
|
30825
31337
|
buildDatasourceChunkSource,
|
|
30826
31338
|
buildDatasourceInstanceSource,
|
|
30827
31339
|
buildDatasourceSkills,
|
|
@@ -30830,16 +31342,21 @@ export {
|
|
|
30830
31342
|
buildFSearchIndexArgs,
|
|
30831
31343
|
buildFSearchSearchArgs,
|
|
30832
31344
|
buildMinSyncPathMap,
|
|
31345
|
+
buildStoreEntry,
|
|
30833
31346
|
buildSystemPrompt,
|
|
30834
31347
|
cachedJikjiBinaryPath,
|
|
30835
31348
|
configuredVectorDimension,
|
|
30836
31349
|
connectorFailureToDiagnosticCode,
|
|
30837
31350
|
createAutoRAGLite,
|
|
30838
31351
|
createAutoRAGMcpServer,
|
|
31352
|
+
createAutoRAGProviderConfig,
|
|
30839
31353
|
createCheckMemoryTool,
|
|
31354
|
+
createCodeChallenge,
|
|
31355
|
+
createCodeVerifier,
|
|
30840
31356
|
createDefaultParserRegistry,
|
|
30841
|
-
|
|
31357
|
+
createPkcePair,
|
|
30842
31358
|
createReranker,
|
|
31359
|
+
createState,
|
|
30843
31360
|
createTesseractOcrProvider,
|
|
30844
31361
|
datasourceChunkStorePath,
|
|
30845
31362
|
datasourceSourceHasFragment,
|
|
@@ -30847,7 +31364,6 @@ export {
|
|
|
30847
31364
|
derivedDatasourceIds,
|
|
30848
31365
|
describeRetrievalError,
|
|
30849
31366
|
detectMirrorStaleness,
|
|
30850
|
-
emitResultsSchema,
|
|
30851
31367
|
emptyMirrorIndex,
|
|
30852
31368
|
ensureEverythingBinaries,
|
|
30853
31369
|
ensureJikjiBinary,
|
|
@@ -30856,8 +31372,11 @@ export {
|
|
|
30856
31372
|
everythingArch,
|
|
30857
31373
|
everythingBinaryPaths,
|
|
30858
31374
|
everythingInstanceName,
|
|
31375
|
+
exchangeCodeForToken,
|
|
30859
31376
|
executableName,
|
|
31377
|
+
extractErrorPayload,
|
|
30860
31378
|
fetchLatestMinSyncRelease,
|
|
31379
|
+
fetchModels,
|
|
30861
31380
|
filterDatasourceScope,
|
|
30862
31381
|
findSimilarQuestions,
|
|
30863
31382
|
fsearchSocketPath,
|
|
@@ -30874,20 +31393,29 @@ export {
|
|
|
30874
31393
|
loadManifests,
|
|
30875
31394
|
loadMemoryContext,
|
|
30876
31395
|
loadMirrorIndex,
|
|
31396
|
+
loginAutorag,
|
|
30877
31397
|
lookupExecutableInPath,
|
|
30878
31398
|
mapDatasourceDiagnostic,
|
|
30879
31399
|
mapDatasourceDiagnostics,
|
|
30880
31400
|
mapJikjiPath,
|
|
31401
|
+
mapModelsError,
|
|
31402
|
+
mapServerModel,
|
|
31403
|
+
mapServerModels,
|
|
31404
|
+
mapTokenExchangeError,
|
|
30881
31405
|
matchesDatasourceScope,
|
|
30882
31406
|
matchesVirtualPathScope,
|
|
30883
31407
|
minSyncConfigPath,
|
|
30884
31408
|
minSyncDocumentPath,
|
|
30885
31409
|
minSyncEmbeddingIdentityPath,
|
|
30886
31410
|
minSyncWorkspaceRoot,
|
|
31411
|
+
modelsFromStore,
|
|
31412
|
+
normalizeBaseUrl,
|
|
30887
31413
|
normalizeJikjiAnswerPath,
|
|
30888
31414
|
normalizeSessionEvidenceRef,
|
|
30889
31415
|
normalizeVirtualPath2 as normalizeVirtualPath,
|
|
30890
31416
|
normalizeVirtualPathScope,
|
|
31417
|
+
parseCallbackInput,
|
|
31418
|
+
parseCallbackQuery,
|
|
30891
31419
|
parseCronExpr,
|
|
30892
31420
|
parseEverythingJson,
|
|
30893
31421
|
parseFSearchJsonLines,
|
|
@@ -30897,11 +31425,17 @@ export {
|
|
|
30897
31425
|
parsedMirrorRoot,
|
|
30898
31426
|
parsedOutputPath,
|
|
30899
31427
|
planJikjiSourceRoots,
|
|
31428
|
+
refreshAutoragCredentials,
|
|
31429
|
+
refreshAutoragModels,
|
|
30900
31430
|
refreshReadinessPath,
|
|
31431
|
+
registerAutoRAGProvider,
|
|
30901
31432
|
renderMemoryContext,
|
|
30902
31433
|
reportSchema,
|
|
31434
|
+
requireAuthorizationCode,
|
|
31435
|
+
resolveBaseUrl,
|
|
30903
31436
|
resolveConfig,
|
|
30904
31437
|
resolveConfigReadOnly,
|
|
31438
|
+
resolveCredentialKey,
|
|
30905
31439
|
resolveEverythingBundleDir,
|
|
30906
31440
|
resolveParserOptions,
|
|
30907
31441
|
resolveReturnedPath,
|
|
@@ -30913,6 +31447,7 @@ export {
|
|
|
30913
31447
|
scanWithDupey,
|
|
30914
31448
|
selectExactDuplicateExclusions,
|
|
30915
31449
|
selectReleaseAsset,
|
|
31450
|
+
startCallbackServer,
|
|
30916
31451
|
syncMinSyncWorkspace,
|
|
30917
31452
|
syncParsedMirrors,
|
|
30918
31453
|
tokenize,
|