@lacneu/openclaw-knowledge 3.1.2 → 3.2.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +264 -1
  2. package/README.md +131 -0
  3. package/dist/config.d.ts +4 -0
  4. package/dist/config.js +26 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/index.d.ts +25 -4
  7. package/dist/index.js +295 -46
  8. package/dist/index.js.map +1 -1
  9. package/dist/jina/classifier.d.ts +55 -0
  10. package/dist/jina/classifier.js +170 -0
  11. package/dist/jina/classifier.js.map +1 -0
  12. package/dist/jina/client.d.ts +30 -0
  13. package/dist/jina/client.js +131 -0
  14. package/dist/jina/client.js.map +1 -0
  15. package/dist/jina/errors.d.ts +42 -0
  16. package/dist/jina/errors.js +113 -0
  17. package/dist/jina/errors.js.map +1 -0
  18. package/dist/jina/reranker.d.ts +34 -0
  19. package/dist/jina/reranker.js +95 -0
  20. package/dist/jina/reranker.js.map +1 -0
  21. package/dist/jina/types.d.ts +78 -0
  22. package/dist/jina/types.js +12 -0
  23. package/dist/jina/types.js.map +1 -0
  24. package/dist/pgvector.d.ts +29 -0
  25. package/dist/pgvector.js +68 -0
  26. package/dist/pgvector.js.map +1 -1
  27. package/dist/router/heuristic.d.ts +29 -0
  28. package/dist/router/heuristic.js +104 -0
  29. package/dist/router/heuristic.js.map +1 -0
  30. package/dist/router/index.d.ts +33 -0
  31. package/dist/router/index.js +94 -0
  32. package/dist/router/index.js.map +1 -0
  33. package/dist/router/labels.d.ts +33 -0
  34. package/dist/router/labels.js +67 -0
  35. package/dist/router/labels.js.map +1 -0
  36. package/dist/router/types.d.ts +23 -0
  37. package/dist/router/types.js +7 -0
  38. package/dist/router/types.js.map +1 -0
  39. package/dist/tracing/events.d.ts +83 -0
  40. package/dist/tracing/events.js +86 -0
  41. package/dist/tracing/events.js.map +1 -0
  42. package/dist/types.d.ts +57 -0
  43. package/openclaw.plugin.json +97 -4
  44. package/package.json +3 -3
