@with-logic/intent 0.1.0 → 0.1.1
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/dist/index.cjs +1143 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.mjs +1102 -0
- package/dist/index.mjs.map +7 -0
- package/package.json +13 -6
- package/dist/batches.js +0 -91
- package/dist/batches.js.map +0 -1
- package/dist/config.js +0 -29
- package/dist/config.js.map +0 -1
- package/dist/extractors.js +0 -88
- package/dist/extractors.js.map +0 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +0 -1
- package/dist/intent.js +0 -540
- package/dist/intent.js.map +0 -1
- package/dist/lib/config.js +0 -81
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/number.js +0 -15
- package/dist/lib/number.js.map +0 -1
- package/dist/llm_client.js +0 -29
- package/dist/llm_client.js.map +0 -1
- package/dist/messages.js +0 -136
- package/dist/messages.js.map +0 -1
- package/dist/providers/groq.js +0 -335
- package/dist/providers/groq.js.map +0 -1
- package/dist/schema.js +0 -114
- package/dist/schema.js.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
package/dist/llm_client.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { CONFIG } from "./config";
|
|
2
|
-
import { createDefaultGroqClient } from "./providers/groq";
|
|
3
|
-
/**
|
|
4
|
-
* Select an LLM client to use for reranking.
|
|
5
|
-
*
|
|
6
|
-
* Implements the client selection logic:
|
|
7
|
-
* 1. If ctx.llm is provided, use it directly
|
|
8
|
-
* 2. Else if GROQ_API_KEY environment variable is set, create default Groq client
|
|
9
|
-
* 3. Else return undefined (caller must handle error)
|
|
10
|
-
*
|
|
11
|
-
* @param ctx - Context object potentially containing an LLM client
|
|
12
|
-
* @returns Selected LLM client, or undefined if none available
|
|
13
|
-
*/
|
|
14
|
-
export function selectLlmClient(ctx, config = CONFIG) {
|
|
15
|
-
if (ctx.llm) {
|
|
16
|
-
return ctx.llm;
|
|
17
|
-
}
|
|
18
|
-
const groqKey = config.GROQ.API_KEY;
|
|
19
|
-
if (groqKey && groqKey !== "") {
|
|
20
|
-
return createDefaultGroqClient(groqKey, {
|
|
21
|
-
defaults: {
|
|
22
|
-
model: config.GROQ.DEFAULT_MODEL,
|
|
23
|
-
reasoningEffort: config.GROQ.DEFAULT_REASONING_EFFORT,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=llm_client.js.map
|
package/dist/llm_client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"llm_client.js","sourceRoot":"","sources":["../src/llm_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAI3D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAkB,EAClB,SAAwB,MAAM;IAE9B,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,OAAO,GAAG,CAAC,GAAG,CAAC;IACjB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IACpC,IAAI,OAAO,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QAC9B,OAAO,uBAAuB,CAAC,OAAO,EAAE;YACtC,QAAQ,EAAE;gBACR,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa;gBAChC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,wBAAwB;aACtD;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/messages.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { jsonStringify } from "./extractors";
|
|
2
|
-
/**
|
|
3
|
-
* Build system + user messages instructing the model to score candidates.
|
|
4
|
-
*
|
|
5
|
-
* Constructs a two-message conversation:
|
|
6
|
-
* 1. System message: Defines the scoring task, output format, and constraints
|
|
7
|
-
* 2. User message: Contains the query and candidate items as JSON
|
|
8
|
-
*
|
|
9
|
-
* The system prompt emphasizes using the full configured score range and being decisive
|
|
10
|
-
* about relevance, with strict instructions to return only the score mapping.
|
|
11
|
-
*
|
|
12
|
-
* @param query - The search query or user intent
|
|
13
|
-
* @param candidates - Array of candidates with keys and summaries
|
|
14
|
-
* @returns Array of chat messages ready for LLM consumption
|
|
15
|
-
*/
|
|
16
|
-
export function buildMessages(query, candidates, scoreRange) {
|
|
17
|
-
const system = `You will receive a JSON blob containing candidate_search_results (each candidate has a key and a short summary) plus a short user request.
|
|
18
|
-
|
|
19
|
-
Your task is to assess each candidate and return a JSON object that maps candidate keys to objects of the form {"explanation": string, "score": integer} avoiding ambiguity.
|
|
20
|
-
|
|
21
|
-
The score must be an integer from ${scoreRange.minScore} to ${scoreRange.maxScore}:
|
|
22
|
-
- ${scoreRange.minScore} means not relevant at all
|
|
23
|
-
- ${scoreRange.maxScore} means highly relevant
|
|
24
|
-
|
|
25
|
-
Sometimes none are relevant, sometimes all are relevant. Be decisive.
|
|
26
|
-
|
|
27
|
-
It is okay to return ${scoreRange.minScore} if the candidate is not relevant to the query. It is okay to return ${scoreRange.maxScore} if the candidate is highly relevant to the query. Use the full range of scores.
|
|
28
|
-
|
|
29
|
-
Every candidate MUST include an explanation. Write the explanation first, then the score. The explanation should be concise (1-3 sentences), concrete, and reference the query intent and the candidate summary.
|
|
30
|
-
|
|
31
|
-
Write explanations as end-user-facing justifications:
|
|
32
|
-
- Do NOT say "the query" or talk about prompt mechanics.
|
|
33
|
-
- Write in a direct, item-first voice (e.g., "gpt-5.2 is best here because it specializes in feature implementation and testing.").
|
|
34
|
-
- Avoid "I"/"we".
|
|
35
|
-
|
|
36
|
-
Every key in candidate_search_results must be present in your output mapping. Do not add any keys that are not present in candidate_search_results.
|
|
37
|
-
Every key in candidate_search_results must map to an object with:
|
|
38
|
-
- explanation: string
|
|
39
|
-
- score: integer from ${scoreRange.minScore} to ${scoreRange.maxScore}
|
|
40
|
-
Do not, in your generated JSON, include anything other than the \`"{key}": {"explanation": "...", "score": 7}\` mappings. Do not include any other text outside the JSON.
|
|
41
|
-
|
|
42
|
-
Return a JSON object that matches the enforced JSON schema for response formatting. Use the candidate.key as the property name in the output mapping.
|
|
43
|
-
|
|
44
|
-
The JSON you return should be of the form: {
|
|
45
|
-
"Key for document 1": { "explanation": "...", "score": ${scoreRange.minScore} },
|
|
46
|
-
"Key for document 2": { "explanation": "...", "score": ${scoreRange.maxScore} },
|
|
47
|
-
...
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
Pretty-print the JSON for readability.`;
|
|
51
|
-
const payload = {
|
|
52
|
-
query,
|
|
53
|
-
candidate_search_results: candidates.map((c) => ({ key: c.key, summary: c.summary })),
|
|
54
|
-
};
|
|
55
|
-
return [
|
|
56
|
-
{ role: "system", content: system },
|
|
57
|
-
{ role: "user", content: jsonStringify(payload) },
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Build system + user messages instructing the model to filter candidates.
|
|
62
|
-
*
|
|
63
|
-
* The model must output a JSON object mapping each candidate key to:
|
|
64
|
-
* Example: {"Some key": {"explanation": "...", "isRelevant": true}}.
|
|
65
|
-
*
|
|
66
|
-
* @param query - The search query or user intent
|
|
67
|
-
* @param candidates - Array of candidates with keys and summaries
|
|
68
|
-
* @returns Array of chat messages ready for LLM consumption
|
|
69
|
-
*/
|
|
70
|
-
export function buildFilterMessages(query, candidates) {
|
|
71
|
-
const system = `You will receive a JSON blob containing candidate_search_results (each candidate has a key and a short summary) plus a short user request.
|
|
72
|
-
|
|
73
|
-
Your task is to assess each candidate and return a JSON object that maps candidate keys to objects of the form {"explanation": string, "isRelevant": boolean}.
|
|
74
|
-
|
|
75
|
-
Return isRelevant=true only when the candidate clearly helps satisfy the query intent. Otherwise return isRelevant=false.
|
|
76
|
-
|
|
77
|
-
Every candidate MUST include an explanation. Write the explanation first, then the boolean. The explanation should be concise (1-3 sentences), concrete, and reference the query intent and the candidate summary.
|
|
78
|
-
|
|
79
|
-
Write explanations as end-user-facing justifications:
|
|
80
|
-
- Do NOT say "the query" or talk about prompt mechanics.
|
|
81
|
-
- Write in a direct, item-first voice.
|
|
82
|
-
- Avoid "I"/"we".
|
|
83
|
-
|
|
84
|
-
Every key in candidate_search_results must be present in your output mapping. Do not add any keys that are not present in candidate_search_results.
|
|
85
|
-
Every key in candidate_search_results must map to an object with:
|
|
86
|
-
- explanation: string
|
|
87
|
-
- isRelevant: boolean
|
|
88
|
-
Do not include anything other than the mapping JSON object. Return only JSON matching the enforced schema.
|
|
89
|
-
|
|
90
|
-
Pretty-print the JSON for readability.`;
|
|
91
|
-
const payload = {
|
|
92
|
-
query,
|
|
93
|
-
candidate_search_results: candidates.map((c) => ({ key: c.key, summary: c.summary })),
|
|
94
|
-
};
|
|
95
|
-
return [
|
|
96
|
-
{ role: "system", content: system },
|
|
97
|
-
{ role: "user", content: jsonStringify(payload) },
|
|
98
|
-
];
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Build system + user messages instructing the model to choose exactly one candidate.
|
|
102
|
-
*
|
|
103
|
-
* The model must output a JSON object of the form:
|
|
104
|
-
* Example: {"explanation": "...", "selectedKey": "Some key"}.
|
|
105
|
-
*
|
|
106
|
-
* @param query - The search query or user intent
|
|
107
|
-
* @param candidates - Array of candidates with keys and summaries
|
|
108
|
-
* @returns Array of chat messages ready for LLM consumption
|
|
109
|
-
*/
|
|
110
|
-
export function buildChoiceMessages(query, candidates) {
|
|
111
|
-
const system = `You will receive a JSON blob containing candidate_search_results (each candidate has a key and a short summary) plus a short user request.
|
|
112
|
-
|
|
113
|
-
Your task is to choose exactly one candidate as the best match for what the user wants.
|
|
114
|
-
|
|
115
|
-
You MUST choose one candidate key from the provided list. Do not choose multiple.
|
|
116
|
-
|
|
117
|
-
Return ONLY JSON of the form: {"explanation": string, "selectedKey": string} where selectedKey is exactly one of the candidate keys. The explanation should be concise (1-3 sentences), concrete, and reference the query intent and the candidate summary.
|
|
118
|
-
|
|
119
|
-
Write the explanation as an end-user-facing justification:
|
|
120
|
-
- Do NOT say "the query" or talk about prompt mechanics.
|
|
121
|
-
- Write in a direct, item-first voice.
|
|
122
|
-
- Avoid "I"/"we".
|
|
123
|
-
|
|
124
|
-
Do not include any other text outside the JSON. Return only JSON matching the enforced schema.
|
|
125
|
-
|
|
126
|
-
Pretty-print the JSON for readability.`;
|
|
127
|
-
const payload = {
|
|
128
|
-
query,
|
|
129
|
-
candidate_search_results: candidates.map((c) => ({ key: c.key, summary: c.summary })),
|
|
130
|
-
};
|
|
131
|
-
return [
|
|
132
|
-
{ role: "system", content: system },
|
|
133
|
-
{ role: "user", content: jsonStringify(payload) },
|
|
134
|
-
];
|
|
135
|
-
}
|
|
136
|
-
//# sourceMappingURL=messages.js.map
|
package/dist/messages.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,UAA6B,EAC7B,UAAkD;IAElD,MAAM,MAAM,GAAG;;;;oCAImB,UAAU,CAAC,QAAQ,OAAO,UAAU,CAAC,QAAQ;IAC7E,UAAU,CAAC,QAAQ;IACnB,UAAU,CAAC,QAAQ;;;;uBAIA,UAAU,CAAC,QAAQ,wEAAwE,UAAU,CAAC,QAAQ;;;;;;;;;;;;wBAY7G,UAAU,CAAC,QAAQ,OAAO,UAAU,CAAC,QAAQ;;;;;;6DAMR,UAAU,CAAC,QAAQ;6DACnB,UAAU,CAAC,QAAQ;;;;uCAIzC,CAAC;IAEtC,MAAM,OAAO,GAAG;QACd,KAAK;QACL,wBAAwB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;KAC7E,CAAC;IAEX,OAAO;QACL,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;QACnC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE;KAClD,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,UAA6B;IAC9E,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;uCAmBsB,CAAC;IAEtC,MAAM,OAAO,GAAG;QACd,KAAK;QACL,wBAAwB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;KAC7E,CAAC;IAEX,OAAO;QACL,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;QACnC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE;KAClD,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,UAA6B;IAC9E,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;uCAesB,CAAC;IAEtC,MAAM,OAAO,GAAG;QACd,KAAK;QACL,wBAAwB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;KAC7E,CAAC;IAEX,OAAO;QACL,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;QACnC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE;KAClD,CAAC;AACJ,CAAC"}
|
package/dist/providers/groq.js
DELETED
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
import Groq from "groq-sdk";
|
|
2
|
-
import { CONFIG } from "../config";
|
|
3
|
-
/**
|
|
4
|
-
* Return a best-effort nested error record from groq-sdk.
|
|
5
|
-
*
|
|
6
|
-
* @param err - Any thrown value
|
|
7
|
-
* @returns Nested `error` object when present
|
|
8
|
-
* @private
|
|
9
|
-
*/
|
|
10
|
-
function getNestedErrorObject(err) {
|
|
11
|
-
if (err == null || typeof err !== "object") {
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
const record = err;
|
|
15
|
-
const error = record.error;
|
|
16
|
-
if (error == null || typeof error !== "object") {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
return error;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Map internal ChatMessage to groq-sdk ChatCompletionMessageParam.
|
|
23
|
-
*
|
|
24
|
-
* Converts our generic message format to Groq's expected format.
|
|
25
|
-
* Only supports system, user, and assistant roles. Throws on unsupported
|
|
26
|
-
* roles (like "tool") to ensure predictable provider behavior.
|
|
27
|
-
*
|
|
28
|
-
* @param messages - Array of generic chat messages
|
|
29
|
-
* @returns Array of Groq-formatted messages
|
|
30
|
-
* @throws {Error} If message contains unsupported role
|
|
31
|
-
* @private
|
|
32
|
-
*/
|
|
33
|
-
function mapToGroqMessages(messages) {
|
|
34
|
-
return messages.map((m) => {
|
|
35
|
-
if (m.role === "system" || m.role === "user" || m.role === "assistant") {
|
|
36
|
-
return { role: m.role, content: m.content };
|
|
37
|
-
}
|
|
38
|
-
throw new Error(`intent: '${m.role}' role messages are not supported in provider calls`);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Build the request payload expected by groq-sdk with strict JSON schema.
|
|
43
|
-
*
|
|
44
|
-
* Constructs the complete request object including model, reasoning effort, messages,
|
|
45
|
-
* optional user ID, and the response_format configuration that enforces strict
|
|
46
|
-
* JSON schema validation on the model's output.
|
|
47
|
-
*
|
|
48
|
-
* @param outputSchema - JSON schema defining expected response structure
|
|
49
|
-
* @param groqMessages - Formatted chat messages
|
|
50
|
-
* @param config - Optional config overriding model and reasoning effort
|
|
51
|
-
* @param userId - Optional user identifier for Groq's abuse monitoring
|
|
52
|
-
* @returns Request payload ready for groq-sdk
|
|
53
|
-
* @private
|
|
54
|
-
*/
|
|
55
|
-
function buildGroqRequest(outputSchema, groqMessages, config, userId, defaults) {
|
|
56
|
-
return {
|
|
57
|
-
model: config?.model ?? defaults.model,
|
|
58
|
-
reasoning_effort: config?.reasoningEffort ?? defaults.reasoningEffort,
|
|
59
|
-
messages: groqMessages,
|
|
60
|
-
...(userId ? { user: userId } : {}),
|
|
61
|
-
response_format: {
|
|
62
|
-
type: "json_schema",
|
|
63
|
-
json_schema: {
|
|
64
|
-
name: "intent_relevancy",
|
|
65
|
-
schema: outputSchema,
|
|
66
|
-
strict: true,
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Execute the chat completion with an optional timeout.
|
|
73
|
-
*
|
|
74
|
-
* Wraps the Groq SDK's chat.completions.create call with optional timeout support.
|
|
75
|
-
*
|
|
76
|
-
* @param client - Initialized Groq SDK client
|
|
77
|
-
* @param request - Complete request payload
|
|
78
|
-
* @param timeoutMs - Optional timeout in milliseconds
|
|
79
|
-
* @returns Raw completion response from Groq
|
|
80
|
-
* @private
|
|
81
|
-
*/
|
|
82
|
-
async function executeCompletion(client, request, timeoutMs) {
|
|
83
|
-
const timeout = typeof timeoutMs === "number" ? { timeout: timeoutMs } : undefined;
|
|
84
|
-
return client.chat.completions.create(request, timeout);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Extract and validate the content string from a Groq response.
|
|
88
|
-
*
|
|
89
|
-
* Safely navigates the response structure to find the message content.
|
|
90
|
-
* Throws if content is missing or not a string.
|
|
91
|
-
*
|
|
92
|
-
* @param response - Raw completion response from Groq SDK
|
|
93
|
-
* @returns The message content as a string
|
|
94
|
-
* @throws {Error} If content is missing or invalid
|
|
95
|
-
* @private
|
|
96
|
-
*/
|
|
97
|
-
function getResponseContent(response) {
|
|
98
|
-
const content = response?.choices?.[0]?.message?.content;
|
|
99
|
-
if (typeof content !== "string") {
|
|
100
|
-
throw new Error("Groq did not return content");
|
|
101
|
-
}
|
|
102
|
-
return content;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Parse the model's JSON content, throwing a clear error on failure.
|
|
106
|
-
*
|
|
107
|
-
* Attempts to parse the string content as JSON and wraps it in a { data } object
|
|
108
|
-
* to match the expected LlmClient return type.
|
|
109
|
-
*
|
|
110
|
-
* @param content - JSON string from model response
|
|
111
|
-
* @returns Wrapped parsed data
|
|
112
|
-
* @throws {Error} If content is not valid JSON
|
|
113
|
-
* @private
|
|
114
|
-
*/
|
|
115
|
-
function parseJson(content) {
|
|
116
|
-
try {
|
|
117
|
-
const data = JSON.parse(content);
|
|
118
|
-
return { data };
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
122
|
-
const err = new Error(`Groq returned invalid JSON: ${detail}`);
|
|
123
|
-
err.rawOutput = content;
|
|
124
|
-
throw err;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Build a repair conversation turn to help the model correct invalid JSON.
|
|
129
|
-
*
|
|
130
|
-
* We include the raw output and the error message, then remind the model to
|
|
131
|
-
* return only valid JSON that matches the already-provided schema.
|
|
132
|
-
*
|
|
133
|
-
* @param baseMessages - Original Groq-formatted messages
|
|
134
|
-
* @param rawOutput - Raw model output that failed parsing
|
|
135
|
-
* @param errorMessage - Parse/validation error message
|
|
136
|
-
* @returns New messages array including a repair request
|
|
137
|
-
* @private
|
|
138
|
-
*/
|
|
139
|
-
function buildJsonRepairMessages(baseMessages, rawOutput, errorMessage) {
|
|
140
|
-
return [
|
|
141
|
-
...baseMessages,
|
|
142
|
-
{ role: "assistant", content: rawOutput },
|
|
143
|
-
{
|
|
144
|
-
role: "user",
|
|
145
|
-
content: "Your previous response was invalid JSON or did not match the required JSON schema. " +
|
|
146
|
-
"Please correct it and return ONLY valid JSON that matches the schema.\n\n" +
|
|
147
|
-
`Error: ${errorMessage}`,
|
|
148
|
-
},
|
|
149
|
-
];
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Build a repair request object if we still have attempts remaining.
|
|
153
|
-
*
|
|
154
|
-
* @param remaining - Attempts remaining for the overall call
|
|
155
|
-
* @param request - The current Groq request
|
|
156
|
-
* @param repair - Repair context
|
|
157
|
-
* @returns The repaired request and decremented remaining attempts, or undefined
|
|
158
|
-
* @private
|
|
159
|
-
*/
|
|
160
|
-
function buildRepairRetry(state, repair) {
|
|
161
|
-
if (state.remaining <= 1) {
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
|
-
const repairedRequest = {
|
|
165
|
-
...state.request,
|
|
166
|
-
messages: buildJsonRepairMessages(state.request.messages, repair.rawOutput, repair.errorMessage),
|
|
167
|
-
};
|
|
168
|
-
return { remaining: state.remaining - 1, request: repairedRequest };
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Convert a JSON parse error into a repair input.
|
|
172
|
-
*
|
|
173
|
-
* @param rawOutput - Raw model output
|
|
174
|
-
* @param parseError - JSON.parse error
|
|
175
|
-
* @returns Repair input
|
|
176
|
-
* @private
|
|
177
|
-
*/
|
|
178
|
-
function parseErrorToRepairInput(rawOutput, parseError) {
|
|
179
|
-
return { rawOutput, errorMessage: String(parseError) };
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Extract raw output from a JSON parse error thrown by parseJson.
|
|
183
|
-
*
|
|
184
|
-
* @param error - Error thrown by parseJson
|
|
185
|
-
* @returns Raw output when present
|
|
186
|
-
* @private
|
|
187
|
-
*/
|
|
188
|
-
function getRawOutputFromParseJsonError(error) {
|
|
189
|
-
if (!(error instanceof Error)) {
|
|
190
|
-
return undefined;
|
|
191
|
-
}
|
|
192
|
-
const record = error;
|
|
193
|
-
return typeof record.rawOutput === "string" ? record.rawOutput : undefined;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Extract repair inputs from a Groq schema-validation failure.
|
|
197
|
-
*
|
|
198
|
-
* Groq can return a rich error payload for `json_validate_failed`, sometimes
|
|
199
|
-
* including the model's `generated_response`. We use this to ask the model to
|
|
200
|
-
* correct its output without re-sending the schema.
|
|
201
|
-
*
|
|
202
|
-
* @param err - Unknown thrown error from groq-sdk
|
|
203
|
-
* @returns Repair inputs when present; otherwise undefined
|
|
204
|
-
* @private
|
|
205
|
-
*/
|
|
206
|
-
function extractJsonValidateFailedRepairInput(err) {
|
|
207
|
-
if (err instanceof Error) {
|
|
208
|
-
const match = err.message.match(/"failed_generation":"(\{.*?\})"/);
|
|
209
|
-
const failedGeneration = match?.[1] ? match[1].replace(/\\"/g, '"') : undefined;
|
|
210
|
-
if (err.message.includes('"code":"json_validate_failed"')) {
|
|
211
|
-
return {
|
|
212
|
-
rawOutput: failedGeneration ?? "(Groq did not include the rejected generation in the error payload)",
|
|
213
|
-
errorMessage: err.message,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
const errorObj = getNestedErrorObject(err);
|
|
218
|
-
const nested = errorObj && typeof errorObj.error === "object"
|
|
219
|
-
? errorObj.error
|
|
220
|
-
: undefined;
|
|
221
|
-
const serverError = nested ?? errorObj;
|
|
222
|
-
if (!serverError) {
|
|
223
|
-
return undefined;
|
|
224
|
-
}
|
|
225
|
-
const code = typeof serverError.code === "string" ? serverError.code : undefined;
|
|
226
|
-
if (code !== "json_validate_failed") {
|
|
227
|
-
return undefined;
|
|
228
|
-
}
|
|
229
|
-
const message = typeof serverError.message === "string" ? serverError.message : undefined;
|
|
230
|
-
const generatedResponse = typeof serverError.generated_response === "string" ? serverError.generated_response : undefined;
|
|
231
|
-
const failedGeneration = typeof serverError.failed_generation === "string" ? serverError.failed_generation : undefined;
|
|
232
|
-
const rawOutput = generatedResponse ?? failedGeneration;
|
|
233
|
-
return {
|
|
234
|
-
rawOutput: rawOutput ?? "(Groq did not include the rejected generation in the error payload)",
|
|
235
|
-
errorMessage: message ?? String(err),
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Create a GroqSdkLike wrapper around groq-sdk.
|
|
240
|
-
*
|
|
241
|
-
* This keeps our provider surface strongly typed while isolating groq-sdk's
|
|
242
|
-
* broader request/response types to a single boundary.
|
|
243
|
-
*
|
|
244
|
-
* @param apiKey - Groq API key
|
|
245
|
-
* @returns GroqSdkLike wrapper
|
|
246
|
-
* @private
|
|
247
|
-
*/
|
|
248
|
-
export function createGroqSdkLike(apiKey) {
|
|
249
|
-
const sdk = new Groq({ apiKey });
|
|
250
|
-
return {
|
|
251
|
-
chat: {
|
|
252
|
-
completions: {
|
|
253
|
-
create: async (req, opts) => {
|
|
254
|
-
// groq-sdk's types lag behind json_schema support; keep the boundary localized.
|
|
255
|
-
return (await sdk.chat.completions.create(req, opts));
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Create the underlying Groq SDK client.
|
|
263
|
-
*
|
|
264
|
-
* This wrapper exists to make the default SDK construction path unit-testable.
|
|
265
|
-
*
|
|
266
|
-
* @param options - Groq SDK constructor options
|
|
267
|
-
* @returns Groq SDK client
|
|
268
|
-
* @private
|
|
269
|
-
*/
|
|
270
|
-
export function createGroqSdk(options) {
|
|
271
|
-
return new Groq(options);
|
|
272
|
-
}
|
|
273
|
-
export function createDefaultGroqClient(apiKey, options) {
|
|
274
|
-
const defaults = {
|
|
275
|
-
model: options?.defaults?.model ?? CONFIG.GROQ.DEFAULT_MODEL,
|
|
276
|
-
reasoningEffort: options?.defaults?.reasoningEffort ?? CONFIG.GROQ.DEFAULT_REASONING_EFFORT,
|
|
277
|
-
};
|
|
278
|
-
const makeSdk = options?.makeSdk ?? createGroqSdkLike;
|
|
279
|
-
const jsonRepairAttempts = options?.jsonRepairAttempts ?? CONFIG.GROQ.JSON_REPAIR_ATTEMPTS;
|
|
280
|
-
return {
|
|
281
|
-
/**
|
|
282
|
-
* Call Groq with JSON schema enforced response and return parsed data.
|
|
283
|
-
*
|
|
284
|
-
* Implements the LlmClient interface with Groq-specific features:
|
|
285
|
-
* - Creates a new SDK client per call with the provided API key
|
|
286
|
-
* - Maps generic messages to Groq format
|
|
287
|
-
* - Builds request with strict JSON schema response format
|
|
288
|
-
* - Retries up to 3 times on json_validate_failed errors
|
|
289
|
-
* - Parses and returns the structured response
|
|
290
|
-
*
|
|
291
|
-
* @param messages - Chat messages to send to the model
|
|
292
|
-
* @param outputSchema - JSON schema defining expected response structure
|
|
293
|
-
* @param config - Optional model, reasoning effort, and timeout overrides
|
|
294
|
-
* @param userId - Optional user ID for Groq's abuse monitoring
|
|
295
|
-
* @returns Parsed response data wrapped in { data } object
|
|
296
|
-
* @throws {Error} If all retry attempts fail or response is invalid
|
|
297
|
-
*/
|
|
298
|
-
async call(messages, outputSchema, config, userId) {
|
|
299
|
-
const client = makeSdk(apiKey);
|
|
300
|
-
const groqMessages = mapToGroqMessages(messages);
|
|
301
|
-
const baseRequest = buildGroqRequest(outputSchema, groqMessages, config, userId, defaults);
|
|
302
|
-
const createWithRetry = async (state) => {
|
|
303
|
-
try {
|
|
304
|
-
const response = await executeCompletion(client, state.request, config?.timeoutMs);
|
|
305
|
-
const content = getResponseContent(response);
|
|
306
|
-
const parsed = parseJson(content);
|
|
307
|
-
return parsed;
|
|
308
|
-
}
|
|
309
|
-
catch (err) {
|
|
310
|
-
// If the model returned bad JSON, retry by appending a repair turn.
|
|
311
|
-
const parseRawOutput = getRawOutputFromParseJsonError(err);
|
|
312
|
-
if (parseRawOutput !== undefined) {
|
|
313
|
-
const retry = buildRepairRetry(state, parseErrorToRepairInput(parseRawOutput, err));
|
|
314
|
-
if (retry) {
|
|
315
|
-
return createWithRetry(retry);
|
|
316
|
-
}
|
|
317
|
-
throw err;
|
|
318
|
-
}
|
|
319
|
-
const validationRepairInput = extractJsonValidateFailedRepairInput(err);
|
|
320
|
-
if (validationRepairInput) {
|
|
321
|
-
const retry = buildRepairRetry(state, validationRepairInput);
|
|
322
|
-
if (retry) {
|
|
323
|
-
return createWithRetry(retry);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
// Non-JSON errors are terminal (quota/outage/etc.).
|
|
327
|
-
throw err;
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
const attempts = Math.max(1, jsonRepairAttempts);
|
|
331
|
-
return createWithRetry({ remaining: attempts, request: baseRequest });
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
//# sourceMappingURL=groq.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"groq.js","sourceRoot":"","sources":["../../src/providers/groq.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Build the schema used for a single candidate's evaluation.
|
|
3
|
-
*
|
|
4
|
-
* Property order is intentional: `explanation` is defined before `score` to
|
|
5
|
-
* encourage structured-output models to generate explanations first.
|
|
6
|
-
*
|
|
7
|
-
* @returns JSON schema for a single candidate evaluation
|
|
8
|
-
*/
|
|
9
|
-
export function buildCandidateEvaluationSchema() {
|
|
10
|
-
return {
|
|
11
|
-
type: "object",
|
|
12
|
-
properties: {
|
|
13
|
-
explanation: { type: "string" },
|
|
14
|
-
score: { type: "integer" },
|
|
15
|
-
},
|
|
16
|
-
required: ["explanation", "score"],
|
|
17
|
-
additionalProperties: false,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Build the schema used for a single candidate's filter decision.
|
|
22
|
-
*
|
|
23
|
-
* Property order is intentional: `explanation` is defined before `isRelevant`.
|
|
24
|
-
*
|
|
25
|
-
* @returns JSON schema for a single candidate filter decision
|
|
26
|
-
*/
|
|
27
|
-
export function buildCandidateFilterSchema() {
|
|
28
|
-
return {
|
|
29
|
-
type: "object",
|
|
30
|
-
properties: {
|
|
31
|
-
explanation: { type: "string" },
|
|
32
|
-
isRelevant: { type: "boolean" },
|
|
33
|
-
},
|
|
34
|
-
required: ["explanation", "isRelevant"],
|
|
35
|
-
additionalProperties: false,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Build a strict JSON schema mapping candidate keys to evaluation objects.
|
|
40
|
-
*
|
|
41
|
-
* Each candidate key maps to an object containing:
|
|
42
|
-
* - explanation: a short justification of the score
|
|
43
|
-
* - score: an integer within the configured range
|
|
44
|
-
*
|
|
45
|
-
* Property order is intentional (`explanation` then `score`) to encourage the
|
|
46
|
-
* model to generate explanations before scores in structured-output modes.
|
|
47
|
-
*
|
|
48
|
-
* @param keys - Array of unique candidate keys
|
|
49
|
-
* @returns JSON schema object enforcing exact structure of response
|
|
50
|
-
*/
|
|
51
|
-
export function buildRelevancySchema(keys, minScore, maxScore) {
|
|
52
|
-
const evaluationSchema = buildCandidateEvaluationSchema();
|
|
53
|
-
const properties = {};
|
|
54
|
-
for (const k of keys) {
|
|
55
|
-
properties[k] = evaluationSchema;
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
title: "Query / Candidate Relevancy Assessment",
|
|
59
|
-
description: `Map candidate results for a search query to relevancy scores (${minScore}-${maxScore}) with explanations.`,
|
|
60
|
-
type: "object",
|
|
61
|
-
properties,
|
|
62
|
-
required: keys,
|
|
63
|
-
additionalProperties: false,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Build a strict JSON schema mapping candidate keys to boolean relevancy decisions.
|
|
68
|
-
*
|
|
69
|
-
* Each candidate key maps to an object containing:
|
|
70
|
-
* - explanation: a short justification
|
|
71
|
-
* - isRelevant: boolean
|
|
72
|
-
*
|
|
73
|
-
* @param keys - Array of unique candidate keys
|
|
74
|
-
* @returns JSON schema object enforcing exact structure of response
|
|
75
|
-
*/
|
|
76
|
-
export function buildFilterSchema(keys) {
|
|
77
|
-
const decisionSchema = buildCandidateFilterSchema();
|
|
78
|
-
const properties = {};
|
|
79
|
-
for (const k of keys) {
|
|
80
|
-
properties[k] = decisionSchema;
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
title: "Query / Candidate Relevancy Filter",
|
|
84
|
-
description: "Map candidate results for a search query to boolean relevancy decisions with explanations.",
|
|
85
|
-
type: "object",
|
|
86
|
-
properties,
|
|
87
|
-
required: keys,
|
|
88
|
-
additionalProperties: false,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Build a strict JSON schema for choosing a single candidate key.
|
|
93
|
-
*
|
|
94
|
-
* The model must return:
|
|
95
|
-
* - explanation: string
|
|
96
|
-
* - selectedKey: one of the provided candidate keys (enum)
|
|
97
|
-
*
|
|
98
|
-
* @param keys - Array of unique candidate keys
|
|
99
|
-
* @returns JSON schema enforcing a single selected key
|
|
100
|
-
*/
|
|
101
|
-
export function buildChoiceSchema(keys) {
|
|
102
|
-
return {
|
|
103
|
-
title: "Query / Candidate Single Choice",
|
|
104
|
-
description: "Choose exactly one candidate key for the query and explain why.",
|
|
105
|
-
type: "object",
|
|
106
|
-
properties: {
|
|
107
|
-
explanation: { type: "string" },
|
|
108
|
-
selectedKey: { type: "string", enum: keys },
|
|
109
|
-
},
|
|
110
|
-
required: ["explanation", "selectedKey"],
|
|
111
|
-
additionalProperties: false,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
//# sourceMappingURL=schema.js.map
|
package/dist/schema.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAoCA;;;;;;;GAOG;AACH,MAAM,UAAU,8BAA8B;IAC5C,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC3B;QACD,QAAQ,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC;QAClC,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAChC;QACD,QAAQ,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC;QACvC,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAc,EACd,QAAgB,EAChB,QAAgB;IAEhB,MAAM,gBAAgB,GAAG,8BAA8B,EAAE,CAAC;IAE1D,MAAM,UAAU,GAA8C,EAAE,CAAC;IACjE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,UAAU,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC;IACnC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,wCAAwC;QAC/C,WAAW,EAAE,iEAAiE,QAAQ,IAAI,QAAQ,sBAAsB;QACxH,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,QAAQ,EAAE,IAAI;QACd,oBAAoB,EAAE,KAAK;KACd,CAAC;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,MAAM,cAAc,GAAG,0BAA0B,EAAE,CAAC;IAEpD,MAAM,UAAU,GAA0C,EAAE,CAAC;IAC7D,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC;IACjC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,oCAAoC;QAC3C,WAAW,EACT,4FAA4F;QAC9F,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,QAAQ,EAAE,IAAI;QACd,oBAAoB,EAAE,KAAK;KACd,CAAC;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,OAAO;QACL,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE,iEAAiE;QAC9E,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;SAC5C;QACD,QAAQ,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;QACxC,oBAAoB,EAAE,KAAK;KACE,CAAC;AAClC,CAAC"}
|
package/dist/types.js
DELETED
package/dist/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|