@gaunt-sloth/core 2.0.0-alpha.35 → 2.0.0-alpha.37
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/config/configDiscovery.d.ts +79 -0
- package/dist/config/configDiscovery.js +80 -0
- package/dist/config/configDiscovery.js.map +1 -0
- package/dist/config/loader.d.ts +6 -5
- package/dist/config/loader.js +229 -92
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +3 -2
- package/dist/config/schema.js +57 -9
- package/dist/config/schema.js.map +1 -1
- package/dist/config/shell-policy.d.ts +58 -26
- package/dist/config/shell-policy.js +60 -27
- package/dist/config/shell-policy.js.map +1 -1
- package/dist/config/tool-descriptions.d.ts +6 -6
- package/dist/config/tool-descriptions.js +7 -7
- package/dist/config/tool-descriptions.js.map +1 -1
- package/dist/config/types.d.ts +34 -31
- package/dist/config/types.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/core/GthAbstractAgent.d.ts +11 -13
- package/dist/core/GthAbstractAgent.js +9 -11
- package/dist/core/GthAbstractAgent.js.map +1 -1
- package/dist/core/GthAgentRunner.d.ts +17 -33
- package/dist/core/GthAgentRunner.js +31 -41
- package/dist/core/GthAgentRunner.js.map +1 -1
- package/dist/core/GthLangChainAgent.js +25 -34
- package/dist/core/GthLangChainAgent.js.map +1 -1
- package/dist/core/approvals/toolAnnotationSources.d.ts +4 -4
- package/dist/core/approvals/toolAnnotationSources.js +8 -8
- package/dist/core/debugCapture.d.ts +2 -3
- package/dist/core/debugCapture.js +1 -2
- package/dist/core/debugCapture.js.map +1 -1
- package/dist/core/gthLeanAgentFactory.d.ts +4 -4
- package/dist/core/gthLeanAgentFactory.js +4 -4
- package/dist/core/launchBanner.d.ts +10 -0
- package/dist/core/launchBanner.js +6 -1
- package/dist/core/launchBanner.js.map +1 -1
- package/dist/core/reasoningBlocks.d.ts +7 -2
- package/dist/core/reasoningBlocks.js +7 -2
- package/dist/core/reasoningBlocks.js.map +1 -1
- package/dist/core/shell/ShellCommandFailedError.d.ts +3 -4
- package/dist/core/shell/ShellCommandFailedError.js +3 -4
- package/dist/core/shell/ShellCommandFailedError.js.map +1 -1
- package/dist/core/shell/approvalStop.d.ts +68 -29
- package/dist/core/shell/approvalStop.js +178 -28
- package/dist/core/shell/approvalStop.js.map +1 -1
- package/dist/core/shell/hardline.d.ts +22 -0
- package/dist/core/shell/hardline.js +81 -0
- package/dist/core/shell/hardline.js.map +1 -1
- package/dist/core/shell/negotiation.d.ts +81 -2
- package/dist/core/shell/negotiation.js +144 -11
- package/dist/core/shell/negotiation.js.map +1 -1
- package/dist/core/shell/rater.d.ts +7 -69
- package/dist/core/shell/rater.js +5 -24
- package/dist/core/shell/rater.js.map +1 -1
- package/dist/core/shell/raterVocabulary.d.ts +119 -0
- package/dist/core/shell/raterVocabulary.js +114 -0
- package/dist/core/shell/raterVocabulary.js.map +1 -0
- package/dist/core/types.d.ts +17 -3
- package/dist/providers/anthropic.js +12 -0
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/configurationPassthrough.d.ts +107 -0
- package/dist/providers/configurationPassthrough.js +148 -0
- package/dist/providers/configurationPassthrough.js.map +1 -0
- package/dist/providers/geminiThinking.d.ts +8 -0
- package/dist/providers/geminiThinking.js +33 -13
- package/dist/providers/geminiThinking.js.map +1 -1
- package/dist/providers/google-genai.js +11 -0
- package/dist/providers/google-genai.js.map +1 -1
- package/dist/providers/groq.js +12 -0
- package/dist/providers/groq.js.map +1 -1
- package/dist/providers/ollama.js +12 -0
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openrouter.d.ts +23 -0
- package/dist/providers/openrouter.js +71 -4
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/vertexai.js +12 -0
- package/dist/providers/vertexai.js.map +1 -1
- package/dist/providers/xai.js +20 -0
- package/dist/providers/xai.js.map +1 -1
- package/dist/runtime/conversation.d.ts +2 -2
- package/dist/runtime/conversation.js +19 -4
- package/dist/runtime/conversation.js.map +1 -1
- package/dist/runtime/singleShot.d.ts +2 -3
- package/dist/runtime/singleShot.js +22 -7
- package/dist/runtime/singleShot.js.map +1 -1
- package/dist/utils/systemPromptNotes.d.ts +17 -20
- package/dist/utils/systemPromptNotes.js +22 -24
- package/dist/utils/systemPromptNotes.js.map +1 -1
- package/dist/utils/untrustedText.d.ts +24 -4
- package/dist/utils/untrustedText.js +25 -4
- package/dist/utils/untrustedText.js.map +1 -1
- package/package.json +4 -4
- package/schema/gsloth-config.schema.json +0 -1
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Model families
|
|
3
|
-
* send any thinking config for a 2.5 image model, so injecting one there would
|
|
4
|
-
* library deliberately withheld; image/tts generations have no reasoning panel to
|
|
5
|
-
* Skipping them keeps
|
|
2
|
+
* Model families to leave alone when ADDING a request for thought summaries. `@langchain/google`
|
|
3
|
+
* itself declines to send any thinking config for a 2.5 image model, so injecting one there would
|
|
4
|
+
* send a field the library deliberately withheld; image/tts generations have no reasoning panel to
|
|
5
|
+
* fill either way. Skipping them keeps the enable path to the models it is about.
|
|
6
|
+
*
|
|
7
|
+
* This gates the ENABLE direction only, and it must never gate the disable one. The sentence it
|
|
8
|
+
* encodes — "we are unsure this model produces a summary, so do not ask for one" — inverts into
|
|
9
|
+
* "…so let one through" the moment the same test is applied to a leak-prevention override, and
|
|
10
|
+
* these families are exactly where `@langchain/google` sets `includeThoughts: true` on its own
|
|
11
|
+
* once a thinking budget is configured.
|
|
6
12
|
*/
|
|
7
13
|
function producesThoughtSummaries(model) {
|
|
8
14
|
if (typeof model !== 'string')
|
|
@@ -18,6 +24,9 @@ function producesThoughtSummaries(model) {
|
|
|
18
24
|
* that decision is left exactly as it stands. Returns the same model instance for chaining.
|
|
19
25
|
*/
|
|
20
26
|
export function applyGeminiThoughtSummaries(model) {
|
|
27
|
+
if (!producesThoughtSummaries(model.model)) {
|
|
28
|
+
return model;
|
|
29
|
+
}
|
|
21
30
|
return overrideThinkingConfig(model, (thinkingConfig) =>
|
|
22
31
|
// `thinkingConfig` is always PRESENT as a key and may hold `undefined`; an explicit value means
|
|
23
32
|
// the user's budget/level was honoured and must win.
|
|
@@ -34,24 +43,35 @@ export function applyGeminiThoughtSummaries(model) {
|
|
|
34
43
|
* no way to tell them apart and prints the thinking as the assistant's answer. Not asking for the
|
|
35
44
|
* summary is the only thing that reliably stops that; nothing is stripped, so the message kept in
|
|
36
45
|
* graph state (and any `thoughtSignature` riding on it) is untouched. Returns the same instance.
|
|
46
|
+
*
|
|
47
|
+
* It applies to EVERY model family, including the image/tts ones the enable path skips: those are
|
|
48
|
+
* precisely where `@langchain/google` sets `includeThoughts: true` itself once a budget or level is
|
|
49
|
+
* configured, so a shared "does this model produce summaries?" guard would let exactly those
|
|
50
|
+
* summaries through. What it will not do is INTRODUCE a thinking config where the library built
|
|
51
|
+
* none — a request that carries no `thinkingConfig` gets no summary anyway (that is the whole
|
|
52
|
+
* premise of {@link applyGeminiThoughtSummaries}), and adding the field to a model family the
|
|
53
|
+
* library withholds it from would send something it deliberately did not.
|
|
37
54
|
*/
|
|
38
55
|
export function disableGeminiThoughtSummaries(model) {
|
|
39
|
-
return overrideThinkingConfig(model, (thinkingConfig) =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
return overrideThinkingConfig(model, (thinkingConfig) => thinkingConfig === undefined
|
|
57
|
+
? thinkingConfig
|
|
58
|
+
: {
|
|
59
|
+
...(typeof thinkingConfig === 'object' && thinkingConfig !== null ? thinkingConfig : {}),
|
|
60
|
+
includeThoughts: false,
|
|
61
|
+
});
|
|
43
62
|
}
|
|
44
63
|
/**
|
|
45
64
|
* Shared plumbing: re-derive `generationConfig.thinkingConfig` on every built request. Models that
|
|
46
|
-
* build no `generationConfig` (every non-Google provider)
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
65
|
+
* build no `generationConfig` (every non-Google provider) are left completely alone, so this is a
|
|
66
|
+
* no-op wherever it does not apply. Which model families to skip is the CALLER's decision, because
|
|
67
|
+
* it differs by direction — see {@link producesThoughtSummaries}. Overrides stack: the outermost one
|
|
68
|
+
* sees what the inner ones produced, which is what lets a surface-level decision override the
|
|
69
|
+
* construction-time default.
|
|
50
70
|
*/
|
|
51
71
|
function overrideThinkingConfig(model, next) {
|
|
52
72
|
const holder = model;
|
|
53
73
|
const original = holder.invocationParams;
|
|
54
|
-
if (typeof original !== 'function'
|
|
74
|
+
if (typeof original !== 'function') {
|
|
55
75
|
return model;
|
|
56
76
|
}
|
|
57
77
|
const bound = original.bind(model);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geminiThinking.js","sourceRoot":"","sources":["../../src/providers/geminiThinking.ts"],"names":[],"mappings":"AAmCA
|
|
1
|
+
{"version":3,"file":"geminiThinking.js","sourceRoot":"","sources":["../../src/providers/geminiThinking.ts"],"names":[],"mappings":"AAmCA;;;;;;;;;;;GAWG;AACH,SAAS,wBAAwB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CAA0B,KAAQ;IAC3E,IAAI,CAAC,wBAAwB,CAAE,KAAwC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,sBAAsB,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,EAAE;IACtD,gGAAgG;IAChG,qDAAqD;IACrD,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,cAAc,CAC1E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,6BAA6B,CAA0B,KAAQ;IAC7E,OAAO,sBAAsB,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,EAAE,CACtD,cAAc,KAAK,SAAS;QAC1B,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC;YACE,GAAG,CAAC,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,eAAe,EAAE,KAAK;SACvB,CACN,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAC7B,KAAQ,EACR,IAA2C;IAE3C,MAAM,MAAM,GAAG,KAA8E,CAAC;IAC9F,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACzC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAuB,CAAC;IACzD,MAAM,CAAC,gBAAgB,GAAG,SAAS,kCAAkC,CACnE,OAAiB;QAEjB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,gBAAgB,GAAG,MAAM,EAAE,gBAAgB,CAAC;QAClD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;QAC7D,IAAI,cAAc,KAAK,gBAAgB,CAAC,cAAc,EAAE,CAAC;YACvD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,GAAG,MAAM,EAAE,gBAAgB,EAAE,EAAE,GAAG,gBAAgB,EAAE,cAAc,EAAE,EAAE,CAAC;IAClF,CAAC,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
|
|
|
4
4
|
import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
|
|
5
5
|
import { applyGeminiToolSchemaSanitizer } from '#src/providers/geminiSchemaSanitizer.js';
|
|
6
6
|
import { applyGeminiThoughtSummaries } from '#src/providers/geminiThinking.js';
|
|
7
|
+
import { NATIVE_CLIENT_REASON, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
|
|
7
8
|
// Function to process JSON config and create Google GenAI LLM instance
|
|
8
9
|
export async function processJsonConfig(llmConfig) {
|
|
9
10
|
const { ChatGoogle } = await import('@langchain/google/node');
|
|
@@ -17,6 +18,16 @@ export async function processJsonConfig(llmConfig) {
|
|
|
17
18
|
};
|
|
18
19
|
delete configFields.type;
|
|
19
20
|
delete configFields.apiKeyEnvironmentVariable;
|
|
21
|
+
// `ChatGoogle` is a native client for the Gemini API, so nothing in a `configuration` block
|
|
22
|
+
// reaches it — say so before dropping it.
|
|
23
|
+
warnUnusedConfiguration({
|
|
24
|
+
provider: 'google-genai',
|
|
25
|
+
configuration: llmConfig.configuration,
|
|
26
|
+
consumedPaths: [],
|
|
27
|
+
reason: NATIVE_CLIENT_REASON,
|
|
28
|
+
guidance: 'ChatGoogle talks to the Gemini API through its own client instead: set "customHeaders", ' +
|
|
29
|
+
'"endpoint" or "apiVersion" as top-level fields of the "llm" block beside "model".',
|
|
30
|
+
});
|
|
20
31
|
// GS2-58: normalise every tool's JSON-Schema at the ChatGoogle boundary so Gemini's OpenAPI-3.0
|
|
21
32
|
// subset accepts built-in, custom, and MCP tools alike (see geminiSchemaSanitizer).
|
|
22
33
|
// CFG-33: ask for the thought summaries of the thinking Gemini already does and already bills,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-genai.js","sourceRoot":"","sources":["../../src/providers/google-genai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"google-genai.js","sourceRoot":"","sources":["../../src/providers/google-genai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAmF;IAEnF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAC9D,wEAAwE;IACxE,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC;IAC5D,MAAM,YAAY,GAAG;QACnB,GAAG,SAAS;QACZ,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,cAAc,CAAC;QACjE,YAAY,EAAE,KAAc;KAC7B,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,CAAC;IACzB,OAAO,YAAY,CAAC,yBAAyB,CAAC;IAC9C,4FAA4F;IAC5F,0CAA0C;IAC1C,uBAAuB,CAAC;QACtB,QAAQ,EAAE,cAAc;QACxB,aAAa,EAAG,SAAyC,CAAC,aAAa;QACvE,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EACN,0FAA0F;YAC1F,mFAAmF;KACtF,CAAC,CAAC;IACH,gGAAgG;IAChG,oFAAoF;IACpF,+FAA+F;IAC/F,6EAA6E;IAC7E,OAAO,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAClG,cAAc,CACZ,2BAA2B,cAAc,qCAAqC;QAC5E,gDAAgD,CACnD,CAAC;AACJ,CAAC"}
|
package/dist/providers/groq.js
CHANGED
|
@@ -2,11 +2,23 @@ import { displayWarning } from '#src/utils/consoleUtils.js';
|
|
|
2
2
|
import { env } from '#src/utils/systemUtils.js';
|
|
3
3
|
import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
|
|
4
4
|
import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
|
|
5
|
+
import { NATIVE_CLIENT_REASON, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
|
|
5
6
|
// Function to process JSON config and create Groq LLM instance
|
|
6
7
|
export async function processJsonConfig(llmConfig) {
|
|
7
8
|
const groq = await import('@langchain/groq');
|
|
8
9
|
// Use config value if available, otherwise use the environment variable
|
|
9
10
|
const groqApiKey = llmConfig.apiKey || env.GROQ_API_KEY;
|
|
11
|
+
// `ChatGroq` builds a Groq SDK client from its own TOP-LEVEL fields, so nothing in a
|
|
12
|
+
// `configuration` block reaches it — say so before dropping it.
|
|
13
|
+
warnUnusedConfiguration({
|
|
14
|
+
provider: 'groq',
|
|
15
|
+
configuration: llmConfig.configuration,
|
|
16
|
+
consumedPaths: [],
|
|
17
|
+
reason: NATIVE_CLIENT_REASON,
|
|
18
|
+
guidance: 'ChatGroq builds a Groq SDK client from top-level fields of the "llm" block instead: set ' +
|
|
19
|
+
'"baseUrl" (note the lower-case "url"), "timeout", "defaultHeaders", "defaultQuery", ' +
|
|
20
|
+
'"httpAgent" or "fetch" beside "model".',
|
|
21
|
+
});
|
|
10
22
|
return new groq.ChatGroq({
|
|
11
23
|
...llmConfig,
|
|
12
24
|
apiKey: groqApiKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groq.js","sourceRoot":"","sources":["../../src/providers/groq.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"groq.js","sourceRoot":"","sources":["../../src/providers/groq.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAwB;IAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC7C,wEAAwE;IACxE,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC;IACxD,qFAAqF;IACrF,gEAAgE;IAChE,uBAAuB,CAAC;QACtB,QAAQ,EAAE,MAAM;QAChB,aAAa,EAAG,SAAyC,CAAC,aAAa;QACvE,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EACN,0FAA0F;YAC1F,sFAAsF;YACtF,wCAAwC;KAC3C,CAAC,CAAC;IACH,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC;QACvB,GAAG,SAAS;QACZ,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,MAAM,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1F,cAAc,CACZ,yBAAyB,cAAc,uBAAuB;QAC5D,8CAA8C,CACjD,CAAC;AACJ,CAAC"}
|
package/dist/providers/ollama.js
CHANGED
|
@@ -2,6 +2,7 @@ import { displayWarning } from '#src/utils/consoleUtils.js';
|
|
|
2
2
|
import { env } from '#src/utils/systemUtils.js';
|
|
3
3
|
import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
|
|
4
4
|
import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
|
|
5
|
+
import { NATIVE_CLIENT_REASON, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
|
|
5
6
|
/**
|
|
6
7
|
* Default Ollama daemon host, matching the Ollama CLI/library default. GS2-59 — `ChatOllama` talks
|
|
7
8
|
* to the daemon's NATIVE endpoint (`/api/chat`), NOT the OpenAI-compatible `/v1` shim this provider
|
|
@@ -68,6 +69,17 @@ export async function processJsonConfig(llmConfig) {
|
|
|
68
69
|
baseUrl: llmConfig.baseUrl ?? resolveBaseUrl(),
|
|
69
70
|
numCtx: llmConfig.numCtx ?? DEFAULT_OLLAMA_NUM_CTX,
|
|
70
71
|
};
|
|
72
|
+
// `ChatOllama` is a native client, so NOTHING in a `configuration` block reaches it — say so
|
|
73
|
+
// before dropping it, rather than letting a stale config behave differently than it reads.
|
|
74
|
+
warnUnusedConfiguration({
|
|
75
|
+
provider: 'ollama',
|
|
76
|
+
configuration: configFields.configuration,
|
|
77
|
+
consumedPaths: [],
|
|
78
|
+
reason: NATIVE_CLIENT_REASON,
|
|
79
|
+
guidance: 'Ollama runs as a local, unauthenticated daemon: point elsewhere with the OLLAMA_HOST ' +
|
|
80
|
+
'environment variable or the "baseUrl" field of the "llm" block, and set "headers" there ' +
|
|
81
|
+
'if a reverse proxy in front of it needs auth.',
|
|
82
|
+
});
|
|
71
83
|
// Strip OpenAI-client / gaunt-sloth-internal keys ChatOllama neither needs nor understands.
|
|
72
84
|
for (const key of ['type', 'apiKeyEnvironmentVariable', 'apiKey', 'configuration']) {
|
|
73
85
|
delete configFields[key];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAOhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAOhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAErC;;;;;GAKG;AACH,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC;IAC7B,IAAI,CAAC,IAAI;QAAE,OAAO,mBAAmB,CAAC;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC;IACjE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAgD;IAEhD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACzD,MAAM,YAAY,GAA4B;QAC5C,GAAG,SAAS;QACZ,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,QAAQ,CAAC;QAC3D,wFAAwF;QACxF,6FAA6F;QAC7F,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,cAAc,EAAE;QAC9C,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,sBAAsB;KACnD,CAAC;IACF,6FAA6F;IAC7F,2FAA2F;IAC3F,uBAAuB,CAAC;QACtB,QAAQ,EAAE,QAAQ;QAClB,aAAa,EAAE,YAAY,CAAC,aAAa;QACzC,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EACN,uFAAuF;YACvF,0FAA0F;YAC1F,+CAA+C;KAClD,CAAC,CAAC;IACH,4FAA4F;IAC5F,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,2BAA2B,EAAE,QAAQ,EAAE,eAAe,CAAC,EAAE,CAAC;QACnF,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,YAA+B,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5F,cAAc,CACZ,yBAAyB,cAAc,2BAA2B;QAChE,2EAA2E;QAC3E,+CAA+C,CAClD,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import type { BaseChatModel, BaseChatModelParams } from '@langchain/core/language_models/chat_models';
|
|
2
2
|
import type { ChatOpenRouterInput } from '@langchain/openrouter';
|
|
3
|
+
/**
|
|
4
|
+
* Build a native `ChatOpenRouter` (`@langchain/openrouter`). It is NOT a `ChatOpenAI` subclass: it
|
|
5
|
+
* talks to the OpenRouter REST API through the global `fetch` with no SDK client in between, and
|
|
6
|
+
* `_llmType()` reports `openrouter`.
|
|
7
|
+
*
|
|
8
|
+
* OpenRouter's own options are therefore native TOP-LEVEL fields of the `llm` block, forwarded by
|
|
9
|
+
* the `...restConfig` spread below: `provider` (routing preferences), `models` (the fallback list),
|
|
10
|
+
* `route`, `plugins`, `transforms`, `trace`, `minP`, `topA`, `repetitionPenalty`, `seed`,
|
|
11
|
+
* `logitBias`, `topLogprobs`, `sessionId`. Write them beside `model`, not under `configuration`.
|
|
12
|
+
*
|
|
13
|
+
* Migration note — the OpenAI-client knobs a `configuration` block used to carry are gone, because
|
|
14
|
+
* there is no client to give them to. `configuration.baseURL` still works (mapped to the native
|
|
15
|
+
* `baseURL`), and the two attribution headers are still honoured as a fallback for
|
|
16
|
+
* `siteUrl`/`siteName`. What has no injection point at all is transport: `fetch`, `fetchOptions`,
|
|
17
|
+
* `timeout`, `maxRetries`, `defaultQuery`, `dangerouslyAllowBrowser`, and any other
|
|
18
|
+
* `defaultHeaders` entry. That is an upstream surface gap, not something this module can restore —
|
|
19
|
+
* per-provider transport would need a `fetch` option added to `@langchain/openrouter`.
|
|
20
|
+
*
|
|
21
|
+
* The replacement is PROCESS-WIDE rather than per-provider, and it is verified working: run node
|
|
22
|
+
* with `--use-env-proxy` (or set `NODE_USE_ENV_PROXY=1`) together with `HTTP_PROXY`/`HTTPS_PROXY`,
|
|
23
|
+
* and the global `fetch` this model calls routes through the proxy — measured end to end against a
|
|
24
|
+
* local proxy, with a no-proxy control that stayed direct.
|
|
25
|
+
*/
|
|
3
26
|
export declare function processJsonConfig(llmConfig: ChatOpenRouterInput & BaseChatModelParams & Record<string, unknown>): Promise<BaseChatModel>;
|
|
4
27
|
export declare function init(configFileName: string, force?: boolean, model?: string): void;
|
|
@@ -2,7 +2,46 @@ import { displayWarning } from '#src/utils/consoleUtils.js';
|
|
|
2
2
|
import { env } from '#src/utils/systemUtils.js';
|
|
3
3
|
import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
|
|
4
4
|
import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
|
|
5
|
-
|
|
5
|
+
import { NATIVE_CLIENT_REASON, warnConfigurationOverridesTopLevelField, warnUnappliedConfigurationPath, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
|
|
6
|
+
/**
|
|
7
|
+
* The OpenRouter attribution headers, and the native `ChatOpenRouter` field each one is set from.
|
|
8
|
+
* Declared once because they are read in two places that MUST agree: the `siteUrl`/`siteName`
|
|
9
|
+
* fallback below, and the list of `configuration` paths this factory consumes — if those drift, the
|
|
10
|
+
* orphaned-config warning starts firing on a header that is in fact honoured.
|
|
11
|
+
*/
|
|
12
|
+
const ATTRIBUTION_HEADERS = { siteUrl: 'HTTP-Referer', siteName: 'X-Title' };
|
|
13
|
+
/**
|
|
14
|
+
* The only paths inside a user's `configuration` block that this factory reads. Everything else in
|
|
15
|
+
* it reaches nothing — see the migration note on {@link processJsonConfig}.
|
|
16
|
+
*/
|
|
17
|
+
const CONSUMED_CONFIGURATION_PATHS = [
|
|
18
|
+
'baseURL',
|
|
19
|
+
`defaultHeaders.${ATTRIBUTION_HEADERS.siteUrl}`,
|
|
20
|
+
`defaultHeaders.${ATTRIBUTION_HEADERS.siteName}`,
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Build a native `ChatOpenRouter` (`@langchain/openrouter`). It is NOT a `ChatOpenAI` subclass: it
|
|
24
|
+
* talks to the OpenRouter REST API through the global `fetch` with no SDK client in between, and
|
|
25
|
+
* `_llmType()` reports `openrouter`.
|
|
26
|
+
*
|
|
27
|
+
* OpenRouter's own options are therefore native TOP-LEVEL fields of the `llm` block, forwarded by
|
|
28
|
+
* the `...restConfig` spread below: `provider` (routing preferences), `models` (the fallback list),
|
|
29
|
+
* `route`, `plugins`, `transforms`, `trace`, `minP`, `topA`, `repetitionPenalty`, `seed`,
|
|
30
|
+
* `logitBias`, `topLogprobs`, `sessionId`. Write them beside `model`, not under `configuration`.
|
|
31
|
+
*
|
|
32
|
+
* Migration note — the OpenAI-client knobs a `configuration` block used to carry are gone, because
|
|
33
|
+
* there is no client to give them to. `configuration.baseURL` still works (mapped to the native
|
|
34
|
+
* `baseURL`), and the two attribution headers are still honoured as a fallback for
|
|
35
|
+
* `siteUrl`/`siteName`. What has no injection point at all is transport: `fetch`, `fetchOptions`,
|
|
36
|
+
* `timeout`, `maxRetries`, `defaultQuery`, `dangerouslyAllowBrowser`, and any other
|
|
37
|
+
* `defaultHeaders` entry. That is an upstream surface gap, not something this module can restore —
|
|
38
|
+
* per-provider transport would need a `fetch` option added to `@langchain/openrouter`.
|
|
39
|
+
*
|
|
40
|
+
* The replacement is PROCESS-WIDE rather than per-provider, and it is verified working: run node
|
|
41
|
+
* with `--use-env-proxy` (or set `NODE_USE_ENV_PROXY=1`) together with `HTTP_PROXY`/`HTTPS_PROXY`,
|
|
42
|
+
* and the global `fetch` this model calls routes through the proxy — measured end to end against a
|
|
43
|
+
* local proxy, with a no-proxy control that stayed direct.
|
|
44
|
+
*/
|
|
6
45
|
// noinspection JSUnusedGlobalSymbols
|
|
7
46
|
export async function processJsonConfig(llmConfig) {
|
|
8
47
|
const { ChatOpenRouter } = await import('@langchain/openrouter');
|
|
@@ -12,15 +51,43 @@ export async function processJsonConfig(llmConfig) {
|
|
|
12
51
|
}
|
|
13
52
|
const { type: _type, apiKeyEnvironmentVariable: _envVar, configuration, siteUrl, siteName, ...restConfig } = llmConfig;
|
|
14
53
|
const configObj = configuration;
|
|
15
|
-
|
|
16
|
-
|
|
54
|
+
// The one place that decides whether the user's `configuration.baseURL` is applied; the warning
|
|
55
|
+
// below reads THIS result instead of re-testing the value, so the guard and what the user is told
|
|
56
|
+
// cannot drift apart.
|
|
57
|
+
const baseURLOverride = configObj?.baseURL ? { baseURL: configObj.baseURL } : {};
|
|
58
|
+
warnUnusedConfiguration({
|
|
59
|
+
provider: 'openrouter',
|
|
60
|
+
configuration,
|
|
61
|
+
consumedPaths: CONSUMED_CONFIGURATION_PATHS,
|
|
62
|
+
reason: NATIVE_CLIENT_REASON,
|
|
63
|
+
// Scope the advice to the options that HAVE a top-level home: told plainly to "put it at the
|
|
64
|
+
// top level", a user with a transport key would move it from a warned location to an unwarned
|
|
65
|
+
// one, which is worse than where they started.
|
|
66
|
+
guidance: 'OpenRouter\'s own options are native top-level fields of the "llm" block — set "provider" ' +
|
|
67
|
+
'(routing preferences), "models", "route", "plugins" or "transforms" beside "model" rather ' +
|
|
68
|
+
'than under "configuration". Transport settings (proxy, custom fetch, timeout, other ' +
|
|
69
|
+
'headers) have no top-level field and no per-provider hook at all: run node with ' +
|
|
70
|
+
'--use-env-proxy (or set NODE_USE_ENV_PROXY=1) plus HTTP_PROXY/HTTPS_PROXY to route this ' +
|
|
71
|
+
'provider through a proxy process-wide.',
|
|
72
|
+
});
|
|
73
|
+
warnUnappliedConfigurationPath('openrouter', configuration, 'baseURL', 'baseURL' in baseURLOverride, 'Give it the full base URL of the OpenRouter-compatible endpoint, or remove it to use the ' +
|
|
74
|
+
'default https://openrouter.ai/api/v1.');
|
|
75
|
+
// `baseURL` is ALSO a native top-level field of `ChatOpenRouter`, forwarded by `...restConfig`
|
|
76
|
+
// below — and the block's value is spread after it, so it wins. Both are honoured surfaces, so
|
|
77
|
+
// the defect is only the silence: say which one takes effect rather than dropping the other
|
|
78
|
+
// without a word.
|
|
79
|
+
warnConfigurationOverridesTopLevelField('openrouter', 'baseURL', restConfig.baseURL, baseURLOverride.baseURL);
|
|
80
|
+
const resolvedSiteUrl = siteUrl ??
|
|
81
|
+
configObj?.defaultHeaders?.[ATTRIBUTION_HEADERS.siteUrl] ??
|
|
82
|
+
'https://gauntsloth.app/';
|
|
83
|
+
const resolvedSiteName = siteName ?? configObj?.defaultHeaders?.[ATTRIBUTION_HEADERS.siteName] ?? 'Gaunt Sloth';
|
|
17
84
|
return new ChatOpenRouter({
|
|
18
85
|
...restConfig,
|
|
19
86
|
apiKey: openRouterApiKey,
|
|
20
87
|
model: llmConfig.model || getCuratedFallbackModel('openrouter'),
|
|
21
88
|
siteUrl: resolvedSiteUrl,
|
|
22
89
|
siteName: resolvedSiteName,
|
|
23
|
-
...
|
|
90
|
+
...baseURLOverride,
|
|
24
91
|
});
|
|
25
92
|
}
|
|
26
93
|
function getApiKey(llmConfig) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAOhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
|
|
|
15
15
|
import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
|
|
16
16
|
import { applyGeminiToolSchemaSanitizer } from '#src/providers/geminiSchemaSanitizer.js';
|
|
17
17
|
import { applyGeminiThoughtSummaries } from '#src/providers/geminiThinking.js';
|
|
18
|
+
import { NATIVE_CLIENT_REASON, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
|
|
18
19
|
export function init(configFileName, force = false, model) {
|
|
19
20
|
// Determine which content to use based on file extension
|
|
20
21
|
if (!configFileName.endsWith('.json')) {
|
|
@@ -33,6 +34,17 @@ export async function processJsonConfig(llmConfig) {
|
|
|
33
34
|
};
|
|
34
35
|
delete configFields.type;
|
|
35
36
|
delete configFields.apiKeyEnvironmentVariable;
|
|
37
|
+
// `ChatGoogle` is a native client for the Gemini API, so nothing in a `configuration` block
|
|
38
|
+
// reaches it — say so before dropping it.
|
|
39
|
+
warnUnusedConfiguration({
|
|
40
|
+
provider: 'vertexai',
|
|
41
|
+
configuration: llmConfig.configuration,
|
|
42
|
+
consumedPaths: [],
|
|
43
|
+
reason: NATIVE_CLIENT_REASON,
|
|
44
|
+
guidance: 'ChatGoogle talks to Vertex AI through its own client instead: set "customHeaders", ' +
|
|
45
|
+
'"endpoint", "apiVersion" or "location" as top-level fields of the "llm" block beside ' +
|
|
46
|
+
'"model".',
|
|
47
|
+
});
|
|
36
48
|
// GS2-58: normalise every tool's JSON-Schema at the ChatGoogle boundary so Gemini's OpenAPI-3.0
|
|
37
49
|
// subset accepts built-in, custom, and MCP tools alike (see geminiSchemaSanitizer).
|
|
38
50
|
// CFG-33: Vertex serves the same Gemini models through the same ChatGoogle class, so it has the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vertexai.js","sourceRoot":"","sources":["../../src/providers/vertexai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"vertexai.js","sourceRoot":"","sources":["../../src/providers/vertexai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9F,cAAc,CACZ,+GAA+G,CAChH,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAmF;IAEnF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG;QACnB,GAAG,SAAS;QACZ,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,UAAU,CAAC;QAC7D,QAAQ,EAAE,IAAI;KACf,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,CAAC;IACzB,OAAO,YAAY,CAAC,yBAAyB,CAAC;IAC9C,4FAA4F;IAC5F,0CAA0C;IAC1C,uBAAuB,CAAC;QACtB,QAAQ,EAAE,UAAU;QACpB,aAAa,EAAG,SAAyC,CAAC,aAAa;QACvE,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EACN,qFAAqF;YACrF,uFAAuF;YACvF,UAAU;KACb,CAAC,CAAC;IACH,gGAAgG;IAChG,oFAAoF;IACpF,gGAAgG;IAChG,yFAAyF;IACzF,OAAO,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC"}
|
package/dist/providers/xai.js
CHANGED
|
@@ -2,11 +2,31 @@ import { displayWarning } from '#src/utils/consoleUtils.js';
|
|
|
2
2
|
import { env } from '#src/utils/systemUtils.js';
|
|
3
3
|
import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
|
|
4
4
|
import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
|
|
5
|
+
import { warnUnusedConfiguration } from '#src/providers/configurationPassthrough.js';
|
|
5
6
|
// Function to process JSON config and create XAI LLM instance
|
|
6
7
|
export async function processJsonConfig(llmConfig) {
|
|
7
8
|
const { ChatXAI } = await import('@langchain/xai');
|
|
8
9
|
// Use config value if available, otherwise use the environment variable
|
|
9
10
|
const apiKey = llmConfig.apiKey || env.XAI_API_KEY;
|
|
11
|
+
// `ChatXAI` DOES build an OpenAI client, and still consumes none of the user's block: its
|
|
12
|
+
// constructor passes `configuration: { baseURL: fields.baseURL ?? <xAI default> }` to `super`,
|
|
13
|
+
// replacing whatever was set here. So the reason clause is xai's own — the shared native-client
|
|
14
|
+
// sentence would be a false explanation — and the replacements are the top-level fields that were
|
|
15
|
+
// measured to reach the client: `baseURL` (a declared `ChatXAIInput` field) and `timeout` (read
|
|
16
|
+
// by the OpenAI base class from the same spread). Headers reach it by no route at all.
|
|
17
|
+
warnUnusedConfiguration({
|
|
18
|
+
provider: 'xai',
|
|
19
|
+
configuration: llmConfig.configuration,
|
|
20
|
+
consumedPaths: [],
|
|
21
|
+
reason: 'builds its OpenAI client with a "configuration" block of its own, replacing anything set here',
|
|
22
|
+
// The escape hatch is only followable with the key hint: the "openai" provider reads
|
|
23
|
+
// OPENAI_API_KEY, so a user who moves to it for the headers alone hits a missing-key error.
|
|
24
|
+
guidance: 'Set "baseURL" or "timeout" as top-level fields of the "llm" block instead, beside "model". ' +
|
|
25
|
+
'Extra headers have no home on this provider at all — to send them, use the "openai" ' +
|
|
26
|
+
'provider with "configuration.baseURL" pointed at the xAI endpoint, and set ' +
|
|
27
|
+
'"apiKeyEnvironmentVariable" to XAI_API_KEY there, since that provider otherwise reads ' +
|
|
28
|
+
'OPENAI_API_KEY.',
|
|
29
|
+
});
|
|
10
30
|
return new ChatXAI({
|
|
11
31
|
...llmConfig,
|
|
12
32
|
apiKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xai.js","sourceRoot":"","sources":["../../src/providers/xai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAOhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"xai.js","sourceRoot":"","sources":["../../src/providers/xai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAOhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAErF,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAA6C;IAE7C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACnD,wEAAwE;IACxE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC;IACnD,0FAA0F;IAC1F,+FAA+F;IAC/F,gGAAgG;IAChG,kGAAkG;IAClG,gGAAgG;IAChG,uFAAuF;IACvF,uBAAuB,CAAC;QACtB,QAAQ,EAAE,KAAK;QACf,aAAa,EAAG,SAAyC,CAAC,aAAa;QACvE,aAAa,EAAE,EAAE;QACjB,MAAM,EACJ,+FAA+F;QACjG,qFAAqF;QACrF,4FAA4F;QAC5F,QAAQ,EACN,6FAA6F;YAC7F,sFAAsF;YACtF,6EAA6E;YAC7E,wFAAwF;YACxF,iBAAiB;KACpB,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC;QACjB,GAAG,SAAS;QACZ,MAAM;QACN,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,KAAK,CAAC;KACzD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IACzF,cAAc,CACZ,2BAA2B,cAAc,4BAA4B;QACnE,6CAA6C,CAChD,CAAC;AACJ,CAAC"}
|
|
@@ -53,8 +53,8 @@ export interface ConversationTurnResult extends GthRunStats {
|
|
|
53
53
|
* @param config - The resolved config.
|
|
54
54
|
* @param resolvers - Optional agent resolvers (tools/middleware); the caller owns their cleanup.
|
|
55
55
|
* @param command - The originating command (defaults to `ask`); selects the agent mode prompt.
|
|
56
|
-
* @param agentFactory - Optional backend factory (B5); omitted = the runner's lean default,
|
|
57
|
-
*
|
|
56
|
+
* @param agentFactory - Optional backend factory (B5); omitted = the runner's lean default, which
|
|
57
|
+
* is also what the shared backend seam resolves to.
|
|
58
58
|
* @returns One {@link ConversationTurnResult} per turn attempted, in turn order.
|
|
59
59
|
*/
|
|
60
60
|
export declare function runConversation(source: string, _preamble: string, userMessages: string[], config: GthConfig, resolvers?: AgentResolvers, command?: GthCommand, agentFactory?: GthAgentFactory): Promise<ConversationTurnResult[]>;
|
|
@@ -5,7 +5,8 @@ import { MemorySaver } from '@langchain/langgraph';
|
|
|
5
5
|
import { AIMessage, HumanMessage } from '@langchain/core/messages';
|
|
6
6
|
import { ProgressIndicator } from '#src/utils/ProgressIndicator.js';
|
|
7
7
|
import { recordSessionSafe } from '#src/history/recordSession.js';
|
|
8
|
-
import { getProjectDir } from '#src/utils/systemUtils.js';
|
|
8
|
+
import { getProjectDir, stdout } from '#src/utils/systemUtils.js';
|
|
9
|
+
import { ApprovalStopError, approvalStopRows } from '#src/core/shell/approvalStop.js';
|
|
9
10
|
/**
|
|
10
11
|
* Run a scripted MULTI-TURN conversation and return one {@link ConversationTurnResult} per turn.
|
|
11
12
|
*
|
|
@@ -43,8 +44,8 @@ import { getProjectDir } from '#src/utils/systemUtils.js';
|
|
|
43
44
|
* @param config - The resolved config.
|
|
44
45
|
* @param resolvers - Optional agent resolvers (tools/middleware); the caller owns their cleanup.
|
|
45
46
|
* @param command - The originating command (defaults to `ask`); selects the agent mode prompt.
|
|
46
|
-
* @param agentFactory - Optional backend factory (B5); omitted = the runner's lean default,
|
|
47
|
-
*
|
|
47
|
+
* @param agentFactory - Optional backend factory (B5); omitted = the runner's lean default, which
|
|
48
|
+
* is also what the shared backend seam resolves to.
|
|
48
49
|
* @returns One {@link ConversationTurnResult} per turn attempted, in turn order.
|
|
49
50
|
*/
|
|
50
51
|
export async function runConversation(source, _preamble, userMessages, config, resolvers, command = 'ask', agentFactory) {
|
|
@@ -86,7 +87,21 @@ export async function runConversation(source, _preamble, userMessages, config, r
|
|
|
86
87
|
catch (err) {
|
|
87
88
|
ok = false;
|
|
88
89
|
error = err instanceof Error ? err.message : String(err);
|
|
89
|
-
|
|
90
|
+
// [[TUI-C71]] — the SAME branch `runSingleShot` carries, and for a sharper reason: this
|
|
91
|
+
// surface wires no tool-approval callback either, so every escalation it meets is a
|
|
92
|
+
// §6.2 `NonInteractiveEscalationError` — the error class that carries the command, the
|
|
93
|
+
// rating, the rater's reason AND the whole negotiation transcript. The hostile path is
|
|
94
|
+
// not an edge case here, it is the only path. `error` above keeps the neutralised
|
|
95
|
+
// message for the turn record, which is a data consumer and wants the string.
|
|
96
|
+
if (err instanceof ApprovalStopError) {
|
|
97
|
+
displayError('Failed to get answer:');
|
|
98
|
+
for (const row of approvalStopRows(err.parts, { columns: stdout.columns })) {
|
|
99
|
+
displayError(row);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
displayError(`Failed to get answer: ${error}`);
|
|
104
|
+
}
|
|
90
105
|
}
|
|
91
106
|
// GS2-16: read this turn's token/tool delta from the live agent (before cleanup). Fail-soft
|
|
92
107
|
// — analytics must never affect the run. `processMessages` reset the tally at its top, so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/runtime/conversation.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,OAAO,EACP,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/runtime/conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,9 +28,8 @@ export interface SingleShotResult extends GthRunStats {
|
|
|
28
28
|
* @param resolvers - Optional agent resolvers (tools/middleware)
|
|
29
29
|
* @param command - The originating command (defaults to `ask`); selects the agent mode prompt
|
|
30
30
|
* @param agentFactory - Optional backend factory (B5). When omitted the runner uses its built-in
|
|
31
|
-
* lean {@link GthLangChainAgent} default
|
|
32
|
-
*
|
|
33
|
-
* `resolveAgentFactory(config, 'lean')` so an explicit `agent.backend` is honored.
|
|
31
|
+
* lean {@link GthLangChainAgent} default. The app layer passes `resolveAgentFactory(config,
|
|
32
|
+
* 'lean')`, which resolves to the same agent through the shared backend seam.
|
|
34
33
|
* @returns A {@link SingleShotResult}: `ok` is `true` when the run completed without error, `false`
|
|
35
34
|
* when it failed (so callers such as `exec` can set a non-zero exit code); `answer`/`tokensInput`/
|
|
36
35
|
* `tokensOutput`/`tools` carry the SUT's answer text and run stats for callers that need them
|
|
@@ -5,7 +5,8 @@ import { MemorySaver } from '@langchain/langgraph';
|
|
|
5
5
|
import { HumanMessage } from '@langchain/core/messages';
|
|
6
6
|
import { ProgressIndicator } from '#src/utils/ProgressIndicator.js';
|
|
7
7
|
import { recordSessionSafe } from '#src/history/recordSession.js';
|
|
8
|
-
import { getProjectDir } from '#src/utils/systemUtils.js';
|
|
8
|
+
import { getProjectDir, stdout } from '#src/utils/systemUtils.js';
|
|
9
|
+
import { ApprovalStopError, approvalStopRows } from '#src/core/shell/approvalStop.js';
|
|
9
10
|
/**
|
|
10
11
|
* Ask a question and get an answer from the LLM.
|
|
11
12
|
*
|
|
@@ -21,9 +22,8 @@ import { getProjectDir } from '#src/utils/systemUtils.js';
|
|
|
21
22
|
* @param resolvers - Optional agent resolvers (tools/middleware)
|
|
22
23
|
* @param command - The originating command (defaults to `ask`); selects the agent mode prompt
|
|
23
24
|
* @param agentFactory - Optional backend factory (B5). When omitted the runner uses its built-in
|
|
24
|
-
* lean {@link GthLangChainAgent} default
|
|
25
|
-
*
|
|
26
|
-
* `resolveAgentFactory(config, 'lean')` so an explicit `agent.backend` is honored.
|
|
25
|
+
* lean {@link GthLangChainAgent} default. The app layer passes `resolveAgentFactory(config,
|
|
26
|
+
* 'lean')`, which resolves to the same agent through the shared backend seam.
|
|
27
27
|
* @returns A {@link SingleShotResult}: `ok` is `true` when the run completed without error, `false`
|
|
28
28
|
* when it failed (so callers such as `exec` can set a non-zero exit code); `answer`/`tokensInput`/
|
|
29
29
|
* `tokensOutput`/`tools` carry the SUT's answer text and run stats for callers that need them
|
|
@@ -31,8 +31,8 @@ import { getProjectDir } from '#src/utils/systemUtils.js';
|
|
|
31
31
|
*/
|
|
32
32
|
export async function runSingleShot(source,
|
|
33
33
|
// BATCH-13: `_preamble` is retained for signature stability but is NO LONGER injected as a
|
|
34
|
-
// SystemMessage. The agent
|
|
35
|
-
//
|
|
34
|
+
// SystemMessage. The agent (lean `GthLangChainAgent`, since GS2-21) COMPOSES the full system
|
|
35
|
+
// prompt itself from the config — backstory + guidelines +
|
|
36
36
|
// per-command mode prompt + system prompt, PLUS the model-identity (GS2-34) and MCP-instructions
|
|
37
37
|
// (EXT-32) notes — and hand it to `createAgent` as `systemPrompt`. Also passing this preamble as a
|
|
38
38
|
// leading SystemMessage produced TWO system messages, which `@langchain/anthropic` rejects
|
|
@@ -60,7 +60,22 @@ _preamble, content, config, resolvers, command = 'ask', agentFactory) {
|
|
|
60
60
|
}
|
|
61
61
|
catch (err) {
|
|
62
62
|
succeeded = false;
|
|
63
|
-
|
|
63
|
+
// [[TUI-C71]] — §6.2's escalation and §4.2's halt reach a person HERE and nowhere else on
|
|
64
|
+
// this path: there is no prompt to attach anything to, so this message is the whole
|
|
65
|
+
// explanation and it is built almost entirely out of model-authored text. Its untrusted
|
|
66
|
+
// halves go through the [[TUI-C26]] gutter, one row per line, so a payload crafted to forge
|
|
67
|
+
// terminal chrome cannot reach column 0 even on a line the terminal would have wrapped. The
|
|
68
|
+
// rows are printed on the same channel as the wrapper so a redirected stderr still carries
|
|
69
|
+
// the whole thing.
|
|
70
|
+
if (err instanceof ApprovalStopError) {
|
|
71
|
+
displayError('Failed to get answer:');
|
|
72
|
+
for (const row of approvalStopRows(err.parts, { columns: stdout.columns })) {
|
|
73
|
+
displayError(row);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
displayError(`Failed to get answer: ${err instanceof Error ? err.message : String(err)}`);
|
|
78
|
+
}
|
|
64
79
|
}
|
|
65
80
|
finally {
|
|
66
81
|
await runner.cleanup();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleShot.js","sourceRoot":"","sources":["../../src/runtime/singleShot.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,OAAO,EACP,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"singleShot.js","sourceRoot":"","sources":["../../src/runtime/singleShot.ts"],"names":[],"mappings":"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"}
|