@@ -0,0 +1,170 @@
1
+ // Jina Classifier client.
2
+ //
3
+ // Wraps POST /v1/classify in both modes:
4
+ //
5
+ // - **zero-shot** — caller supplies `labels`; Jina embeds them on the fly
6
+ // and matches against the input. Up to 256 classes.
7
+ // Stateless.
8
+ //
9
+ // - **few-shot** — caller supplies a `classifier_id` from a prior
10
+ // training run. The plugin does NOT implement training
11
+ // (/v1/train) — that is an explicit out-of-band step
12
+ // performed via the Jina Playground or a one-off
13
+ // script. Rationale: training is a rare, deliberate
14
+ // act; baking it into the plugin would invite
15
+ // accidental retraining on every plugin reload.
16
+ //
17
+ // Defensive response parsing:
18
+ // Jina has historically used several field names for the predicted label
19
+ // across docs revisions: `predictions[0].label`, `predictions[0].prediction`,
20
+ // `label`, `prediction`. The parser tries each known path in turn and falls
21
+ // back to `null` if none matches (callers treat `null` like a Jina outage
22
+ // → fail-open route).
23
+ import { postJson } from "./client.js";
24
+ const CLASSIFY_URL = "https://api.jina.ai/v1/classify";
25
+ /** Defaults aligned with the plugin's "no-config" mode. */
26
+ const DEFAULT_CLASSIFIER_MODEL = "jina-embeddings-v3";
27
+ /**
28
+ * Classify `text` against a list of semantic labels.
29
+ *
30
+ * Returns `null` when:
31
+ * - the response shape is unexpected (Jina rev mismatch),
32
+ * - the predicted label does not exactly match any provided label (we
33
+ * refuse to invent a class — the router should treat this as "unknown").
34
+ *
35
+ * Throws on network / API errors so the caller's circuit breaker can react.
36
+ */
37
+ export async function classifyZeroShot({ apiKey, text, labels, model = DEFAULT_CLASSIFIER_MODEL, timeoutMs, signal, }) {
38
+ if (labels.length < 2) {
39
+ // Jina rejects requests with fewer than 2 labels; surface a clearer
40
+ // error than the upstream's generic 400.
41
+ throw new Error("classifyZeroShot: at least 2 labels are required");
42
+ }
43
+ const body = {
44
+ model,
45
+ input: [{ text }],
46
+ labels,
47
+ };
48
+ const raw = await postJson({
49
+ url: CLASSIFY_URL,
50
+ body,
51
+ apiKey,
52
+ timeoutMs,
53
+ signal,
54
+ });
55
+ return parseClassificationResponse(raw, labels);
56
+ }
57
+ /**
58
+ * Classify `text` using a pre-trained few-shot classifier identified by
59
+ * `classifierId`. Same `null`-vs-throw contract as `classifyZeroShot`.
60
+ */
61
+ export async function classifyFewShot({ apiKey, text, classifierId, expectedLabels, timeoutMs, signal, }) {
62
+ if (!classifierId) {
63
+ throw new Error("classifyFewShot: classifierId is required");
64
+ }
65
+ const body = {
66
+ classifier_id: classifierId,
67
+ input: [{ text }],
68
+ };
69
+ const raw = await postJson({
70
+ url: CLASSIFY_URL,
71
+ body,
72
+ apiKey,
73
+ timeoutMs,
74
+ signal,
75
+ });
76
+ return parseClassificationResponse(raw, expectedLabels);
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // Defensive response parser
80
+ // ---------------------------------------------------------------------------
81
+ /**
82
+ * Extract the predicted label + optional score from a Classifier response.
83
+ *
84
+ * Known shapes (in order tried):
85
+ * 1. `{ data: [ { predictions: [ { label, score } ] } ] }`
86
+ * 2. `{ results: [ { label, score } ] }`
87
+ * 3. `{ data: [ { label, score } ] }`
88
+ * 4. `{ data: [ { prediction, confidence } ] }`
89
+ *
90
+ * The first match wins. When `allowedLabels` is provided, the picked label
91
+ * MUST be an exact (case-sensitive) member — otherwise we return `null` and
92
+ * the caller falls back to its safe default (the router treats `null` like
93
+ * an outage).
94
+ *
95
+ * @internal exported only for unit testing
96
+ */
97
+ export function parseClassificationResponse(raw, allowedLabels) {
98
+ const candidates = extractCandidates(raw);
99
+ for (const candidate of candidates) {
100
+ const label = candidate.label;
101
+ if (typeof label !== "string" || label.length === 0)
102
+ continue;
103
+ if (allowedLabels && allowedLabels.length > 0 && !allowedLabels.includes(label)) {
104
+ // Silent skip — Jina occasionally hallucinates a "best" label that
105
+ // is not in the input set. We never invent a class.
106
+ continue;
107
+ }
108
+ return {
109
+ label,
110
+ score: typeof candidate.score === "number" ? candidate.score : null,
111
+ };
112
+ }
113
+ return null;
114
+ }
115
+ function extractCandidates(raw) {
116
+ if (!isRecord(raw))
117
+ return [];
118
+ const candidates = [];
119
+ // Shape #1: data[].predictions[] — newer Jina docs. Falls through when
120
+ // `predictions` is empty so the same payload can still be parsed via
121
+ // shape #3 (data[] flat) below.
122
+ if (Array.isArray(raw.data) && raw.data.length > 0) {
123
+ const first = raw.data[0];
124
+ if (isRecord(first) && Array.isArray(first.predictions)) {
125
+ for (const p of first.predictions) {
126
+ if (!isRecord(p))
127
+ continue;
128
+ candidates.push({
129
+ label: p.label ?? p.prediction,
130
+ score: p.score ?? p.confidence,
131
+ });
132
+ }
133
+ }
134
+ }
135
+ // Shape #2: results[] — older docs / few-shot path.
136
+ if (Array.isArray(raw.results)) {
137
+ for (const r of raw.results) {
138
+ if (!isRecord(r))
139
+ continue;
140
+ candidates.push({
141
+ label: r.label ?? r.prediction,
142
+ score: r.score ?? r.confidence,
143
+ });
144
+ }
145
+ }
146
+ // Shape #3 & #4: data[] flat — `{label, score}` or `{prediction, confidence}`.
147
+ if (Array.isArray(raw.data)) {
148
+ for (const d of raw.data) {
149
+ if (!isRecord(d))
150
+ continue;
151
+ // Only push if at least one of the recognized keys is present, to
152
+ // avoid duplicating the predictions[] entries already captured above
153
+ // when both shapes are present on the same record.
154
+ if (d.label !== undefined ||
155
+ d.prediction !== undefined ||
156
+ d.score !== undefined ||
157
+ d.confidence !== undefined) {
158
+ candidates.push({
159
+ label: d.label ?? d.prediction,
160
+ score: d.score ?? d.confidence,
161
+ });
162
+ }
163
+ }
164
+ }
165
+ return candidates;
166
+ }
167
+ function isRecord(value) {
168
+ return typeof value === "object" && value !== null && !Array.isArray(value);
169
+ }
170
+ //# sourceMappingURL=classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/jina/classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /** Options accepted by every Jina request helper. */
2
+ export interface JinaRequestOptions {
3
+ /** Bearer token sent in `Authorization`. Required. */
4
+ apiKey: string;
5
+ /** Override the default 8 s timeout. */
6
+ timeoutMs?: number;
7
+ /**
8
+ * Optional AbortSignal from the caller. Composed with the internal timeout
9
+ * signal so either source can cancel the request.
10
+ */
11
+ signal?: AbortSignal;
12
+ }
13
+ interface PostJsonParams<Req> extends JinaRequestOptions {
14
+ url: string;
15
+ body: Req;
16
+ }
17
+ /**
18
+ * POST `body` to `url` as JSON, return the parsed JSON response as `unknown`.
19
+ *
20
+ * The response is `unknown` on purpose: callers MUST narrow it with their
21
+ * own defensive parser (Jina occasionally changes response shapes).
22
+ *
23
+ * @throws {JinaAuthError} on 401/403
24
+ * @throws {JinaRateLimitError} on 429
25
+ * @throws {JinaApiError} on any other non-OK status (incl. HTML
26
+ * bodies from upstream CDNs/LBs)
27
+ * @throws {JinaNetworkError} on fetch failure, abort, or timeout
28
+ */
29
+ export declare function postJson<Req>({ url, body, apiKey, timeoutMs, signal: callerSignal, }: PostJsonParams<Req>): Promise<unknown>;
30
+ export {};
@@ -0,0 +1,131 @@
1
+ // HTTP client for the Jina AI cloud API.
2
+ //
3
+ // Centralized so every endpoint wrapper (classifier, reranker) shares the
4
+ // same auth, timeout, and error handling. The client is intentionally tiny
5
+ // and dependency-free — `fetch` + `AbortController` only.
6
+ //
7
+ // Design choices:
8
+ //
9
+ // 1. **Bearer-only auth.** The API key is sent in the `Authorization` header,
10
+ // never in the URL or in error messages. Operators copy the key from the
11
+ // Jina console into the plugin config (with `${JINA_API_KEY}` env
12
+ // substitution) and that's the only place it touches.
13
+ //
14
+ // 2. **Hard timeout via AbortController, covering BOTH the connection AND
15
+ // the body read.** A stalled connection — or, worse, an endpoint that
16
+ // sends headers immediately but never finishes streaming the body —
17
+ // would otherwise hold the agent turn open until the SDK's outer
18
+ // timeout kicks in (usually too long). The internal `controller`
19
+ // remains armed until JSON.parse completes, so `resp.text()` is
20
+ // cancelled by the same `controller.abort()` call as the underlying
21
+ // fetch. Default 8 s — comfortable for cross-Atlantic Jina latency but
22
+ // short enough to keep `before_prompt_build` snappy.
23
+ //
24
+ // 3. **Defensive JSON parsing.** Some upstream errors (502 from a CDN, 503
25
+ // from a load balancer in front of Jina) return HTML, not JSON. Treating
26
+ // the body as JSON without try/catch would crash the plugin with a
27
+ // SyntaxError. We always read as text first, then try to parse; failures
28
+ // become `JinaApiError` with a 200-char body preview.
29
+ //
30
+ // 4. **No automatic retry on 5xx.** The plugin's outer circuit breaker
31
+ // already handles repeated failures (3 errors → 5 min cooldown). Retrying
32
+ // here would just consume more tokens during an outage. Callers that want
33
+ // retries should layer them above this client.
34
+ import { errorForStatus, JinaApiError, JinaNetworkError, previewBody, } from "./errors.js";
35
+ const DEFAULT_TIMEOUT_MS = 8_000;
36
+ /**
37
+ * POST `body` to `url` as JSON, return the parsed JSON response as `unknown`.
38
+ *
39
+ * The response is `unknown` on purpose: callers MUST narrow it with their
40
+ * own defensive parser (Jina occasionally changes response shapes).
41
+ *
42
+ * @throws {JinaAuthError} on 401/403
43
+ * @throws {JinaRateLimitError} on 429
44
+ * @throws {JinaApiError} on any other non-OK status (incl. HTML
45
+ * bodies from upstream CDNs/LBs)
46
+ * @throws {JinaNetworkError} on fetch failure, abort, or timeout
47
+ */
48
+ export async function postJson({ url, body, apiKey, timeoutMs = DEFAULT_TIMEOUT_MS, signal: callerSignal, }) {
49
+ const controller = new AbortController();
50
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
51
+ // If the caller supplied a signal, abort the local controller when it
52
+ // fires so both signals merge into one.
53
+ const onCallerAbort = () => controller.abort();
54
+ if (callerSignal) {
55
+ if (callerSignal.aborted)
56
+ controller.abort();
57
+ else
58
+ callerSignal.addEventListener("abort", onCallerAbort, { once: true });
59
+ }
60
+ try {
61
+ let resp;
62
+ try {
63
+ resp = await fetch(url, {
64
+ method: "POST",
65
+ headers: {
66
+ "Content-Type": "application/json",
67
+ Accept: "application/json",
68
+ Authorization: `Bearer ${apiKey}`,
69
+ },
70
+ body: JSON.stringify(body),
71
+ signal: controller.signal,
72
+ });
73
+ }
74
+ catch (err) {
75
+ throw new JinaNetworkError(networkErrorReason(controller, timeoutMs), err);
76
+ }
77
+ // IMPORTANT: the body read happens BEFORE the timeout is cleared. If
78
+ // the upstream server sends headers immediately but stalls or slowly
79
+ // streams the body, `controller.abort()` (still armed) will reject
80
+ // `resp.text()` with the underlying fetch's abort reason. Without
81
+ // this, the hook could hang for the SDK's outer timeout window.
82
+ const rawBody = await safeReadText(resp, controller, timeoutMs);
83
+ if (!resp.ok) {
84
+ throw errorForStatus(resp.status, previewBody(rawBody));
85
+ }
86
+ try {
87
+ return JSON.parse(rawBody);
88
+ }
89
+ catch {
90
+ // Upstream sometimes returns HTML on partial failures even with HTTP 200.
91
+ throw new JinaApiError(resp.status, previewBody(rawBody));
92
+ }
93
+ }
94
+ finally {
95
+ clearTimeout(timeoutId);
96
+ if (callerSignal)
97
+ callerSignal.removeEventListener("abort", onCallerAbort);
98
+ }
99
+ }
100
+ /**
101
+ * Read the response body as text under the same abort controller as the
102
+ * underlying fetch. A connection that delivered headers but stalls on the
103
+ * body is the failure mode this guards against: when `controller.abort()`
104
+ * fires (timeout OR caller-initiated), the WHATWG fetch spec rejects the
105
+ * pending `resp.text()` promise with the abort reason.
106
+ *
107
+ * Errors during read are mapped:
108
+ * - aborted by timeout/caller → re-throw as `JinaNetworkError`
109
+ * - any other I/O failure → empty string (we still want to attempt
110
+ * error mapping based on the HTTP status)
111
+ */
112
+ async function safeReadText(resp, controller, timeoutMs) {
113
+ try {
114
+ return await resp.text();
115
+ }
116
+ catch (err) {
117
+ if (controller.signal.aborted) {
118
+ throw new JinaNetworkError(networkErrorReason(controller, timeoutMs), err);
119
+ }
120
+ return "";
121
+ }
122
+ }
123
+ /**
124
+ * Format a consistent reason string for a network-level failure.
125
+ * The two distinct cases (timeout vs. raw fetch error) need different
126
+ * wording for log readability.
127
+ */
128
+ function networkErrorReason(controller, timeoutMs) {
129
+ return controller.signal.aborted ? `timed out after ${timeoutMs}ms` : "fetch failed";
130
+ }
131
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/jina/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /** Truncate an upstream error body to a safe length for logging. */
2
+ export declare function previewBody(body: string): string;
3
+ /** Base class for any Jina-related error. */
4
+ export declare class JinaError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ /** 401/403 — operator must rotate or refill the API key. */
8
+ export declare class JinaAuthError extends JinaError {
9
+ constructor(status: number, bodyPreview: string);
10
+ }
11
+ /** 429 — Jina backed off; transient. */
12
+ export declare class JinaRateLimitError extends JinaError {
13
+ constructor(bodyPreview: string);
14
+ }
15
+ /** Any other non-OK HTTP response. */
16
+ export declare class JinaApiError extends JinaError {
17
+ readonly status: number;
18
+ constructor(status: number, bodyPreview: string);
19
+ }
20
+ /** Network failure, abort, timeout. `cause` carries the original error. */
21
+ export declare class JinaNetworkError extends JinaError {
22
+ constructor(reason: string, cause?: unknown);
23
+ }
24
+ /**
25
+ * Classify an HTTP status code into the appropriate Jina error class.
26
+ * Centralized so every endpoint wrapper produces consistent errors.
27
+ */
28
+ export declare function errorForStatus(status: number, bodyPreview: string): JinaError;
29
+ /**
30
+ * Build a privacy-safe one-line description of any thrown value, suitable
31
+ * for `logger.error(...)` in the hook handler.
32
+ *
33
+ * IMPORTANT: this MUST NOT include the upstream body preview that
34
+ * `JinaError.message` carries — that preview can echo the user query or
35
+ * document chunks if Jina's error path mirrors the request. We expose
36
+ * only the error CLASS and (when applicable) the HTTP status code.
37
+ *
38
+ * Non-Jina errors fall through to `error.name`, which is safe by design
39
+ * (it's a class name, not a message). The raw message of an unknown
40
+ * error is NEVER logged here.
41
+ */
42
+ export declare function summarizeJinaError(err: unknown): string;
@@ -0,0 +1,113 @@
1
+ // Typed errors for Jina API calls.
2
+ //
3
+ // We distinguish three failure modes the caller may want to react to
4
+ // differently:
5
+ //
6
+ // - `JinaAuthError` → API key invalid/expired. Permanent until the
7
+ // operator fixes the config; no point retrying.
8
+ // - `JinaRateLimitError` → 429 from Jina. Transient; the circuit breaker
9
+ // should back off but the plugin remains usable
10
+ // on the next turn.
11
+ // - `JinaApiError` → generic non-OK response. Catches every 4xx/5xx
12
+ // that isn't auth or rate-limit.
13
+ // - `JinaNetworkError` → fetch threw / aborted before we got a response.
14
+ // Includes timeouts.
15
+ //
16
+ // All concrete classes extend `JinaError` so callers can `catch (e instanceof
17
+ // JinaError)` to handle them uniformly when they don't care about the
18
+ // subtype.
19
+ //
20
+ // IMPORTANT: error messages NEVER include the API key, the full request body,
21
+ // or the user query verbatim. Bodies are truncated to 200 chars to match the
22
+ // existing pattern in `embeddings.ts` and `lightrag.ts`.
23
+ const ERROR_BODY_PREVIEW_CHARS = 200;
24
+ /** Truncate an upstream error body to a safe length for logging. */
25
+ export function previewBody(body) {
26
+ if (body.length <= ERROR_BODY_PREVIEW_CHARS)
27
+ return body;
28
+ return body.slice(0, ERROR_BODY_PREVIEW_CHARS);
29
+ }
30
+ /** Base class for any Jina-related error. */
31
+ export class JinaError extends Error {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = "JinaError";
35
+ }
36
+ }
37
+ /** 401/403 — operator must rotate or refill the API key. */
38
+ export class JinaAuthError extends JinaError {
39
+ constructor(status, bodyPreview) {
40
+ super(`Jina auth failed (${status}): ${bodyPreview}`);
41
+ this.name = "JinaAuthError";
42
+ }
43
+ }
44
+ /** 429 — Jina backed off; transient. */
45
+ export class JinaRateLimitError extends JinaError {
46
+ constructor(bodyPreview) {
47
+ super(`Jina rate-limited (429): ${bodyPreview}`);
48
+ this.name = "JinaRateLimitError";
49
+ }
50
+ }
51
+ /** Any other non-OK HTTP response. */
52
+ export class JinaApiError extends JinaError {
53
+ status;
54
+ constructor(status, bodyPreview) {
55
+ super(`Jina request failed (${status}): ${bodyPreview}`);
56
+ this.status = status;
57
+ this.name = "JinaApiError";
58
+ }
59
+ }
60
+ /** Network failure, abort, timeout. `cause` carries the original error. */
61
+ export class JinaNetworkError extends JinaError {
62
+ constructor(reason, cause) {
63
+ super(`Jina network error: ${reason}`);
64
+ this.name = "JinaNetworkError";
65
+ if (cause !== undefined) {
66
+ // `Error.cause` is standard since ES2022; keep it readable in stack
67
+ // traces without leaking sensitive context.
68
+ this.cause = cause;
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * Classify an HTTP status code into the appropriate Jina error class.
74
+ * Centralized so every endpoint wrapper produces consistent errors.
75
+ */
76
+ export function errorForStatus(status, bodyPreview) {
77
+ if (status === 401 || status === 403) {
78
+ return new JinaAuthError(status, bodyPreview);
79
+ }
80
+ if (status === 429) {
81
+ return new JinaRateLimitError(bodyPreview);
82
+ }
83
+ return new JinaApiError(status, bodyPreview);
84
+ }
85
+ /**
86
+ * Build a privacy-safe one-line description of any thrown value, suitable
87
+ * for `logger.error(...)` in the hook handler.
88
+ *
89
+ * IMPORTANT: this MUST NOT include the upstream body preview that
90
+ * `JinaError.message` carries — that preview can echo the user query or
91
+ * document chunks if Jina's error path mirrors the request. We expose
92
+ * only the error CLASS and (when applicable) the HTTP status code.
93
+ *
94
+ * Non-Jina errors fall through to `error.name`, which is safe by design
95
+ * (it's a class name, not a message). The raw message of an unknown
96
+ * error is NEVER logged here.
97
+ */
98
+ export function summarizeJinaError(err) {
99
+ if (err instanceof JinaApiError)
100
+ return `JinaApiError(status=${err.status})`;
101
+ if (err instanceof JinaAuthError)
102
+ return "JinaAuthError";
103
+ if (err instanceof JinaRateLimitError)
104
+ return "JinaRateLimitError";
105
+ if (err instanceof JinaNetworkError)
106
+ return "JinaNetworkError";
107
+ if (err instanceof JinaError)
108
+ return err.name;
109
+ if (err instanceof Error)
110
+ return err.name;
111
+ return "unknown-error";
112
+ }
113
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/jina/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { RerankedItem, RerankerModel } from "./types.js";
2
+ export interface RerankParams {
3
+ apiKey: string;
4
+ query: string;
5
+ /** Document texts to rerank. Order MUST match the caller's source array. */
6
+ documents: string[];
7
+ /** Override the default model. */
8
+ model?: RerankerModel;
9
+ /**
10
+ * Keep only the top-N results. When omitted, Jina returns all reranked
11
+ * items (still useful when the caller wants to keep full ordering).
12
+ */
13
+ topN?: number;
14
+ timeoutMs?: number;
15
+ signal?: AbortSignal;
16
+ }
17
+ /**
18
+ * Rerank `documents` against `query` and return the new ordering.
19
+ *
20
+ * Each item carries the ORIGINAL index from the input array plus the new
21
+ * relevance score. Callers should use the `index` to look up their own
22
+ * data structures rather than relying on document text.
23
+ *
24
+ * @returns `[]` for an empty input (no API call) or when the response
25
+ * shape is unrecognized (fail-open semantics).
26
+ * @throws on network / auth / API errors so the cooldown breaker can react.
27
+ */
28
+ export declare function rerank({ apiKey, query, documents, model, topN, timeoutMs, signal, }: RerankParams): Promise<RerankedItem[]>;
29
+ /**
30
+ * Defensive parser for the /v1/rerank response.
31
+ *
32
+ * @internal exported for unit testing
33
+ */
34
+ export declare function parseRerankResponse(raw: unknown, inputCount: number): RerankedItem[];
@@ -0,0 +1,95 @@
1
+ // Jina Reranker client.
2
+ //
3
+ // Wraps POST /v1/rerank for use after a pgvector cosine-similarity pass:
4
+ // vector search returns N coarse candidates, then a cross-encoder rerank
5
+ // promotes the ones that actually answer the query.
6
+ //
7
+ // Implementation choices:
8
+ //
9
+ // 1. **`return_documents: false` is hardcoded.** The caller (pgvector source)
10
+ // already owns the `PgvectorResult` objects and only needs the new
11
+ // ordering. Asking Jina to echo the documents back would multiply the
12
+ // response payload by ~10× for nothing.
13
+ //
14
+ // 2. **`truncate: true` by default.** Lets Jina silently shrink each document
15
+ // to the model's per-doc cap rather than failing the whole batch. The
16
+ // LightRAG-side reranker uses the same setting (`RERANK_ENABLE_CHUNKING`).
17
+ //
18
+ // 3. **Defensive response parsing.** We validate the structural shape
19
+ // (`results: [{index, score}]`) and silently skip malformed entries
20
+ // rather than crashing. An empty or unrecognized response yields an
21
+ // empty array — the caller falls back to the original cosine order.
22
+ import { postJson } from "./client.js";
23
+ const RERANK_URL = "https://api.jina.ai/v1/rerank";
24
+ /**
25
+ * Default reranker model. v2-base-multilingual is the best-balanced choice
26
+ * for French-heavy corpora (LightRAG-side tuning notes from 2026-05-14 show
27
+ * v3 plateauing at 0.05-0.15 on short French queries vs dense chunks).
28
+ */
29
+ const DEFAULT_RERANKER_MODEL = "jina-reranker-v2-base-multilingual";
30
+ /**
31
+ * Rerank `documents` against `query` and return the new ordering.
32
+ *
33
+ * Each item carries the ORIGINAL index from the input array plus the new
34
+ * relevance score. Callers should use the `index` to look up their own
35
+ * data structures rather than relying on document text.
36
+ *
37
+ * @returns `[]` for an empty input (no API call) or when the response
38
+ * shape is unrecognized (fail-open semantics).
39
+ * @throws on network / auth / API errors so the cooldown breaker can react.
40
+ */
41
+ export async function rerank({ apiKey, query, documents, model = DEFAULT_RERANKER_MODEL, topN, timeoutMs, signal, }) {
42
+ if (documents.length === 0)
43
+ return [];
44
+ const body = {
45
+ model,
46
+ query,
47
+ documents,
48
+ return_documents: false,
49
+ truncate: true,
50
+ };
51
+ if (typeof topN === "number" && topN > 0) {
52
+ body.top_n = topN;
53
+ }
54
+ const raw = await postJson({
55
+ url: RERANK_URL,
56
+ body,
57
+ apiKey,
58
+ timeoutMs,
59
+ signal,
60
+ });
61
+ return parseRerankResponse(raw, documents.length);
62
+ }
63
+ /**
64
+ * Defensive parser for the /v1/rerank response.
65
+ *
66
+ * @internal exported for unit testing
67
+ */
68
+ export function parseRerankResponse(raw, inputCount) {
69
+ if (!isRecord(raw))
70
+ return [];
71
+ const results = raw.results;
72
+ if (!Array.isArray(results))
73
+ return [];
74
+ const out = [];
75
+ for (const item of results) {
76
+ if (!isRecord(item))
77
+ continue;
78
+ const index = item.index;
79
+ const score = item.relevance_score ?? item.score;
80
+ if (typeof index !== "number" ||
81
+ !Number.isInteger(index) ||
82
+ index < 0 ||
83
+ index >= inputCount ||
84
+ typeof score !== "number" ||
85
+ !Number.isFinite(score)) {
86
+ continue;
87
+ }
88
+ out.push({ index, score });
89
+ }
90
+ return out;
91
+ }
92
+ function isRecord(value) {
93
+ return typeof value === "object" && value !== null && !Array.isArray(value);
94
+ }
95
+ //# sourceMappingURL=reranker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../src/jina/reranker.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,oDAAoD;AACpD,EAAE;AACF,0BAA0B;AAC1B,EAAE;AACF,8EAA8E;AAC9E,sEAAsE;AACtE,yEAAyE;AACzE,2CAA2C;AAC3C,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,8EAA8E;AAC9E,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,uEAAuE;AACvE,uEAAuE;AAEvE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOvC,MAAM,UAAU,GAAG,+BAA+B,CAAC;AAEnD;;;;GAIG;AACH,MAAM,sBAAsB,GAAkB,oCAAoC,CAAC;AAkBnF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,EAC3B,MAAM,EACN,KAAK,EACL,SAAS,EACT,KAAK,GAAG,sBAAsB,EAC9B,IAAI,EACJ,SAAS,EACT,MAAM,GACO;IACb,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEtC,MAAM,IAAI,GAAsB;QAC9B,KAAK;QACL,KAAK;QACL,SAAS;QACT,gBAAgB,EAAE,KAAK;QACvB,QAAQ,EAAE,IAAI;KACf,CAAC;IACF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAoB;QAC5C,GAAG,EAAE,UAAU;QACf,IAAI;QACJ,MAAM;QACN,SAAS;QACT,MAAM;KACP,CAAC,CAAC;IAEH,OAAO,mBAAmB,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAY,EACZ,UAAkB;IAElB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC;QACjD,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;YACxB,KAAK,GAAG,CAAC;YACT,KAAK,IAAI,UAAU;YACnB,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EACvB,CAAC;YACD,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}