@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/cli/index.js
CHANGED
|
@@ -1394,7 +1394,8 @@ function searchEnvelope(resp, debug) {
|
|
|
1394
1394
|
if (r.source !== undefined)
|
|
1395
1395
|
base.source = r.source;
|
|
1396
1396
|
if (debug) {
|
|
1397
|
-
|
|
1397
|
+
if (r.confidence !== undefined)
|
|
1398
|
+
base.confidence = r.confidence;
|
|
1398
1399
|
base.evidence = r.evidence.map((e) => {
|
|
1399
1400
|
const ev = { excerpt: e.excerpt };
|
|
1400
1401
|
if (e.lineNumber !== undefined)
|
|
@@ -1431,7 +1432,8 @@ function renderSearchHuman(resp, debug) {
|
|
|
1431
1432
|
if (r.summary)
|
|
1432
1433
|
lines.push(` ${r.summary}`);
|
|
1433
1434
|
if (debug) {
|
|
1434
|
-
|
|
1435
|
+
if (r.confidence !== undefined)
|
|
1436
|
+
lines.push(` confidence: ${r.confidence}`);
|
|
1435
1437
|
for (const ev of r.evidence) {
|
|
1436
1438
|
const ln = ev.lineNumber !== undefined ? ` (line ${ev.lineNumber})` : "";
|
|
1437
1439
|
lines.push(` evidence${ln}: ${ev.excerpt}`);
|
|
@@ -1712,6 +1714,599 @@ function loadLocalAutoRAGModel(options = {}) {
|
|
|
1712
1714
|
var DEFAULT_MODEL_ID = "gpt-5.6-sol";
|
|
1713
1715
|
var init_local_model = () => {};
|
|
1714
1716
|
|
|
1717
|
+
// src/cloud/config.ts
|
|
1718
|
+
function normalizeBaseUrl(value) {
|
|
1719
|
+
const trimmed = value.trim();
|
|
1720
|
+
let end = trimmed.length;
|
|
1721
|
+
while (end > 0 && trimmed.charCodeAt(end - 1) === 47)
|
|
1722
|
+
end--;
|
|
1723
|
+
return trimmed.slice(0, end);
|
|
1724
|
+
}
|
|
1725
|
+
function resolveBaseUrl(env) {
|
|
1726
|
+
const configured = env[AUTORAG_BASE_URL_ENV];
|
|
1727
|
+
const value = typeof configured === "string" && configured.trim() !== "" ? configured : DEFAULT_BASE_URL;
|
|
1728
|
+
return normalizeBaseUrl(value);
|
|
1729
|
+
}
|
|
1730
|
+
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;
|
|
1731
|
+
var init_config = __esm(() => {
|
|
1732
|
+
API_KEY_CONFIG_VALUE = `$${AUTORAG_API_KEY_ENV}`;
|
|
1733
|
+
});
|
|
1734
|
+
|
|
1735
|
+
// src/cloud/errors.ts
|
|
1736
|
+
function extractErrorPayload(body) {
|
|
1737
|
+
if (typeof body !== "object" || body === null)
|
|
1738
|
+
return {};
|
|
1739
|
+
const record = body;
|
|
1740
|
+
const error = record.error;
|
|
1741
|
+
if (typeof error === "string")
|
|
1742
|
+
return error.length > 0 ? { message: error } : {};
|
|
1743
|
+
if (typeof error === "object" && error !== null) {
|
|
1744
|
+
const inner = error;
|
|
1745
|
+
const payload = {};
|
|
1746
|
+
if (typeof inner.message === "string")
|
|
1747
|
+
payload.message = inner.message;
|
|
1748
|
+
if (typeof inner.code === "string")
|
|
1749
|
+
payload.code = inner.code;
|
|
1750
|
+
if (typeof inner.type === "string")
|
|
1751
|
+
payload.type = inner.type;
|
|
1752
|
+
return payload;
|
|
1753
|
+
}
|
|
1754
|
+
return typeof record.message === "string" ? { message: record.message } : {};
|
|
1755
|
+
}
|
|
1756
|
+
var AutoragError, AutoragOAuthError, AutoragHttpError;
|
|
1757
|
+
var init_errors = __esm(() => {
|
|
1758
|
+
AutoragError = class AutoragError extends Error {
|
|
1759
|
+
constructor(message, options) {
|
|
1760
|
+
super(message, options);
|
|
1761
|
+
this.name = "AutoragError";
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
AutoragOAuthError = class AutoragOAuthError extends AutoragError {
|
|
1765
|
+
constructor(message, options) {
|
|
1766
|
+
super(message, options);
|
|
1767
|
+
this.name = "AutoragOAuthError";
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
AutoragHttpError = class AutoragHttpError extends AutoragError {
|
|
1771
|
+
status;
|
|
1772
|
+
code;
|
|
1773
|
+
type;
|
|
1774
|
+
constructor(message, options) {
|
|
1775
|
+
super(message, { cause: options.cause });
|
|
1776
|
+
this.name = "AutoragHttpError";
|
|
1777
|
+
this.status = options.status;
|
|
1778
|
+
if (options.code !== undefined)
|
|
1779
|
+
this.code = options.code;
|
|
1780
|
+
if (options.type !== undefined)
|
|
1781
|
+
this.type = options.type;
|
|
1782
|
+
}
|
|
1783
|
+
};
|
|
1784
|
+
});
|
|
1785
|
+
|
|
1786
|
+
// src/cloud/models.ts
|
|
1787
|
+
function resolveCredentialKey(credential) {
|
|
1788
|
+
if (credential === undefined)
|
|
1789
|
+
return;
|
|
1790
|
+
const value = credential.type === "oauth" ? credential.access : credential.key;
|
|
1791
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
1792
|
+
}
|
|
1793
|
+
async function fetchModels(options) {
|
|
1794
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
1795
|
+
let response;
|
|
1796
|
+
try {
|
|
1797
|
+
response = await doFetch(`${normalizeBaseUrl(options.baseUrl)}${MODELS_PATH}`, {
|
|
1798
|
+
headers: { authorization: `Bearer ${options.apiKey}`, accept: "application/json" },
|
|
1799
|
+
signal: options.signal
|
|
1800
|
+
});
|
|
1801
|
+
} catch (cause) {
|
|
1802
|
+
if (options.signal?.aborted) {
|
|
1803
|
+
throw new AutoragOAuthError("AutoRAG model refresh was cancelled.", { cause });
|
|
1804
|
+
}
|
|
1805
|
+
throw new AutoragOAuthError(`AutoRAG model listing could not reach ${normalizeBaseUrl(options.baseUrl)}.`, {
|
|
1806
|
+
cause
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
let body;
|
|
1810
|
+
try {
|
|
1811
|
+
body = await response.json();
|
|
1812
|
+
} catch {
|
|
1813
|
+
body = undefined;
|
|
1814
|
+
}
|
|
1815
|
+
if (!response.ok)
|
|
1816
|
+
throw mapModelsError(response.status, body);
|
|
1817
|
+
return mapServerModels(body);
|
|
1818
|
+
}
|
|
1819
|
+
function mapModelsError(status, body) {
|
|
1820
|
+
const payload = extractErrorPayload(body);
|
|
1821
|
+
if (status === 401) {
|
|
1822
|
+
return new AutoragHttpError("AutoRAG rejected the API key (HTTP 401). Run /login again or set AUTORAG_API_KEY.", {
|
|
1823
|
+
status,
|
|
1824
|
+
code: payload.code ?? "unauthorized",
|
|
1825
|
+
type: payload.type
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
const reason = payload.message ?? "the server returned no error message";
|
|
1829
|
+
return new AutoragHttpError(`AutoRAG model listing failed (HTTP ${status}): ${reason}`, {
|
|
1830
|
+
status,
|
|
1831
|
+
code: payload.code,
|
|
1832
|
+
type: payload.type
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1835
|
+
function mapServerModels(payload) {
|
|
1836
|
+
if (typeof payload !== "object" || payload === null)
|
|
1837
|
+
return [];
|
|
1838
|
+
const data = payload.data;
|
|
1839
|
+
if (!Array.isArray(data))
|
|
1840
|
+
return [];
|
|
1841
|
+
const models = [];
|
|
1842
|
+
for (const entry of data) {
|
|
1843
|
+
if (typeof entry !== "object" || entry === null)
|
|
1844
|
+
continue;
|
|
1845
|
+
const model = mapServerModel(entry);
|
|
1846
|
+
if (model !== undefined)
|
|
1847
|
+
models.push(model);
|
|
1848
|
+
}
|
|
1849
|
+
return models;
|
|
1850
|
+
}
|
|
1851
|
+
function mapServerModel(entry) {
|
|
1852
|
+
const id = readString(entry.id);
|
|
1853
|
+
if (id === undefined)
|
|
1854
|
+
return;
|
|
1855
|
+
return {
|
|
1856
|
+
type: "chat",
|
|
1857
|
+
id,
|
|
1858
|
+
name: readString(entry.name) ?? id,
|
|
1859
|
+
input: readInputModalities(entry.input_modalities),
|
|
1860
|
+
cost: readPricing(entry.pricing),
|
|
1861
|
+
reasoning: entry.reasoning === true,
|
|
1862
|
+
contextWindow: readPositiveNumber(entry.context_window) ?? DEFAULT_CONTEXT_WINDOW,
|
|
1863
|
+
maxTokens: readPositiveNumber(entry.max_output_tokens) ?? DEFAULT_MAX_TOKENS
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
function buildStoreEntry(models, providerId, baseUrl) {
|
|
1867
|
+
const stored = [];
|
|
1868
|
+
for (const model of models) {
|
|
1869
|
+
if (model.type === "image" || model.type === "classifier")
|
|
1870
|
+
continue;
|
|
1871
|
+
stored.push({
|
|
1872
|
+
type: "chat",
|
|
1873
|
+
id: model.id,
|
|
1874
|
+
name: model.name,
|
|
1875
|
+
api: model.api ?? "openai-responses",
|
|
1876
|
+
provider: providerId,
|
|
1877
|
+
baseUrl: model.baseUrl ?? baseUrl,
|
|
1878
|
+
input: model.input,
|
|
1879
|
+
cost: model.cost,
|
|
1880
|
+
reasoning: model.reasoning,
|
|
1881
|
+
contextWindow: model.contextWindow,
|
|
1882
|
+
maxTokens: model.maxTokens
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
return { models: stored, checkedAt: Date.now() };
|
|
1886
|
+
}
|
|
1887
|
+
function modelsFromStore(stored) {
|
|
1888
|
+
if (stored === undefined)
|
|
1889
|
+
return [];
|
|
1890
|
+
const models = [];
|
|
1891
|
+
for (const entry of stored.models) {
|
|
1892
|
+
if (entry.type === "image" || entry.type === "classifier")
|
|
1893
|
+
continue;
|
|
1894
|
+
models.push({
|
|
1895
|
+
type: "chat",
|
|
1896
|
+
id: entry.id,
|
|
1897
|
+
name: entry.name,
|
|
1898
|
+
input: entry.input,
|
|
1899
|
+
cost: entry.cost,
|
|
1900
|
+
reasoning: entry.reasoning,
|
|
1901
|
+
contextWindow: entry.contextWindow,
|
|
1902
|
+
maxTokens: entry.maxTokens
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
return models;
|
|
1906
|
+
}
|
|
1907
|
+
function readString(value) {
|
|
1908
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : undefined;
|
|
1909
|
+
}
|
|
1910
|
+
function readPositiveNumber(value) {
|
|
1911
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
|
|
1912
|
+
}
|
|
1913
|
+
function readInputModalities(value) {
|
|
1914
|
+
if (!Array.isArray(value))
|
|
1915
|
+
return ["text"];
|
|
1916
|
+
const modalities = value.filter((item) => item === "text" || item === "image");
|
|
1917
|
+
const unique = Array.from(new Set(modalities));
|
|
1918
|
+
return unique.length > 0 ? unique : ["text"];
|
|
1919
|
+
}
|
|
1920
|
+
function readPricing(value) {
|
|
1921
|
+
const pricing = typeof value === "object" && value !== null ? value : {};
|
|
1922
|
+
return {
|
|
1923
|
+
input: readPositiveNumber(pricing.input) ?? 0,
|
|
1924
|
+
output: readPositiveNumber(pricing.output) ?? 0,
|
|
1925
|
+
cacheRead: readPositiveNumber(pricing.cache_read) ?? 0,
|
|
1926
|
+
cacheWrite: readPositiveNumber(pricing.cache_write) ?? 0
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
var DEFAULT_CONTEXT_WINDOW = 128000, DEFAULT_MAX_TOKENS = 16384;
|
|
1930
|
+
var init_models = __esm(() => {
|
|
1931
|
+
init_config();
|
|
1932
|
+
init_errors();
|
|
1933
|
+
});
|
|
1934
|
+
|
|
1935
|
+
// src/cloud/authorize.ts
|
|
1936
|
+
function buildAuthorizeUrl(params) {
|
|
1937
|
+
const url = new URL(`${normalizeBaseUrl(params.baseUrl)}${AUTHORIZE_PATH}`);
|
|
1938
|
+
url.searchParams.set("client", OAUTH_CLIENT_ID);
|
|
1939
|
+
url.searchParams.set("redirect_uri", params.redirectUri);
|
|
1940
|
+
url.searchParams.set("state", params.state);
|
|
1941
|
+
url.searchParams.set("code_challenge", params.codeChallenge);
|
|
1942
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
1943
|
+
return url.toString();
|
|
1944
|
+
}
|
|
1945
|
+
var init_authorize = __esm(() => {
|
|
1946
|
+
init_config();
|
|
1947
|
+
});
|
|
1948
|
+
|
|
1949
|
+
// src/cloud/callback.ts
|
|
1950
|
+
function parseCallbackQuery(params) {
|
|
1951
|
+
const result = {};
|
|
1952
|
+
const code = params.get("code");
|
|
1953
|
+
const error = params.get("error");
|
|
1954
|
+
const state = params.get("state");
|
|
1955
|
+
if (code !== null && code !== "")
|
|
1956
|
+
result.code = code;
|
|
1957
|
+
if (error !== null && error !== "")
|
|
1958
|
+
result.error = error;
|
|
1959
|
+
if (state !== null && state !== "")
|
|
1960
|
+
result.state = state;
|
|
1961
|
+
return result;
|
|
1962
|
+
}
|
|
1963
|
+
function parseCallbackInput(input) {
|
|
1964
|
+
const trimmed = input.trim();
|
|
1965
|
+
if (trimmed === "") {
|
|
1966
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: nothing was pasted.");
|
|
1967
|
+
}
|
|
1968
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
1969
|
+
try {
|
|
1970
|
+
return parseCallbackQuery(new URL(trimmed).searchParams);
|
|
1971
|
+
} catch {
|
|
1972
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: the pasted URL is not valid.");
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
const query = trimmed.startsWith("?") ? trimmed.slice(1) : trimmed;
|
|
1976
|
+
if (!query.includes(" ")) {
|
|
1977
|
+
const params = new URLSearchParams(query);
|
|
1978
|
+
if (params.has("code") || params.has("error") || params.has("state")) {
|
|
1979
|
+
return parseCallbackQuery(params);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
return { code: trimmed };
|
|
1983
|
+
}
|
|
1984
|
+
function requireAuthorizationCode(result, expectedState) {
|
|
1985
|
+
if (result.state !== undefined && result.state !== expectedState) {
|
|
1986
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: state mismatch (the callback did not originate from this login attempt).");
|
|
1987
|
+
}
|
|
1988
|
+
if (result.error !== undefined) {
|
|
1989
|
+
throw new AutoragOAuthError(result.error === "access_denied" ? "AutoRAG sign-in was cancelled in the browser." : `AutoRAG sign-in failed: ${result.error}.`);
|
|
1990
|
+
}
|
|
1991
|
+
if (result.code === undefined) {
|
|
1992
|
+
throw new AutoragOAuthError("AutoRAG sign-in failed: the callback carried no authorization code.");
|
|
1993
|
+
}
|
|
1994
|
+
return { code: result.code };
|
|
1995
|
+
}
|
|
1996
|
+
var init_callback = __esm(() => {
|
|
1997
|
+
init_errors();
|
|
1998
|
+
});
|
|
1999
|
+
|
|
2000
|
+
// src/cloud/callback-server.ts
|
|
2001
|
+
import { createServer as createServer3 } from "node:http";
|
|
2002
|
+
function createDeferred() {
|
|
2003
|
+
let resolve;
|
|
2004
|
+
let reject;
|
|
2005
|
+
const promise = new Promise((res, rej) => {
|
|
2006
|
+
resolve = res;
|
|
2007
|
+
reject = rej;
|
|
2008
|
+
});
|
|
2009
|
+
return { promise, resolve, reject };
|
|
2010
|
+
}
|
|
2011
|
+
function renderCallbackPage(failed) {
|
|
2012
|
+
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.";
|
|
2013
|
+
return [
|
|
2014
|
+
"<!doctype html>",
|
|
2015
|
+
'<html lang="en">',
|
|
2016
|
+
"<head>",
|
|
2017
|
+
'<meta charset="utf-8">',
|
|
2018
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
2019
|
+
"<title>AutoRAG</title>",
|
|
2020
|
+
"</head>",
|
|
2021
|
+
'<body style="font-family: system-ui, sans-serif; margin: 4rem auto; max-width: 32rem; text-align: center;">',
|
|
2022
|
+
`<p>${message}</p>`,
|
|
2023
|
+
"</body>",
|
|
2024
|
+
"</html>"
|
|
2025
|
+
].join(`
|
|
2026
|
+
`);
|
|
2027
|
+
}
|
|
2028
|
+
function startCallbackServer(options) {
|
|
2029
|
+
const host = options.host ?? "127.0.0.1";
|
|
2030
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS;
|
|
2031
|
+
const server = createServer3();
|
|
2032
|
+
const started = createDeferred();
|
|
2033
|
+
const callback = createDeferred();
|
|
2034
|
+
callback.promise.catch(() => {});
|
|
2035
|
+
let finished = false;
|
|
2036
|
+
let startSettled = false;
|
|
2037
|
+
let timer;
|
|
2038
|
+
function cleanup() {
|
|
2039
|
+
clearTimeout(timer);
|
|
2040
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
2041
|
+
if (server.listening) {
|
|
2042
|
+
server.closeAllConnections();
|
|
2043
|
+
server.close();
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
function fail(error) {
|
|
2047
|
+
if (finished)
|
|
2048
|
+
return;
|
|
2049
|
+
finished = true;
|
|
2050
|
+
cleanup();
|
|
2051
|
+
callback.reject(error);
|
|
2052
|
+
}
|
|
2053
|
+
function onAbort() {
|
|
2054
|
+
fail(new AutoragOAuthError("AutoRAG sign-in was cancelled."));
|
|
2055
|
+
}
|
|
2056
|
+
server.on("request", (req, res) => {
|
|
2057
|
+
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
2058
|
+
if (req.method !== "GET" || url.pathname !== CALLBACK_PATH) {
|
|
2059
|
+
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
2060
|
+
res.end("Not found");
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
if (finished) {
|
|
2064
|
+
res.writeHead(410, { "content-type": "text/plain; charset=utf-8" });
|
|
2065
|
+
res.end("Callback already handled");
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
const params = url.searchParams;
|
|
2069
|
+
const code = params.get("code");
|
|
2070
|
+
const oauthError = params.get("error");
|
|
2071
|
+
const hasResponse = code !== null && code !== "" || oauthError !== null && oauthError !== "";
|
|
2072
|
+
if (params.get("state") !== options.state || !hasResponse) {
|
|
2073
|
+
res.writeHead(400, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" });
|
|
2074
|
+
res.end(renderCallbackPage(true));
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
finished = true;
|
|
2078
|
+
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" });
|
|
2079
|
+
res.end(renderCallbackPage(params.has("error")));
|
|
2080
|
+
cleanup();
|
|
2081
|
+
callback.resolve(params);
|
|
2082
|
+
});
|
|
2083
|
+
server.on("error", (error) => {
|
|
2084
|
+
const wrapped = error instanceof Error ? error : new Error(String(error));
|
|
2085
|
+
if (!startSettled) {
|
|
2086
|
+
startSettled = true;
|
|
2087
|
+
cleanup();
|
|
2088
|
+
started.reject(wrapped);
|
|
2089
|
+
return;
|
|
2090
|
+
}
|
|
2091
|
+
fail(wrapped);
|
|
2092
|
+
});
|
|
2093
|
+
server.listen(0, host, () => {
|
|
2094
|
+
const address = server.address();
|
|
2095
|
+
const port = typeof address === "object" && address !== null ? address.port : 0;
|
|
2096
|
+
const redirectUri = `http://${host}:${port}${CALLBACK_PATH}`;
|
|
2097
|
+
timer = setTimeout(() => fail(new AutoragOAuthError("AutoRAG sign-in timed out waiting for the browser callback.")), timeoutMs);
|
|
2098
|
+
if (options.signal?.aborted)
|
|
2099
|
+
onAbort();
|
|
2100
|
+
else
|
|
2101
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
2102
|
+
startSettled = true;
|
|
2103
|
+
options.onListening?.(redirectUri);
|
|
2104
|
+
started.resolve({
|
|
2105
|
+
redirectUri,
|
|
2106
|
+
waitForCallback: () => callback.promise,
|
|
2107
|
+
close: () => {
|
|
2108
|
+
if (!finished)
|
|
2109
|
+
fail(new AutoragOAuthError("AutoRAG sign-in was cancelled."));
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
});
|
|
2113
|
+
return started.promise;
|
|
2114
|
+
}
|
|
2115
|
+
var CALLBACK_PATH = "/callback", DEFAULT_LOGIN_TIMEOUT_MS;
|
|
2116
|
+
var init_callback_server = __esm(() => {
|
|
2117
|
+
init_errors();
|
|
2118
|
+
DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
2119
|
+
});
|
|
2120
|
+
|
|
2121
|
+
// src/cloud/pkce.ts
|
|
2122
|
+
import { createHash as createHash2, randomBytes } from "node:crypto";
|
|
2123
|
+
function base64UrlEncode(bytes) {
|
|
2124
|
+
return Buffer.from(bytes).toString("base64url");
|
|
2125
|
+
}
|
|
2126
|
+
function createCodeChallenge(verifier) {
|
|
2127
|
+
return base64UrlEncode(createHash2("sha256").update(verifier, "ascii").digest());
|
|
2128
|
+
}
|
|
2129
|
+
function createCodeVerifier(byteLength = 32) {
|
|
2130
|
+
return base64UrlEncode(randomBytes(byteLength));
|
|
2131
|
+
}
|
|
2132
|
+
function createState(byteLength = 24) {
|
|
2133
|
+
return base64UrlEncode(randomBytes(byteLength));
|
|
2134
|
+
}
|
|
2135
|
+
function createPkcePair(byteLength = 32) {
|
|
2136
|
+
const verifier = createCodeVerifier(byteLength);
|
|
2137
|
+
return { verifier, challenge: createCodeChallenge(verifier) };
|
|
2138
|
+
}
|
|
2139
|
+
var init_pkce = () => {};
|
|
2140
|
+
|
|
2141
|
+
// src/cloud/token.ts
|
|
2142
|
+
function mapTokenExchangeError(status, body) {
|
|
2143
|
+
const payload = extractErrorPayload(body);
|
|
2144
|
+
const reason = payload.message ?? "the server returned no error message";
|
|
2145
|
+
return new AutoragHttpError(`AutoRAG token exchange failed (HTTP ${status}): ${reason}`, {
|
|
2146
|
+
status,
|
|
2147
|
+
code: payload.code,
|
|
2148
|
+
type: payload.type
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
async function exchangeCodeForToken(options) {
|
|
2152
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
2153
|
+
let response;
|
|
2154
|
+
try {
|
|
2155
|
+
response = await doFetch(`${normalizeBaseUrl(options.baseUrl)}${TOKEN_PATH}`, {
|
|
2156
|
+
method: "POST",
|
|
2157
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
2158
|
+
body: JSON.stringify({
|
|
2159
|
+
code: options.code,
|
|
2160
|
+
code_verifier: options.codeVerifier,
|
|
2161
|
+
redirect_uri: options.redirectUri
|
|
2162
|
+
}),
|
|
2163
|
+
signal: options.signal
|
|
2164
|
+
});
|
|
2165
|
+
} catch (cause) {
|
|
2166
|
+
if (options.signal?.aborted) {
|
|
2167
|
+
throw new AutoragOAuthError("AutoRAG sign-in was cancelled.", { cause });
|
|
2168
|
+
}
|
|
2169
|
+
throw new AutoragOAuthError(`AutoRAG token exchange could not reach ${normalizeBaseUrl(options.baseUrl)}.`, {
|
|
2170
|
+
cause
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
let body;
|
|
2174
|
+
try {
|
|
2175
|
+
body = await response.json();
|
|
2176
|
+
} catch {
|
|
2177
|
+
body = undefined;
|
|
2178
|
+
}
|
|
2179
|
+
if (!response.ok)
|
|
2180
|
+
throw mapTokenExchangeError(response.status, body);
|
|
2181
|
+
const accessToken = readAccessToken(body);
|
|
2182
|
+
if (accessToken === undefined) {
|
|
2183
|
+
throw new AutoragOAuthError("AutoRAG token exchange succeeded but returned no access token.");
|
|
2184
|
+
}
|
|
2185
|
+
const email = readEmail(body);
|
|
2186
|
+
return email === undefined ? { accessToken } : { accessToken, email };
|
|
2187
|
+
}
|
|
2188
|
+
function readAccessToken(body) {
|
|
2189
|
+
if (typeof body !== "object" || body === null)
|
|
2190
|
+
return;
|
|
2191
|
+
const value = body.access_token;
|
|
2192
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
2193
|
+
}
|
|
2194
|
+
function readEmail(body) {
|
|
2195
|
+
if (typeof body !== "object" || body === null)
|
|
2196
|
+
return;
|
|
2197
|
+
const value = body.email;
|
|
2198
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
2199
|
+
}
|
|
2200
|
+
var init_token = __esm(() => {
|
|
2201
|
+
init_config();
|
|
2202
|
+
init_errors();
|
|
2203
|
+
});
|
|
2204
|
+
|
|
2205
|
+
// src/cloud/oauth-login.ts
|
|
2206
|
+
function refreshAutoragCredentials(credentials) {
|
|
2207
|
+
return credentials;
|
|
2208
|
+
}
|
|
2209
|
+
async function loginAutorag(callbacks, options) {
|
|
2210
|
+
const { verifier, challenge } = createPkcePair();
|
|
2211
|
+
const state = createState();
|
|
2212
|
+
const server = await startCallbackServer({
|
|
2213
|
+
state,
|
|
2214
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS,
|
|
2215
|
+
signal: callbacks.signal
|
|
2216
|
+
});
|
|
2217
|
+
try {
|
|
2218
|
+
callbacks.onAuth({
|
|
2219
|
+
url: buildAuthorizeUrl({
|
|
2220
|
+
baseUrl: options.baseUrl,
|
|
2221
|
+
redirectUri: server.redirectUri,
|
|
2222
|
+
state,
|
|
2223
|
+
codeChallenge: challenge
|
|
2224
|
+
}),
|
|
2225
|
+
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.`
|
|
2226
|
+
});
|
|
2227
|
+
callbacks.onProgress?.(`Listening for the AutoRAG sign-in callback on ${server.redirectUri}`);
|
|
2228
|
+
const outcome = await Promise.race([
|
|
2229
|
+
server.waitForCallback().then((params) => ({ params })),
|
|
2230
|
+
callbacks.onPrompt({
|
|
2231
|
+
message: "Complete the AutoRAG sign-in in your browser, or paste the final redirect URL / authorization code here:",
|
|
2232
|
+
placeholder: server.redirectUri,
|
|
2233
|
+
allowEmpty: true
|
|
2234
|
+
}).then((value) => ({ value }))
|
|
2235
|
+
]);
|
|
2236
|
+
const parsed = "params" in outcome ? parseCallbackQuery(outcome.params) : parseCallbackInput(outcome.value);
|
|
2237
|
+
const { code } = requireAuthorizationCode(parsed, state);
|
|
2238
|
+
const token = await exchangeCodeForToken({
|
|
2239
|
+
baseUrl: options.baseUrl,
|
|
2240
|
+
code,
|
|
2241
|
+
codeVerifier: verifier,
|
|
2242
|
+
redirectUri: server.redirectUri,
|
|
2243
|
+
signal: callbacks.signal,
|
|
2244
|
+
fetchImpl: options.fetchImpl
|
|
2245
|
+
});
|
|
2246
|
+
return {
|
|
2247
|
+
access: token.accessToken,
|
|
2248
|
+
refresh: "",
|
|
2249
|
+
expires: Number.MAX_SAFE_INTEGER,
|
|
2250
|
+
...token.email !== undefined ? { email: token.email } : {}
|
|
2251
|
+
};
|
|
2252
|
+
} finally {
|
|
2253
|
+
server.close();
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
var init_oauth_login = __esm(() => {
|
|
2257
|
+
init_authorize();
|
|
2258
|
+
init_callback();
|
|
2259
|
+
init_callback_server();
|
|
2260
|
+
init_pkce();
|
|
2261
|
+
init_token();
|
|
2262
|
+
});
|
|
2263
|
+
|
|
2264
|
+
// src/cloud/provider.ts
|
|
2265
|
+
async function refreshAutoragModels(context, endpoints) {
|
|
2266
|
+
const stored = modelsFromStore(context.stored);
|
|
2267
|
+
const apiKey = resolveCredentialKey(context.credential);
|
|
2268
|
+
if (!context.allowNetwork || apiKey === undefined)
|
|
2269
|
+
return stored;
|
|
2270
|
+
let models;
|
|
2271
|
+
try {
|
|
2272
|
+
models = await fetchModels({ baseUrl: endpoints.baseUrl, apiKey, signal: context.signal });
|
|
2273
|
+
} catch {
|
|
2274
|
+
return stored;
|
|
2275
|
+
}
|
|
2276
|
+
if (models.length === 0)
|
|
2277
|
+
return stored;
|
|
2278
|
+
try {
|
|
2279
|
+
await context.publish({ persist: buildStoreEntry(models, PROVIDER_ID, endpoints.apiBaseUrl) });
|
|
2280
|
+
} catch {}
|
|
2281
|
+
return models;
|
|
2282
|
+
}
|
|
2283
|
+
function createAutoRAGProviderConfig(env = process.env) {
|
|
2284
|
+
const baseUrl = resolveBaseUrl(env);
|
|
2285
|
+
const endpoints = { baseUrl, apiBaseUrl: `${baseUrl}${API_PATH}` };
|
|
2286
|
+
return {
|
|
2287
|
+
name: PROVIDER_NAME,
|
|
2288
|
+
baseUrl: endpoints.apiBaseUrl,
|
|
2289
|
+
api: "openai-responses",
|
|
2290
|
+
apiKey: API_KEY_CONFIG_VALUE,
|
|
2291
|
+
oauth: {
|
|
2292
|
+
name: PROVIDER_NAME,
|
|
2293
|
+
login: (callbacks) => loginAutorag(callbacks, { baseUrl }),
|
|
2294
|
+
refreshToken: async (credentials) => refreshAutoragCredentials(credentials),
|
|
2295
|
+
getApiKey: (credentials) => credentials.access
|
|
2296
|
+
},
|
|
2297
|
+
refreshModels: (context) => refreshAutoragModels(context, endpoints)
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
async function registerAutoRAGProvider(runtime, env = process.env) {
|
|
2301
|
+
runtime.registerProvider(PROVIDER_ID, createAutoRAGProviderConfig(env));
|
|
2302
|
+
await runtime.refresh({ allowNetwork: false, providers: [PROVIDER_ID] });
|
|
2303
|
+
}
|
|
2304
|
+
var init_provider = __esm(() => {
|
|
2305
|
+
init_config();
|
|
2306
|
+
init_models();
|
|
2307
|
+
init_oauth_login();
|
|
2308
|
+
});
|
|
2309
|
+
|
|
1715
2310
|
// src/datasource/tool-naming.ts
|
|
1716
2311
|
function datasourceSearchToolName(datasourceId) {
|
|
1717
2312
|
const collapsed = datasourceId.toLowerCase().replace(/[^a-z0-9]+/g, "_");
|
|
@@ -2159,7 +2754,7 @@ function datasourceCliError(datasourceId, command, failure) {
|
|
|
2159
2754
|
return new DatasourceCliError(datasourceId, command, failure);
|
|
2160
2755
|
}
|
|
2161
2756
|
var DatasourceCliError;
|
|
2162
|
-
var
|
|
2757
|
+
var init_errors2 = __esm(() => {
|
|
2163
2758
|
DatasourceCliError = class DatasourceCliError extends Error {
|
|
2164
2759
|
datasourceId;
|
|
2165
2760
|
command;
|
|
@@ -2275,7 +2870,7 @@ var init_source_paths = __esm(() => {
|
|
|
2275
2870
|
});
|
|
2276
2871
|
|
|
2277
2872
|
// src/mirror/paths.ts
|
|
2278
|
-
import { createHash as
|
|
2873
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
2279
2874
|
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
2280
2875
|
import { join as join5 } from "node:path";
|
|
2281
2876
|
function parsedMirrorRoot(root) {
|
|
@@ -2285,7 +2880,7 @@ function parsedMirrorIndexPath(root) {
|
|
|
2285
2880
|
return join5(parsedMirrorRoot(root), PARSED_INDEX_FILE);
|
|
2286
2881
|
}
|
|
2287
2882
|
function parsedOutputPath(root, virtualPath) {
|
|
2288
|
-
const digest =
|
|
2883
|
+
const digest = createHash3("sha256").update(virtualPath).digest("hex");
|
|
2289
2884
|
return join5(parsedMirrorRoot(root), PARSED_FILES_SUBDIR, `${digest}.md`);
|
|
2290
2885
|
}
|
|
2291
2886
|
function refreshReadinessPath(root) {
|
|
@@ -2646,7 +3241,7 @@ function toResult(hit, source, mode, instanceId) {
|
|
|
2646
3241
|
};
|
|
2647
3242
|
}
|
|
2648
3243
|
var init_methods = __esm(() => {
|
|
2649
|
-
|
|
3244
|
+
init_errors2();
|
|
2650
3245
|
init_scope2();
|
|
2651
3246
|
});
|
|
2652
3247
|
|
|
@@ -2829,7 +3424,7 @@ function messageFrom(cause) {
|
|
|
2829
3424
|
return "unknown parser failure";
|
|
2830
3425
|
}
|
|
2831
3426
|
var ParseError;
|
|
2832
|
-
var
|
|
3427
|
+
var init_errors3 = __esm(() => {
|
|
2833
3428
|
ParseError = class ParseError extends Error {
|
|
2834
3429
|
parserName;
|
|
2835
3430
|
virtualPath;
|
|
@@ -2900,7 +3495,7 @@ function addressText(address) {
|
|
|
2900
3495
|
}
|
|
2901
3496
|
var EmlParser;
|
|
2902
3497
|
var init_eml = __esm(() => {
|
|
2903
|
-
|
|
3498
|
+
init_errors3();
|
|
2904
3499
|
init_text();
|
|
2905
3500
|
EmlParser = class EmlParser extends Parser {
|
|
2906
3501
|
name = "eml";
|
|
@@ -2957,7 +3552,7 @@ var KORDOC_EXTENSIONS, KORDOC_IMAGE_EXTENSIONS, defaultParse = async (bytes, opt
|
|
|
2957
3552
|
return { success: false, fileType: result.fileType, error: result.error, code: result.code };
|
|
2958
3553
|
}, KordocParser;
|
|
2959
3554
|
var init_kordoc = __esm(() => {
|
|
2960
|
-
|
|
3555
|
+
init_errors3();
|
|
2961
3556
|
KORDOC_EXTENSIONS = [".hwp", ".hwpx", ".hml", ".hwpml", ".pdf", ".docx", ".xlsx", ".xls"];
|
|
2962
3557
|
KORDOC_IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".webp"];
|
|
2963
3558
|
KordocParser = class KordocParser extends Parser {
|
|
@@ -3209,7 +3804,7 @@ var init_xml_text = __esm(() => {
|
|
|
3209
3804
|
// src/parser/office.ts
|
|
3210
3805
|
var PptxParser;
|
|
3211
3806
|
var init_office = __esm(() => {
|
|
3212
|
-
|
|
3807
|
+
init_errors3();
|
|
3213
3808
|
init_text();
|
|
3214
3809
|
init_xml_text();
|
|
3215
3810
|
PptxParser = class PptxParser extends Parser {
|
|
@@ -3782,7 +4377,7 @@ function bm25Scores(query, documents) {
|
|
|
3782
4377
|
}
|
|
3783
4378
|
|
|
3784
4379
|
// src/datasource/connector.ts
|
|
3785
|
-
import { createHash as
|
|
4380
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
3786
4381
|
function connectorFailureToDiagnosticCode(reason) {
|
|
3787
4382
|
switch (reason) {
|
|
3788
4383
|
case "auth":
|
|
@@ -3816,7 +4411,7 @@ function sanitizeIdSegment(value) {
|
|
|
3816
4411
|
const cleaned = normalized.slice(start, end);
|
|
3817
4412
|
if (cleaned === value && cleaned.length > 0 && cleaned.length <= 80)
|
|
3818
4413
|
return cleaned;
|
|
3819
|
-
const hash =
|
|
4414
|
+
const hash = createHash4("sha256").update(value).digest("hex").slice(0, 8);
|
|
3820
4415
|
const stem = cleaned.slice(0, 60);
|
|
3821
4416
|
return stem.length > 0 ? `${stem}-${hash}` : hash;
|
|
3822
4417
|
}
|
|
@@ -5015,7 +5610,7 @@ function toRetrievalResult(hit, source, methodName, instanceId, mode, diagnostic
|
|
|
5015
5610
|
}
|
|
5016
5611
|
var DISCORD_DATASOURCE_ID = "discord", DEFAULT_DISCORD_TAGS, DEFAULT_TOP_K2 = 20;
|
|
5017
5612
|
var init_methods2 = __esm(() => {
|
|
5018
|
-
|
|
5613
|
+
init_errors2();
|
|
5019
5614
|
init_scope2();
|
|
5020
5615
|
init_paths2();
|
|
5021
5616
|
DEFAULT_DISCORD_TAGS = ["discord", "chat", "pii"];
|
|
@@ -5313,7 +5908,7 @@ class GitHubConnector {
|
|
|
5313
5908
|
if (repos.length === 0)
|
|
5314
5909
|
return { ok: false, reason: "not-configured", message: "no repositories configured" };
|
|
5315
5910
|
const token = resolveToken(this.options.token, this.options.tokenEnv ?? DEFAULT_TOKEN_ENV);
|
|
5316
|
-
const baseUrl = this.options.baseUrl ??
|
|
5911
|
+
const baseUrl = this.options.baseUrl ?? DEFAULT_BASE_URL2;
|
|
5317
5912
|
const request = {
|
|
5318
5913
|
headers: {
|
|
5319
5914
|
Accept: "application/vnd.github+json",
|
|
@@ -5386,7 +5981,7 @@ ${body}` : title,
|
|
|
5386
5981
|
return { ok: true, documents, ...warnings.length > 0 ? { warnings } : {} };
|
|
5387
5982
|
}
|
|
5388
5983
|
}
|
|
5389
|
-
var
|
|
5984
|
+
var DEFAULT_BASE_URL2 = "https://api.github.com", DEFAULT_TOKEN_ENV = "GITHUB_TOKEN", DEFAULT_MAX_PAGES = 10, DEFAULT_MAX_DOCUMENTS2 = 500;
|
|
5390
5985
|
var init_connector2 = () => {};
|
|
5391
5986
|
|
|
5392
5987
|
// src/datasource/skills/github/skill.ts
|
|
@@ -5453,7 +6048,7 @@ class GitHubGistConnector {
|
|
|
5453
6048
|
message: "no GitHub token: set GITHUB_TOKEN (or connector.tokenEnv) or authenticate the gh CLI"
|
|
5454
6049
|
};
|
|
5455
6050
|
}
|
|
5456
|
-
const baseUrl = this.options.baseUrl ??
|
|
6051
|
+
const baseUrl = this.options.baseUrl ?? DEFAULT_BASE_URL3;
|
|
5457
6052
|
const request = {
|
|
5458
6053
|
headers: {
|
|
5459
6054
|
Accept: "application/vnd.github+json",
|
|
@@ -5602,15 +6197,15 @@ ${content}`);
|
|
|
5602
6197
|
}
|
|
5603
6198
|
};
|
|
5604
6199
|
}
|
|
5605
|
-
var
|
|
6200
|
+
var DEFAULT_BASE_URL3 = "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;
|
|
5606
6201
|
var init_connector3 = () => {};
|
|
5607
6202
|
|
|
5608
6203
|
// src/datasource/skills/github-gist/semantic.ts
|
|
5609
|
-
import { createHash as
|
|
6204
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
5610
6205
|
import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "node:fs";
|
|
5611
6206
|
import { dirname as dirname8 } from "node:path";
|
|
5612
6207
|
function contentHash(chunk) {
|
|
5613
|
-
return
|
|
6208
|
+
return createHash5("sha256").update(`${chunk.title ?? ""}
|
|
5614
6209
|
${chunk.content}`).digest("hex");
|
|
5615
6210
|
}
|
|
5616
6211
|
function sameIdentity(a, b) {
|
|
@@ -6593,7 +7188,7 @@ function isRemoteEmbedder(value) {
|
|
|
6593
7188
|
}
|
|
6594
7189
|
var CHAT_TAG = "lark:chat", DOCS_TAG = "lark:docs", DEFAULT_TAGS2, REMOTE_NOTE = "remote-search datasource: no local mirror";
|
|
6595
7190
|
var init_skill6 = __esm(() => {
|
|
6596
|
-
|
|
7191
|
+
init_errors2();
|
|
6597
7192
|
init_scope2();
|
|
6598
7193
|
init_client3();
|
|
6599
7194
|
DEFAULT_TAGS2 = [CHAT_TAG, DOCS_TAG];
|
|
@@ -7121,7 +7716,7 @@ function toRetrievalResult2(hit, source, methodName, instanceId, mode) {
|
|
|
7121
7716
|
}
|
|
7122
7717
|
var KAKAO_DATASOURCE_ID = "kakao", DEFAULT_KAKAO_TAGS, DEFAULT_TOP_K4 = 20;
|
|
7123
7718
|
var init_methods3 = __esm(() => {
|
|
7124
|
-
|
|
7719
|
+
init_errors2();
|
|
7125
7720
|
init_paths3();
|
|
7126
7721
|
DEFAULT_KAKAO_TAGS = ["kakaotalk", "personal", "pii"];
|
|
7127
7722
|
});
|
|
@@ -7516,7 +8111,7 @@ function ensurePrivateMailcrawlDataDir(path) {
|
|
|
7516
8111
|
if (process.platform !== "win32")
|
|
7517
8112
|
chmodSync(path, 448);
|
|
7518
8113
|
}
|
|
7519
|
-
var
|
|
8114
|
+
var init_config2 = () => {};
|
|
7520
8115
|
|
|
7521
8116
|
// src/datasource/skills/mailcrawl/client.ts
|
|
7522
8117
|
import { spawn as spawn7 } from "node:child_process";
|
|
@@ -7842,7 +8437,7 @@ function truncateUtf8(value, maxBytes) {
|
|
|
7842
8437
|
var DEFAULT_BINARY3 = "mailcrawl", DEFAULT_SEARCH_TIMEOUT_MS2 = 60000, DEFAULT_INDEX_TIMEOUT_MS = 1800000, DEFAULT_MAX_BUFFER_BYTES3 = 1048576, LOOPBACK_HOSTS, SAFE_ENV_KEYS2, SAFE_MAILCRAWL_ENV_KEYS, REMOTE_EMBEDDING_ENV_KEYS;
|
|
7843
8438
|
var init_client5 = __esm(() => {
|
|
7844
8439
|
init_portable_spawn();
|
|
7845
|
-
|
|
8440
|
+
init_config2();
|
|
7846
8441
|
LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "[::1]", "::1"]);
|
|
7847
8442
|
SAFE_ENV_KEYS2 = new Set(["HOME", "LANG", "LC_ALL", "PATH", "TMPDIR", "TMP", "TEMP", "NO_COLOR"]);
|
|
7848
8443
|
SAFE_MAILCRAWL_ENV_KEYS = new Set([
|
|
@@ -7941,7 +8536,7 @@ class MailcrawlMethod {
|
|
|
7941
8536
|
}
|
|
7942
8537
|
var modes, MAILCRAWL_MODES;
|
|
7943
8538
|
var init_methods4 = __esm(() => {
|
|
7944
|
-
|
|
8539
|
+
init_errors2();
|
|
7945
8540
|
init_scope2();
|
|
7946
8541
|
modes = ["bm25", "semantic", "hybrid"];
|
|
7947
8542
|
MAILCRAWL_MODES = modes;
|
|
@@ -8089,7 +8684,7 @@ var TAGS;
|
|
|
8089
8684
|
var init_skill9 = __esm(() => {
|
|
8090
8685
|
init_scope2();
|
|
8091
8686
|
init_client5();
|
|
8092
|
-
|
|
8687
|
+
init_config2();
|
|
8093
8688
|
init_methods4();
|
|
8094
8689
|
TAGS = ["mailcrawl", "email", "pii"];
|
|
8095
8690
|
});
|
|
@@ -8309,7 +8904,7 @@ function failureCode2(reason) {
|
|
|
8309
8904
|
}
|
|
8310
8905
|
var DEFAULT_INSTANCE_ID5 = "default", DEFAULT_POLLING_INTERVAL_MS4;
|
|
8311
8906
|
var init_crawler_skill = __esm(() => {
|
|
8312
|
-
|
|
8907
|
+
init_errors2();
|
|
8313
8908
|
init_scope2();
|
|
8314
8909
|
DEFAULT_POLLING_INTERVAL_MS4 = 15 * 60 * 1000;
|
|
8315
8910
|
});
|
|
@@ -8947,7 +9542,7 @@ function toRetrievalResult3(hit, source, methodName, instanceId, mode) {
|
|
|
8947
9542
|
}
|
|
8948
9543
|
var OBSIDIAN_DATASOURCE_ID = "obsidian", DEFAULT_OBSIDIAN_TAGS, DEFAULT_TOP_K5 = 20;
|
|
8949
9544
|
var init_methods5 = __esm(() => {
|
|
8950
|
-
|
|
9545
|
+
init_errors2();
|
|
8951
9546
|
init_scope2();
|
|
8952
9547
|
DEFAULT_OBSIDIAN_TAGS = ["obsidian", "notes"];
|
|
8953
9548
|
});
|
|
@@ -9485,7 +10080,7 @@ var init_slack = __esm(() => {
|
|
|
9485
10080
|
|
|
9486
10081
|
// src/datasource/skills/spotlight/connector.ts
|
|
9487
10082
|
import { spawn as spawn9 } from "node:child_process";
|
|
9488
|
-
import { createHash as
|
|
10083
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
9489
10084
|
import { readFile as fsReadFile, stat as stat4 } from "node:fs/promises";
|
|
9490
10085
|
import { basename as basename6, extname as extname4 } from "node:path";
|
|
9491
10086
|
|
|
@@ -9570,7 +10165,7 @@ class SpotlightConnector {
|
|
|
9570
10165
|
if (content.length === 0)
|
|
9571
10166
|
continue;
|
|
9572
10167
|
documents.push({
|
|
9573
|
-
docId:
|
|
10168
|
+
docId: createHash6("sha256").update(path).digest("hex").slice(0, 16),
|
|
9574
10169
|
hierarchy: ["files"],
|
|
9575
10170
|
title: basename6(path),
|
|
9576
10171
|
content,
|
|
@@ -11637,11 +12232,15 @@ function getModelRuntime(agentDir) {
|
|
|
11637
12232
|
const cached = modelRuntimeCache.get(agentDir);
|
|
11638
12233
|
if (cached !== undefined)
|
|
11639
12234
|
return cached;
|
|
11640
|
-
const created =
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
12235
|
+
const created = (async () => {
|
|
12236
|
+
const runtime = await ModelRuntime.create({
|
|
12237
|
+
authPath: join14(agentDir, "auth.json"),
|
|
12238
|
+
modelsPath: join14(agentDir, "models.json"),
|
|
12239
|
+
allowModelNetwork: false
|
|
12240
|
+
});
|
|
12241
|
+
await registerAutoRAGProvider(runtime);
|
|
12242
|
+
return runtime;
|
|
12243
|
+
})();
|
|
11645
12244
|
modelRuntimeCache.set(agentDir, created);
|
|
11646
12245
|
created.catch(() => {
|
|
11647
12246
|
modelRuntimeCache.delete(agentDir);
|
|
@@ -11970,8 +12569,9 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
11970
12569
|
}
|
|
11971
12570
|
}
|
|
11972
12571
|
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_PATTERN, 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;
|
|
11973
|
-
var
|
|
12572
|
+
var init_config3 = __esm(() => {
|
|
11974
12573
|
init_local_model();
|
|
12574
|
+
init_provider();
|
|
11975
12575
|
init_home();
|
|
11976
12576
|
init_factory();
|
|
11977
12577
|
init_file_lock();
|
|
@@ -12211,7 +12811,7 @@ function parseEmbedderFlags(flags) {
|
|
|
12211
12811
|
}
|
|
12212
12812
|
var init_init = __esm(() => {
|
|
12213
12813
|
init_language();
|
|
12214
|
-
|
|
12814
|
+
init_config3();
|
|
12215
12815
|
});
|
|
12216
12816
|
|
|
12217
12817
|
// src/minsync/embedder-config.ts
|
|
@@ -12531,7 +13131,7 @@ var init_setup = __esm(() => {
|
|
|
12531
13131
|
init_manifest();
|
|
12532
13132
|
init_file_lock();
|
|
12533
13133
|
init_embedder_config();
|
|
12534
|
-
|
|
13134
|
+
init_config3();
|
|
12535
13135
|
BUILTIN_BINARIES = {
|
|
12536
13136
|
kakao: "lazykatok",
|
|
12537
13137
|
lark: "lark-cli",
|
|
@@ -12589,7 +13189,7 @@ function renderSetup(report) {
|
|
|
12589
13189
|
}
|
|
12590
13190
|
var init_setup2 = __esm(() => {
|
|
12591
13191
|
init_embedding_runtime();
|
|
12592
|
-
|
|
13192
|
+
init_config3();
|
|
12593
13193
|
init_setup();
|
|
12594
13194
|
});
|
|
12595
13195
|
|
|
@@ -12767,7 +13367,7 @@ var init_dupey = __esm(() => {
|
|
|
12767
13367
|
});
|
|
12768
13368
|
|
|
12769
13369
|
// src/everything/bundle.ts
|
|
12770
|
-
import { createHash as
|
|
13370
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
12771
13371
|
import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync15, renameSync as renameSync4, rmSync as rmSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
12772
13372
|
import { dirname as dirname12, join as join17 } from "node:path";
|
|
12773
13373
|
import { fileURLToPath } from "node:url";
|
|
@@ -12885,7 +13485,7 @@ function writeAtomic(path, bytes) {
|
|
|
12885
13485
|
}
|
|
12886
13486
|
}
|
|
12887
13487
|
function sha256(bytes) {
|
|
12888
|
-
return
|
|
13488
|
+
return createHash7("sha256").update(bytes).digest("hex");
|
|
12889
13489
|
}
|
|
12890
13490
|
function errorMessage(error) {
|
|
12891
13491
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -12895,12 +13495,12 @@ var init_bundle = () => {};
|
|
|
12895
13495
|
|
|
12896
13496
|
// src/everything/client.ts
|
|
12897
13497
|
import { spawn as spawn11 } from "node:child_process";
|
|
12898
|
-
import { createHash as
|
|
13498
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
12899
13499
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync11 } from "node:fs";
|
|
12900
13500
|
import { join as join18, resolve as resolve9 } from "node:path";
|
|
12901
13501
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
12902
13502
|
function everythingInstanceName(root) {
|
|
12903
|
-
return `autorag-${
|
|
13503
|
+
return `autorag-${createHash8("sha256").update(resolve9(root).toLowerCase()).digest("hex").slice(0, 12)}`;
|
|
12904
13504
|
}
|
|
12905
13505
|
function buildEverythingIni(input) {
|
|
12906
13506
|
const list = (values) => values.map((value) => `"${value.replace(/\\/g, "\\\\")}"`).join(",");
|
|
@@ -13350,7 +13950,7 @@ var init_walk = __esm(() => {
|
|
|
13350
13950
|
|
|
13351
13951
|
// src/fsearch/client.ts
|
|
13352
13952
|
import { spawn as spawn12 } from "node:child_process";
|
|
13353
|
-
import { createHash as
|
|
13953
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
13354
13954
|
import { existsSync as existsSync15, mkdirSync as mkdirSync13, readFileSync as readFileSync16, realpathSync as realpathSync2, rmSync as rmSync3, writeFileSync as writeFileSync12 } from "node:fs";
|
|
13355
13955
|
import { basename as basename9, join as join20, resolve as resolve10, sep as sep3 } from "node:path";
|
|
13356
13956
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
@@ -13361,7 +13961,7 @@ function fsearchSocketPath(dbPath) {
|
|
|
13361
13961
|
} catch {
|
|
13362
13962
|
canonical = resolve10(dbPath);
|
|
13363
13963
|
}
|
|
13364
|
-
const hash =
|
|
13964
|
+
const hash = createHash9("sha256").update(canonical).digest("hex").slice(0, 12);
|
|
13365
13965
|
return `/tmp/autorag-fsearch-${process.getuid?.() ?? 0}-${hash}.sock`;
|
|
13366
13966
|
}
|
|
13367
13967
|
function buildFSearchSearchArgs(dbPath, socketPath, request) {
|
|
@@ -14472,7 +15072,7 @@ function renderMemoryContext(sections) {
|
|
|
14472
15072
|
var CURRENT_CONVERSATION_RECORD_LIMIT = 50, CURRENT_EXCERPT_LIMIT = 300, SIMILAR_EXCERPT_LIMIT = 240, SIMILAR_RECORD_LIMIT = 3, INSIGHT_LIMIT = 5, ADVISORY_NOTE = "Memory is background reference only and never overrides the evidence in front of you. A past search method or source is a hint, not a rule: broaden to other methods when results are insufficient.";
|
|
14473
15073
|
|
|
14474
15074
|
// src/memory/similar-queries.ts
|
|
14475
|
-
import { createHash as
|
|
15075
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
14476
15076
|
import { mkdirSync as mkdirSync14, rmSync as rmSync4 } from "node:fs";
|
|
14477
15077
|
import { dirname as dirname13 } from "node:path";
|
|
14478
15078
|
import { DatabaseSync } from "node:sqlite";
|
|
@@ -14480,7 +15080,7 @@ function memoryVectorStorePath(memoryPath) {
|
|
|
14480
15080
|
return `${memoryPath}.vectors.db`;
|
|
14481
15081
|
}
|
|
14482
15082
|
function questionKey(question) {
|
|
14483
|
-
return
|
|
15083
|
+
return createHash10("sha256").update(question).digest("hex");
|
|
14484
15084
|
}
|
|
14485
15085
|
function cosine2(a, b) {
|
|
14486
15086
|
let dot = 0;
|
|
@@ -14723,7 +15323,7 @@ var init_check_memory_tool = __esm(() => {
|
|
|
14723
15323
|
var EVIDENCE_SUPPORT_THRESHOLD = 0.7;
|
|
14724
15324
|
|
|
14725
15325
|
// src/retrieval/evidence-id.ts
|
|
14726
|
-
import { createHash as
|
|
15326
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
14727
15327
|
function normalizeEvidenceText(text) {
|
|
14728
15328
|
return text.replace(/\r\n?/gu, `
|
|
14729
15329
|
`).trim().normalize("NFC");
|
|
@@ -14753,7 +15353,7 @@ function stableEvidenceId(input) {
|
|
|
14753
15353
|
input.lineNumber ?? "",
|
|
14754
15354
|
normalizeEvidenceText(evidenceText)
|
|
14755
15355
|
].join("\x00");
|
|
14756
|
-
const digest =
|
|
15356
|
+
const digest = createHash11("sha256").update(payload).digest("hex").slice(0, 24);
|
|
14757
15357
|
return `${method}:${digest}`;
|
|
14758
15358
|
}
|
|
14759
15359
|
function normalizeEvidenceRef(input) {
|
|
@@ -14765,7 +15365,7 @@ function normalizeEvidenceRef(input) {
|
|
|
14765
15365
|
var init_evidence_id = () => {};
|
|
14766
15366
|
|
|
14767
15367
|
// src/memory/memory.ts
|
|
14768
|
-
import { createHash as
|
|
15368
|
+
import { createHash as createHash12, randomUUID as randomUUID4 } from "node:crypto";
|
|
14769
15369
|
import { existsSync as existsSync19, mkdirSync as mkdirSync15, readFileSync as readFileSync18, renameSync as renameSync5, unlinkSync as unlinkSync3, writeFileSync as writeFileSync13 } from "node:fs";
|
|
14770
15370
|
import { dirname as dirname14 } from "node:path";
|
|
14771
15371
|
import { z } from "zod";
|
|
@@ -14855,7 +15455,7 @@ function normalizeEvidenceChunkRecord(record) {
|
|
|
14855
15455
|
return { ...base, ...normalizeEvidenceContext(record) };
|
|
14856
15456
|
}
|
|
14857
15457
|
function hashText(value) {
|
|
14858
|
-
return
|
|
15458
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
14859
15459
|
}
|
|
14860
15460
|
function resultId(sessionId, number) {
|
|
14861
15461
|
return `${sessionId}:${number}`;
|
|
@@ -15297,7 +15897,7 @@ function minSyncInstallFailedError(cause) {
|
|
|
15297
15897
|
return new MinSyncRequiredError(`MinSync is required but installing the \`minsync\` binary failed: ${detail}. ` + "Install it manually with `cargo install minsync`.");
|
|
15298
15898
|
}
|
|
15299
15899
|
var MinSyncRequiredError;
|
|
15300
|
-
var
|
|
15900
|
+
var init_errors4 = __esm(() => {
|
|
15301
15901
|
MinSyncRequiredError = class MinSyncRequiredError extends Error {
|
|
15302
15902
|
constructor(message) {
|
|
15303
15903
|
super(message);
|
|
@@ -15733,7 +16333,7 @@ function isRecord11(value) {
|
|
|
15733
16333
|
var MINSYNC_OLLAMA_MIGRATION_MESSAGE = "This workspace uses the legacy 768-dimensional Ollama/TEI embedding path. Reindex explicitly, or pin an explicit profile config before using the new default runtime.", API_KEY_ENV_PATTERN2, MinSyncQueryError;
|
|
15734
16334
|
var init_client10 = __esm(() => {
|
|
15735
16335
|
init_embedder_config();
|
|
15736
|
-
|
|
16336
|
+
init_errors4();
|
|
15737
16337
|
init_local_embedder();
|
|
15738
16338
|
init_process();
|
|
15739
16339
|
API_KEY_ENV_PATTERN2 = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -15755,7 +16355,7 @@ var init_client10 = __esm(() => {
|
|
|
15755
16355
|
});
|
|
15756
16356
|
|
|
15757
16357
|
// src/minsync/installer.ts
|
|
15758
|
-
import { createHash as
|
|
16358
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
15759
16359
|
import { copyFileSync, createWriteStream as createWriteStream2, existsSync as existsSync21, mkdirSync as mkdirSync16, renameSync as renameSync6, rmSync as rmSync5 } from "node:fs";
|
|
15760
16360
|
import { chmod as chmod2, mkdtemp } from "node:fs/promises";
|
|
15761
16361
|
import { get } from "node:https";
|
|
@@ -15861,7 +16461,7 @@ async function downloadFile(url, destination) {
|
|
|
15861
16461
|
await pipeline(await openHttps(url), createWriteStream2(destination));
|
|
15862
16462
|
}
|
|
15863
16463
|
async function verifySha256(path, expected) {
|
|
15864
|
-
const hash =
|
|
16464
|
+
const hash = createHash13("sha256");
|
|
15865
16465
|
const stream = await import("node:fs").then((fs) => fs.createReadStream(path));
|
|
15866
16466
|
await pipeline(stream, hash);
|
|
15867
16467
|
const actual = hash.digest("hex");
|
|
@@ -15974,7 +16574,7 @@ function isGitHubAsset(value) {
|
|
|
15974
16574
|
function isRecord12(value) {
|
|
15975
16575
|
return typeof value === "object" && value !== null;
|
|
15976
16576
|
}
|
|
15977
|
-
var LATEST_RELEASE_URL = "https://api.github.com/repos/NomaDamas/MinSync/releases/latest", SHA256_HEX_PATTERN, MINSYNC_VERSION = "0.4.
|
|
16577
|
+
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;
|
|
15978
16578
|
var init_installer2 = __esm(() => {
|
|
15979
16579
|
init_process();
|
|
15980
16580
|
SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/;
|
|
@@ -16340,7 +16940,7 @@ var init_method = __esm(() => {
|
|
|
16340
16940
|
init_embedding_runtime();
|
|
16341
16941
|
init_scope();
|
|
16342
16942
|
init_client10();
|
|
16343
|
-
|
|
16943
|
+
init_errors4();
|
|
16344
16944
|
init_installer2();
|
|
16345
16945
|
init_paths5();
|
|
16346
16946
|
init_workspace();
|
|
@@ -16366,7 +16966,7 @@ var init_method = __esm(() => {
|
|
|
16366
16966
|
var init_minsync = __esm(() => {
|
|
16367
16967
|
init_client10();
|
|
16368
16968
|
init_embedder_config();
|
|
16369
|
-
|
|
16969
|
+
init_errors4();
|
|
16370
16970
|
init_installer2();
|
|
16371
16971
|
init_local_embedder();
|
|
16372
16972
|
init_method();
|
|
@@ -16688,7 +17288,7 @@ var DEFAULT_MAX_SOURCE_BYTES, MIRROR_CHECKPOINT_EVERY = 25, PRODUCT_ARTIFACT_FIL
|
|
|
16688
17288
|
var init_sync = __esm(() => {
|
|
16689
17289
|
init_source_paths();
|
|
16690
17290
|
init_defaults();
|
|
16691
|
-
|
|
17291
|
+
init_errors3();
|
|
16692
17292
|
init_text();
|
|
16693
17293
|
init_index_store();
|
|
16694
17294
|
init_paths();
|
|
@@ -17372,7 +17972,7 @@ var init_simplex_transport = __esm(() => {
|
|
|
17372
17972
|
var init_parser = __esm(() => {
|
|
17373
17973
|
init_defaults();
|
|
17374
17974
|
init_eml();
|
|
17375
|
-
|
|
17975
|
+
init_errors3();
|
|
17376
17976
|
init_kordoc();
|
|
17377
17977
|
init_ocr_engines();
|
|
17378
17978
|
init_office();
|
|
@@ -17515,7 +18115,7 @@ class ParallelRetriever {
|
|
|
17515
18115
|
}
|
|
17516
18116
|
var SAME_SOURCE_CORROBORATION_BONUS = 0.15, MAX_CORROBORATION_BONUS = 0.3;
|
|
17517
18117
|
var init_merger = __esm(() => {
|
|
17518
|
-
|
|
18118
|
+
init_errors4();
|
|
17519
18119
|
init_skip();
|
|
17520
18120
|
});
|
|
17521
18121
|
|
|
@@ -17767,13 +18367,403 @@ var init_model_auth = __esm(() => {
|
|
|
17767
18367
|
};
|
|
17768
18368
|
});
|
|
17769
18369
|
|
|
17770
|
-
// src/agent/
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
|
|
17775
|
-
|
|
17776
|
-
|
|
18370
|
+
// src/agent/citations.ts
|
|
18371
|
+
function isAsciiDigit(code) {
|
|
18372
|
+
return code >= 48 && code <= 57;
|
|
18373
|
+
}
|
|
18374
|
+
function digitsEndAt(text, from) {
|
|
18375
|
+
let end = from;
|
|
18376
|
+
while (end < text.length && isAsciiDigit(text.charCodeAt(end)))
|
|
18377
|
+
end += 1;
|
|
18378
|
+
return end;
|
|
18379
|
+
}
|
|
18380
|
+
function continuesAsProse(answer, from) {
|
|
18381
|
+
if (answer[from] !== " " && answer[from] !== " ")
|
|
18382
|
+
return false;
|
|
18383
|
+
const next = answer.codePointAt(from + 1);
|
|
18384
|
+
return next !== undefined && /[\p{L}\p{N}]/u.test(String.fromCodePoint(next));
|
|
18385
|
+
}
|
|
18386
|
+
function evidenceMarkerAt(answer, index) {
|
|
18387
|
+
const ids = [];
|
|
18388
|
+
let cursor = index + 1;
|
|
18389
|
+
for (;; ) {
|
|
18390
|
+
if (answer[cursor] !== "e")
|
|
18391
|
+
return;
|
|
18392
|
+
const digitsEnd = digitsEndAt(answer, cursor + 1);
|
|
18393
|
+
if (digitsEnd === cursor + 1)
|
|
18394
|
+
return;
|
|
18395
|
+
ids.push(answer.slice(cursor, digitsEnd));
|
|
18396
|
+
cursor = digitsEnd;
|
|
18397
|
+
if (answer[cursor] === "]")
|
|
18398
|
+
return { ids, end: cursor + 1 };
|
|
18399
|
+
if (answer[cursor] !== ",")
|
|
18400
|
+
return;
|
|
18401
|
+
cursor += 1;
|
|
18402
|
+
while (answer[cursor] === " " || answer[cursor] === "\t")
|
|
18403
|
+
cursor += 1;
|
|
18404
|
+
}
|
|
18405
|
+
}
|
|
18406
|
+
function filePathFrom(raw) {
|
|
18407
|
+
const trimmed = raw.trim();
|
|
18408
|
+
return trimmed.startsWith("<") && trimmed.endsWith(">") ? trimmed.slice(1, -1).trim() : trimmed;
|
|
18409
|
+
}
|
|
18410
|
+
function fileMarkerAt(answer, index, isFile) {
|
|
18411
|
+
if (!answer.startsWith(FILE_MARKER_PREFIX, index))
|
|
18412
|
+
return;
|
|
18413
|
+
const bodyStart = index + FILE_MARKER_PREFIX.length;
|
|
18414
|
+
let closer = answer.indexOf("]", bodyStart);
|
|
18415
|
+
for (let attempt = 0;closer !== -1 && attempt < MAX_FILE_MARKER_CLOSERS; attempt++) {
|
|
18416
|
+
const path = filePathFrom(answer.slice(bodyStart, closer));
|
|
18417
|
+
if (path.length > 0 && isFile(path))
|
|
18418
|
+
return { path, end: closer + 1 };
|
|
18419
|
+
closer = answer.indexOf("]", closer + 1);
|
|
18420
|
+
}
|
|
18421
|
+
return;
|
|
18422
|
+
}
|
|
18423
|
+
function answerMarkers(answer, isFile = () => false) {
|
|
18424
|
+
const markers = [];
|
|
18425
|
+
let floor = 0;
|
|
18426
|
+
let closeIndex = -1;
|
|
18427
|
+
let index = 0;
|
|
18428
|
+
const leadingStart = (from) => {
|
|
18429
|
+
let start = from;
|
|
18430
|
+
while (start > floor && (answer[start - 1] === " " || answer[start - 1] === "\t"))
|
|
18431
|
+
start -= 1;
|
|
18432
|
+
return start;
|
|
18433
|
+
};
|
|
18434
|
+
while (index < answer.length) {
|
|
18435
|
+
const char = answer[index];
|
|
18436
|
+
if (char === "(" && answer[index + 1] === "<") {
|
|
18437
|
+
if (closeIndex < index + 2) {
|
|
18438
|
+
const found = answer.indexOf(">", index + 2);
|
|
18439
|
+
closeIndex = found === -1 ? answer.length : found;
|
|
18440
|
+
}
|
|
18441
|
+
if (answer[closeIndex + 1] === ")") {
|
|
18442
|
+
index = closeIndex + 2;
|
|
18443
|
+
floor = index;
|
|
18444
|
+
continue;
|
|
18445
|
+
}
|
|
18446
|
+
index += 1;
|
|
18447
|
+
continue;
|
|
18448
|
+
}
|
|
18449
|
+
if (char === "[") {
|
|
18450
|
+
const digitsEnd = digitsEndAt(answer, index + 1);
|
|
18451
|
+
if (digitsEnd > index + 1 && answer[digitsEnd] === "]" && answer[digitsEnd + 1] !== "(" && !continuesAsProse(answer, digitsEnd + 1)) {
|
|
18452
|
+
markers.push({
|
|
18453
|
+
kind: "number",
|
|
18454
|
+
start: leadingStart(index),
|
|
18455
|
+
end: digitsEnd + 1,
|
|
18456
|
+
number: Number(answer.slice(index + 1, digitsEnd))
|
|
18457
|
+
});
|
|
18458
|
+
index = digitsEnd + 1;
|
|
18459
|
+
floor = index;
|
|
18460
|
+
continue;
|
|
18461
|
+
}
|
|
18462
|
+
const evidence = evidenceMarkerAt(answer, index);
|
|
18463
|
+
if (evidence !== undefined && answer[evidence.end] !== "(") {
|
|
18464
|
+
markers.push({ kind: "evidence", start: leadingStart(index), end: evidence.end, ids: evidence.ids });
|
|
18465
|
+
index = evidence.end;
|
|
18466
|
+
floor = index;
|
|
18467
|
+
continue;
|
|
18468
|
+
}
|
|
18469
|
+
const file = fileMarkerAt(answer, index, isFile);
|
|
18470
|
+
if (file !== undefined && answer[file.end] !== "(") {
|
|
18471
|
+
markers.push({ kind: "file", start: leadingStart(index), end: file.end, path: file.path });
|
|
18472
|
+
index = file.end;
|
|
18473
|
+
floor = index;
|
|
18474
|
+
continue;
|
|
18475
|
+
}
|
|
18476
|
+
}
|
|
18477
|
+
index += 1;
|
|
18478
|
+
}
|
|
18479
|
+
return markers;
|
|
18480
|
+
}
|
|
18481
|
+
function stripUnresolvedCitations(answer, results) {
|
|
18482
|
+
const known = new Set(results.map((result) => result.number));
|
|
18483
|
+
const unresolved = new Set;
|
|
18484
|
+
let stripped = "";
|
|
18485
|
+
let cursor = 0;
|
|
18486
|
+
for (const marker of answerMarkers(answer)) {
|
|
18487
|
+
if (marker.kind !== "number" || known.has(marker.number))
|
|
18488
|
+
continue;
|
|
18489
|
+
unresolved.add(marker.number);
|
|
18490
|
+
stripped += answer.slice(cursor, marker.start);
|
|
18491
|
+
cursor = marker.end;
|
|
18492
|
+
}
|
|
18493
|
+
if (unresolved.size === 0)
|
|
18494
|
+
return { answer, unresolved: [] };
|
|
18495
|
+
return { answer: stripped + answer.slice(cursor), unresolved: [...unresolved].sort((a, b) => a - b) };
|
|
18496
|
+
}
|
|
18497
|
+
function formatCitationList(numbers) {
|
|
18498
|
+
return numbers.length === 0 ? "none" : numbers.map((number) => `[${number}]`).join(", ");
|
|
18499
|
+
}
|
|
18500
|
+
function duplicateNumbers(sortedNumbers) {
|
|
18501
|
+
const duplicates = [];
|
|
18502
|
+
for (let index = 1;index < sortedNumbers.length; index++) {
|
|
18503
|
+
const number = sortedNumbers[index];
|
|
18504
|
+
if (number === sortedNumbers[index - 1] && duplicates[duplicates.length - 1] !== number)
|
|
18505
|
+
duplicates.push(number);
|
|
18506
|
+
}
|
|
18507
|
+
return duplicates;
|
|
18508
|
+
}
|
|
18509
|
+
function assertResultsMappingOneToOne(label, results, mapping) {
|
|
18510
|
+
const resultNumbers = results.map((result) => result.number).sort((a, b) => a - b);
|
|
18511
|
+
const mappingNumbers = mapping.map((entry) => entry.number).sort((a, b) => a - b);
|
|
18512
|
+
const resultDuplicates = duplicateNumbers(resultNumbers);
|
|
18513
|
+
const mappingDuplicates = duplicateNumbers(mappingNumbers);
|
|
18514
|
+
const sameNumbers = resultNumbers.length === mappingNumbers.length && resultNumbers.every((number, index) => number === mappingNumbers[index]);
|
|
18515
|
+
if (sameNumbers && resultDuplicates.length === 0 && mappingDuplicates.length === 0)
|
|
18516
|
+
return;
|
|
18517
|
+
const duplicateNotes = [
|
|
18518
|
+
resultDuplicates.length > 0 ? `results repeat ${formatCitationList(resultDuplicates)}` : undefined,
|
|
18519
|
+
mappingDuplicates.length > 0 ? `mapping repeats ${formatCitationList(mappingDuplicates)}` : undefined
|
|
18520
|
+
].filter((note) => note !== undefined);
|
|
18521
|
+
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.");
|
|
18522
|
+
}
|
|
18523
|
+
var MAX_FILE_MARKER_CLOSERS = 8, FILE_MARKER_PREFIX = "[file:";
|
|
18524
|
+
|
|
18525
|
+
// src/agent/evidence-ledger.ts
|
|
18526
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
18527
|
+
import { closeSync as closeSync2, openSync as openSync2, readSync, statSync } from "node:fs";
|
|
18528
|
+
import { isAbsolute as isAbsolute9 } from "node:path";
|
|
18529
|
+
function metadataString(metadata, key) {
|
|
18530
|
+
const value = metadata[key];
|
|
18531
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
18532
|
+
}
|
|
18533
|
+
function metadataNumber(metadata, key) {
|
|
18534
|
+
const value = metadata[key];
|
|
18535
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
18536
|
+
}
|
|
18537
|
+
function isRegularFile2(path) {
|
|
18538
|
+
try {
|
|
18539
|
+
return statSync(path).isFile();
|
|
18540
|
+
} catch {
|
|
18541
|
+
return false;
|
|
18542
|
+
}
|
|
18543
|
+
}
|
|
18544
|
+
function readFileExcerpt(path) {
|
|
18545
|
+
let descriptor;
|
|
18546
|
+
try {
|
|
18547
|
+
descriptor = openSync2(path, "r");
|
|
18548
|
+
const buffer = Buffer.alloc(MAX_CONTENT_CHARS4 * 4);
|
|
18549
|
+
const bytes = readSync(descriptor, buffer, 0, buffer.length, 0);
|
|
18550
|
+
const head = buffer.subarray(0, bytes);
|
|
18551
|
+
return head.includes(0) ? path : head.toString("utf8").slice(0, MAX_CONTENT_CHARS4);
|
|
18552
|
+
} catch {
|
|
18553
|
+
return path;
|
|
18554
|
+
} finally {
|
|
18555
|
+
if (descriptor !== undefined)
|
|
18556
|
+
closeSync2(descriptor);
|
|
18557
|
+
}
|
|
18558
|
+
}
|
|
18559
|
+
function toEvidenceRef(entry) {
|
|
18560
|
+
return {
|
|
18561
|
+
method: entry.method,
|
|
18562
|
+
source: entry.source,
|
|
18563
|
+
content: entry.content,
|
|
18564
|
+
retrieverMix: [...entry.retrieverMix],
|
|
18565
|
+
...entry.retrievalResultId !== undefined ? { retrievalResultId: entry.retrievalResultId } : {},
|
|
18566
|
+
...entry.chunkIndex !== undefined ? { chunkIndex: entry.chunkIndex } : {},
|
|
18567
|
+
...entry.lineNumber !== undefined ? { lineNumber: entry.lineNumber } : {},
|
|
18568
|
+
...entry.parserType !== undefined ? { parserType: entry.parserType } : {},
|
|
18569
|
+
...entry.documentType !== undefined ? { documentType: entry.documentType } : {},
|
|
18570
|
+
...entry.documentArea !== undefined ? { documentArea: entry.documentArea } : {},
|
|
18571
|
+
...entry.evidenceType !== undefined ? { evidenceType: entry.evidenceType } : {},
|
|
18572
|
+
...entry.evidenceLocation !== undefined ? { evidenceLocation: entry.evidenceLocation } : {}
|
|
18573
|
+
};
|
|
18574
|
+
}
|
|
18575
|
+
|
|
18576
|
+
class EvidenceLedger {
|
|
18577
|
+
entries = [];
|
|
18578
|
+
byKey = new Map;
|
|
18579
|
+
byId = new Map;
|
|
18580
|
+
lastOrdinal = 0;
|
|
18581
|
+
register(input) {
|
|
18582
|
+
const content = input.content.slice(0, MAX_CONTENT_CHARS4);
|
|
18583
|
+
const digest = createHash14("sha256").update(input.content.replace(/\s+/gu, " ").trim()).digest("hex");
|
|
18584
|
+
const key = `${input.source}\x00${digest}`;
|
|
18585
|
+
const existing = this.byKey.get(key);
|
|
18586
|
+
if (existing !== undefined) {
|
|
18587
|
+
if (!existing.retrieverMix.includes(input.method))
|
|
18588
|
+
existing.retrieverMix.push(input.method);
|
|
18589
|
+
return existing.id;
|
|
18590
|
+
}
|
|
18591
|
+
const entry = {
|
|
18592
|
+
...input,
|
|
18593
|
+
content,
|
|
18594
|
+
id: `e${++this.lastOrdinal}`,
|
|
18595
|
+
retrieverMix: [input.method]
|
|
18596
|
+
};
|
|
18597
|
+
this.entries.push(entry);
|
|
18598
|
+
this.byKey.set(key, entry);
|
|
18599
|
+
this.byId.set(entry.id, entry);
|
|
18600
|
+
return entry.id;
|
|
18601
|
+
}
|
|
18602
|
+
registerResult(tool, result) {
|
|
18603
|
+
const metadata = result.metadata;
|
|
18604
|
+
const chunkIndex = metadataNumber(metadata, "chunkIndex");
|
|
18605
|
+
const lineNumber = metadataNumber(metadata, "lineNumber");
|
|
18606
|
+
const parserType = metadataString(metadata, "parserType");
|
|
18607
|
+
const documentType = metadataString(metadata, "documentType");
|
|
18608
|
+
const documentArea = metadataString(metadata, "documentArea");
|
|
18609
|
+
const evidenceType = metadataString(metadata, "evidenceType");
|
|
18610
|
+
const evidenceLocation = metadataString(metadata, "evidenceLocation");
|
|
18611
|
+
return this.register({
|
|
18612
|
+
method: metadataString(metadata, "method") ?? tool,
|
|
18613
|
+
source: result.source,
|
|
18614
|
+
content: result.content,
|
|
18615
|
+
retrievalResultId: result.id,
|
|
18616
|
+
...chunkIndex !== undefined ? { chunkIndex } : {},
|
|
18617
|
+
...lineNumber !== undefined ? { lineNumber } : {},
|
|
18618
|
+
...parserType !== undefined ? { parserType } : {},
|
|
18619
|
+
...documentType !== undefined ? { documentType } : {},
|
|
18620
|
+
...documentArea !== undefined ? { documentArea } : {},
|
|
18621
|
+
...evidenceType !== undefined ? { evidenceType } : {},
|
|
18622
|
+
...evidenceLocation !== undefined ? { evidenceLocation } : {}
|
|
18623
|
+
});
|
|
18624
|
+
}
|
|
18625
|
+
lookup(raw, options) {
|
|
18626
|
+
const trimmed = raw.trim();
|
|
18627
|
+
const ref = trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1).trim() : trimmed;
|
|
18628
|
+
const byId = this.byId.get(ref);
|
|
18629
|
+
if (byId !== undefined)
|
|
18630
|
+
return [toEvidenceRef(byId)];
|
|
18631
|
+
const bySource = this.entries.filter((entry) => entry.source === ref);
|
|
18632
|
+
if (bySource.length > 0)
|
|
18633
|
+
return bySource.map(toEvidenceRef);
|
|
18634
|
+
if (options.allowLocalFiles && isAbsolute9(ref) && isRegularFile2(ref)) {
|
|
18635
|
+
return [{ method: "bash", source: ref, content: readFileExcerpt(ref) }];
|
|
18636
|
+
}
|
|
18637
|
+
return [];
|
|
18638
|
+
}
|
|
18639
|
+
clear() {
|
|
18640
|
+
this.entries = [];
|
|
18641
|
+
this.byKey.clear();
|
|
18642
|
+
this.byId.clear();
|
|
18643
|
+
}
|
|
18644
|
+
}
|
|
18645
|
+
var MAX_CONTENT_CHARS4 = 2000;
|
|
18646
|
+
var init_evidence_ledger = () => {};
|
|
18647
|
+
|
|
18648
|
+
// src/agent/answer-citations.ts
|
|
18649
|
+
import { isAbsolute as isAbsolute10 } from "node:path";
|
|
18650
|
+
function claimBefore(text, end) {
|
|
18651
|
+
const window = text.slice(Math.max(0, end - CLAIM_LOOKBACK_CHARS), end);
|
|
18652
|
+
const lineStart = window.lastIndexOf(`
|
|
18653
|
+
`) + 1;
|
|
18654
|
+
const line = window.slice(lineStart).replace(EVIDENCE_MARKER_TEXT, "");
|
|
18655
|
+
let start = 0;
|
|
18656
|
+
for (let index = line.length - 2;index >= 0; index--) {
|
|
18657
|
+
if (SENTENCE_END.test(line.charAt(index)) && /\s/u.test(line.charAt(index + 1))) {
|
|
18658
|
+
start = index + 2;
|
|
18659
|
+
break;
|
|
18660
|
+
}
|
|
18661
|
+
}
|
|
18662
|
+
const claim = line.slice(start).replace(LEADING_LIST_MARK, "").replace(/\s+/gu, " ").trim();
|
|
18663
|
+
return claim.length > MAX_CLAIM_CHARS ? `${claim.slice(0, MAX_CLAIM_CHARS)}…` : claim;
|
|
18664
|
+
}
|
|
18665
|
+
function deriveResultsFromAnswer(text, ledger, options) {
|
|
18666
|
+
const isFile = (path) => options.allowLocalFiles && isAbsolute10(path) && isRegularFile2(path);
|
|
18667
|
+
const sources = new Map;
|
|
18668
|
+
const dropped = new Set;
|
|
18669
|
+
let answer = "";
|
|
18670
|
+
let cursor = 0;
|
|
18671
|
+
let lastEmitted;
|
|
18672
|
+
const cite = (reference, claimEnd) => {
|
|
18673
|
+
const refs = ledger.lookup(reference, options);
|
|
18674
|
+
const [primary] = refs;
|
|
18675
|
+
if (primary === undefined) {
|
|
18676
|
+
dropped.add(reference);
|
|
18677
|
+
return;
|
|
18678
|
+
}
|
|
18679
|
+
let cited = sources.get(primary.source);
|
|
18680
|
+
if (cited === undefined) {
|
|
18681
|
+
cited = { number: sources.size + 1, refs: [], chunkKeys: new Set, claim: claimBefore(text, claimEnd) };
|
|
18682
|
+
sources.set(primary.source, cited);
|
|
18683
|
+
}
|
|
18684
|
+
for (const ref of refs) {
|
|
18685
|
+
const chunkKey = `${ref.source}\x00${ref.content ?? ""}`;
|
|
18686
|
+
if (cited.chunkKeys.has(chunkKey))
|
|
18687
|
+
continue;
|
|
18688
|
+
cited.chunkKeys.add(chunkKey);
|
|
18689
|
+
cited.refs.push(ref);
|
|
18690
|
+
}
|
|
18691
|
+
return cited.number;
|
|
18692
|
+
};
|
|
18693
|
+
for (const marker of answerMarkers(text, isFile)) {
|
|
18694
|
+
answer += text.slice(cursor, marker.start);
|
|
18695
|
+
cursor = marker.end;
|
|
18696
|
+
if (marker.kind === "number") {
|
|
18697
|
+
dropped.add(`[${marker.number}]`);
|
|
18698
|
+
continue;
|
|
18699
|
+
}
|
|
18700
|
+
const references = marker.kind === "evidence" ? marker.ids : [`file:${marker.path}`];
|
|
18701
|
+
const numbers = [];
|
|
18702
|
+
for (const reference of references) {
|
|
18703
|
+
const number = cite(marker.kind === "file" ? marker.path : reference, marker.start);
|
|
18704
|
+
if (number !== undefined && !numbers.includes(number))
|
|
18705
|
+
numbers.push(number);
|
|
18706
|
+
}
|
|
18707
|
+
if (numbers.length === 0)
|
|
18708
|
+
continue;
|
|
18709
|
+
const adjacent = lastEmitted !== undefined && text.slice(lastEmitted.end, marker.start).trim() === "";
|
|
18710
|
+
const fresh = numbers.filter((number) => !(adjacent && lastEmitted?.number === number));
|
|
18711
|
+
lastEmitted = { number: numbers[numbers.length - 1], end: marker.end };
|
|
18712
|
+
if (fresh.length === 0)
|
|
18713
|
+
continue;
|
|
18714
|
+
const leading = LEADING_BLANK.exec(text.slice(marker.start, marker.end))?.[0] ?? "";
|
|
18715
|
+
answer += leading + fresh.map((number) => `[${number}]`).join("");
|
|
18716
|
+
}
|
|
18717
|
+
answer += text.slice(cursor);
|
|
18718
|
+
const results = [];
|
|
18719
|
+
const mapping = [];
|
|
18720
|
+
for (const [source, cited] of sources) {
|
|
18721
|
+
const [primary] = cited.refs;
|
|
18722
|
+
if (primary === undefined)
|
|
18723
|
+
continue;
|
|
18724
|
+
results.push({
|
|
18725
|
+
number: cited.number,
|
|
18726
|
+
title: source.split(/[\\/]/u).filter((part) => part.length > 0).pop() ?? source,
|
|
18727
|
+
summary: cited.claim,
|
|
18728
|
+
evidence: cited.refs.map((ref) => {
|
|
18729
|
+
const excerpt = (ref.content ?? "").replace(/\s+/gu, " ").trim().slice(0, MAX_EXCERPT_CHARS);
|
|
18730
|
+
return ref.lineNumber !== undefined ? { excerpt, lineNumber: ref.lineNumber } : { excerpt };
|
|
18731
|
+
})
|
|
18732
|
+
});
|
|
18733
|
+
mapping.push({
|
|
18734
|
+
number: cited.number,
|
|
18735
|
+
source,
|
|
18736
|
+
method: primary.method,
|
|
18737
|
+
content: primary.content ?? "",
|
|
18738
|
+
evidenceRefs: cited.refs
|
|
18739
|
+
});
|
|
18740
|
+
}
|
|
18741
|
+
const diagnostics = dropped.size === 0 ? [] : [
|
|
18742
|
+
{
|
|
18743
|
+
code: "citation-without-result",
|
|
18744
|
+
severity: "warning",
|
|
18745
|
+
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.`,
|
|
18746
|
+
source: "agent"
|
|
18747
|
+
}
|
|
18748
|
+
];
|
|
18749
|
+
return { details: { answer: answer.trim(), results, mapping, warnings: [] }, diagnostics };
|
|
18750
|
+
}
|
|
18751
|
+
var MAX_EXCERPT_CHARS = 400, MAX_CLAIM_CHARS = 280, CLAIM_LOOKBACK_CHARS = 600, SENTENCE_END, LEADING_LIST_MARK, EVIDENCE_MARKER_TEXT, LEADING_BLANK;
|
|
18752
|
+
var init_answer_citations = __esm(() => {
|
|
18753
|
+
init_evidence_ledger();
|
|
18754
|
+
SENTENCE_END = /[.!?。!?]/u;
|
|
18755
|
+
LEADING_LIST_MARK = /^[\s\-*•>]+/u;
|
|
18756
|
+
EVIDENCE_MARKER_TEXT = /\[(?:e\d+(?:,\s*)?)+\]|\[file:[^\]]*\]/gu;
|
|
18757
|
+
LEADING_BLANK = /^[ \t]*/u;
|
|
18758
|
+
});
|
|
18759
|
+
|
|
18760
|
+
// src/agent/answer-guidelines.ts
|
|
18761
|
+
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.";
|
|
18762
|
+
|
|
18763
|
+
// src/agent/datasource-skill.ts
|
|
18764
|
+
import { Type as Type2 } from "typebox";
|
|
18765
|
+
function escapeXml(value) {
|
|
18766
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
17777
18767
|
}
|
|
17778
18768
|
function formatSkillsListing(skills) {
|
|
17779
18769
|
const lines = [
|
|
@@ -17895,7 +18885,7 @@ function renderFamily(family) {
|
|
|
17895
18885
|
const members = family.members.length > 0 ? family.members : family.files.map((path) => ({ path }));
|
|
17896
18886
|
const lines = [` [${family.relation}] family ${family.id}: ${members.length} file(s)`];
|
|
17897
18887
|
for (const member of members.slice(0, MAX_RENDERED_MEMBERS)) {
|
|
17898
|
-
const path =
|
|
18888
|
+
const path = readString2(member, "path");
|
|
17899
18889
|
if (path === undefined)
|
|
17900
18890
|
continue;
|
|
17901
18891
|
lines.push(` - ${path}${formatMemberScores(member)}`);
|
|
@@ -17913,7 +18903,7 @@ function selectedCandidate(family) {
|
|
|
17913
18903
|
const top = ranked[0];
|
|
17914
18904
|
if (!isKeyedRecord(top))
|
|
17915
18905
|
return;
|
|
17916
|
-
const path =
|
|
18906
|
+
const path = readString2(top, "path");
|
|
17917
18907
|
if (path === undefined)
|
|
17918
18908
|
return;
|
|
17919
18909
|
const score = formatScore(readNumber(top, "score"));
|
|
@@ -17942,10 +18932,10 @@ function readReasons(source) {
|
|
|
17942
18932
|
const rendered = reasons.flatMap((reason) => {
|
|
17943
18933
|
if (!isKeyedRecord(reason))
|
|
17944
18934
|
return [];
|
|
17945
|
-
const name =
|
|
18935
|
+
const name = readString2(reason, "name");
|
|
17946
18936
|
if (name === undefined)
|
|
17947
18937
|
return [];
|
|
17948
|
-
const detail =
|
|
18938
|
+
const detail = readString2(reason, "detail");
|
|
17949
18939
|
return [detail === undefined ? name : `${name} — ${detail}`];
|
|
17950
18940
|
});
|
|
17951
18941
|
return rendered.length === 0 ? "" : `reason: ${rendered.join(", ")}`;
|
|
@@ -17953,7 +18943,7 @@ function readReasons(source) {
|
|
|
17953
18943
|
function isKeyedRecord(value) {
|
|
17954
18944
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17955
18945
|
}
|
|
17956
|
-
function
|
|
18946
|
+
function readString2(source, key) {
|
|
17957
18947
|
const value = source[key];
|
|
17958
18948
|
return typeof value === "string" ? value : undefined;
|
|
17959
18949
|
}
|
|
@@ -17969,230 +18959,8 @@ var init_dupey_tool = __esm(() => {
|
|
|
17969
18959
|
scanDuplicateDocumentsSchema = Type3.Object({});
|
|
17970
18960
|
});
|
|
17971
18961
|
|
|
17972
|
-
// src/agent/citations.ts
|
|
17973
|
-
function isAsciiDigit(code) {
|
|
17974
|
-
return code >= 48 && code <= 57;
|
|
17975
|
-
}
|
|
17976
|
-
function citationMarkers(answer) {
|
|
17977
|
-
const markers = [];
|
|
17978
|
-
let floor = 0;
|
|
17979
|
-
let closeIndex = -1;
|
|
17980
|
-
let index = 0;
|
|
17981
|
-
while (index < answer.length) {
|
|
17982
|
-
const char = answer[index];
|
|
17983
|
-
if (char === "(" && answer[index + 1] === "<") {
|
|
17984
|
-
if (closeIndex < index + 2) {
|
|
17985
|
-
const found = answer.indexOf(">", index + 2);
|
|
17986
|
-
closeIndex = found === -1 ? answer.length : found;
|
|
17987
|
-
}
|
|
17988
|
-
if (answer[closeIndex + 1] === ")") {
|
|
17989
|
-
index = closeIndex + 2;
|
|
17990
|
-
floor = index;
|
|
17991
|
-
continue;
|
|
17992
|
-
}
|
|
17993
|
-
index += 1;
|
|
17994
|
-
continue;
|
|
17995
|
-
}
|
|
17996
|
-
if (char === "[") {
|
|
17997
|
-
let digitsEnd = index + 1;
|
|
17998
|
-
while (digitsEnd < answer.length && isAsciiDigit(answer.charCodeAt(digitsEnd)))
|
|
17999
|
-
digitsEnd += 1;
|
|
18000
|
-
if (digitsEnd > index + 1 && answer[digitsEnd] === "]" && answer[digitsEnd + 1] !== "(") {
|
|
18001
|
-
let start = index;
|
|
18002
|
-
while (start > floor && (answer[start - 1] === " " || answer[start - 1] === "\t"))
|
|
18003
|
-
start -= 1;
|
|
18004
|
-
markers.push({ start, end: digitsEnd + 1, number: Number(answer.slice(index + 1, digitsEnd)) });
|
|
18005
|
-
index = digitsEnd + 1;
|
|
18006
|
-
floor = index;
|
|
18007
|
-
continue;
|
|
18008
|
-
}
|
|
18009
|
-
}
|
|
18010
|
-
index += 1;
|
|
18011
|
-
}
|
|
18012
|
-
return markers;
|
|
18013
|
-
}
|
|
18014
|
-
function unresolvedCitations(answer, results) {
|
|
18015
|
-
const known = new Set(results.map((result) => result.number));
|
|
18016
|
-
const unresolved = new Set;
|
|
18017
|
-
for (const marker of citationMarkers(answer)) {
|
|
18018
|
-
if (!known.has(marker.number))
|
|
18019
|
-
unresolved.add(marker.number);
|
|
18020
|
-
}
|
|
18021
|
-
return [...unresolved].sort((a, b) => a - b);
|
|
18022
|
-
}
|
|
18023
|
-
function stripUnresolvedCitations(answer, results) {
|
|
18024
|
-
const known = new Set(results.map((result) => result.number));
|
|
18025
|
-
const unresolved = new Set;
|
|
18026
|
-
let stripped = "";
|
|
18027
|
-
let cursor = 0;
|
|
18028
|
-
for (const marker of citationMarkers(answer)) {
|
|
18029
|
-
if (known.has(marker.number))
|
|
18030
|
-
continue;
|
|
18031
|
-
unresolved.add(marker.number);
|
|
18032
|
-
stripped += answer.slice(cursor, marker.start);
|
|
18033
|
-
cursor = marker.end;
|
|
18034
|
-
}
|
|
18035
|
-
if (unresolved.size === 0)
|
|
18036
|
-
return { answer, unresolved: [] };
|
|
18037
|
-
return { answer: stripped + answer.slice(cursor), unresolved: [...unresolved].sort((a, b) => a - b) };
|
|
18038
|
-
}
|
|
18039
|
-
function formatCitationList(numbers) {
|
|
18040
|
-
return numbers.length === 0 ? "none" : numbers.map((number) => `[${number}]`).join(", ");
|
|
18041
|
-
}
|
|
18042
|
-
function duplicateNumbers(sortedNumbers) {
|
|
18043
|
-
const duplicates = [];
|
|
18044
|
-
for (let index = 1;index < sortedNumbers.length; index++) {
|
|
18045
|
-
const number = sortedNumbers[index];
|
|
18046
|
-
if (number === sortedNumbers[index - 1] && duplicates[duplicates.length - 1] !== number)
|
|
18047
|
-
duplicates.push(number);
|
|
18048
|
-
}
|
|
18049
|
-
return duplicates;
|
|
18050
|
-
}
|
|
18051
|
-
function assertUniqueResultNumbers(label, results) {
|
|
18052
|
-
const duplicates = duplicateNumbers(results.map((result) => result.number).sort((a, b) => a - b));
|
|
18053
|
-
if (duplicates.length === 0)
|
|
18054
|
-
return;
|
|
18055
|
-
throw new Error(`${label}: result numbers must be unique, but results repeat ${formatCitationList(duplicates)}. Give every result its own number and re-emit.`);
|
|
18056
|
-
}
|
|
18057
|
-
function assertResultsMappingOneToOne(label, results, mapping) {
|
|
18058
|
-
const resultNumbers = results.map((result) => result.number).sort((a, b) => a - b);
|
|
18059
|
-
const mappingNumbers = mapping.map((entry) => entry.number).sort((a, b) => a - b);
|
|
18060
|
-
const resultDuplicates = duplicateNumbers(resultNumbers);
|
|
18061
|
-
const mappingDuplicates = duplicateNumbers(mappingNumbers);
|
|
18062
|
-
const sameNumbers = resultNumbers.length === mappingNumbers.length && resultNumbers.every((number, index) => number === mappingNumbers[index]);
|
|
18063
|
-
if (sameNumbers && resultDuplicates.length === 0 && mappingDuplicates.length === 0)
|
|
18064
|
-
return;
|
|
18065
|
-
const duplicateNotes = [
|
|
18066
|
-
resultDuplicates.length > 0 ? `results repeat ${formatCitationList(resultDuplicates)}` : undefined,
|
|
18067
|
-
mappingDuplicates.length > 0 ? `mapping repeats ${formatCitationList(mappingDuplicates)}` : undefined
|
|
18068
|
-
].filter((note) => note !== undefined);
|
|
18069
|
-
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.");
|
|
18070
|
-
}
|
|
18071
|
-
function assertCitationsResolve(label, answer, results) {
|
|
18072
|
-
const unresolved = unresolvedCitations(answer, results);
|
|
18073
|
-
if (unresolved.length === 0)
|
|
18074
|
-
return;
|
|
18075
|
-
const emitted = [...new Set(results.map((result) => result.number))].sort((a, b) => a - b);
|
|
18076
|
-
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.");
|
|
18077
|
-
}
|
|
18078
|
-
|
|
18079
|
-
// src/agent/emit-results-tool.ts
|
|
18080
|
-
import { Type as Type4 } from "typebox";
|
|
18081
|
-
function createEmitResultsTool(capture, options) {
|
|
18082
|
-
return {
|
|
18083
|
-
name: EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
18084
|
-
label: "Emit AutoRAG Results",
|
|
18085
|
-
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.",
|
|
18086
|
-
parameters: emitResultsSchema,
|
|
18087
|
-
async execute(_toolCallId, params) {
|
|
18088
|
-
assertCitationsResolve(EMIT_AUTORAG_RESULTS_TOOL_NAME, params.answer, params.results);
|
|
18089
|
-
assertUniqueResultNumbers(EMIT_AUTORAG_RESULTS_TOOL_NAME, params.results);
|
|
18090
|
-
const mapping = params.results.map((result) => {
|
|
18091
|
-
const evidenceRefs = options.ledger.resolve(result.refs, {
|
|
18092
|
-
label: EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
18093
|
-
number: result.number,
|
|
18094
|
-
fallbackContent: result.evidence.map((evidence) => evidence.excerpt).join(`
|
|
18095
|
-
`) || result.summary,
|
|
18096
|
-
allowLocalFiles: options.allowLocalFiles
|
|
18097
|
-
});
|
|
18098
|
-
const primary = evidenceRefs[0];
|
|
18099
|
-
if (primary === undefined) {
|
|
18100
|
-
throw new Error(`${EMIT_AUTORAG_RESULTS_TOOL_NAME}: result ${result.number} resolved no evidence. Give it at least one valid ref.`);
|
|
18101
|
-
}
|
|
18102
|
-
return {
|
|
18103
|
-
number: result.number,
|
|
18104
|
-
source: primary.source,
|
|
18105
|
-
method: primary.method,
|
|
18106
|
-
content: primary.content ?? "",
|
|
18107
|
-
evidenceRefs
|
|
18108
|
-
};
|
|
18109
|
-
});
|
|
18110
|
-
const details = {
|
|
18111
|
-
answer: params.answer,
|
|
18112
|
-
results: params.results.map((result) => ({
|
|
18113
|
-
number: result.number,
|
|
18114
|
-
title: result.title,
|
|
18115
|
-
summary: result.summary,
|
|
18116
|
-
evidence: result.evidence.map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
18117
|
-
confidence: result.confidence
|
|
18118
|
-
})),
|
|
18119
|
-
mapping,
|
|
18120
|
-
warnings: params.warnings ?? []
|
|
18121
|
-
};
|
|
18122
|
-
capture(details);
|
|
18123
|
-
return {
|
|
18124
|
-
content: [{ type: "text", text: "AutoRAG results emitted." }],
|
|
18125
|
-
details,
|
|
18126
|
-
terminate: true
|
|
18127
|
-
};
|
|
18128
|
-
}
|
|
18129
|
-
};
|
|
18130
|
-
}
|
|
18131
|
-
var EMIT_AUTORAG_RESULTS_TOOL_NAME = "emit_autorag_results", evidenceRefSchema, answerSchema, warningsSchema, curatedResultFields, emitResultsSchema, reportSchema;
|
|
18132
|
-
var init_emit_results_tool = __esm(() => {
|
|
18133
|
-
evidenceRefSchema = Type4.Object({
|
|
18134
|
-
method: Type4.String({ description: "Retrieval method namespace for this evidence chunk" }),
|
|
18135
|
-
source: Type4.String({ description: "Internal opaque source identifier for this evidence chunk" }),
|
|
18136
|
-
excerpt: Type4.Optional(Type4.String({ description: "Evidence excerpt used for stable ID normalization" })),
|
|
18137
|
-
content: Type4.Optional(Type4.String({ description: "Evidence content used for stable ID normalization" })),
|
|
18138
|
-
retrievalResultId: Type4.Optional(Type4.String({ description: "Backend retrieval ID when path-opaque and stable" })),
|
|
18139
|
-
chunkIndex: Type4.Optional(Type4.Integer({ description: "Chunk index, if available" })),
|
|
18140
|
-
lineNumber: Type4.Optional(Type4.Integer({ description: "Line number, if available" })),
|
|
18141
|
-
stableEvidenceId: Type4.Optional(Type4.String({ description: "Stable evidence ID, if already normalized" })),
|
|
18142
|
-
retrieverMix: Type4.Optional(Type4.Array(Type4.String({ maxLength: 64 }), {
|
|
18143
|
-
description: "Retrievers that contributed to this result",
|
|
18144
|
-
maxItems: 8
|
|
18145
|
-
})),
|
|
18146
|
-
parserType: Type4.Optional(Type4.String({ description: "Parser that produced this evidence", maxLength: 120 })),
|
|
18147
|
-
documentType: Type4.Optional(Type4.String({ description: "Document type, if known", maxLength: 120 })),
|
|
18148
|
-
documentArea: Type4.Optional(Type4.String({ description: "Document collection area, if known", maxLength: 120 })),
|
|
18149
|
-
evidenceType: Type4.Optional(Type4.String({ description: "Evidence type, if known", maxLength: 120 })),
|
|
18150
|
-
evidenceLocation: Type4.Optional(Type4.String({ description: "Human-readable evidence location", maxLength: 120 })),
|
|
18151
|
-
confidence: Type4.Optional(Type4.Number({ description: "Evidence confidence, 0..1", minimum: 0, maximum: 1 }))
|
|
18152
|
-
});
|
|
18153
|
-
answerSchema = Type4.String({
|
|
18154
|
-
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}`
|
|
18155
|
-
});
|
|
18156
|
-
warningsSchema = Type4.Optional(Type4.Array(Type4.String(), { description: "Optional warnings about this result set" }));
|
|
18157
|
-
curatedResultFields = {
|
|
18158
|
-
number: Type4.Integer({ description: "1-based result number" }),
|
|
18159
|
-
title: Type4.String({ description: "Short name of the curated knowledge unit" }),
|
|
18160
|
-
summary: Type4.String({ description: "Key insight: purpose, details, and line range" }),
|
|
18161
|
-
evidence: Type4.Array(Type4.Object({
|
|
18162
|
-
excerpt: Type4.String({ description: "Supporting excerpt" }),
|
|
18163
|
-
lineNumber: Type4.Optional(Type4.Integer({ description: "Line number of the excerpt, if known" }))
|
|
18164
|
-
})),
|
|
18165
|
-
confidence: Type4.Number({ description: "Confidence in this result, 0..1", minimum: 0, maximum: 1 })
|
|
18166
|
-
};
|
|
18167
|
-
emitResultsSchema = Type4.Object({
|
|
18168
|
-
answer: answerSchema,
|
|
18169
|
-
results: Type4.Array(Type4.Object({
|
|
18170
|
-
...curatedResultFields,
|
|
18171
|
-
refs: Type4.Array(Type4.String(), {
|
|
18172
|
-
minItems: 1,
|
|
18173
|
-
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."
|
|
18174
|
-
})
|
|
18175
|
-
}), { description: "Numbered curated knowledge units." }),
|
|
18176
|
-
warnings: warningsSchema
|
|
18177
|
-
});
|
|
18178
|
-
reportSchema = Type4.Object({
|
|
18179
|
-
answer: answerSchema,
|
|
18180
|
-
results: Type4.Array(Type4.Object(curatedResultFields), { description: "Numbered curated knowledge units." }),
|
|
18181
|
-
mapping: Type4.Array(Type4.Object({
|
|
18182
|
-
number: Type4.Integer({ description: "Matches the result number this entry maps" }),
|
|
18183
|
-
source: Type4.String({ description: "Source identifier — a real file path or a datasource id" }),
|
|
18184
|
-
method: Type4.String({ description: "Retrieval method or tool that produced the source" }),
|
|
18185
|
-
content: Type4.String({ description: "Raw content snippet of the evidence behind this result" }),
|
|
18186
|
-
evidenceRefs: Type4.Optional(Type4.Array(evidenceRefSchema, {
|
|
18187
|
-
description: "Hidden evidence chunk references supporting this curated result"
|
|
18188
|
-
}))
|
|
18189
|
-
}), { description: "Internal number -> source/method mapping. One entry per result number." }),
|
|
18190
|
-
warnings: warningsSchema
|
|
18191
|
-
});
|
|
18192
|
-
});
|
|
18193
|
-
|
|
18194
18962
|
// src/agent/everything-search-tool.ts
|
|
18195
|
-
import { Type as
|
|
18963
|
+
import { Type as Type4 } from "typebox";
|
|
18196
18964
|
function createEverythingSearchTool(provider) {
|
|
18197
18965
|
return {
|
|
18198
18966
|
name: EVERYTHING_SEARCH_TOOL_NAME,
|
|
@@ -18244,28 +19012,28 @@ ${lines.join(`
|
|
|
18244
19012
|
}
|
|
18245
19013
|
var EVERYTHING_SEARCH_TOOL_NAME = "everything_search", MAX_RESULTS_CAP2 = 1000, DEFAULT_MAX_RESULTS3 = 100, everythingSearchSchema;
|
|
18246
19014
|
var init_everything_search_tool = __esm(() => {
|
|
18247
|
-
everythingSearchSchema =
|
|
18248
|
-
query:
|
|
19015
|
+
everythingSearchSchema = Type4.Object({
|
|
19016
|
+
query: Type4.String({
|
|
18249
19017
|
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.'
|
|
18250
19018
|
}),
|
|
18251
|
-
regex:
|
|
18252
|
-
matchCase:
|
|
18253
|
-
matchPath:
|
|
18254
|
-
wholeWord:
|
|
18255
|
-
kind:
|
|
18256
|
-
path:
|
|
18257
|
-
sort:
|
|
18258
|
-
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
19019
|
+
regex: Type4.Optional(Type4.Boolean({ description: "Treat query as a regular expression." })),
|
|
19020
|
+
matchCase: Type4.Optional(Type4.Boolean()),
|
|
19021
|
+
matchPath: Type4.Optional(Type4.Boolean({ description: "Match against the full path instead of the name." })),
|
|
19022
|
+
wholeWord: Type4.Optional(Type4.Boolean()),
|
|
19023
|
+
kind: Type4.Optional(Type4.Union([Type4.Literal("files"), Type4.Literal("folders")])),
|
|
19024
|
+
path: Type4.Optional(Type4.String({ description: "Absolute folder to search within." })),
|
|
19025
|
+
sort: Type4.Optional(Type4.Union([
|
|
19026
|
+
Type4.Literal("name-ascending"),
|
|
19027
|
+
Type4.Literal("name-descending"),
|
|
19028
|
+
Type4.Literal("path-ascending"),
|
|
19029
|
+
Type4.Literal("path-descending"),
|
|
19030
|
+
Type4.Literal("size-ascending"),
|
|
19031
|
+
Type4.Literal("size-descending"),
|
|
19032
|
+
Type4.Literal("date-modified-ascending"),
|
|
19033
|
+
Type4.Literal("date-modified-descending")
|
|
18266
19034
|
])),
|
|
18267
|
-
offset:
|
|
18268
|
-
maxResults:
|
|
19035
|
+
offset: Type4.Optional(Type4.Integer({ minimum: 0, description: "Skip this many results (pagination)." })),
|
|
19036
|
+
maxResults: Type4.Optional(Type4.Integer({
|
|
18269
19037
|
minimum: 1,
|
|
18270
19038
|
description: `Maximum results (default ${DEFAULT_MAX_RESULTS3}, cap ${MAX_RESULTS_CAP2}).`
|
|
18271
19039
|
}))
|
|
@@ -18321,220 +19089,80 @@ function citesResult(sentence, marker) {
|
|
|
18321
19089
|
function boundExcerpt(excerpt) {
|
|
18322
19090
|
if (excerpt.length <= MAX_EVIDENCE_CHARACTERS)
|
|
18323
19091
|
return excerpt;
|
|
18324
|
-
return `${excerpt.slice(0, MAX_EVIDENCE_CHARACTERS - 1)}…`;
|
|
18325
|
-
}
|
|
18326
|
-
function describeState(input) {
|
|
18327
|
-
return [
|
|
18328
|
-
STATE_INSTRUCTION,
|
|
18329
|
-
`User question: ${JSON.stringify(input.question)}`,
|
|
18330
|
-
"Full answer (reference only):",
|
|
18331
|
-
input.answer
|
|
18332
|
-
].join(`
|
|
18333
|
-
`);
|
|
18334
|
-
}
|
|
18335
|
-
function evidenceQuestion(unit, input) {
|
|
18336
|
-
const sentences = answerSentencesCiting(input.answer, unit.resultNumber);
|
|
18337
|
-
const backed = sentences.length > 0 ? `the answer sentence it backs: ${sentences.map((sentence) => JSON.stringify(sentence)).join(" ")}` : `the claim that the answer never cites result [${unit.resultNumber}] (title ${JSON.stringify(unit.title)}, summary ${JSON.stringify(unit.summary)})`;
|
|
18338
|
-
return {
|
|
18339
|
-
...EVIDENCE_QUESTION,
|
|
18340
|
-
id: evidenceQuestionId(unit.id),
|
|
18341
|
-
question: [
|
|
18342
|
-
`Does the evidence below directly support ${backed} and is it needed to answer the user's question?`,
|
|
18343
|
-
`Search query that surfaced it: ${JSON.stringify(unit.searchQuery)}`,
|
|
18344
|
-
`Retrieval method: ${JSON.stringify(unit.method)}`,
|
|
18345
|
-
`Evidence: ${JSON.stringify(boundExcerpt(unit.excerpt))}`
|
|
18346
|
-
].join(`
|
|
18347
|
-
`)
|
|
18348
|
-
};
|
|
18349
|
-
}
|
|
18350
|
-
async function judgeEvidence(judge, input) {
|
|
18351
|
-
if (input.units.length === 0)
|
|
18352
|
-
return { probabilities: {}, kept: [] };
|
|
18353
|
-
let verdicts;
|
|
18354
|
-
try {
|
|
18355
|
-
verdicts = (await judge(describeState(input), input.units.map((unit) => evidenceQuestion(unit, input)))).verdicts;
|
|
18356
|
-
} catch (error) {
|
|
18357
|
-
return { probabilities: {}, kept: [], fallbackReason: error instanceof Error ? error.message : String(error) };
|
|
18358
|
-
}
|
|
18359
|
-
const byId = {};
|
|
18360
|
-
for (const verdict of verdicts)
|
|
18361
|
-
byId[verdict.id] = verdict;
|
|
18362
|
-
const probabilities = {};
|
|
18363
|
-
const kept = [];
|
|
18364
|
-
let firstHint;
|
|
18365
|
-
for (const unit of input.units) {
|
|
18366
|
-
const verdict = byId[evidenceQuestionId(unit.id)];
|
|
18367
|
-
if (typeof verdict?.answer !== "number") {
|
|
18368
|
-
firstHint ??= verdict?.hint;
|
|
18369
|
-
continue;
|
|
18370
|
-
}
|
|
18371
|
-
probabilities[unit.id] = verdict.answer;
|
|
18372
|
-
if (verdict.answer >= EVIDENCE_SUPPORT_THRESHOLD)
|
|
18373
|
-
kept.push(unit.id);
|
|
18374
|
-
}
|
|
18375
|
-
if (Object.keys(probabilities).length === 0) {
|
|
18376
|
-
return { probabilities, kept, fallbackReason: firstHint ?? NO_VERDICT_FALLBACK };
|
|
18377
|
-
}
|
|
18378
|
-
return { probabilities, kept };
|
|
18379
|
-
}
|
|
18380
|
-
var EVIDENCE_QUESTION_ID_PREFIX = "evidence:", NO_VERDICT_FALLBACK = "Jev returned no usable evidence verdict.", MAX_EVIDENCE_CHARACTERS = 1500, STATE_INSTRUCTION, EVIDENCE_QUESTION, SENTENCE_TERMINATORS;
|
|
18381
|
-
var init_evidence_judgment = __esm(() => {
|
|
18382
|
-
STATE_INSTRUCTION = [
|
|
18383
|
-
"Each question asks whether one piece of evidence really supports answering the user's question.",
|
|
18384
|
-
"Judge only that evidence against the sentence it backs; the full answer is shown for reference only."
|
|
18385
|
-
].join(" ");
|
|
18386
|
-
EVIDENCE_QUESTION = check("Does the evidence directly support the cited sentence and is it needed to answer the user's question?", {
|
|
18387
|
-
true: "The evidence states or confirms what the cited sentence claims about the user's question, and leaving it out would leave that claim unsupported.",
|
|
18388
|
-
false: "The evidence is unrelated, only loosely related, redundant noise, or contradicts the cited sentence."
|
|
18389
|
-
});
|
|
18390
|
-
SENTENCE_TERMINATORS = {
|
|
18391
|
-
".": true,
|
|
18392
|
-
"!": true,
|
|
18393
|
-
"?": true,
|
|
18394
|
-
"。": true,
|
|
18395
|
-
"!": true,
|
|
18396
|
-
"?": true
|
|
18397
|
-
};
|
|
18398
|
-
});
|
|
18399
|
-
|
|
18400
|
-
// src/agent/evidence-ledger.ts
|
|
18401
|
-
import { createHash as createHash13 } from "node:crypto";
|
|
18402
|
-
import { statSync } from "node:fs";
|
|
18403
|
-
import { isAbsolute as isAbsolute9 } from "node:path";
|
|
18404
|
-
function metadataString(metadata, key) {
|
|
18405
|
-
const value = metadata[key];
|
|
18406
|
-
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
18407
|
-
}
|
|
18408
|
-
function metadataNumber(metadata, key) {
|
|
18409
|
-
const value = metadata[key];
|
|
18410
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
18411
|
-
}
|
|
18412
|
-
function isRegularFile2(path) {
|
|
18413
|
-
try {
|
|
18414
|
-
return statSync(path).isFile();
|
|
18415
|
-
} catch {
|
|
18416
|
-
return false;
|
|
18417
|
-
}
|
|
18418
|
-
}
|
|
18419
|
-
function toEvidenceRef(entry) {
|
|
18420
|
-
return {
|
|
18421
|
-
method: entry.method,
|
|
18422
|
-
source: entry.source,
|
|
18423
|
-
content: entry.content,
|
|
18424
|
-
retrieverMix: [...entry.retrieverMix],
|
|
18425
|
-
...entry.retrievalResultId !== undefined ? { retrievalResultId: entry.retrievalResultId } : {},
|
|
18426
|
-
...entry.chunkIndex !== undefined ? { chunkIndex: entry.chunkIndex } : {},
|
|
18427
|
-
...entry.lineNumber !== undefined ? { lineNumber: entry.lineNumber } : {},
|
|
18428
|
-
...entry.parserType !== undefined ? { parserType: entry.parserType } : {},
|
|
18429
|
-
...entry.documentType !== undefined ? { documentType: entry.documentType } : {},
|
|
18430
|
-
...entry.documentArea !== undefined ? { documentArea: entry.documentArea } : {},
|
|
18431
|
-
...entry.evidenceType !== undefined ? { evidenceType: entry.evidenceType } : {},
|
|
18432
|
-
...entry.evidenceLocation !== undefined ? { evidenceLocation: entry.evidenceLocation } : {}
|
|
18433
|
-
};
|
|
18434
|
-
}
|
|
18435
|
-
|
|
18436
|
-
class EvidenceLedger {
|
|
18437
|
-
entries = [];
|
|
18438
|
-
byKey = new Map;
|
|
18439
|
-
byId = new Map;
|
|
18440
|
-
lastOrdinal = 0;
|
|
18441
|
-
register(input) {
|
|
18442
|
-
const content = input.content.slice(0, MAX_CONTENT_CHARS4);
|
|
18443
|
-
const digest = createHash13("sha256").update(input.content.replace(/\s+/gu, " ").trim()).digest("hex");
|
|
18444
|
-
const key = `${input.source}\x00${digest}`;
|
|
18445
|
-
const existing = this.byKey.get(key);
|
|
18446
|
-
if (existing !== undefined) {
|
|
18447
|
-
if (!existing.retrieverMix.includes(input.method))
|
|
18448
|
-
existing.retrieverMix.push(input.method);
|
|
18449
|
-
return existing.id;
|
|
18450
|
-
}
|
|
18451
|
-
const entry = {
|
|
18452
|
-
...input,
|
|
18453
|
-
content,
|
|
18454
|
-
id: `e${++this.lastOrdinal}`,
|
|
18455
|
-
retrieverMix: [input.method]
|
|
18456
|
-
};
|
|
18457
|
-
this.entries.push(entry);
|
|
18458
|
-
this.byKey.set(key, entry);
|
|
18459
|
-
this.byId.set(entry.id, entry);
|
|
18460
|
-
return entry.id;
|
|
18461
|
-
}
|
|
18462
|
-
registerResult(tool, result) {
|
|
18463
|
-
const metadata = result.metadata;
|
|
18464
|
-
const chunkIndex = metadataNumber(metadata, "chunkIndex");
|
|
18465
|
-
const lineNumber = metadataNumber(metadata, "lineNumber");
|
|
18466
|
-
const parserType = metadataString(metadata, "parserType");
|
|
18467
|
-
const documentType = metadataString(metadata, "documentType");
|
|
18468
|
-
const documentArea = metadataString(metadata, "documentArea");
|
|
18469
|
-
const evidenceType = metadataString(metadata, "evidenceType");
|
|
18470
|
-
const evidenceLocation = metadataString(metadata, "evidenceLocation");
|
|
18471
|
-
return this.register({
|
|
18472
|
-
method: metadataString(metadata, "method") ?? tool,
|
|
18473
|
-
source: result.source,
|
|
18474
|
-
content: result.content,
|
|
18475
|
-
retrievalResultId: result.id,
|
|
18476
|
-
...chunkIndex !== undefined ? { chunkIndex } : {},
|
|
18477
|
-
...lineNumber !== undefined ? { lineNumber } : {},
|
|
18478
|
-
...parserType !== undefined ? { parserType } : {},
|
|
18479
|
-
...documentType !== undefined ? { documentType } : {},
|
|
18480
|
-
...documentArea !== undefined ? { documentArea } : {},
|
|
18481
|
-
...evidenceType !== undefined ? { evidenceType } : {},
|
|
18482
|
-
...evidenceLocation !== undefined ? { evidenceLocation } : {}
|
|
18483
|
-
});
|
|
19092
|
+
return `${excerpt.slice(0, MAX_EVIDENCE_CHARACTERS - 1)}…`;
|
|
19093
|
+
}
|
|
19094
|
+
function describeState(input) {
|
|
19095
|
+
return [
|
|
19096
|
+
STATE_INSTRUCTION,
|
|
19097
|
+
`User question: ${JSON.stringify(input.question)}`,
|
|
19098
|
+
"Full answer (reference only):",
|
|
19099
|
+
input.answer
|
|
19100
|
+
].join(`
|
|
19101
|
+
`);
|
|
19102
|
+
}
|
|
19103
|
+
function evidenceQuestion(unit, input) {
|
|
19104
|
+
const sentences = answerSentencesCiting(input.answer, unit.resultNumber);
|
|
19105
|
+
const backed = sentences.length > 0 ? `the answer sentence it backs: ${sentences.map((sentence) => JSON.stringify(sentence)).join(" ")}` : `the claim that the answer never cites result [${unit.resultNumber}] (title ${JSON.stringify(unit.title)}, summary ${JSON.stringify(unit.summary)})`;
|
|
19106
|
+
return {
|
|
19107
|
+
...EVIDENCE_QUESTION,
|
|
19108
|
+
id: evidenceQuestionId(unit.id),
|
|
19109
|
+
question: [
|
|
19110
|
+
`Does the evidence below directly support ${backed} and is it needed to answer the user's question?`,
|
|
19111
|
+
`Search query that surfaced it: ${JSON.stringify(unit.searchQuery)}`,
|
|
19112
|
+
`Retrieval method: ${JSON.stringify(unit.method)}`,
|
|
19113
|
+
`Evidence: ${JSON.stringify(boundExcerpt(unit.excerpt))}`
|
|
19114
|
+
].join(`
|
|
19115
|
+
`)
|
|
19116
|
+
};
|
|
19117
|
+
}
|
|
19118
|
+
async function judgeEvidence(judge, input) {
|
|
19119
|
+
if (input.units.length === 0)
|
|
19120
|
+
return { probabilities: {}, kept: [] };
|
|
19121
|
+
let verdicts;
|
|
19122
|
+
try {
|
|
19123
|
+
verdicts = (await judge(describeState(input), input.units.map((unit) => evidenceQuestion(unit, input)))).verdicts;
|
|
19124
|
+
} catch (error) {
|
|
19125
|
+
return { probabilities: {}, kept: [], fallbackReason: error instanceof Error ? error.message : String(error) };
|
|
18484
19126
|
}
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18491
|
-
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
const ref = trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1).trim() : trimmed;
|
|
18497
|
-
const byId = this.byId.get(ref);
|
|
18498
|
-
if (byId !== undefined) {
|
|
18499
|
-
push(byId);
|
|
18500
|
-
continue;
|
|
18501
|
-
}
|
|
18502
|
-
const bySource = this.entries.filter((entry) => entry.source === ref);
|
|
18503
|
-
if (bySource.length > 0) {
|
|
18504
|
-
for (const entry of bySource)
|
|
18505
|
-
push(entry);
|
|
18506
|
-
continue;
|
|
18507
|
-
}
|
|
18508
|
-
if (options.allowLocalFiles && isAbsolute9(ref) && isRegularFile2(ref)) {
|
|
18509
|
-
const key = `file\x00${ref}`;
|
|
18510
|
-
if (seen.has(key))
|
|
18511
|
-
continue;
|
|
18512
|
-
seen.add(key);
|
|
18513
|
-
resolved.push({
|
|
18514
|
-
method: "bash",
|
|
18515
|
-
source: ref,
|
|
18516
|
-
content: (options.fallbackContent.trim() || ref).slice(0, MAX_CONTENT_CHARS4)
|
|
18517
|
-
});
|
|
18518
|
-
continue;
|
|
18519
|
-
}
|
|
18520
|
-
throw new Error(this.unresolvedMessage(ref, EVIDENCE_ID_PATTERN.test(ref), options));
|
|
19127
|
+
const byId = {};
|
|
19128
|
+
for (const verdict of verdicts)
|
|
19129
|
+
byId[verdict.id] = verdict;
|
|
19130
|
+
const probabilities = {};
|
|
19131
|
+
const kept = [];
|
|
19132
|
+
let firstHint;
|
|
19133
|
+
for (const unit of input.units) {
|
|
19134
|
+
const verdict = byId[evidenceQuestionId(unit.id)];
|
|
19135
|
+
if (typeof verdict?.answer !== "number") {
|
|
19136
|
+
firstHint ??= verdict?.hint;
|
|
19137
|
+
continue;
|
|
18521
19138
|
}
|
|
18522
|
-
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
this.entries = [];
|
|
18526
|
-
this.byKey.clear();
|
|
18527
|
-
this.byId.clear();
|
|
19139
|
+
probabilities[unit.id] = verdict.answer;
|
|
19140
|
+
if (verdict.answer >= EVIDENCE_SUPPORT_THRESHOLD)
|
|
19141
|
+
kept.push(unit.id);
|
|
18528
19142
|
}
|
|
18529
|
-
|
|
18530
|
-
|
|
18531
|
-
const local = options.allowLocalFiles ? " For a file you opened yourself with bash, pass its absolute path." : "";
|
|
18532
|
-
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.`;
|
|
19143
|
+
if (Object.keys(probabilities).length === 0) {
|
|
19144
|
+
return { probabilities, kept, fallbackReason: firstHint ?? NO_VERDICT_FALLBACK };
|
|
18533
19145
|
}
|
|
19146
|
+
return { probabilities, kept };
|
|
18534
19147
|
}
|
|
18535
|
-
var
|
|
18536
|
-
var
|
|
18537
|
-
|
|
19148
|
+
var EVIDENCE_QUESTION_ID_PREFIX = "evidence:", NO_VERDICT_FALLBACK = "Jev returned no usable evidence verdict.", MAX_EVIDENCE_CHARACTERS = 1500, STATE_INSTRUCTION, EVIDENCE_QUESTION, SENTENCE_TERMINATORS;
|
|
19149
|
+
var init_evidence_judgment = __esm(() => {
|
|
19150
|
+
STATE_INSTRUCTION = [
|
|
19151
|
+
"Each question asks whether one piece of evidence really supports answering the user's question.",
|
|
19152
|
+
"Judge only that evidence against the sentence it backs; the full answer is shown for reference only."
|
|
19153
|
+
].join(" ");
|
|
19154
|
+
EVIDENCE_QUESTION = check("Does the evidence directly support the cited sentence and is it needed to answer the user's question?", {
|
|
19155
|
+
true: "The evidence states or confirms what the cited sentence claims about the user's question, and leaving it out would leave that claim unsupported.",
|
|
19156
|
+
false: "The evidence is unrelated, only loosely related, redundant noise, or contradicts the cited sentence."
|
|
19157
|
+
});
|
|
19158
|
+
SENTENCE_TERMINATORS = {
|
|
19159
|
+
".": true,
|
|
19160
|
+
"!": true,
|
|
19161
|
+
"?": true,
|
|
19162
|
+
"。": true,
|
|
19163
|
+
"!": true,
|
|
19164
|
+
"?": true
|
|
19165
|
+
};
|
|
18538
19166
|
});
|
|
18539
19167
|
|
|
18540
19168
|
// src/agent/evidence-origins.ts
|
|
@@ -18644,81 +19272,8 @@ class EvidenceOriginIndex {
|
|
|
18644
19272
|
}
|
|
18645
19273
|
var MAX_CANDIDATES = 2000, MAX_CONTENT_LENGTH = 4000, MIN_MATCH_LENGTH = 12;
|
|
18646
19274
|
|
|
18647
|
-
// src/agent/fast-answer-tool.ts
|
|
18648
|
-
import { Type as Type6 } from "typebox";
|
|
18649
|
-
function createEmitFastAnswerTool(capture, options) {
|
|
18650
|
-
return {
|
|
18651
|
-
name: EMIT_FAST_ANSWER_TOOL_NAME,
|
|
18652
|
-
label: "Emit Fast Answer",
|
|
18653
|
-
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.",
|
|
18654
|
-
parameters: fastAnswerSchema,
|
|
18655
|
-
async execute(_toolCallId, params) {
|
|
18656
|
-
assertCitationsResolve(EMIT_FAST_ANSWER_TOOL_NAME, params.answer, params.results);
|
|
18657
|
-
const evidenceRefs = [];
|
|
18658
|
-
for (const result of params.results) {
|
|
18659
|
-
if (result.refs === undefined || result.refs.length === 0)
|
|
18660
|
-
continue;
|
|
18661
|
-
const refs = options.ledger.resolve(result.refs, {
|
|
18662
|
-
label: EMIT_FAST_ANSWER_TOOL_NAME,
|
|
18663
|
-
number: result.number,
|
|
18664
|
-
fallbackContent: result.summary,
|
|
18665
|
-
allowLocalFiles: false
|
|
18666
|
-
});
|
|
18667
|
-
if (refs.length > 0)
|
|
18668
|
-
evidenceRefs.push({ number: result.number, refs });
|
|
18669
|
-
}
|
|
18670
|
-
const details = {
|
|
18671
|
-
answer: params.answer,
|
|
18672
|
-
results: params.results.map((result) => ({
|
|
18673
|
-
number: result.number,
|
|
18674
|
-
title: result.title,
|
|
18675
|
-
summary: result.summary,
|
|
18676
|
-
evidence: (result.evidence ?? []).map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
18677
|
-
...result.confidence !== undefined ? { confidence: result.confidence } : {}
|
|
18678
|
-
})),
|
|
18679
|
-
sources: evidenceRefs.flatMap((entry) => {
|
|
18680
|
-
const [primary] = entry.refs;
|
|
18681
|
-
return primary === undefined ? [] : [{ number: entry.number, source: primary.source }];
|
|
18682
|
-
}),
|
|
18683
|
-
evidenceRefs
|
|
18684
|
-
};
|
|
18685
|
-
capture(details);
|
|
18686
|
-
return {
|
|
18687
|
-
content: [
|
|
18688
|
-
{
|
|
18689
|
-
type: "text",
|
|
18690
|
-
text: "Fast answer delivered to the user. Stop now; a deeper verification pass follows separately."
|
|
18691
|
-
}
|
|
18692
|
-
],
|
|
18693
|
-
details
|
|
18694
|
-
};
|
|
18695
|
-
}
|
|
18696
|
-
};
|
|
18697
|
-
}
|
|
18698
|
-
var EMIT_FAST_ANSWER_TOOL_NAME = "emit_fast_answer", fastAnswerSchema;
|
|
18699
|
-
var init_fast_answer_tool = __esm(() => {
|
|
18700
|
-
fastAnswerSchema = Type6.Object({
|
|
18701
|
-
answer: Type6.String({
|
|
18702
|
-
description: `Complete, self-contained first answer for the caller in at most 5 bullet points (plus optional explanation), produced immediately from baseline retrieval evidence. 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}`
|
|
18703
|
-
}),
|
|
18704
|
-
results: Type6.Array(Type6.Object({
|
|
18705
|
-
number: Type6.Integer({ description: "1-based result number" }),
|
|
18706
|
-
title: Type6.String({ description: "Short name of the knowledge unit" }),
|
|
18707
|
-
summary: Type6.String({ description: "Key insight backing the first answer" }),
|
|
18708
|
-
evidence: Type6.Optional(Type6.Array(Type6.Object({
|
|
18709
|
-
excerpt: Type6.String({ description: "Supporting excerpt" }),
|
|
18710
|
-
lineNumber: Type6.Optional(Type6.Integer({ description: "Line number of the excerpt, if known" }))
|
|
18711
|
-
}))),
|
|
18712
|
-
confidence: Type6.Optional(Type6.Number({ description: "Confidence in this result, 0..1", minimum: 0, maximum: 1 })),
|
|
18713
|
-
refs: Type6.Optional(Type6.Array(Type6.String(), {
|
|
18714
|
-
description: "Evidence ids from the baseline evidence that support this result (e.g. e3). The source path is attached for you. Omit only when no baseline evidence backs the result."
|
|
18715
|
-
}))
|
|
18716
|
-
}), { description: "Numbered knowledge units backing the first answer." })
|
|
18717
|
-
});
|
|
18718
|
-
});
|
|
18719
|
-
|
|
18720
19275
|
// src/agent/fsearch-search-tool.ts
|
|
18721
|
-
import { Type as
|
|
19276
|
+
import { Type as Type5 } from "typebox";
|
|
18722
19277
|
function createFSearchSearchTool(provider) {
|
|
18723
19278
|
return {
|
|
18724
19279
|
name: FSEARCH_SEARCH_TOOL_NAME,
|
|
@@ -18774,27 +19329,27 @@ ${lines.join(`
|
|
|
18774
19329
|
}
|
|
18775
19330
|
var FSEARCH_SEARCH_TOOL_NAME = "fsearch_search", MAX_RESULTS_CAP3 = 1000, DEFAULT_MAX_RESULTS4 = 100, fsearchSearchSchema;
|
|
18776
19331
|
var init_fsearch_search_tool = __esm(() => {
|
|
18777
|
-
fsearchSearchSchema =
|
|
18778
|
-
query:
|
|
19332
|
+
fsearchSearchSchema = Type5.Object({
|
|
19333
|
+
query: Type5.String({
|
|
18779
19334
|
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.'
|
|
18780
19335
|
}),
|
|
18781
|
-
regex:
|
|
18782
|
-
matchCase:
|
|
18783
|
-
matchPath:
|
|
18784
|
-
kind:
|
|
18785
|
-
path:
|
|
18786
|
-
sort:
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
|
|
19336
|
+
regex: Type5.Optional(Type5.Boolean({ description: "Treat query as a regular expression." })),
|
|
19337
|
+
matchCase: Type5.Optional(Type5.Boolean()),
|
|
19338
|
+
matchPath: Type5.Optional(Type5.Boolean({ description: "Match against the full path instead of the name." })),
|
|
19339
|
+
kind: Type5.Optional(Type5.Union([Type5.Literal("files"), Type5.Literal("folders")])),
|
|
19340
|
+
path: Type5.Optional(Type5.String({ description: "Absolute folder to search within." })),
|
|
19341
|
+
sort: Type5.Optional(Type5.Union([
|
|
19342
|
+
Type5.Literal("name-ascending"),
|
|
19343
|
+
Type5.Literal("name-descending"),
|
|
19344
|
+
Type5.Literal("path-ascending"),
|
|
19345
|
+
Type5.Literal("path-descending"),
|
|
19346
|
+
Type5.Literal("size-ascending"),
|
|
19347
|
+
Type5.Literal("size-descending"),
|
|
19348
|
+
Type5.Literal("date-modified-ascending"),
|
|
19349
|
+
Type5.Literal("date-modified-descending")
|
|
18795
19350
|
])),
|
|
18796
|
-
offset:
|
|
18797
|
-
maxResults:
|
|
19351
|
+
offset: Type5.Optional(Type5.Integer({ minimum: 0, description: "Skip this many results (pagination)." })),
|
|
19352
|
+
maxResults: Type5.Optional(Type5.Integer({
|
|
18798
19353
|
minimum: 1,
|
|
18799
19354
|
description: `Maximum results (default ${DEFAULT_MAX_RESULTS4}, cap ${MAX_RESULTS_CAP3}).`
|
|
18800
19355
|
}))
|
|
@@ -18927,6 +19482,7 @@ async function createAutoRAGPiSession(options) {
|
|
|
18927
19482
|
authPath: join30(agentDir, "auth.json"),
|
|
18928
19483
|
modelsPath: join30(agentDir, "models.json")
|
|
18929
19484
|
});
|
|
19485
|
+
await registerAutoRAGProvider(modelRuntime);
|
|
18930
19486
|
await configureModelRuntime(modelRuntime, options.model, options.apiKey, options.providerApiKeys);
|
|
18931
19487
|
const customTools = [...options.customTools];
|
|
18932
19488
|
const extensionToolNames = [...options.extensionToolNames ?? []];
|
|
@@ -18976,6 +19532,7 @@ async function createAutoRAGPiInteractiveRuntime(options) {
|
|
|
18976
19532
|
authPath: join30(agentDir, "auth.json"),
|
|
18977
19533
|
modelsPath: join30(agentDir, "models.json")
|
|
18978
19534
|
});
|
|
19535
|
+
await registerAutoRAGProvider(modelRuntime);
|
|
18979
19536
|
await configureModelRuntime(modelRuntime, options.model, options.apiKey, options.providerApiKeys);
|
|
18980
19537
|
const sessionManager = options.sessionPath ? SessionManager.open(options.sessionPath, options.sessionDir, options.cwd) : SessionManager.create(options.cwd, options.sessionDir);
|
|
18981
19538
|
const createRuntime = async ({
|
|
@@ -19025,12 +19582,13 @@ async function createAutoRAGPiInteractiveRuntime(options) {
|
|
|
19025
19582
|
}
|
|
19026
19583
|
var PI_BUILTIN_TOOL_NAMES, EMBEDDED_AUTH_MARKER = "<autorag-embedded-model>";
|
|
19027
19584
|
var init_pi_session = __esm(() => {
|
|
19585
|
+
init_provider();
|
|
19028
19586
|
PI_BUILTIN_TOOL_NAMES = ["read", "bash", "edit", "write", "grep", "find", "ls"];
|
|
19029
19587
|
});
|
|
19030
19588
|
|
|
19031
19589
|
// src/agent/jev-extension.ts
|
|
19032
19590
|
import { Jev } from "jev-use";
|
|
19033
|
-
import { Type as
|
|
19591
|
+
import { Type as Type6 } from "typebox";
|
|
19034
19592
|
function createJevJudge(options = {}) {
|
|
19035
19593
|
let client;
|
|
19036
19594
|
return async (state, questions, callOptions = {}) => {
|
|
@@ -19083,32 +19641,32 @@ var JEV_TOOL_NAME = "jev", OPENROUTER_DEFAULT_MODEL = "typesafe/jev-1.13", BACKE
|
|
|
19083
19641
|
var init_jev_extension = __esm(() => {
|
|
19084
19642
|
init_pi_session();
|
|
19085
19643
|
BACKEND_DEFAULT_MODEL = { openrouter: OPENROUTER_DEFAULT_MODEL };
|
|
19086
|
-
jevQuestionSchema =
|
|
19087
|
-
id:
|
|
19088
|
-
type:
|
|
19644
|
+
jevQuestionSchema = Type6.Object({
|
|
19645
|
+
id: Type6.Optional(Type6.String({ description: "Caller-assigned id, echoed back in the verdict" })),
|
|
19646
|
+
type: Type6.Union([Type6.Literal("noul"), Type6.Literal("choice"), Type6.Literal("score")], {
|
|
19089
19647
|
description: "noul = P(yes), choice = pick one option, score = ordered level index"
|
|
19090
19648
|
}),
|
|
19091
|
-
question:
|
|
19649
|
+
question: Type6.String({
|
|
19092
19650
|
minLength: 1,
|
|
19093
19651
|
description: "One narrow question about the state. Jev answers exactly this."
|
|
19094
19652
|
}),
|
|
19095
|
-
options:
|
|
19653
|
+
options: Type6.Optional(Type6.Union([Type6.Array(Type6.String()), Type6.Record(Type6.String(), Type6.String())], {
|
|
19096
19654
|
description: "choice only: at least two option labels (or label -> meaning)"
|
|
19097
19655
|
})),
|
|
19098
|
-
levels:
|
|
19656
|
+
levels: Type6.Optional(Type6.Array(Type6.String(), {
|
|
19099
19657
|
description: "score only: at least two ordered level descriptions; the answer indexes into them"
|
|
19100
19658
|
})),
|
|
19101
|
-
criteria:
|
|
19659
|
+
criteria: Type6.Optional(Type6.Object({ true: Type6.String(), false: Type6.String() }, { description: "noul only: what yes and no mean, to sharpen calibration" }))
|
|
19102
19660
|
});
|
|
19103
|
-
jevParameters =
|
|
19104
|
-
state:
|
|
19661
|
+
jevParameters = Type6.Object({
|
|
19662
|
+
state: Type6.Unknown({
|
|
19105
19663
|
description: "Text, JSON object, or JSON array Jev should judge. Keep it small and self-contained."
|
|
19106
19664
|
}),
|
|
19107
|
-
questions:
|
|
19665
|
+
questions: Type6.Array(jevQuestionSchema, {
|
|
19108
19666
|
minItems: 1,
|
|
19109
19667
|
description: "Named questions, all evaluated against the same state in one batched request."
|
|
19110
19668
|
}),
|
|
19111
|
-
confidence_threshold:
|
|
19669
|
+
confidence_threshold: Type6.Optional(Type6.Number({
|
|
19112
19670
|
minimum: 0,
|
|
19113
19671
|
maximum: 1,
|
|
19114
19672
|
description: "Escalate any verdict below this confidence; omitted uses jev-use's per-source defaults"
|
|
@@ -19117,7 +19675,7 @@ var init_jev_extension = __esm(() => {
|
|
|
19117
19675
|
});
|
|
19118
19676
|
|
|
19119
19677
|
// src/agent/jikji-find-tool.ts
|
|
19120
|
-
import { Type as
|
|
19678
|
+
import { Type as Type7 } from "typebox";
|
|
19121
19679
|
function createJikjiFindTool(provider, ledger = new EvidenceLedger) {
|
|
19122
19680
|
return {
|
|
19123
19681
|
name: JIKJI_FIND_TOOL_NAME,
|
|
@@ -19248,10 +19806,10 @@ function formatDirective(policy) {
|
|
|
19248
19806
|
var JIKJI_FIND_TOOL_NAME = "jikji_find", jikjiFindSchema;
|
|
19249
19807
|
var init_jikji_find_tool = __esm(() => {
|
|
19250
19808
|
init_evidence_ledger();
|
|
19251
|
-
jikjiFindSchema =
|
|
19252
|
-
query:
|
|
19253
|
-
topK:
|
|
19254
|
-
first:
|
|
19809
|
+
jikjiFindSchema = Type7.Object({
|
|
19810
|
+
query: Type7.String({ description: "Query for Jikji local file discovery." }),
|
|
19811
|
+
topK: Type7.Optional(Type7.Integer({ description: "Maximum number of answer paths / candidates to return." })),
|
|
19812
|
+
first: Type7.Optional(Type7.Boolean({ description: "Return only the first/best answer." }))
|
|
19255
19813
|
});
|
|
19256
19814
|
});
|
|
19257
19815
|
|
|
@@ -20173,57 +20731,57 @@ var init_policy = __esm(() => {
|
|
|
20173
20731
|
});
|
|
20174
20732
|
|
|
20175
20733
|
// src/p2p/wire.ts
|
|
20176
|
-
import { Type as
|
|
20734
|
+
import { Type as Type8 } from "typebox";
|
|
20177
20735
|
var PeerRefusalCodeSchema, PeerDiagnosticSchema, PeerFileEntrySchema, PeerResultEntrySchema, PeerQueryRequestSchema, PeerQueryResponseSchema;
|
|
20178
20736
|
var init_wire = __esm(() => {
|
|
20179
|
-
PeerRefusalCodeSchema =
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
|
|
20737
|
+
PeerRefusalCodeSchema = Type8.Union([
|
|
20738
|
+
Type8.Literal("auth-error"),
|
|
20739
|
+
Type8.Literal("replay-rejected"),
|
|
20740
|
+
Type8.Literal("rate-limited"),
|
|
20741
|
+
Type8.Literal("injection-detected"),
|
|
20742
|
+
Type8.Literal("policy-denied"),
|
|
20743
|
+
Type8.Literal("queue-full"),
|
|
20744
|
+
Type8.Literal("internal-error")
|
|
20187
20745
|
]);
|
|
20188
|
-
PeerDiagnosticSchema =
|
|
20189
|
-
code:
|
|
20190
|
-
message:
|
|
20746
|
+
PeerDiagnosticSchema = Type8.Object({
|
|
20747
|
+
code: Type8.String({ minLength: 1, description: "Diagnostic or refusal code" }),
|
|
20748
|
+
message: Type8.String({ description: "Human-readable diagnostic message" })
|
|
20191
20749
|
});
|
|
20192
|
-
PeerFileEntrySchema =
|
|
20193
|
-
source:
|
|
20750
|
+
PeerFileEntrySchema = Type8.Object({
|
|
20751
|
+
source: Type8.String({
|
|
20194
20752
|
description: "Canonical retrieval source identifier"
|
|
20195
20753
|
}),
|
|
20196
|
-
contentBase64:
|
|
20197
|
-
redacted:
|
|
20754
|
+
contentBase64: Type8.String({ description: "Base64-encoded file content" }),
|
|
20755
|
+
redacted: Type8.Boolean({ description: "Whether the content was PII-redacted" })
|
|
20198
20756
|
});
|
|
20199
|
-
PeerResultEntrySchema =
|
|
20200
|
-
number:
|
|
20201
|
-
title:
|
|
20202
|
-
summary:
|
|
20203
|
-
source:
|
|
20757
|
+
PeerResultEntrySchema = Type8.Object({
|
|
20758
|
+
number: Type8.Integer({ minimum: 1, description: "1-based result number" }),
|
|
20759
|
+
title: Type8.String({ minLength: 1, description: "Short title of the result" }),
|
|
20760
|
+
summary: Type8.String({ description: "Key insight summary" }),
|
|
20761
|
+
source: Type8.String({
|
|
20204
20762
|
description: "Canonical retrieval source identifier"
|
|
20205
20763
|
}),
|
|
20206
|
-
excerpt:
|
|
20764
|
+
excerpt: Type8.String({ description: "Supporting excerpt" })
|
|
20207
20765
|
});
|
|
20208
|
-
PeerQueryRequestSchema =
|
|
20209
|
-
v:
|
|
20210
|
-
query:
|
|
20211
|
-
topK:
|
|
20212
|
-
scope:
|
|
20766
|
+
PeerQueryRequestSchema = Type8.Object({
|
|
20767
|
+
v: Type8.Literal(1, { description: "Protocol version" }),
|
|
20768
|
+
query: Type8.String({ minLength: 1, maxLength: 4096, description: "Search query (max 4096 chars)" }),
|
|
20769
|
+
topK: Type8.Optional(Type8.Integer({ minimum: 1, maximum: 20, description: "Max results to return (max 20)" })),
|
|
20770
|
+
scope: Type8.Optional(Type8.String({ description: "Optional search scope hint" }))
|
|
20213
20771
|
});
|
|
20214
|
-
PeerQueryResponseSchema =
|
|
20215
|
-
v:
|
|
20216
|
-
status:
|
|
20772
|
+
PeerQueryResponseSchema = Type8.Object({
|
|
20773
|
+
v: Type8.Literal(1, { description: "Protocol version" }),
|
|
20774
|
+
status: Type8.Union([Type8.Literal("ok"), Type8.Literal("rejected")], {
|
|
20217
20775
|
description: "Response status"
|
|
20218
20776
|
}),
|
|
20219
|
-
answer:
|
|
20220
|
-
results:
|
|
20777
|
+
answer: Type8.String({ description: "Curated answer text" }),
|
|
20778
|
+
results: Type8.Array(PeerResultEntrySchema, {
|
|
20221
20779
|
description: "Curated result entries with opaque source ids"
|
|
20222
20780
|
}),
|
|
20223
|
-
files:
|
|
20781
|
+
files: Type8.Array(PeerFileEntrySchema, {
|
|
20224
20782
|
description: "Attached original files with opaque source ids"
|
|
20225
20783
|
}),
|
|
20226
|
-
diagnostics:
|
|
20784
|
+
diagnostics: Type8.Array(PeerDiagnosticSchema, {
|
|
20227
20785
|
description: "Diagnostic messages (degraded-mode, rejection reasons, etc.)"
|
|
20228
20786
|
})
|
|
20229
20787
|
});
|
|
@@ -20470,7 +21028,7 @@ var init_simplex_query_store = __esm(() => {
|
|
|
20470
21028
|
// src/p2p/simplex-server.ts
|
|
20471
21029
|
import { existsSync as existsSync28, mkdirSync as mkdirSync23, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "node:fs";
|
|
20472
21030
|
import { join as join34 } from "node:path";
|
|
20473
|
-
import { Type as
|
|
21031
|
+
import { Type as Type9 } from "typebox";
|
|
20474
21032
|
import { Value as Value2 } from "typebox/value";
|
|
20475
21033
|
function targetTokens(value) {
|
|
20476
21034
|
return new Set((value.toLocaleLowerCase().match(TARGET_TOKEN_PATTERN) ?? []).filter((token) => token.length > 1));
|
|
@@ -20784,11 +21342,11 @@ var init_simplex_server = __esm(() => {
|
|
|
20784
21342
|
shareBytes: false,
|
|
20785
21343
|
redact: true
|
|
20786
21344
|
};
|
|
20787
|
-
SimplexWireEnvelopeSchema =
|
|
20788
|
-
v:
|
|
20789
|
-
kind:
|
|
20790
|
-
id:
|
|
20791
|
-
payload:
|
|
21345
|
+
SimplexWireEnvelopeSchema = Type9.Object({
|
|
21346
|
+
v: Type9.Literal(1, { description: "Envelope version" }),
|
|
21347
|
+
kind: Type9.Union([Type9.Literal("query"), Type9.Literal("response")], { description: "Payload kind" }),
|
|
21348
|
+
id: Type9.String({ minLength: 1, maxLength: 128, description: "Correlation id" }),
|
|
21349
|
+
payload: Type9.Unknown({ description: "PeerQueryRequest or PeerQueryResponse" })
|
|
20792
21350
|
});
|
|
20793
21351
|
TARGET_TOKEN_PATTERN = /[\p{L}\p{N}]+/gu;
|
|
20794
21352
|
PEERS_DIR = join34(".autorag", "p2p");
|
|
@@ -20801,7 +21359,7 @@ var init_simplex_server = __esm(() => {
|
|
|
20801
21359
|
});
|
|
20802
21360
|
|
|
20803
21361
|
// src/agent/peer-target-tool.ts
|
|
20804
|
-
import { Type as
|
|
21362
|
+
import { Type as Type10 } from "typebox";
|
|
20805
21363
|
function createRecommendPeerTargetsTool(workspacePath) {
|
|
20806
21364
|
return {
|
|
20807
21365
|
name: RECOMMEND_PEER_TARGETS_TOOL_NAME,
|
|
@@ -20834,8 +21392,8 @@ function createRecommendPeerTargetsTool(workspacePath) {
|
|
|
20834
21392
|
var RECOMMEND_PEER_TARGETS_TOOL_NAME = "recommend_peer_targets", recommendPeerTargetsSchema;
|
|
20835
21393
|
var init_peer_target_tool = __esm(() => {
|
|
20836
21394
|
init_simplex_server();
|
|
20837
|
-
recommendPeerTargetsSchema =
|
|
20838
|
-
query:
|
|
21395
|
+
recommendPeerTargetsSchema = Type10.Object({
|
|
21396
|
+
query: Type10.String({ description: "Question or topic to match against local peer personas." })
|
|
20839
21397
|
});
|
|
20840
21398
|
});
|
|
20841
21399
|
|
|
@@ -20911,7 +21469,7 @@ var MAX_DECOMPOSED_QUERIES = 5;
|
|
|
20911
21469
|
var init_query_decomposition = () => {};
|
|
20912
21470
|
|
|
20913
21471
|
// src/agent/query-peer-tool.ts
|
|
20914
|
-
import { Type as
|
|
21472
|
+
import { Type as Type11 } from "typebox";
|
|
20915
21473
|
function failure4(alias, message) {
|
|
20916
21474
|
const details = { method: "query_peer_agent", ok: false, alias, message };
|
|
20917
21475
|
return { content: [{ type: "text", text: message }], details };
|
|
@@ -21026,11 +21584,11 @@ var init_query_peer_tool = __esm(() => {
|
|
|
21026
21584
|
init_simplex_query_store();
|
|
21027
21585
|
init_simplex_server();
|
|
21028
21586
|
init_evidence_ledger();
|
|
21029
|
-
queryPeerAgentSchema =
|
|
21030
|
-
alias:
|
|
21031
|
-
query:
|
|
21032
|
-
topK:
|
|
21033
|
-
scope:
|
|
21587
|
+
queryPeerAgentSchema = Type11.Object({
|
|
21588
|
+
alias: Type11.String({ minLength: 1 }),
|
|
21589
|
+
query: Type11.String({ minLength: 1, maxLength: 4096 }),
|
|
21590
|
+
topK: Type11.Optional(Type11.Integer({ minimum: 1, maximum: 20 })),
|
|
21591
|
+
scope: Type11.Optional(Type11.String())
|
|
21034
21592
|
});
|
|
21035
21593
|
});
|
|
21036
21594
|
|
|
@@ -21297,29 +21855,29 @@ function reconcileCitations(answer, results) {
|
|
|
21297
21855
|
]
|
|
21298
21856
|
};
|
|
21299
21857
|
}
|
|
21300
|
-
function
|
|
21301
|
-
|
|
21302
|
-
const results = details.results.map((result) => ({
|
|
21858
|
+
function toSearchResults(details, sourceByNumber) {
|
|
21859
|
+
return details.results.map((result) => ({
|
|
21303
21860
|
number: result.number,
|
|
21304
21861
|
title: result.title,
|
|
21305
21862
|
summary: result.summary,
|
|
21306
21863
|
evidence: result.evidence.map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
21307
|
-
confidence: confidenceFrom(result.confidence
|
|
21864
|
+
...result.confidence !== undefined ? { confidence: confidenceFrom(result.confidence) } : {},
|
|
21308
21865
|
source: sourceByNumber.get(result.number)
|
|
21309
21866
|
}));
|
|
21310
|
-
|
|
21867
|
+
}
|
|
21868
|
+
function createPreliminarySearchDocumentsResponse(sessionId, query, details, diagnostics = []) {
|
|
21869
|
+
const sourceByNumber = new Map(details.mapping.map((entry) => [entry.number, entry.source]));
|
|
21311
21870
|
return {
|
|
21312
21871
|
sessionId,
|
|
21313
21872
|
query,
|
|
21314
|
-
results,
|
|
21315
|
-
answer:
|
|
21873
|
+
results: toSearchResults(details, sourceByNumber),
|
|
21874
|
+
answer: details.answer,
|
|
21316
21875
|
searched: details.results.length,
|
|
21317
21876
|
warnings: [],
|
|
21318
|
-
diagnostics: [...
|
|
21877
|
+
diagnostics: [...diagnostics]
|
|
21319
21878
|
};
|
|
21320
21879
|
}
|
|
21321
|
-
function createEmptySearchDocumentsResponse(sessionId, query,
|
|
21322
|
-
sessions.set(sessionId, { query, registry: new Map });
|
|
21880
|
+
function createEmptySearchDocumentsResponse(sessionId, query, diagnostics = []) {
|
|
21323
21881
|
return {
|
|
21324
21882
|
sessionId,
|
|
21325
21883
|
query,
|
|
@@ -21335,7 +21893,7 @@ function normalizeEntryEvidenceRefs(entry) {
|
|
|
21335
21893
|
const derivedRetrieverMix = Array.from(new Set(rawRefs.map((ref) => ref.method)));
|
|
21336
21894
|
return rawRefs.map((ref) => {
|
|
21337
21895
|
if (ref.excerpt === undefined && ref.content === undefined) {
|
|
21338
|
-
throw new Error("
|
|
21896
|
+
throw new Error("results: every evidenceRef must include excerpt or content");
|
|
21339
21897
|
}
|
|
21340
21898
|
return normalizeSessionEvidenceRef({
|
|
21341
21899
|
method: ref.method,
|
|
@@ -21356,19 +21914,11 @@ function normalizeEntryEvidenceRefs(entry) {
|
|
|
21356
21914
|
});
|
|
21357
21915
|
});
|
|
21358
21916
|
}
|
|
21359
|
-
function recordStructuredResultsSession(sessionId, query, details,
|
|
21360
|
-
assertResultsMappingOneToOne("
|
|
21361
|
-
const registry = new Map;
|
|
21917
|
+
function recordStructuredResultsSession(sessionId, query, details, memory, componentDiagnostics = [], options = {}) {
|
|
21918
|
+
assertResultsMappingOneToOne("results", details.results, details.mapping);
|
|
21362
21919
|
const memoryResults = [];
|
|
21363
21920
|
for (const entry of details.mapping) {
|
|
21364
21921
|
const evidenceRefs = normalizeEntryEvidenceRefs(entry);
|
|
21365
|
-
registry.set(entry.number, {
|
|
21366
|
-
index: entry.number,
|
|
21367
|
-
content: entry.content,
|
|
21368
|
-
source: entry.source,
|
|
21369
|
-
method: entry.method,
|
|
21370
|
-
evidenceRefs
|
|
21371
|
-
});
|
|
21372
21922
|
const emittedResult = details.results.find((result) => result.number === entry.number);
|
|
21373
21923
|
memoryResults.push({
|
|
21374
21924
|
number: entry.number,
|
|
@@ -21377,23 +21927,15 @@ function recordStructuredResultsSession(sessionId, query, details, sessions, mem
|
|
|
21377
21927
|
content: entry.content,
|
|
21378
21928
|
method: entry.method,
|
|
21379
21929
|
source: entry.source,
|
|
21380
|
-
...emittedResult !== undefined ? { confidence: confidenceFrom(emittedResult.confidence) } : {},
|
|
21930
|
+
...emittedResult?.confidence !== undefined ? { confidence: confidenceFrom(emittedResult.confidence) } : {},
|
|
21381
21931
|
evidenceRefs
|
|
21382
21932
|
});
|
|
21383
21933
|
}
|
|
21384
|
-
sessions.set(sessionId, { query, registry });
|
|
21385
21934
|
if (!options.isolateMemory) {
|
|
21386
21935
|
memory.recordCuratedResultsSession({ sessionId, query, results: memoryResults });
|
|
21387
21936
|
memory.save();
|
|
21388
21937
|
}
|
|
21389
|
-
const results = details.
|
|
21390
|
-
number: result.number,
|
|
21391
|
-
title: result.title,
|
|
21392
|
-
summary: result.summary,
|
|
21393
|
-
evidence: result.evidence.map((evidence) => evidence.lineNumber !== undefined ? { excerpt: evidence.excerpt, lineNumber: evidence.lineNumber } : { excerpt: evidence.excerpt }),
|
|
21394
|
-
confidence: confidenceFrom(result.confidence),
|
|
21395
|
-
source: registry.get(result.number)?.source || undefined
|
|
21396
|
-
}));
|
|
21938
|
+
const results = toSearchResults(details, new Map(details.mapping.map((entry) => [entry.number, entry.source || undefined])));
|
|
21397
21939
|
const citations = reconcileCitations(details.answer, results);
|
|
21398
21940
|
const answer = citations.answer;
|
|
21399
21941
|
const diagnostics = [...citations.diagnostics];
|
|
@@ -21423,7 +21965,7 @@ var init_search_documents = __esm(() => {
|
|
|
21423
21965
|
});
|
|
21424
21966
|
|
|
21425
21967
|
// src/agent/search-all-tool.ts
|
|
21426
|
-
import { Type as
|
|
21968
|
+
import { Type as Type12 } from "typebox";
|
|
21427
21969
|
function createSearchAllDocumentsTool(provider, ledger = new EvidenceLedger) {
|
|
21428
21970
|
return {
|
|
21429
21971
|
name: SEARCH_ALL_DOCUMENTS_TOOL_NAME,
|
|
@@ -21478,17 +22020,17 @@ var SEARCH_ALL_DOCUMENTS_TOOL_NAME = "search_all_documents", searchAllSchema;
|
|
|
21478
22020
|
var init_search_all_tool = __esm(() => {
|
|
21479
22021
|
init_evidence_ledger();
|
|
21480
22022
|
init_search_documents();
|
|
21481
|
-
searchAllSchema =
|
|
21482
|
-
query:
|
|
21483
|
-
topK:
|
|
22023
|
+
searchAllSchema = Type12.Object({
|
|
22024
|
+
query: Type12.String({ description: "Query to search across all configured retrieval methods." }),
|
|
22025
|
+
topK: Type12.Optional(Type12.Integer({
|
|
21484
22026
|
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."
|
|
21485
22027
|
})),
|
|
21486
|
-
scope:
|
|
22028
|
+
scope: Type12.Optional(Type12.String({ description: "Optional opaque virtual-path scope, e.g. /docs or /docs/**." }))
|
|
21487
22029
|
});
|
|
21488
22030
|
});
|
|
21489
22031
|
|
|
21490
22032
|
// src/agent/search-minsync-tool.ts
|
|
21491
|
-
import { Type as
|
|
22033
|
+
import { Type as Type13 } from "typebox";
|
|
21492
22034
|
function createSearchMinSyncDocumentsTool(getMethod, resolveScope = (scope) => scope, ledger = new EvidenceLedger) {
|
|
21493
22035
|
return {
|
|
21494
22036
|
name: SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME,
|
|
@@ -21538,17 +22080,17 @@ var SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME = "semantic_search_local_docs", searchMin
|
|
|
21538
22080
|
var init_search_minsync_tool = __esm(() => {
|
|
21539
22081
|
init_evidence_ledger();
|
|
21540
22082
|
init_search_documents();
|
|
21541
|
-
searchMinSyncSchema =
|
|
21542
|
-
query:
|
|
22083
|
+
searchMinSyncSchema = Type13.Object({
|
|
22084
|
+
query: Type13.String({
|
|
21543
22085
|
description: "Semantic query to search parsed document mirrors with MinSync vector retrieval."
|
|
21544
22086
|
}),
|
|
21545
|
-
topK:
|
|
21546
|
-
scope:
|
|
22087
|
+
topK: Type13.Optional(Type13.Integer({ description: "Maximum number of MinSync semantic chunks to return. Defaults to 50." })),
|
|
22088
|
+
scope: Type13.Optional(Type13.String({ description: "Optional opaque virtual-path scope, e.g. /docs or /docs/**." }))
|
|
21547
22089
|
});
|
|
21548
22090
|
});
|
|
21549
22091
|
|
|
21550
22092
|
// src/agent/search-single-datasource-tool.ts
|
|
21551
|
-
import { Type as
|
|
22093
|
+
import { Type as Type14 } from "typebox";
|
|
21552
22094
|
function createSingleDatasourceSearchTools(provider, specs, ledger = new EvidenceLedger) {
|
|
21553
22095
|
return specs.map((spec) => createTool(provider, spec, ledger));
|
|
21554
22096
|
}
|
|
@@ -21614,10 +22156,10 @@ var init_search_single_datasource_tool = __esm(() => {
|
|
|
21614
22156
|
init_evidence_ledger();
|
|
21615
22157
|
init_search_documents();
|
|
21616
22158
|
singleDatasourceToolName = datasourceSearchToolName;
|
|
21617
|
-
searchSingleDatasourceSchema =
|
|
21618
|
-
query:
|
|
21619
|
-
topK:
|
|
21620
|
-
scope:
|
|
22159
|
+
searchSingleDatasourceSchema = Type14.Object({
|
|
22160
|
+
query: Type14.String({ description: "Query to search within this datasource connection." }),
|
|
22161
|
+
topK: Type14.Optional(Type14.Integer({ description: "Maximum number of chunks to return. Defaults to 20." })),
|
|
22162
|
+
scope: Type14.Optional(Type14.String({ description: "Optional scope narrowing inside this datasource, e.g. one instance root." }))
|
|
21621
22163
|
});
|
|
21622
22164
|
});
|
|
21623
22165
|
|
|
@@ -21702,7 +22244,7 @@ ${input.skill}
|
|
|
21702
22244
|
|
|
21703
22245
|
${input.query}
|
|
21704
22246
|
|
|
21705
|
-
` + `When done,
|
|
22247
|
+
` + `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.`;
|
|
21706
22248
|
}
|
|
21707
22249
|
var SETUP_SKILL_RELATIVE_PATH;
|
|
21708
22250
|
var init_self_config = __esm(() => {
|
|
@@ -21733,7 +22275,6 @@ function buildSystemPrompt(config) {
|
|
|
21733
22275
|
toolLine(config, "check_memory", "inspect evidence earlier searches found for similar questions"),
|
|
21734
22276
|
toolLine(config, "recommend_peer_targets", "recommend local peer personas to ask about a topic without contacting them"),
|
|
21735
22277
|
toolLine(config, "query_peer_agent", "ask one trusted peer agent over SimpleX"),
|
|
21736
|
-
toolLine(config, "emit_autorag_results", "return the final structured answer with evidence ids for each result"),
|
|
21737
22278
|
...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`),
|
|
21738
22279
|
...config.toolNames.filter((name) => ![
|
|
21739
22280
|
"bash",
|
|
@@ -21749,8 +22290,7 @@ function buildSystemPrompt(config) {
|
|
|
21749
22290
|
"jev",
|
|
21750
22291
|
"check_memory",
|
|
21751
22292
|
"recommend_peer_targets",
|
|
21752
|
-
"query_peer_agent"
|
|
21753
|
-
"emit_autorag_results"
|
|
22293
|
+
"query_peer_agent"
|
|
21754
22294
|
].includes(name) && !name.startsWith("search_datasource_")).map((name) => `- **${name}**: caller-provided tool`)
|
|
21755
22295
|
].filter((line) => line !== undefined);
|
|
21756
22296
|
const manifests = config.manifests.length === 0 ? "" : `
|
|
@@ -21814,12 +22354,12 @@ Your job is to retrieve candidates, read the relevant source material directly,
|
|
|
21814
22354
|
## Workflow
|
|
21815
22355
|
|
|
21816
22356
|
Searches follow a progressive, two-phase loop:
|
|
21817
|
-
1. **PLAN & FAST ANSWER** — Decide whether the query is answerable from general knowledge or memory. When baseline retrieval evidence is provided,
|
|
22357
|
+
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.
|
|
21818
22358
|
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.
|
|
21819
22359
|
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.
|
|
21820
22360
|
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.
|
|
21821
22361
|
5. **CURATE** — Produce concise numbered knowledge units grounded in source evidence.
|
|
21822
|
-
6. **FINALIZE** —
|
|
22362
|
+
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.
|
|
21823
22363
|
|
|
21824
22364
|
## Available Tools
|
|
21825
22365
|
|
|
@@ -21864,17 +22404,17 @@ ${fsearch}
|
|
|
21864
22404
|
${manifests}
|
|
21865
22405
|
## Output Format
|
|
21866
22406
|
|
|
21867
|
-
|
|
21868
|
-
-
|
|
21869
|
-
-
|
|
21870
|
-
-
|
|
22407
|
+
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:
|
|
22408
|
+
- 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.
|
|
22409
|
+
- For a local file you opened yourself with \`bash\`, cite \`[file:<absolute path>]\`.
|
|
22410
|
+
- 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.
|
|
22411
|
+
- A citation whose id no tool returned in this run is dropped, so cite only ids you saw.
|
|
21871
22412
|
|
|
21872
22413
|
## Answer Guidelines
|
|
21873
22414
|
|
|
21874
22415
|
- **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.
|
|
21875
22416
|
- **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.
|
|
21876
|
-
- **Direct answer only**: The caller only needs the answer to their question. Never include specific file paths, datasource descriptions, or retrieval mechanics/principles in
|
|
21877
|
-
- **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\`.
|
|
22417
|
+
- **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.
|
|
21878
22418
|
- ${ANSWER_CITATION_RULE}
|
|
21879
22419
|
- ${ANSWER_IMAGE_EMBED_RULE} ${ANSWER_IMAGE_DELTA_RULE}
|
|
21880
22420
|
- **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.
|
|
@@ -21887,7 +22427,7 @@ Call \`emit_autorag_results\` exactly once with:
|
|
|
21887
22427
|
- **Curate, don't dump**: return useful knowledge units, not raw search output.
|
|
21888
22428
|
- **Address intent**: answer the caller's actual need.
|
|
21889
22429
|
- **Preserve traceability**: cite evidence by the ids retrieval tools show, so source paths and excerpts are attached for you.
|
|
21890
|
-
- **Finalize once**: the
|
|
22430
|
+
- **Finalize once**: the last reply, with no tool call, is the final answer.
|
|
21891
22431
|
`;
|
|
21892
22432
|
}
|
|
21893
22433
|
var init_system_prompt = __esm(() => {
|
|
@@ -23874,7 +24414,7 @@ var init_render = __esm(() => {
|
|
|
23874
24414
|
});
|
|
23875
24415
|
|
|
23876
24416
|
// src/agent/web-fetch-tool.ts
|
|
23877
|
-
import { Type as
|
|
24417
|
+
import { Type as Type15 } from "typebox";
|
|
23878
24418
|
function truncateHead(output, maxBytes, maxLines) {
|
|
23879
24419
|
const lines = output.split(`
|
|
23880
24420
|
`);
|
|
@@ -23978,9 +24518,9 @@ var init_web_fetch_tool = __esm(() => {
|
|
|
23978
24518
|
init_render();
|
|
23979
24519
|
init_evidence_ledger();
|
|
23980
24520
|
FETCH_MAX_OUTPUT_BYTES = 50 * 1024;
|
|
23981
|
-
webFetchSchema =
|
|
23982
|
-
url:
|
|
23983
|
-
raw:
|
|
24521
|
+
webFetchSchema = Type15.Object({
|
|
24522
|
+
url: Type15.String({ description: "The http(s) URL to fetch and read." }),
|
|
24523
|
+
raw: Type15.Optional(Type15.Boolean({ description: "Return the raw response body without markdown rendering or formatting." }))
|
|
23984
24524
|
});
|
|
23985
24525
|
});
|
|
23986
24526
|
|
|
@@ -24845,7 +25385,7 @@ function parseResponse(data) {
|
|
|
24845
25385
|
} : {}
|
|
24846
25386
|
};
|
|
24847
25387
|
}
|
|
24848
|
-
var
|
|
25388
|
+
var DEFAULT_BASE_URL4 = "https://generativelanguage.googleapis.com", API_VERSION = "v1beta", DEFAULT_MODEL = "gemini-3.8-flash", MAX_RESPONSE_BYTES, MAX_ERROR_BYTES, GeminiProvider;
|
|
24849
25389
|
var init_gemini = __esm(() => {
|
|
24850
25390
|
init_model_auth();
|
|
24851
25391
|
init_query();
|
|
@@ -24867,7 +25407,7 @@ var init_gemini = __esm(() => {
|
|
|
24867
25407
|
const model = envCredential("GEMINI_SEARCH_MODEL") ?? (credential.source === "injected" ? credential.modelId : undefined) ?? DEFAULT_MODEL;
|
|
24868
25408
|
const parsed = params.parsedQuery ?? parseSearchQuery(params.query);
|
|
24869
25409
|
const query = parsed.hasDirectives ? formatQuery(parsed, GOOGLE_QUERY_SYNTAX) : params.query;
|
|
24870
|
-
const baseUrl = (credential.baseUrl ??
|
|
25410
|
+
const baseUrl = (credential.baseUrl ?? DEFAULT_BASE_URL4).replace(/\/+$/, "");
|
|
24871
25411
|
const fetchImpl = params.fetch ?? fetch;
|
|
24872
25412
|
const response = await fetchImpl(`${baseUrl}/${API_VERSION}/models/${model}:generateContent`, {
|
|
24873
25413
|
method: "POST",
|
|
@@ -25012,7 +25552,7 @@ function parseResponse2(response) {
|
|
|
25012
25552
|
...response.id !== undefined ? { requestId: response.id } : {}
|
|
25013
25553
|
};
|
|
25014
25554
|
}
|
|
25015
|
-
var
|
|
25555
|
+
var DEFAULT_BASE_URL5 = "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;
|
|
25016
25556
|
var init_anthropic = __esm(() => {
|
|
25017
25557
|
init_model_auth();
|
|
25018
25558
|
init_query();
|
|
@@ -25043,7 +25583,7 @@ var init_anthropic = __esm(() => {
|
|
|
25043
25583
|
const model = envCredential("ANTHROPIC_SEARCH_MODEL") ?? (credential.source === "injected" ? credential.modelId : undefined) ?? DEFAULT_MODEL2;
|
|
25044
25584
|
const parsed = params.parsedQuery ?? parseSearchQuery(params.query);
|
|
25045
25585
|
const plan = planQuery(params.query, parsed);
|
|
25046
|
-
const baseUrl = (credential.baseUrl ??
|
|
25586
|
+
const baseUrl = (credential.baseUrl ?? DEFAULT_BASE_URL5).replace(/\/+$/, "");
|
|
25047
25587
|
const fetchImpl = params.fetch ?? fetch;
|
|
25048
25588
|
const response = await fetchImpl(`${baseUrl}/v1/messages?beta=true`, {
|
|
25049
25589
|
method: "POST",
|
|
@@ -25055,7 +25595,7 @@ var init_anthropic = __esm(() => {
|
|
|
25055
25595
|
},
|
|
25056
25596
|
body: JSON.stringify({
|
|
25057
25597
|
model,
|
|
25058
|
-
max_tokens: params.maxOutputTokens ??
|
|
25598
|
+
max_tokens: params.maxOutputTokens ?? DEFAULT_MAX_TOKENS2,
|
|
25059
25599
|
...params.systemPrompt ? { system: params.systemPrompt } : {},
|
|
25060
25600
|
messages: [{ role: "user", content: plan.query }],
|
|
25061
25601
|
tools: [
|
|
@@ -27138,7 +27678,7 @@ async function searchPublicWeb(params, deadlines = {}) {
|
|
|
27138
27678
|
}
|
|
27139
27679
|
var PUBLIC_ENGINE_IDS, DEFAULT_NUM_RESULTS8 = 15, MAX_NUM_RESULTS8 = 30, SOFT_DEADLINE_MS = 5000, HARD_DEADLINE_MS = 30000, PublicWebProvider;
|
|
27140
27680
|
var init_public = __esm(() => {
|
|
27141
|
-
|
|
27681
|
+
init_provider2();
|
|
27142
27682
|
init_types4();
|
|
27143
27683
|
init_utils();
|
|
27144
27684
|
PUBLIC_ENGINE_IDS = [
|
|
@@ -27212,7 +27752,7 @@ function resolveProviderCandidates(routing = {}) {
|
|
|
27212
27752
|
return candidates;
|
|
27213
27753
|
}
|
|
27214
27754
|
var PROVIDER_META, instanceCache;
|
|
27215
|
-
var
|
|
27755
|
+
var init_provider2 = __esm(() => {
|
|
27216
27756
|
init_types4();
|
|
27217
27757
|
init_types4();
|
|
27218
27758
|
PROVIDER_META = {
|
|
@@ -27398,15 +27938,15 @@ async function executeWebSearch(params, options = {}) {
|
|
|
27398
27938
|
}
|
|
27399
27939
|
var TOTAL_TIMEOUT_MULTIPLIER = 2;
|
|
27400
27940
|
var init_search = __esm(() => {
|
|
27401
|
-
|
|
27941
|
+
init_provider2();
|
|
27402
27942
|
init_query();
|
|
27403
27943
|
init_types4();
|
|
27404
|
-
|
|
27944
|
+
init_provider2();
|
|
27405
27945
|
init_types4();
|
|
27406
27946
|
});
|
|
27407
27947
|
|
|
27408
27948
|
// src/agent/web-search-tool.ts
|
|
27409
|
-
import { Type as
|
|
27949
|
+
import { Type as Type16 } from "typebox";
|
|
27410
27950
|
function createWebSearchTool(options = {}, ledger = new EvidenceLedger) {
|
|
27411
27951
|
return {
|
|
27412
27952
|
name: WEB_SEARCH_TOOL_NAME,
|
|
@@ -27482,15 +28022,15 @@ var WEB_SEARCH_TOOL_NAME = "web_search", webSearchSchema;
|
|
|
27482
28022
|
var init_web_search_tool = __esm(() => {
|
|
27483
28023
|
init_search();
|
|
27484
28024
|
init_evidence_ledger();
|
|
27485
|
-
webSearchSchema =
|
|
27486
|
-
query:
|
|
28025
|
+
webSearchSchema = Type16.Object({
|
|
28026
|
+
query: Type16.String({
|
|
27487
28027
|
description: 'Search query. Supports Google-style directives: site:/-site:, after:/before: (YYYY-MM-DD), inurl:, intitle:, filetype:, "exact phrase", -term, OR.'
|
|
27488
28028
|
}),
|
|
27489
|
-
recency:
|
|
28029
|
+
recency: Type16.Optional(Type16.Union([Type16.Literal("day"), Type16.Literal("week"), Type16.Literal("month"), Type16.Literal("year")], {
|
|
27490
28030
|
description: "Optional recency window for results (pure time filter)."
|
|
27491
28031
|
})),
|
|
27492
|
-
limit:
|
|
27493
|
-
num_search_results:
|
|
28032
|
+
limit: Type16.Optional(Type16.Integer({ description: "Maximum number of results to return." })),
|
|
28033
|
+
num_search_results: Type16.Optional(Type16.Integer({ description: "Alias for limit (result count hint)." }))
|
|
27494
28034
|
});
|
|
27495
28035
|
});
|
|
27496
28036
|
|
|
@@ -27537,10 +28077,7 @@ class AutoRAGAgent {
|
|
|
27537
28077
|
runLogger;
|
|
27538
28078
|
lastQuery;
|
|
27539
28079
|
lastSessionId;
|
|
27540
|
-
sessions = new Map;
|
|
27541
28080
|
activeRun = false;
|
|
27542
|
-
resultCapture;
|
|
27543
|
-
interactiveFastAnswerCallback;
|
|
27544
28081
|
modelNativeSearchAuth;
|
|
27545
28082
|
retrievalTrace = [];
|
|
27546
28083
|
evidenceLedger = new EvidenceLedger;
|
|
@@ -27702,10 +28239,6 @@ class AutoRAGAgent {
|
|
|
27702
28239
|
const searchMinSyncTool = createSearchMinSyncDocumentsTool(() => this.remoteFilteredRetrievalMethod(this.minSyncMethod), (scope) => this.resolveRetrievalScope(scope), this.evidenceLedger);
|
|
27703
28240
|
const searchAllTool = createSearchAllDocumentsTool(this, this.evidenceLedger);
|
|
27704
28241
|
const loadDatasourceSkillTool = createLoadDatasourceSkillTool(this);
|
|
27705
|
-
const emitResultsTool = createEmitResultsTool((details) => this.resultCapture?.(details), {
|
|
27706
|
-
ledger: this.evidenceLedger,
|
|
27707
|
-
allowLocalFiles: !this.remoteSession
|
|
27708
|
-
});
|
|
27709
28242
|
const scanDuplicateDocumentsTool = this.dupeyOptions === false ? undefined : createScanDuplicateDocumentsTool(this);
|
|
27710
28243
|
this.jevJudge = options.jev === undefined || options.jev === false || this.remoteSession ? undefined : createJevJudge(options.jev);
|
|
27711
28244
|
this.jevExtension = this.jevJudge === undefined ? undefined : createJevExtension(this.jevJudge);
|
|
@@ -27740,8 +28273,6 @@ class AutoRAGAgent {
|
|
|
27740
28273
|
"check_memory",
|
|
27741
28274
|
...singleDatasourceTools.map((tool) => tool.name),
|
|
27742
28275
|
LOAD_DATASOURCE_SKILL_TOOL_NAME,
|
|
27743
|
-
EMIT_AUTORAG_RESULTS_TOOL_NAME,
|
|
27744
|
-
EMIT_FAST_ANSWER_TOOL_NAME,
|
|
27745
28276
|
SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME,
|
|
27746
28277
|
SEARCH_ALL_DOCUMENTS_TOOL_NAME,
|
|
27747
28278
|
JIKJI_FIND_TOOL_NAME,
|
|
@@ -27772,7 +28303,6 @@ class AutoRAGAgent {
|
|
|
27772
28303
|
loadDatasourceSkillTool,
|
|
27773
28304
|
...webSearchTool !== undefined ? [webSearchTool] : [],
|
|
27774
28305
|
...webFetchTool !== undefined ? [webFetchTool] : [],
|
|
27775
|
-
emitResultsTool,
|
|
27776
28306
|
...scanDuplicateDocumentsTool !== undefined ? [scanDuplicateDocumentsTool] : [],
|
|
27777
28307
|
...jikjiFindTool !== undefined ? [jikjiFindTool] : [],
|
|
27778
28308
|
...everythingSearchTool !== undefined ? [everythingSearchTool] : [],
|
|
@@ -27919,12 +28449,11 @@ ${context.text}
|
|
|
27919
28449
|
source: "memory"
|
|
27920
28450
|
};
|
|
27921
28451
|
}
|
|
27922
|
-
const registry = this.sessions.get(sessionId)?.registry;
|
|
27923
28452
|
const resultByNumber = new Map(details.results.map((result) => [result.number, result]));
|
|
27924
28453
|
const units = [];
|
|
27925
28454
|
for (const entry of details.mapping) {
|
|
27926
28455
|
const result = resultByNumber.get(entry.number);
|
|
27927
|
-
const refs =
|
|
28456
|
+
const refs = normalizeEntryEvidenceRefs(entry);
|
|
27928
28457
|
if (result === undefined || refs.length === 0)
|
|
27929
28458
|
continue;
|
|
27930
28459
|
for (const ref of refs) {
|
|
@@ -28005,7 +28534,7 @@ ${context.text}
|
|
|
28005
28534
|
providerApiKeys: { [local.provider]: local.apiKey }
|
|
28006
28535
|
};
|
|
28007
28536
|
}
|
|
28008
|
-
async createSearchSession(resolved, systemPrompt
|
|
28537
|
+
async createSearchSession(resolved, systemPrompt) {
|
|
28009
28538
|
if (this.boundPiRuntime !== undefined) {
|
|
28010
28539
|
const session = this.boundPiRuntime.session;
|
|
28011
28540
|
return {
|
|
@@ -28025,10 +28554,7 @@ ${context.text}
|
|
|
28025
28554
|
apiKey: resolved.apiKey,
|
|
28026
28555
|
providerApiKeys: resolved.providerApiKeys,
|
|
28027
28556
|
getSystemPrompt: () => systemPrompt,
|
|
28028
|
-
customTools:
|
|
28029
|
-
...this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
28030
|
-
...extraTools
|
|
28031
|
-
],
|
|
28557
|
+
customTools: this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
28032
28558
|
remoteSession: this.remoteSession,
|
|
28033
28559
|
contextTransform: (messages) => this.withMemoryContext(messages),
|
|
28034
28560
|
...this.jevExtension !== undefined ? { extensionFactories: [this.jevExtension], extensionToolNames: [JEV_TOOL_NAME] } : {}
|
|
@@ -28109,19 +28635,12 @@ ${context.text}
|
|
|
28109
28635
|
modelId: this.boundPiRuntime?.session.model?.id ?? resolved?.model.id
|
|
28110
28636
|
})),
|
|
28111
28637
|
contextTransform: (messages) => this.withMemoryContext(messages),
|
|
28112
|
-
customTools:
|
|
28113
|
-
...this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
28114
|
-
createEmitFastAnswerTool((details) => this.interactiveFastAnswerCallback?.(details), {
|
|
28115
|
-
ledger: this.evidenceLedger
|
|
28116
|
-
})
|
|
28117
|
-
],
|
|
28638
|
+
customTools: this.tools.filter((tool) => !PI_BUILTIN_TOOL_NAMES.includes(tool.name)),
|
|
28118
28639
|
onQuery: (query, pi) => this.runInteractivePiQuery(query, pi),
|
|
28119
|
-
inactiveToolNames: [EMIT_FAST_ANSWER_TOOL_NAME],
|
|
28120
28640
|
...this.jevExtension !== undefined ? { extensionFactories: [this.jevExtension], extensionToolNames: [JEV_TOOL_NAME] } : {},
|
|
28121
28641
|
...this.updateNotice === undefined ? {} : { updateNotice: this.updateNotice }
|
|
28122
28642
|
});
|
|
28123
28643
|
this.boundPiRuntime = runtime.runtime;
|
|
28124
|
-
runtime.runtime.session.setActiveToolsByName(runtime.runtime.session.getActiveToolNames().filter((name) => name !== EMIT_FAST_ANSWER_TOOL_NAME));
|
|
28125
28644
|
const dispose = runtime.dispose;
|
|
28126
28645
|
return {
|
|
28127
28646
|
...runtime,
|
|
@@ -28132,17 +28651,14 @@ ${context.text}
|
|
|
28132
28651
|
}
|
|
28133
28652
|
};
|
|
28134
28653
|
}
|
|
28654
|
+
deriveAnswer(text) {
|
|
28655
|
+
const derived = deriveResultsFromAnswer(text, this.evidenceLedger, { allowLocalFiles: !this.remoteSession });
|
|
28656
|
+
this.routingDiagnostics.push(...derived.diagnostics);
|
|
28657
|
+
return derived.details;
|
|
28658
|
+
}
|
|
28135
28659
|
async runInteractivePiQuery(query, pi) {
|
|
28136
28660
|
pi.setSessionName(query.slice(0, 80));
|
|
28137
|
-
for await (const
|
|
28138
|
-
const text = event.type === "progress" ? event.text : event.response.answer;
|
|
28139
|
-
pi.sendMessage({
|
|
28140
|
-
customType: `autorag.${event.type}`,
|
|
28141
|
-
content: [{ type: "text", text }],
|
|
28142
|
-
display: true,
|
|
28143
|
-
details: event
|
|
28144
|
-
}, { triggerTurn: false });
|
|
28145
|
-
}
|
|
28661
|
+
for await (const _event of this.searchDocumentsStream(query)) {}
|
|
28146
28662
|
}
|
|
28147
28663
|
abort() {
|
|
28148
28664
|
this.activeSession?.abort();
|
|
@@ -28173,11 +28689,6 @@ ${context.text}
|
|
|
28173
28689
|
this.refreshing = false;
|
|
28174
28690
|
}
|
|
28175
28691
|
}
|
|
28176
|
-
getResultRegistry(sessionId) {
|
|
28177
|
-
const sid = sessionId ?? this.lastSessionId;
|
|
28178
|
-
const session = sid ? this.sessions.get(sid) : undefined;
|
|
28179
|
-
return session?.registry ?? new Map;
|
|
28180
|
-
}
|
|
28181
28692
|
async searchDocuments(query, options = {}) {
|
|
28182
28693
|
if (this.activeRun) {
|
|
28183
28694
|
throw new Error("AutoRAG agent is busy; await the in-flight searchDocuments() call before starting another");
|
|
@@ -28189,7 +28700,7 @@ ${context.text}
|
|
|
28189
28700
|
if (trimmedQuery.length === 0) {
|
|
28190
28701
|
this.lastQuery = trimmedQuery;
|
|
28191
28702
|
this.lastSessionId = sessionId;
|
|
28192
|
-
return createEmptySearchDocumentsResponse(sessionId, trimmedQuery, this.
|
|
28703
|
+
return createEmptySearchDocumentsResponse(sessionId, trimmedQuery, this.startupDiagnostics);
|
|
28193
28704
|
}
|
|
28194
28705
|
options = this.normalizeRetrievalOptions(options);
|
|
28195
28706
|
if (this.remoteSession && options.observedSources !== undefined)
|
|
@@ -28225,11 +28736,7 @@ ${context.text}
|
|
|
28225
28736
|
publishPreliminary(details);
|
|
28226
28737
|
};
|
|
28227
28738
|
let session;
|
|
28228
|
-
this.interactiveFastAnswerCallback = emitPreliminary;
|
|
28229
28739
|
let unsubscribers = [];
|
|
28230
|
-
this.resultCapture = (details) => {
|
|
28231
|
-
captured = details;
|
|
28232
|
-
};
|
|
28233
28740
|
let searchStarted = false;
|
|
28234
28741
|
try {
|
|
28235
28742
|
const resolved = await this.resolveSessionModel();
|
|
@@ -28247,7 +28754,7 @@ ${context.text}
|
|
|
28247
28754
|
model: resolved.model.id
|
|
28248
28755
|
});
|
|
28249
28756
|
searchStarted = true;
|
|
28250
|
-
session = await this.createSearchSession(resolved, buildSystemPrompt(this.currentSystemPromptConfig({ modelId: resolved.model.id }))
|
|
28757
|
+
session = await this.createSearchSession(resolved, buildSystemPrompt(this.currentSystemPromptConfig({ modelId: resolved.model.id })));
|
|
28251
28758
|
this.activeSession = session;
|
|
28252
28759
|
unsubscribers = this.configureSearchSession(session);
|
|
28253
28760
|
let timeout;
|
|
@@ -28256,45 +28763,36 @@ ${context.text}
|
|
|
28256
28763
|
await Promise.race([
|
|
28257
28764
|
(async () => {
|
|
28258
28765
|
const plan = await this.planQuery(trimmedQuery, resolved, planAbort.signal);
|
|
28259
|
-
const sessionAgent = session.piSession;
|
|
28260
28766
|
const activeSession = session;
|
|
28261
|
-
const
|
|
28262
|
-
|
|
28263
|
-
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
|
|
28267
|
-
|
|
28268
|
-
|
|
28269
|
-
activeSession.agent.state.thinkingLevel = clampThinkingLevel(resolved.model, this.fastThinkingLevel);
|
|
28270
|
-
activeSession.agent.state.tools = [
|
|
28271
|
-
...this.tools,
|
|
28272
|
-
{ name: EMIT_FAST_ANSWER_TOOL_NAME }
|
|
28273
|
-
];
|
|
28274
|
-
}
|
|
28767
|
+
const sessionAgent = activeSession.piSession;
|
|
28768
|
+
const transcript = () => sessionAgent?.messages ?? activeSession.agent.state.messages;
|
|
28769
|
+
const setThinking = (level) => {
|
|
28770
|
+
const clamped = clampThinkingLevel(resolved.model, level);
|
|
28771
|
+
if (sessionAgent !== undefined)
|
|
28772
|
+
sessionAgent.setThinkingLevel(clamped);
|
|
28773
|
+
else
|
|
28774
|
+
activeSession.agent.state.thinkingLevel = clamped;
|
|
28275
28775
|
};
|
|
28276
28776
|
if (plan.route === "config" && plan.selfConfigSkill !== undefined && this.selfConfig !== undefined) {
|
|
28277
28777
|
selfConfigRun = true;
|
|
28278
28778
|
mkdirSync25(this.workspaceProjectRoot, { recursive: true });
|
|
28279
28779
|
const previousTools = sessionAgent?.getActiveToolNames();
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
sessionAgent.setActiveToolsByName([...PI_BUILTIN_TOOL_NAMES
|
|
28283
|
-
|
|
28284
|
-
activeSession.agent.state.
|
|
28285
|
-
activeSession.agent.state.tools = this.tools.filter((tool) => tool.name === EMIT_AUTORAG_RESULTS_TOOL_NAME);
|
|
28286
|
-
}
|
|
28780
|
+
setThinking(this.finalThinkingLevel);
|
|
28781
|
+
if (sessionAgent !== undefined)
|
|
28782
|
+
sessionAgent.setActiveToolsByName([...PI_BUILTIN_TOOL_NAMES]);
|
|
28783
|
+
else
|
|
28784
|
+
activeSession.agent.state.tools = [];
|
|
28287
28785
|
const configBefore = snapshotConfigFile(this.selfConfig.configPath);
|
|
28288
28786
|
try {
|
|
28289
|
-
await
|
|
28787
|
+
await activeSession.prompt(buildSelfConfigPrompt({
|
|
28290
28788
|
query: trimmedQuery,
|
|
28291
28789
|
configPath: this.selfConfig.configPath,
|
|
28292
28790
|
agentDir: this.piAgentDir ?? getAgentDir3(),
|
|
28293
28791
|
skill: plan.selfConfigSkill
|
|
28294
28792
|
}));
|
|
28295
|
-
|
|
28296
|
-
|
|
28297
|
-
|
|
28793
|
+
const report = finalAnswerText(transcript());
|
|
28794
|
+
if (report !== undefined)
|
|
28795
|
+
captured = this.deriveAnswer(report);
|
|
28298
28796
|
const rolledBack = await rollbackIfBroken(this.selfConfig, configBefore);
|
|
28299
28797
|
if (rolledBack !== undefined) {
|
|
28300
28798
|
this.routingDiagnostics.push({
|
|
@@ -28303,11 +28801,10 @@ ${context.text}
|
|
|
28303
28801
|
message: `The edited config did not validate, so the previous config was restored. ${rolledBack}`,
|
|
28304
28802
|
source: "self-config"
|
|
28305
28803
|
});
|
|
28306
|
-
|
|
28307
|
-
if (emitted !== undefined) {
|
|
28804
|
+
if (captured !== undefined) {
|
|
28308
28805
|
captured = {
|
|
28309
|
-
...
|
|
28310
|
-
answer: `${
|
|
28806
|
+
...captured,
|
|
28807
|
+
answer: `${captured.answer}
|
|
28311
28808
|
|
|
28312
28809
|
Warning: the edited config did not validate, so the previous config was restored (nothing was changed). Problem: ${rolledBack}`
|
|
28313
28810
|
};
|
|
@@ -28321,49 +28818,35 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
28321
28818
|
return;
|
|
28322
28819
|
}
|
|
28323
28820
|
if (plan.route === "direct") {
|
|
28324
|
-
|
|
28325
|
-
await
|
|
28326
|
-
const answer =
|
|
28821
|
+
setThinking(this.fastThinkingLevel);
|
|
28822
|
+
await activeSession.prompt(this.buildDirectAnswerPrompt(trimmedQuery));
|
|
28823
|
+
const answer = finalAnswerText(transcript());
|
|
28327
28824
|
if (answer !== undefined)
|
|
28328
|
-
captured =
|
|
28825
|
+
captured = this.deriveAnswer(answer);
|
|
28329
28826
|
return;
|
|
28330
28827
|
}
|
|
28331
28828
|
const baseline = await this.prefetchInitialRetrievalContext(trimmedQuery, plan.queries, options, plan.datasources);
|
|
28332
|
-
|
|
28333
|
-
await
|
|
28334
|
-
|
|
28335
|
-
|
|
28336
|
-
const text = lastAssistantText(session.piSession?.messages ?? session.agent.state.messages);
|
|
28337
|
-
if (text !== undefined)
|
|
28338
|
-
preliminary = { answer: text, results: [], sources: [], evidenceRefs: [] };
|
|
28339
|
-
}
|
|
28340
|
-
if (preliminary !== undefined)
|
|
28341
|
-
emitPreliminary(preliminary);
|
|
28342
|
-
if (captured !== undefined)
|
|
28343
|
-
return;
|
|
28829
|
+
setThinking(this.fastThinkingLevel);
|
|
28830
|
+
await activeSession.prompt(this.buildFastAnswerPrompt(trimmedQuery, options, baseline));
|
|
28831
|
+
const fastText = finalAnswerText(transcript());
|
|
28832
|
+
const preliminary = fastText === undefined ? undefined : this.deriveAnswer(fastText);
|
|
28344
28833
|
if (preliminary !== undefined) {
|
|
28834
|
+
emitPreliminary(preliminary);
|
|
28345
28835
|
const followUp = await this.shouldFollowUp(trimmedQuery, preliminary);
|
|
28346
28836
|
if (planAbort.signal.aborted)
|
|
28347
28837
|
return;
|
|
28348
28838
|
if (!followUp) {
|
|
28349
|
-
captured =
|
|
28839
|
+
captured = preliminary;
|
|
28350
28840
|
return;
|
|
28351
28841
|
}
|
|
28352
|
-
}
|
|
28353
|
-
if (preliminary !== undefined)
|
|
28354
28842
|
publishPreliminary(preliminary);
|
|
28355
|
-
if (sessionAgent !== undefined) {
|
|
28356
|
-
sessionAgent.setThinkingLevel(clampThinkingLevel(resolved.model, this.finalThinkingLevel));
|
|
28357
|
-
sessionAgent.setActiveToolsByName(sessionAgent.getActiveToolNames().filter((name) => name !== EMIT_FAST_ANSWER_TOOL_NAME));
|
|
28358
|
-
} else {
|
|
28359
|
-
session.agent.state.thinkingLevel = clampThinkingLevel(resolved.model, this.finalThinkingLevel);
|
|
28360
|
-
session.agent.state.tools = [...this.tools];
|
|
28361
28843
|
}
|
|
28844
|
+
setThinking(this.finalThinkingLevel);
|
|
28362
28845
|
const fastAnswerDelivered = preliminary !== undefined && this.preliminaryCallback !== undefined;
|
|
28363
|
-
await
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
|
|
28846
|
+
await activeSession.prompt(this.buildRefinementPrompt(trimmedQuery, options, fastText, fastAnswerDelivered));
|
|
28847
|
+
const finalText = finalAnswerText(transcript());
|
|
28848
|
+
if (finalText !== undefined)
|
|
28849
|
+
captured = this.deriveAnswer(finalText);
|
|
28367
28850
|
})(),
|
|
28368
28851
|
new Promise((resolve, reject) => {
|
|
28369
28852
|
timeout = setTimeout(() => {
|
|
@@ -28383,7 +28866,7 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
28383
28866
|
clearTimeout(timeout);
|
|
28384
28867
|
}
|
|
28385
28868
|
if (captured === undefined && timedOutAfterFastAnswer && fastCaptured !== undefined) {
|
|
28386
|
-
const response = recordStructuredResultsSession(sessionId, trimmedQuery,
|
|
28869
|
+
const response = recordStructuredResultsSession(sessionId, trimmedQuery, fastCaptured, this.memory, [
|
|
28387
28870
|
...this.collectComponentDiagnostics(),
|
|
28388
28871
|
{
|
|
28389
28872
|
code: "search-timeout",
|
|
@@ -28417,15 +28900,15 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
28417
28900
|
sessionId,
|
|
28418
28901
|
query: trimmedQuery,
|
|
28419
28902
|
results: [],
|
|
28420
|
-
answer:
|
|
28903
|
+
answer: buildMissingFinalAnswer(trimmedQuery, reason, this.retrievalTrace, modelError),
|
|
28421
28904
|
searched: this.retrievalTrace.reduce((total, entry) => total + entry.resultCount, 0),
|
|
28422
28905
|
warnings: [],
|
|
28423
28906
|
diagnostics: [
|
|
28424
28907
|
...this.collectComponentDiagnostics(),
|
|
28425
28908
|
{
|
|
28426
|
-
code: "
|
|
28909
|
+
code: "no-final-answer",
|
|
28427
28910
|
severity: "warning",
|
|
28428
|
-
message: "The agent ended its run without
|
|
28911
|
+
message: "The agent ended its run without a final answer message; returning a degraded response that carries the run's retrieval trace."
|
|
28429
28912
|
},
|
|
28430
28913
|
...modelError === undefined ? [] : [
|
|
28431
28914
|
{
|
|
@@ -28471,7 +28954,7 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
28471
28954
|
source: "agent"
|
|
28472
28955
|
});
|
|
28473
28956
|
}
|
|
28474
|
-
const recorded = recordStructuredResultsSession(sessionId, trimmedQuery, captured, this.
|
|
28957
|
+
const recorded = recordStructuredResultsSession(sessionId, trimmedQuery, captured, this.memory, componentDiagnostics, { isolateMemory: this.remoteSession || selfConfigRun });
|
|
28475
28958
|
const memoryDiagnostic = selfConfigRun ? undefined : await this.recordJudgedEvidence(sessionId, trimmedQuery, captured);
|
|
28476
28959
|
const response = memoryDiagnostic === undefined ? recorded : { ...recorded, diagnostics: [...recorded.diagnostics ?? [], memoryDiagnostic] };
|
|
28477
28960
|
this.runLogger.write({
|
|
@@ -28512,36 +28995,25 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
28512
28995
|
});
|
|
28513
28996
|
}
|
|
28514
28997
|
this.activeSession = undefined;
|
|
28515
|
-
this.resultCapture = undefined;
|
|
28516
28998
|
this.activeRetrievalOptions = undefined;
|
|
28517
28999
|
this.preliminaryCallback = undefined;
|
|
28518
|
-
if (this.interactiveFastAnswerCallback === emitPreliminary)
|
|
28519
|
-
this.interactiveFastAnswerCallback = undefined;
|
|
28520
29000
|
this.activeRun = false;
|
|
28521
29001
|
this.memoryContextCache = undefined;
|
|
28522
29002
|
}
|
|
28523
29003
|
}
|
|
28524
29004
|
async* searchDocumentsStream(query, options = {}) {
|
|
28525
29005
|
const queue = [];
|
|
28526
|
-
let progressBuffer = "";
|
|
28527
29006
|
let wake;
|
|
28528
29007
|
let settled = false;
|
|
28529
29008
|
const unsubscribe = this.subscribe((event) => {
|
|
28530
|
-
if (event.type !== "
|
|
29009
|
+
if (event.type !== "message_end" || event.message.role !== "assistant")
|
|
28531
29010
|
return;
|
|
28532
|
-
|
|
28533
|
-
if (text.trim().length === 0)
|
|
29011
|
+
if (event.message.stopReason !== "toolUse")
|
|
28534
29012
|
return;
|
|
28535
|
-
|
|
28536
|
-
if (
|
|
29013
|
+
const text = event.message.content.filter((block) => block.type === "text").map((block) => block.text).join("").trim();
|
|
29014
|
+
if (text === "")
|
|
28537
29015
|
return;
|
|
28538
|
-
queue.push({
|
|
28539
|
-
type: "progress",
|
|
28540
|
-
sessionId: this.lastSessionId ?? "",
|
|
28541
|
-
query: query.trim(),
|
|
28542
|
-
text: progressBuffer
|
|
28543
|
-
});
|
|
28544
|
-
progressBuffer = "";
|
|
29016
|
+
queue.push({ type: "progress", sessionId: this.lastSessionId ?? "", query: query.trim(), text });
|
|
28545
29017
|
wake?.();
|
|
28546
29018
|
wake = undefined;
|
|
28547
29019
|
});
|
|
@@ -28557,15 +29029,6 @@ Warning: the edited config did not validate, so the previous config was restored
|
|
|
28557
29029
|
wake = undefined;
|
|
28558
29030
|
};
|
|
28559
29031
|
const run = this.searchDocuments(query, options).then((response) => {
|
|
28560
|
-
if (progressBuffer.trim() !== "") {
|
|
28561
|
-
queue.push({
|
|
28562
|
-
type: "progress",
|
|
28563
|
-
sessionId: this.lastSessionId ?? "",
|
|
28564
|
-
query: query.trim(),
|
|
28565
|
-
text: progressBuffer
|
|
28566
|
-
});
|
|
28567
|
-
progressBuffer = "";
|
|
28568
|
-
}
|
|
28569
29032
|
queue.push({ type: "complete", response });
|
|
28570
29033
|
}).catch((error) => {
|
|
28571
29034
|
settled = true;
|
|
@@ -28956,7 +29419,7 @@ ${result.content.replace(/\s+/gu, " ")}`).join(`
|
|
|
28956
29419
|
}
|
|
28957
29420
|
}
|
|
28958
29421
|
buildFastAnswerPrompt(query, options, baseline) {
|
|
28959
|
-
const limit = typeof options.topK === "number" ? `
|
|
29422
|
+
const limit = typeof options.topK === "number" ? ` Cite at most ${options.topK} sources.` : "";
|
|
28960
29423
|
const scope = options.scope ? ` Restrict search to virtual path scope ${options.scope}.` : "";
|
|
28961
29424
|
return `Answer this original query immediately: ${query}${limit}${scope}
|
|
28962
29425
|
|
|
@@ -28968,21 +29431,18 @@ ${baseline}
|
|
|
28968
29431
|
` + `Formatting and content rules for the answer:
|
|
28969
29432
|
` + `- 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.
|
|
28970
29433
|
` + `- Answer the question directly. Do not include specific file paths, datasource descriptions, or retrieval mechanics in the answer text.
|
|
28971
|
-
` + `- Cite evidence with bracketed numbers only (e.g. [1], [2]); do not quote raw chunks or mention source paths directly in the answer.
|
|
28972
29434
|
` + `- ${ANSWER_CITATION_RULE}
|
|
28973
29435
|
` + `- ${ANSWER_IMAGE_EMBED_RULE}
|
|
28974
29436
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack" or "checked Drive but found nothing").
|
|
28975
29437
|
` + `- When evidence conflicts, treat the freshest (most recent) information as the correct source of truth.
|
|
28976
29438
|
` + `- 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.
|
|
28977
29439
|
|
|
28978
|
-
` + `
|
|
29440
|
+
` + `Write the answer as your reply, then stop.`;
|
|
28979
29441
|
}
|
|
28980
29442
|
buildDirectAnswerPrompt(query) {
|
|
28981
29443
|
return `Answer this query directly from your own general knowledge: ${query}
|
|
28982
29444
|
|
|
28983
|
-
` + `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
|
|
28984
|
-
|
|
28985
|
-
` + `Call emit_fast_answer exactly once with the answer and an empty results list, then stop.`;
|
|
29445
|
+
` + `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.`;
|
|
28986
29446
|
}
|
|
28987
29447
|
discoveryHint(sentence) {
|
|
28988
29448
|
const names = this.tools.map((tool) => tool.name).filter((name) => name === JIKJI_FIND_TOOL_NAME || name === EVERYTHING_SEARCH_TOOL_NAME);
|
|
@@ -28996,22 +29456,20 @@ ${baseline}
|
|
|
28996
29456
|
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. `;
|
|
28997
29457
|
}
|
|
28998
29458
|
buildRefinementPrompt(query, options, fastAnswer, fastAnswerDelivered) {
|
|
28999
|
-
const limit = typeof options.topK === "number" ? `
|
|
29459
|
+
const limit = typeof options.topK === "number" ? ` Cite at most ${options.topK} sources.` : "";
|
|
29000
29460
|
const scope = options.scope ? ` Restrict search to virtual path scope ${options.scope}.` : "";
|
|
29001
29461
|
const firstAnswer = formatFirstAnswerContext(fastAnswer, fastAnswerDelivered);
|
|
29002
|
-
const answerRules = fastAnswerDelivered ? `Formatting and content rules for
|
|
29003
|
-
` + `- The user already has the first answer above.
|
|
29462
|
+
const answerRules = fastAnswerDelivered ? `Formatting and content rules for your final answer (DELTA ONLY):
|
|
29463
|
+
` + `- 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.
|
|
29004
29464
|
` + `- NEVER restate or re-list first-answer facts that remain correct, and never repeat its bullet list.
|
|
29005
29465
|
` + `- Mark each item clearly as a correction or as a new finding.
|
|
29006
29466
|
` + `- 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.
|
|
29007
|
-
` + `-
|
|
29008
|
-
` + `- ${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.
|
|
29467
|
+
` + `- ${ANSWER_CITATION_RULE} A correction or new finding that relies on evidence the first answer cited must cite that evidence's id again.
|
|
29009
29468
|
` + `- ${ANSWER_IMAGE_EMBED_RULE} ${ANSWER_IMAGE_DELTA_RULE}
|
|
29010
29469
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack").
|
|
29011
29470
|
` + `- 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):
|
|
29012
29471
|
` + `- 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.
|
|
29013
29472
|
` + `- Answer the question directly. Do not include specific file paths, datasource descriptions, or retrieval mechanics in the answer text.
|
|
29014
|
-
` + `- Cite evidence with bracketed numbers only (e.g. [1], [2]); do not quote raw chunks or mention source paths directly in the answer.
|
|
29015
29473
|
` + `- ${ANSWER_CITATION_RULE}
|
|
29016
29474
|
` + `- ${ANSWER_IMAGE_EMBED_RULE}
|
|
29017
29475
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack").
|
|
@@ -29020,35 +29478,34 @@ ${baseline}
|
|
|
29020
29478
|
|
|
29021
29479
|
` + `${firstAnswer}
|
|
29022
29480
|
|
|
29023
|
-
` + `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()}
|
|
29481
|
+
` + `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()}
|
|
29024
29482
|
|
|
29025
29483
|
` + `${answerRules}
|
|
29026
29484
|
|
|
29027
|
-
` + `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,
|
|
29485
|
+
` + `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.`;
|
|
29028
29486
|
}
|
|
29029
29487
|
buildSearchPrompt(query, options, initialRetrievalContext) {
|
|
29030
|
-
const limit = typeof options.topK === "number" ? `
|
|
29488
|
+
const limit = typeof options.topK === "number" ? ` Cite at most ${options.topK} sources.` : "";
|
|
29031
29489
|
const scope = options.scope ? ` Restrict search to virtual path scope ${options.scope}.` : "";
|
|
29032
29490
|
return `Find and curate information for this original query: ${query}${limit}${scope}
|
|
29033
29491
|
|
|
29034
|
-
` + `Start by deciding whether this is answerable from general knowledge or memory. If it is a generic, stable question, answer it immediately without retrieval
|
|
29492
|
+
` + `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.
|
|
29035
29493
|
|
|
29036
29494
|
` + `Baseline retrieval context:
|
|
29037
29495
|
${initialRetrievalContext ?? "Pending; continue only with a brief progress statement."}
|
|
29038
29496
|
|
|
29039
|
-
` + `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.
|
|
29497
|
+
` + `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.
|
|
29040
29498
|
|
|
29041
29499
|
` + `Formatting and content rules for the answer:
|
|
29042
29500
|
` + `- 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.
|
|
29043
29501
|
` + `- Answer the question directly. Do not include specific file paths, datasource descriptions, or retrieval mechanics in the answer text.
|
|
29044
|
-
` + `- Cite evidence with bracketed numbers only (e.g. [1], [2]); do not quote raw chunks or mention source paths directly in the answer.
|
|
29045
29502
|
` + `- ${ANSWER_CITATION_RULE}
|
|
29046
29503
|
` + `- ${ANSWER_IMAGE_EMBED_RULE}
|
|
29047
29504
|
` + `- Do not report per-source negative findings (e.g. "no information found in Slack").
|
|
29048
29505
|
` + `- When evidence conflicts, treat the freshest (most recent) information as the correct source of truth.
|
|
29049
29506
|
` + `- If information is incomplete or uncertain, acknowledge it briefly without lengthy explanations. If there are partial clues or leads, mention them concisely.
|
|
29050
29507
|
|
|
29051
|
-
` + `${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,
|
|
29508
|
+
` + `${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.`;
|
|
29052
29509
|
}
|
|
29053
29510
|
async refresh(force = false, opts) {
|
|
29054
29511
|
const methods = opts?.methods;
|
|
@@ -29680,57 +30137,21 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
29680
30137
|
function formatRerankedBaseline(results, evidenceIds) {
|
|
29681
30138
|
const lines = results.map((result, index) => `[${evidenceIds[index]}] ${result.source}
|
|
29682
30139
|
${result.content.replace(/\s+/gu, " ")}`);
|
|
29683
|
-
return `Reranked initial candidates (ordered by relevance to the query; cite evidence by its [eN] id
|
|
30140
|
+
return `Reranked initial candidates (ordered by relevance to the query; cite evidence by its [eN] id):
|
|
29684
30141
|
${lines.join(`
|
|
29685
30142
|
`)}`;
|
|
29686
30143
|
}
|
|
29687
|
-
function fastAnswerAsFinal(fastAnswer) {
|
|
29688
|
-
const refsByNumber = new Map(fastAnswer.evidenceRefs.map((entry) => [entry.number, entry.refs]));
|
|
29689
|
-
return {
|
|
29690
|
-
answer: fastAnswer.answer,
|
|
29691
|
-
results: fastAnswer.results.map((result) => ({
|
|
29692
|
-
number: result.number,
|
|
29693
|
-
title: result.title,
|
|
29694
|
-
summary: result.summary,
|
|
29695
|
-
evidence: result.evidence,
|
|
29696
|
-
confidence: result.confidence ?? 0.5
|
|
29697
|
-
})),
|
|
29698
|
-
mapping: fastAnswer.results.map((result) => {
|
|
29699
|
-
const refs = refsByNumber.get(result.number) ?? [];
|
|
29700
|
-
const primary = refs[0];
|
|
29701
|
-
return {
|
|
29702
|
-
number: result.number,
|
|
29703
|
-
source: primary?.source ?? "",
|
|
29704
|
-
method: primary?.method ?? EMIT_FAST_ANSWER_TOOL_NAME,
|
|
29705
|
-
content: primary?.content ?? (result.evidence.map((evidence) => evidence.excerpt).join(`
|
|
29706
|
-
`) || result.summary),
|
|
29707
|
-
evidenceRefs: refs
|
|
29708
|
-
};
|
|
29709
|
-
}),
|
|
29710
|
-
warnings: []
|
|
29711
|
-
};
|
|
29712
|
-
}
|
|
29713
30144
|
function formatFirstAnswerContext(fastAnswer, delivered) {
|
|
29714
30145
|
if (fastAnswer === undefined) {
|
|
29715
30146
|
return "(the fast phase produced no answer — write the complete answer)";
|
|
29716
30147
|
}
|
|
29717
|
-
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:";
|
|
29718
|
-
const units = fastAnswer.results.length === 0 ? "" : `
|
|
29719
|
-
|
|
29720
|
-
Numbered units of that first answer (its own numbering — NOT citation numbers for your final answer; cite only the results you emit):
|
|
29721
|
-
${fastAnswer.results.map((result) => `[${result.number}] ${result.title} — ${result.summary}`).join(`
|
|
29722
|
-
`)}`;
|
|
29723
|
-
const sources = fastAnswer.sources.length === 0 ? "" : `
|
|
29724
|
-
|
|
29725
|
-
Sources of that first answer:
|
|
29726
|
-
${fastAnswer.sources.map((entry) => `[${entry.number}] -> ${entry.source}`).join(`
|
|
29727
|
-
`)}`;
|
|
30148
|
+
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:";
|
|
29728
30149
|
return `${header}
|
|
29729
|
-
${fastAnswer
|
|
30150
|
+
${fastAnswer}`;
|
|
29730
30151
|
}
|
|
29731
|
-
function
|
|
30152
|
+
function buildMissingFinalAnswer(query, reason, trace, modelError) {
|
|
29732
30153
|
const lines = [
|
|
29733
|
-
`The search run for "${query}" ended without
|
|
30154
|
+
`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.`,
|
|
29734
30155
|
...modelError === undefined ? [] : [`The model request failed: ${modelError}`],
|
|
29735
30156
|
...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}"`],
|
|
29736
30157
|
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.",
|
|
@@ -29751,8 +30172,17 @@ function lastModelRequestError(messages) {
|
|
|
29751
30172
|
}
|
|
29752
30173
|
return;
|
|
29753
30174
|
}
|
|
29754
|
-
function
|
|
29755
|
-
|
|
30175
|
+
function finalAnswerText(messages) {
|
|
30176
|
+
for (let index = messages.length - 1;index >= 0; index--) {
|
|
30177
|
+
const message = messages[index];
|
|
30178
|
+
if (message.role !== "assistant")
|
|
30179
|
+
continue;
|
|
30180
|
+
if (message.stopReason !== "stop")
|
|
30181
|
+
return;
|
|
30182
|
+
const text = message.content.filter((block) => block.type === "text").map((block) => block.text).join("").trim();
|
|
30183
|
+
return text === "" ? undefined : text;
|
|
30184
|
+
}
|
|
30185
|
+
return;
|
|
29756
30186
|
}
|
|
29757
30187
|
function lastAssistantText(messages) {
|
|
29758
30188
|
for (let index = messages.length - 1;index >= 0; index--) {
|
|
@@ -29901,7 +30331,7 @@ var init_agent = __esm(() => {
|
|
|
29901
30331
|
init_context();
|
|
29902
30332
|
init_memory();
|
|
29903
30333
|
init_similar_queries();
|
|
29904
|
-
|
|
30334
|
+
init_errors4();
|
|
29905
30335
|
init_minsync();
|
|
29906
30336
|
init_paths();
|
|
29907
30337
|
init_sync();
|
|
@@ -29914,13 +30344,12 @@ var init_agent = __esm(() => {
|
|
|
29914
30344
|
init_rerank();
|
|
29915
30345
|
init_scope();
|
|
29916
30346
|
init_model_auth();
|
|
30347
|
+
init_answer_citations();
|
|
29917
30348
|
init_datasource_skill();
|
|
29918
30349
|
init_dupey_tool();
|
|
29919
|
-
init_emit_results_tool();
|
|
29920
30350
|
init_everything_search_tool();
|
|
29921
30351
|
init_evidence_judgment();
|
|
29922
30352
|
init_evidence_ledger();
|
|
29923
|
-
init_fast_answer_tool();
|
|
29924
30353
|
init_fsearch_search_tool();
|
|
29925
30354
|
init_jev_extension();
|
|
29926
30355
|
init_jikji_find_tool();
|
|
@@ -30009,7 +30438,7 @@ var ALL_METHOD_NAMES;
|
|
|
30009
30438
|
var init_refresh = __esm(() => {
|
|
30010
30439
|
init_agent();
|
|
30011
30440
|
init_embedding_runtime();
|
|
30012
|
-
|
|
30441
|
+
init_config3();
|
|
30013
30442
|
ALL_METHOD_NAMES = ["all", "minsync", "parsed", "datasources", "jikji", "everything", "fsearch"];
|
|
30014
30443
|
});
|
|
30015
30444
|
|
|
@@ -30028,7 +30457,7 @@ async function runStatus(ctx) {
|
|
|
30028
30457
|
}
|
|
30029
30458
|
var init_status = __esm(() => {
|
|
30030
30459
|
init_agent();
|
|
30031
|
-
|
|
30460
|
+
init_config3();
|
|
30032
30461
|
});
|
|
30033
30462
|
|
|
30034
30463
|
// src/cli/commands/search.ts
|
|
@@ -30177,7 +30606,7 @@ var HEALTH_HINT_MESSAGE = "Run autorag health to diagnose model/provider setup."
|
|
|
30177
30606
|
var init_search2 = __esm(() => {
|
|
30178
30607
|
init_agent();
|
|
30179
30608
|
init_embedding_runtime();
|
|
30180
|
-
|
|
30609
|
+
init_config3();
|
|
30181
30610
|
AUTH_PATTERNS = [
|
|
30182
30611
|
"api key",
|
|
30183
30612
|
"apikey",
|
|
@@ -30275,7 +30704,7 @@ async function runEvidence(ctx) {
|
|
|
30275
30704
|
}
|
|
30276
30705
|
var init_evidence = __esm(() => {
|
|
30277
30706
|
init_memory();
|
|
30278
|
-
|
|
30707
|
+
init_config3();
|
|
30279
30708
|
});
|
|
30280
30709
|
|
|
30281
30710
|
// src/cli/commands/memory.ts
|
|
@@ -30299,7 +30728,7 @@ async function runMemory(ctx) {
|
|
|
30299
30728
|
var USAGE = "Usage: autorag memory inspect";
|
|
30300
30729
|
var init_memory2 = __esm(() => {
|
|
30301
30730
|
init_memory();
|
|
30302
|
-
|
|
30731
|
+
init_config3();
|
|
30303
30732
|
});
|
|
30304
30733
|
|
|
30305
30734
|
// src/cli/commands/index.ts
|
|
@@ -30411,7 +30840,7 @@ var init_commands = __esm(() => {
|
|
|
30411
30840
|
init_refresh_progress();
|
|
30412
30841
|
init_paths5();
|
|
30413
30842
|
init_paths();
|
|
30414
|
-
|
|
30843
|
+
init_config3();
|
|
30415
30844
|
init_refresh();
|
|
30416
30845
|
ALL_RESET_TARGETS = [PARSED_MIRROR_SUBDIR, MINSYNC_SUBDIR];
|
|
30417
30846
|
ALL_RESET_TARGET_NAMES = ["parsed", "minsync"];
|
|
@@ -30479,7 +30908,7 @@ async function runWatch(ctx) {
|
|
|
30479
30908
|
}
|
|
30480
30909
|
var init_watch = __esm(() => {
|
|
30481
30910
|
init_agent();
|
|
30482
|
-
|
|
30911
|
+
init_config3();
|
|
30483
30912
|
});
|
|
30484
30913
|
|
|
30485
30914
|
// src/cli/commands/health.ts
|
|
@@ -30679,7 +31108,7 @@ async function runHealth(ctx, deps = {}) {
|
|
|
30679
31108
|
}
|
|
30680
31109
|
var DEFAULT_TIMEOUT_MS10 = 1e4;
|
|
30681
31110
|
var init_health = __esm(() => {
|
|
30682
|
-
|
|
31111
|
+
init_config3();
|
|
30683
31112
|
});
|
|
30684
31113
|
|
|
30685
31114
|
// src/cli/commands/duplicates.ts
|
|
@@ -30736,7 +31165,7 @@ function exactGroupsFromScan(scan) {
|
|
|
30736
31165
|
}
|
|
30737
31166
|
var init_duplicates = __esm(() => {
|
|
30738
31167
|
init_dupey();
|
|
30739
|
-
|
|
31168
|
+
init_config3();
|
|
30740
31169
|
});
|
|
30741
31170
|
|
|
30742
31171
|
// src/cli/update-check.ts
|
|
@@ -30881,7 +31310,7 @@ var THINKING_LEVELS2;
|
|
|
30881
31310
|
var init_tui = __esm(() => {
|
|
30882
31311
|
init_agent();
|
|
30883
31312
|
init_pi_session();
|
|
30884
|
-
|
|
31313
|
+
init_config3();
|
|
30885
31314
|
init_update_check();
|
|
30886
31315
|
init_version();
|
|
30887
31316
|
THINKING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
@@ -31069,7 +31498,7 @@ var init_serve = __esm(() => {
|
|
|
31069
31498
|
init_policy();
|
|
31070
31499
|
init_simplex_server();
|
|
31071
31500
|
init_simplex_transport();
|
|
31072
|
-
|
|
31501
|
+
init_config3();
|
|
31073
31502
|
});
|
|
31074
31503
|
|
|
31075
31504
|
// src/cli/commands/p2p.ts
|
|
@@ -31285,7 +31714,7 @@ function readLocalFlags(flags) {
|
|
|
31285
31714
|
var init_p2p = __esm(() => {
|
|
31286
31715
|
init_approval_store();
|
|
31287
31716
|
init_simplex_server();
|
|
31288
|
-
|
|
31717
|
+
init_config3();
|
|
31289
31718
|
});
|
|
31290
31719
|
|
|
31291
31720
|
// src/cli/commands/p2p-policy.ts
|
|
@@ -31447,6 +31876,7 @@ async function listModelCatalog(options) {
|
|
|
31447
31876
|
modelsPath: join40(agentDir, "models.json"),
|
|
31448
31877
|
allowModelNetwork: false
|
|
31449
31878
|
});
|
|
31879
|
+
await registerAutoRAGProvider(runtime);
|
|
31450
31880
|
const key = (provider, id) => `${provider}/${id}`;
|
|
31451
31881
|
let availableKeys = new Set;
|
|
31452
31882
|
try {
|
|
@@ -31526,7 +31956,8 @@ async function runModels(ctx, deps = {}) {
|
|
|
31526
31956
|
}
|
|
31527
31957
|
}
|
|
31528
31958
|
var UsageError;
|
|
31529
|
-
var
|
|
31959
|
+
var init_models2 = __esm(() => {
|
|
31960
|
+
init_provider();
|
|
31530
31961
|
init_embedding_runtime();
|
|
31531
31962
|
UsageError = class UsageError extends Error {
|
|
31532
31963
|
};
|
|
@@ -31606,7 +32037,6 @@ class AutoRAGLite {
|
|
|
31606
32037
|
agent;
|
|
31607
32038
|
retrievalEngine;
|
|
31608
32039
|
memory;
|
|
31609
|
-
sessions = new Map;
|
|
31610
32040
|
constructor(config) {
|
|
31611
32041
|
this.config = config;
|
|
31612
32042
|
const agentOptions = buildAgentOptions(config);
|
|
@@ -31661,14 +32091,11 @@ class AutoRAGLite {
|
|
|
31661
32091
|
return this.retrievalEngine.retrieveByMethod(query, options);
|
|
31662
32092
|
}
|
|
31663
32093
|
recordStructuredResultsSession(sessionId, query, details) {
|
|
31664
|
-
return recordStructuredResultsSession(sessionId, query, details, this.
|
|
32094
|
+
return recordStructuredResultsSession(sessionId, query, details, this.memory);
|
|
31665
32095
|
}
|
|
31666
32096
|
recordReport(query, details) {
|
|
31667
32097
|
return this.recordStructuredResultsSession(randomUUID10(), query, details);
|
|
31668
32098
|
}
|
|
31669
|
-
getResultRegistry(sessionId) {
|
|
31670
|
-
return this.sessions.get(sessionId)?.registry ?? new Map;
|
|
31671
|
-
}
|
|
31672
32099
|
getMemorySchema() {
|
|
31673
32100
|
return structuredClone(this.memory.getSchema());
|
|
31674
32101
|
}
|
|
@@ -31686,9 +32113,9 @@ function createAutoRAGLite(options = {}) {
|
|
|
31686
32113
|
var init_core = __esm(() => {
|
|
31687
32114
|
init_agent();
|
|
31688
32115
|
init_search_documents();
|
|
31689
|
-
|
|
32116
|
+
init_config3();
|
|
31690
32117
|
init_memory();
|
|
31691
|
-
|
|
32118
|
+
init_config3();
|
|
31692
32119
|
});
|
|
31693
32120
|
|
|
31694
32121
|
// src/cli/commands/lite-refresh.ts
|
|
@@ -31708,7 +32135,7 @@ async function runLiteRefresh(ctx) {
|
|
|
31708
32135
|
}
|
|
31709
32136
|
var init_lite_refresh = __esm(() => {
|
|
31710
32137
|
init_core();
|
|
31711
|
-
|
|
32138
|
+
init_config3();
|
|
31712
32139
|
init_refresh();
|
|
31713
32140
|
});
|
|
31714
32141
|
|
|
@@ -31950,6 +32377,60 @@ var init_lite_retrieve = __esm(() => {
|
|
|
31950
32377
|
init_parser();
|
|
31951
32378
|
});
|
|
31952
32379
|
|
|
32380
|
+
// src/agent/results.ts
|
|
32381
|
+
import { Type as Type17 } from "typebox";
|
|
32382
|
+
var evidenceRefSchema, answerSchema, warningsSchema, curatedResultFields, reportSchema;
|
|
32383
|
+
var init_results = __esm(() => {
|
|
32384
|
+
evidenceRefSchema = Type17.Object({
|
|
32385
|
+
method: Type17.String({ description: "Retrieval method namespace for this evidence chunk" }),
|
|
32386
|
+
source: Type17.String({ description: "Internal opaque source identifier for this evidence chunk" }),
|
|
32387
|
+
excerpt: Type17.Optional(Type17.String({ description: "Evidence excerpt used for stable ID normalization" })),
|
|
32388
|
+
content: Type17.Optional(Type17.String({ description: "Evidence content used for stable ID normalization" })),
|
|
32389
|
+
retrievalResultId: Type17.Optional(Type17.String({ description: "Backend retrieval ID when path-opaque and stable" })),
|
|
32390
|
+
chunkIndex: Type17.Optional(Type17.Integer({ description: "Chunk index, if available" })),
|
|
32391
|
+
lineNumber: Type17.Optional(Type17.Integer({ description: "Line number, if available" })),
|
|
32392
|
+
stableEvidenceId: Type17.Optional(Type17.String({ description: "Stable evidence ID, if already normalized" })),
|
|
32393
|
+
retrieverMix: Type17.Optional(Type17.Array(Type17.String({ maxLength: 64 }), {
|
|
32394
|
+
description: "Retrievers that contributed to this result",
|
|
32395
|
+
maxItems: 8
|
|
32396
|
+
})),
|
|
32397
|
+
parserType: Type17.Optional(Type17.String({ description: "Parser that produced this evidence", maxLength: 120 })),
|
|
32398
|
+
documentType: Type17.Optional(Type17.String({ description: "Document type, if known", maxLength: 120 })),
|
|
32399
|
+
documentArea: Type17.Optional(Type17.String({ description: "Document collection area, if known", maxLength: 120 })),
|
|
32400
|
+
evidenceType: Type17.Optional(Type17.String({ description: "Evidence type, if known", maxLength: 120 })),
|
|
32401
|
+
evidenceLocation: Type17.Optional(Type17.String({ description: "Human-readable evidence location", maxLength: 120 })),
|
|
32402
|
+
confidence: Type17.Optional(Type17.Number({ description: "Evidence confidence, 0..1", minimum: 0, maximum: 1 }))
|
|
32403
|
+
});
|
|
32404
|
+
answerSchema = Type17.String({
|
|
32405
|
+
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}`
|
|
32406
|
+
});
|
|
32407
|
+
warningsSchema = Type17.Optional(Type17.Array(Type17.String(), { description: "Optional warnings about this result set" }));
|
|
32408
|
+
curatedResultFields = {
|
|
32409
|
+
number: Type17.Integer({ description: "1-based result number" }),
|
|
32410
|
+
title: Type17.String({ description: "Short name of the curated knowledge unit" }),
|
|
32411
|
+
summary: Type17.String({ description: "Key insight: purpose, details, and line range" }),
|
|
32412
|
+
evidence: Type17.Array(Type17.Object({
|
|
32413
|
+
excerpt: Type17.String({ description: "Supporting excerpt" }),
|
|
32414
|
+
lineNumber: Type17.Optional(Type17.Integer({ description: "Line number of the excerpt, if known" }))
|
|
32415
|
+
})),
|
|
32416
|
+
confidence: Type17.Number({ description: "Confidence in this result, 0..1", minimum: 0, maximum: 1 })
|
|
32417
|
+
};
|
|
32418
|
+
reportSchema = Type17.Object({
|
|
32419
|
+
answer: answerSchema,
|
|
32420
|
+
results: Type17.Array(Type17.Object(curatedResultFields), { description: "Numbered curated knowledge units." }),
|
|
32421
|
+
mapping: Type17.Array(Type17.Object({
|
|
32422
|
+
number: Type17.Integer({ description: "Matches the result number this entry maps" }),
|
|
32423
|
+
source: Type17.String({ description: "Source identifier — a real file path or a datasource id" }),
|
|
32424
|
+
method: Type17.String({ description: "Retrieval method or tool that produced the source" }),
|
|
32425
|
+
content: Type17.String({ description: "Raw content snippet of the evidence behind this result" }),
|
|
32426
|
+
evidenceRefs: Type17.Optional(Type17.Array(evidenceRefSchema, {
|
|
32427
|
+
description: "Hidden evidence chunk references supporting this curated result"
|
|
32428
|
+
}))
|
|
32429
|
+
}), { description: "Internal number -> source/method mapping. One entry per result number." }),
|
|
32430
|
+
warnings: warningsSchema
|
|
32431
|
+
});
|
|
32432
|
+
});
|
|
32433
|
+
|
|
31953
32434
|
// src/cli/commands/report.ts
|
|
31954
32435
|
import { readFileSync as readFileSync28 } from "node:fs";
|
|
31955
32436
|
import { Value as Value3 } from "typebox/value";
|
|
@@ -32045,9 +32526,9 @@ async function runReport(ctx) {
|
|
|
32045
32526
|
}
|
|
32046
32527
|
var MAX_REPORTED_SCHEMA_ERRORS = 8;
|
|
32047
32528
|
var init_report = __esm(() => {
|
|
32048
|
-
|
|
32529
|
+
init_results();
|
|
32049
32530
|
init_core();
|
|
32050
|
-
|
|
32531
|
+
init_config3();
|
|
32051
32532
|
});
|
|
32052
32533
|
|
|
32053
32534
|
// src/cli/commands/lite.ts
|
|
@@ -32321,8 +32802,9 @@ var COMMAND_USAGE = {
|
|
|
32321
32802
|
" /resume, /new, /tree Resume, start, or branch sessions",
|
|
32322
32803
|
" /compact, /settings Compact context, edit settings",
|
|
32323
32804
|
"",
|
|
32324
|
-
"AutoRAG
|
|
32325
|
-
"
|
|
32805
|
+
"AutoRAG adds its retrieval tools and runs the two-phase search in the same",
|
|
32806
|
+
"session: the model's progress notes, first answer, and final answer are",
|
|
32807
|
+
"ordinary assistant messages in it.",
|
|
32326
32808
|
"",
|
|
32327
32809
|
"Flags:",
|
|
32328
32810
|
" --fast-thinking <lvl> Thinking level for the fast first answer",
|
|
@@ -32675,7 +33157,7 @@ async function dispatch(command, ctx) {
|
|
|
32675
33157
|
return dispatchLite(ctx);
|
|
32676
33158
|
}
|
|
32677
33159
|
case "models": {
|
|
32678
|
-
await Promise.resolve().then(() =>
|
|
33160
|
+
await Promise.resolve().then(() => init_models2());
|
|
32679
33161
|
return runModels(ctx);
|
|
32680
33162
|
}
|
|
32681
33163
|
case "gateway": {
|