@mcpmesh/sdk 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/agent-single-instance.spec.d.ts +2 -0
- package/dist/__tests__/agent-single-instance.spec.d.ts.map +1 -0
- package/dist/__tests__/agent-single-instance.spec.js +80 -0
- package/dist/__tests__/agent-single-instance.spec.js.map +1 -0
- package/dist/__tests__/event-loop-resilience.spec.d.ts +2 -0
- package/dist/__tests__/event-loop-resilience.spec.d.ts.map +1 -0
- package/dist/__tests__/event-loop-resilience.spec.js +321 -0
- package/dist/__tests__/event-loop-resilience.spec.js.map +1 -0
- package/dist/__tests__/llm-max-iterations.test.js +10 -8
- package/dist/__tests__/llm-max-iterations.test.js.map +1 -1
- package/dist/__tests__/llm-provider-multistep.test.d.ts +20 -0
- package/dist/__tests__/llm-provider-multistep.test.d.ts.map +1 -0
- package/dist/__tests__/llm-provider-multistep.test.js +138 -0
- package/dist/__tests__/llm-provider-multistep.test.js.map +1 -0
- package/dist/__tests__/llm-provider-output-mode.test.js +1 -0
- package/dist/__tests__/llm-provider-output-mode.test.js.map +1 -1
- package/dist/__tests__/llm-provider-stopwhen.test.d.ts +22 -0
- package/dist/__tests__/llm-provider-stopwhen.test.d.ts.map +1 -0
- package/dist/__tests__/llm-provider-stopwhen.test.js +127 -0
- package/dist/__tests__/llm-provider-stopwhen.test.js.map +1 -0
- package/dist/__tests__/llm-provider-system-synthesis.test.js +1 -0
- package/dist/__tests__/llm-provider-system-synthesis.test.js.map +1 -1
- package/dist/__tests__/llm-provider-vertex-settings.test.d.ts +18 -0
- package/dist/__tests__/llm-provider-vertex-settings.test.d.ts.map +1 -0
- package/dist/__tests__/llm-provider-vertex-settings.test.js +128 -0
- package/dist/__tests__/llm-provider-vertex-settings.test.js.map +1 -0
- package/dist/__tests__/port-conflict-fallback.spec.d.ts +2 -0
- package/dist/__tests__/port-conflict-fallback.spec.d.ts.map +1 -0
- package/dist/__tests__/port-conflict-fallback.spec.js +123 -0
- package/dist/__tests__/port-conflict-fallback.spec.js.map +1 -0
- package/dist/__tests__/port-probe-errors.spec.d.ts +2 -0
- package/dist/__tests__/port-probe-errors.spec.d.ts.map +1 -0
- package/dist/__tests__/port-probe-errors.spec.js +100 -0
- package/dist/__tests__/port-probe-errors.spec.js.map +1 -0
- package/dist/__tests__/provider-handler-registry.test.d.ts +0 -1
- package/dist/__tests__/provider-handler-registry.test.d.ts.map +1 -1
- package/dist/__tests__/provider-handler-registry.test.js +23 -1
- package/dist/__tests__/provider-handler-registry.test.js.map +1 -1
- package/dist/__tests__/proxy-sse-no-data.test.d.ts +13 -0
- package/dist/__tests__/proxy-sse-no-data.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-sse-no-data.test.js +147 -0
- package/dist/__tests__/proxy-sse-no-data.test.js.map +1 -0
- package/dist/__tests__/proxy-stream.test.js +26 -0
- package/dist/__tests__/proxy-stream.test.js.map +1 -1
- package/dist/__tests__/proxy-timer-leak.test.d.ts +16 -0
- package/dist/__tests__/proxy-timer-leak.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-timer-leak.test.js +97 -0
- package/dist/__tests__/proxy-timer-leak.test.js.map +1 -0
- package/dist/__tests__/proxy-tool-error.test.d.ts +13 -0
- package/dist/__tests__/proxy-tool-error.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-tool-error.test.js +313 -0
- package/dist/__tests__/proxy-tool-error.test.js.map +1 -0
- package/dist/__tests__/route.test.js +21 -1
- package/dist/__tests__/route.test.js.map +1 -1
- package/dist/__tests__/settle-window.spec.d.ts +2 -0
- package/dist/__tests__/settle-window.spec.d.ts.map +1 -0
- package/dist/__tests__/settle-window.spec.js +324 -0
- package/dist/__tests__/settle-window.spec.js.map +1 -0
- package/dist/__tests__/sse.test.js +12 -0
- package/dist/__tests__/sse.test.js.map +1 -1
- package/dist/__tests__/stop-dispatchers.spec.d.ts +2 -0
- package/dist/__tests__/stop-dispatchers.spec.d.ts.map +1 -0
- package/dist/__tests__/stop-dispatchers.spec.js +227 -0
- package/dist/__tests__/stop-dispatchers.spec.js.map +1 -0
- package/dist/agent.d.ts +65 -5
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +313 -78
- package/dist/agent.js.map +1 -1
- package/dist/api-runtime.d.ts +33 -3
- package/dist/api-runtime.d.ts.map +1 -1
- package/dist/api-runtime.js +125 -32
- package/dist/api-runtime.js.map +1 -1
- package/dist/claim-dispatcher.d.ts +25 -0
- package/dist/claim-dispatcher.d.ts.map +1 -1
- package/dist/claim-dispatcher.js +59 -1
- package/dist/claim-dispatcher.js.map +1 -1
- package/dist/config.d.ts +73 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +108 -2
- package/dist/config.js.map +1 -1
- package/dist/debug.d.ts +1 -1
- package/dist/debug.d.ts.map +1 -1
- package/dist/express.d.ts +33 -0
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +149 -31
- package/dist/express.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/llm-provider.d.ts +18 -0
- package/dist/llm-provider.d.ts.map +1 -1
- package/dist/llm-provider.js +86 -34
- package/dist/llm-provider.js.map +1 -1
- package/dist/provider-handlers/gemini-handler.js +6 -0
- package/dist/provider-handlers/gemini-handler.js.map +1 -1
- package/dist/provider-handlers/provider-handler-registry.d.ts +10 -1
- package/dist/provider-handlers/provider-handler-registry.d.ts.map +1 -1
- package/dist/provider-handlers/provider-handler-registry.js +4 -1
- package/dist/provider-handlers/provider-handler-registry.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +178 -40
- package/dist/proxy.js.map +1 -1
- package/dist/route.d.ts.map +1 -1
- package/dist/route.js +38 -0
- package/dist/route.js.map +1 -1
- package/dist/settle.d.ts +129 -0
- package/dist/settle.d.ts.map +1 -0
- package/dist/settle.js +284 -0
- package/dist/settle.js.map +1 -0
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +5 -2
- package/dist/sse.js.map +1 -1
- package/dist/tracing.d.ts +1 -0
- package/dist/tracing.d.ts.map +1 -1
- package/dist/tracing.js +3 -0
- package/dist/tracing.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini SDK-managed multi-step loop — end-to-end regression test for #1160.
|
|
3
|
+
*
|
|
4
|
+
* Uses the REAL `ai` module (generateText + stopWhen + tool execution) with a
|
|
5
|
+
* `MockLanguageModelV3` (from `ai/test`) injected via a mocked
|
|
6
|
+
* `@ai-sdk/google` provider. The model emits a tool call on step 1 and text
|
|
7
|
+
* on step 2.
|
|
8
|
+
*
|
|
9
|
+
* With the broken `maxSteps` wiring (removed in AI SDK v6), generateText
|
|
10
|
+
* defaulted to `stopWhen: stepCountIs(1)`: the loop stopped right after the
|
|
11
|
+
* tool-call step, `result.text` was empty, and since the tools carried
|
|
12
|
+
* `_mesh_endpoint` the provider also stripped tool_calls — consumers received
|
|
13
|
+
* an empty assistant message. With `stopWhen: stepCountIs(n)` the loop does
|
|
14
|
+
* the follow-up generation and the final text is non-empty.
|
|
15
|
+
*
|
|
16
|
+
* Tool execution goes through the provider's execute functions →
|
|
17
|
+
* `callMcpTool`, which is mocked here to return a canned tool result.
|
|
18
|
+
*/
|
|
19
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
20
|
+
// Per-step model results, controllable per test. vi.hoisted so the
|
|
21
|
+
// vi.mock("@ai-sdk/google") factory can reference it.
|
|
22
|
+
const modelHarness = vi.hoisted(() => ({
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
results: [],
|
|
25
|
+
calls: 0,
|
|
26
|
+
}));
|
|
27
|
+
const callMcpToolMock = vi.hoisted(() => vi.fn());
|
|
28
|
+
vi.mock("@ai-sdk/google", async () => {
|
|
29
|
+
const { MockLanguageModelV3 } = await import("ai/test");
|
|
30
|
+
return {
|
|
31
|
+
google: (modelId) => new MockLanguageModelV3({
|
|
32
|
+
modelId,
|
|
33
|
+
// Function form (not the array form: MockLanguageModelV3 indexes the
|
|
34
|
+
// array AFTER pushing the call, skipping element 0).
|
|
35
|
+
doGenerate: async () => {
|
|
36
|
+
const result = modelHarness.results[modelHarness.calls];
|
|
37
|
+
modelHarness.calls++;
|
|
38
|
+
if (!result) {
|
|
39
|
+
throw new Error(`MockLanguageModelV3: no scripted result for step ${modelHarness.calls}`);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
// Replace only callMcpTool — keep runWithTraceContext etc. real.
|
|
47
|
+
vi.mock("../proxy.js", async (importOriginal) => {
|
|
48
|
+
const actual = await importOriginal();
|
|
49
|
+
return { ...actual, callMcpTool: callMcpToolMock };
|
|
50
|
+
});
|
|
51
|
+
// Keep tracing inert (publishTraceSpan is best-effort fire-and-forget).
|
|
52
|
+
vi.mock("../tracing.js", async (importOriginal) => {
|
|
53
|
+
const actual = await importOriginal();
|
|
54
|
+
return { ...actual, publishTraceSpan: vi.fn(async () => false) };
|
|
55
|
+
});
|
|
56
|
+
import { llmProvider } from "../llm-provider.js";
|
|
57
|
+
const TOOL_CALL_STEP = {
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
60
|
+
type: "tool-call",
|
|
61
|
+
toolCallId: "call-1",
|
|
62
|
+
toolName: "get_weather",
|
|
63
|
+
input: JSON.stringify({ city: "Paris" }),
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
finishReason: "tool-calls",
|
|
67
|
+
usage: { inputTokens: 10, outputTokens: 5, totalTokens: 15 },
|
|
68
|
+
warnings: [],
|
|
69
|
+
};
|
|
70
|
+
const TEXT_STEP = {
|
|
71
|
+
content: [{ type: "text", text: "It is sunny in Paris." }],
|
|
72
|
+
finishReason: "stop",
|
|
73
|
+
usage: { inputTokens: 20, outputTokens: 8, totalTokens: 28 },
|
|
74
|
+
warnings: [],
|
|
75
|
+
};
|
|
76
|
+
function meshToolRequest(modelParams) {
|
|
77
|
+
return {
|
|
78
|
+
request: {
|
|
79
|
+
messages: [{ role: "user", content: "What's the weather in Paris?" }],
|
|
80
|
+
tools: [
|
|
81
|
+
{
|
|
82
|
+
type: "function",
|
|
83
|
+
function: {
|
|
84
|
+
name: "get_weather",
|
|
85
|
+
description: "Get the current weather for a city",
|
|
86
|
+
parameters: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: { city: { type: "string" } },
|
|
89
|
+
required: ["city"],
|
|
90
|
+
},
|
|
91
|
+
_mesh_endpoint: "http://weather-agent.local:9100",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
model_params: { ...modelParams },
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
describe("Gemini multi-step loop with real generateText (#1160)", () => {
|
|
100
|
+
beforeEach(() => {
|
|
101
|
+
modelHarness.results = [TOOL_CALL_STEP, TEXT_STEP];
|
|
102
|
+
modelHarness.calls = 0;
|
|
103
|
+
callMcpToolMock.mockReset();
|
|
104
|
+
callMcpToolMock.mockResolvedValue(JSON.stringify({ temperature_c: 21, condition: "sunny" }));
|
|
105
|
+
});
|
|
106
|
+
afterEach(() => {
|
|
107
|
+
vi.restoreAllMocks();
|
|
108
|
+
});
|
|
109
|
+
it("executes the tool on step 1 and returns the follow-up text from step 2", async () => {
|
|
110
|
+
const tool = llmProvider({ model: "gemini/gemini-2.5-flash", capability: "llm" });
|
|
111
|
+
const raw = await tool.execute(meshToolRequest({ max_iterations: 3 }));
|
|
112
|
+
const response = JSON.parse(raw);
|
|
113
|
+
// The model was called twice: tool-call step + follow-up generation.
|
|
114
|
+
expect(modelHarness.calls).toBe(2);
|
|
115
|
+
// The tool was executed provider-side via its _mesh_endpoint.
|
|
116
|
+
expect(callMcpToolMock).toHaveBeenCalledTimes(1);
|
|
117
|
+
const [endpoint, toolName, toolArgs] = callMcpToolMock.mock.calls[0];
|
|
118
|
+
expect(endpoint).toBe("http://weather-agent.local:9100");
|
|
119
|
+
expect(toolName).toBe("get_weather");
|
|
120
|
+
expect(toolArgs).toEqual({ city: "Paris" });
|
|
121
|
+
// #1160: the assistant message must carry the step-2 text, not be empty.
|
|
122
|
+
expect(response.content).toBe("It is sunny in Paris.");
|
|
123
|
+
// Tools were executed provider-side — no tool_calls leak to the consumer.
|
|
124
|
+
expect(response.tool_calls).toBeUndefined();
|
|
125
|
+
});
|
|
126
|
+
it("honors the forwarded cap: max_iterations=1 stops after the tool-call step", async () => {
|
|
127
|
+
const tool = llmProvider({ model: "gemini/gemini-2.5-flash", capability: "llm" });
|
|
128
|
+
const raw = await tool.execute(meshToolRequest({ max_iterations: 1 }));
|
|
129
|
+
const response = JSON.parse(raw);
|
|
130
|
+
// stopWhen=stepCountIs(1): the tool still executes within step 1, but no
|
|
131
|
+
// follow-up generation happens — proving the cap actually drives the loop.
|
|
132
|
+
expect(modelHarness.calls).toBe(1);
|
|
133
|
+
expect(callMcpToolMock).toHaveBeenCalledTimes(1);
|
|
134
|
+
expect(response.content).toBe("");
|
|
135
|
+
expect(response.tool_calls).toBeUndefined();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=llm-provider-multistep.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider-multistep.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-multistep.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,6 +25,7 @@ vi.mock("ai", () => ({
|
|
|
25
25
|
generateObject: (opts) => generateObjectMock(opts),
|
|
26
26
|
jsonSchema: (schema) => schema,
|
|
27
27
|
tool: (config) => config,
|
|
28
|
+
stepCountIs: (n) => ({ steps }) => steps.length === n,
|
|
28
29
|
}));
|
|
29
30
|
// Keep tracing inert/deterministic (publishTraceSpan is best-effort anyway).
|
|
30
31
|
vi.mock("../tracing.js", () => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-provider-output-mode.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-output-mode.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEzE,MAAM,kBAAkB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AACnC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAEjC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACnB,YAAY,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC;IAC3D,UAAU,EAAE,CAAC,MAA+B,EAAE,EAAE,CAAC,MAAM;IACvD,IAAI,EAAE,CAAC,MAAe,EAAE,EAAE,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"llm-provider-output-mode.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-output-mode.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini SDK-managed agentic loop wiring — issue #1160.
|
|
3
|
+
*
|
|
4
|
+
* AI SDK v6 removed `maxSteps` from generateText; loop control is now
|
|
5
|
+
* `stopWhen` with a default of `stepCountIs(1)`. The provider previously set
|
|
6
|
+
* `requestOptions.maxSteps`, which landed in the `...settings` rest and was
|
|
7
|
+
* silently ignored — Gemini executed the tool-call step but never did the
|
|
8
|
+
* follow-up generation, returning an empty assistant message.
|
|
9
|
+
*
|
|
10
|
+
* These tests mock `generateText` (keeping the REAL `stepCountIs`/`tool`/
|
|
11
|
+
* `jsonSchema` via importOriginal) and assert the options object that reaches
|
|
12
|
+
* the AI SDK:
|
|
13
|
+
*
|
|
14
|
+
* - Gemini + `_mesh_endpoint` tools: `stopWhen` is set to the result of
|
|
15
|
+
* `stepCountIs(resolvedMaxIterations)`. `stepCountIs(n)` returns a
|
|
16
|
+
* predicate `({ steps }) => steps.length === n`, so we assert the
|
|
17
|
+
* predicate's behavior at the boundary (true at n steps, false at n-1).
|
|
18
|
+
* - The removed `maxSteps` key is NOT present (regression guard).
|
|
19
|
+
* - Non-Gemini vendors (manual provider-managed loop) do NOT set `stopWhen`.
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=llm-provider-stopwhen.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider-stopwhen.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/llm-provider-stopwhen.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini SDK-managed agentic loop wiring — issue #1160.
|
|
3
|
+
*
|
|
4
|
+
* AI SDK v6 removed `maxSteps` from generateText; loop control is now
|
|
5
|
+
* `stopWhen` with a default of `stepCountIs(1)`. The provider previously set
|
|
6
|
+
* `requestOptions.maxSteps`, which landed in the `...settings` rest and was
|
|
7
|
+
* silently ignored — Gemini executed the tool-call step but never did the
|
|
8
|
+
* follow-up generation, returning an empty assistant message.
|
|
9
|
+
*
|
|
10
|
+
* These tests mock `generateText` (keeping the REAL `stepCountIs`/`tool`/
|
|
11
|
+
* `jsonSchema` via importOriginal) and assert the options object that reaches
|
|
12
|
+
* the AI SDK:
|
|
13
|
+
*
|
|
14
|
+
* - Gemini + `_mesh_endpoint` tools: `stopWhen` is set to the result of
|
|
15
|
+
* `stepCountIs(resolvedMaxIterations)`. `stepCountIs(n)` returns a
|
|
16
|
+
* predicate `({ steps }) => steps.length === n`, so we assert the
|
|
17
|
+
* predicate's behavior at the boundary (true at n steps, false at n-1).
|
|
18
|
+
* - The removed `maxSteps` key is NOT present (regression guard).
|
|
19
|
+
* - Non-Gemini vendors (manual provider-managed loop) do NOT set `stopWhen`.
|
|
20
|
+
*/
|
|
21
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
22
|
+
const generateTextMock = vi.fn();
|
|
23
|
+
const generateObjectMock = vi.fn();
|
|
24
|
+
vi.mock("ai", async (importOriginal) => {
|
|
25
|
+
const actual = await importOriginal();
|
|
26
|
+
return {
|
|
27
|
+
...actual,
|
|
28
|
+
generateText: (opts) => generateTextMock(opts),
|
|
29
|
+
generateObject: (opts) => generateObjectMock(opts),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
// Keep tracing inert/deterministic (publishTraceSpan is best-effort anyway).
|
|
33
|
+
vi.mock("../tracing.js", async (importOriginal) => {
|
|
34
|
+
const actual = await importOriginal();
|
|
35
|
+
return {
|
|
36
|
+
...actual,
|
|
37
|
+
generateTraceId: () => "trace-mock",
|
|
38
|
+
generateSpanId: () => "span-mock",
|
|
39
|
+
publishTraceSpan: vi.fn(async () => false),
|
|
40
|
+
matchesPropagateHeader: () => false,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
import { llmProvider } from "../llm-provider.js";
|
|
44
|
+
function meshToolRequest(modelParams) {
|
|
45
|
+
return {
|
|
46
|
+
request: {
|
|
47
|
+
messages: [{ role: "user", content: "What's the weather in Paris?" }],
|
|
48
|
+
tools: [
|
|
49
|
+
{
|
|
50
|
+
type: "function",
|
|
51
|
+
function: {
|
|
52
|
+
name: "get_weather",
|
|
53
|
+
description: "Get the current weather for a city",
|
|
54
|
+
parameters: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: { city: { type: "string" } },
|
|
57
|
+
required: ["city"],
|
|
58
|
+
},
|
|
59
|
+
// Mesh-enriched endpoint → provider-managed tool execution
|
|
60
|
+
_mesh_endpoint: "http://weather-agent.local:9100",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
model_params: { ...modelParams },
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function stepsAtCount(stopWhen, count) {
|
|
69
|
+
return await stopWhen({ steps: new Array(count).fill({}) });
|
|
70
|
+
}
|
|
71
|
+
describe("Gemini SDK-managed loop wires stopWhen (#1160)", () => {
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
generateTextMock.mockReset();
|
|
74
|
+
generateObjectMock.mockReset();
|
|
75
|
+
generateTextMock.mockResolvedValue({
|
|
76
|
+
text: "It is sunny in Paris.",
|
|
77
|
+
toolCalls: [],
|
|
78
|
+
usage: { inputTokens: 1, outputTokens: 1 },
|
|
79
|
+
finishReason: "stop",
|
|
80
|
+
});
|
|
81
|
+
// Model creation must not depend on real credentials at request time
|
|
82
|
+
// (generateText is mocked), but keep keys set for construction safety.
|
|
83
|
+
process.env.GOOGLE_GENERATIVE_AI_API_KEY = "test-key";
|
|
84
|
+
process.env.ANTHROPIC_API_KEY = "test-key";
|
|
85
|
+
});
|
|
86
|
+
afterEach(() => {
|
|
87
|
+
delete process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
88
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
89
|
+
vi.restoreAllMocks();
|
|
90
|
+
});
|
|
91
|
+
it("sets stopWhen=stepCountIs(max_iterations) and never the removed maxSteps", async () => {
|
|
92
|
+
const tool = llmProvider({ model: "gemini/gemini-2.5-flash", capability: "llm" });
|
|
93
|
+
await tool.execute(meshToolRequest({ max_iterations: 25 }));
|
|
94
|
+
expect(generateTextMock).toHaveBeenCalledTimes(1);
|
|
95
|
+
const opts = generateTextMock.mock.calls[0][0];
|
|
96
|
+
// AI SDK v6 removed maxSteps — it must not be passed at all.
|
|
97
|
+
expect("maxSteps" in opts).toBe(false);
|
|
98
|
+
// stopWhen must be the stepCountIs(25) predicate: stops exactly when the
|
|
99
|
+
// step count reaches the resolved cap.
|
|
100
|
+
const stopWhen = opts.stopWhen;
|
|
101
|
+
expect(typeof stopWhen).toBe("function");
|
|
102
|
+
expect(await stepsAtCount(stopWhen, 25)).toBe(true);
|
|
103
|
+
expect(await stepsAtCount(stopWhen, 24)).toBe(false);
|
|
104
|
+
expect(await stepsAtCount(stopWhen, 1)).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
it("defaults stopWhen to stepCountIs(10) when no cap is forwarded", async () => {
|
|
107
|
+
delete process.env.MESH_LLM_MAX_ITERATIONS;
|
|
108
|
+
const tool = llmProvider({ model: "gemini/gemini-2.5-flash", capability: "llm" });
|
|
109
|
+
await tool.execute(meshToolRequest({}));
|
|
110
|
+
expect(generateTextMock).toHaveBeenCalledTimes(1);
|
|
111
|
+
const opts = generateTextMock.mock.calls[0][0];
|
|
112
|
+
expect("maxSteps" in opts).toBe(false);
|
|
113
|
+
const stopWhen = opts.stopWhen;
|
|
114
|
+
expect(typeof stopWhen).toBe("function");
|
|
115
|
+
expect(await stepsAtCount(stopWhen, 10)).toBe(true);
|
|
116
|
+
expect(await stepsAtCount(stopWhen, 9)).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
it("non-Gemini vendors keep the manual loop: no stopWhen, no maxSteps", async () => {
|
|
119
|
+
const tool = llmProvider({ model: "anthropic/claude-sonnet-4-5", capability: "llm" });
|
|
120
|
+
await tool.execute(meshToolRequest({ max_iterations: 25 }));
|
|
121
|
+
expect(generateTextMock).toHaveBeenCalledTimes(1);
|
|
122
|
+
const opts = generateTextMock.mock.calls[0][0];
|
|
123
|
+
expect(opts.stopWhen).toBeUndefined();
|
|
124
|
+
expect("maxSteps" in opts).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=llm-provider-stopwhen.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider-stopwhen.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-stopwhen.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@ vi.mock("ai", () => ({
|
|
|
24
24
|
generateObject: (opts) => generateObjectMock(opts),
|
|
25
25
|
jsonSchema: (schema) => schema,
|
|
26
26
|
tool: (config) => config,
|
|
27
|
+
stepCountIs: (n) => ({ steps }) => steps.length === n,
|
|
27
28
|
}));
|
|
28
29
|
vi.mock("../tracing.js", () => ({
|
|
29
30
|
generateTraceId: () => "trace-mock",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-provider-system-synthesis.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-system-synthesis.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEzE,MAAM,kBAAkB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AACnC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAEjC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACnB,YAAY,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC;IAC3D,UAAU,EAAE,CAAC,MAA+B,EAAE,EAAE,CAAC,MAAM;IACvD,IAAI,EAAE,CAAC,MAAe,EAAE,EAAE,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"llm-provider-system-synthesis.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-system-synthesis.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vertex AI provider settings resolution — issue #1181.
|
|
3
|
+
*
|
|
4
|
+
* The mesh contract (#834) is GOOGLE_CLOUD_PROJECT / GOOGLE_CLOUD_LOCATION
|
|
5
|
+
* (honored by the Python runtime). @ai-sdk/google-vertex's default `vertex`
|
|
6
|
+
* instance only reads GOOGLE_VERTEX_PROJECT / GOOGLE_VERTEX_LOCATION at call
|
|
7
|
+
* time, so identically-configured environments worked on Python and threw
|
|
8
|
+
* `AI_LoadSettingError` on TS.
|
|
9
|
+
*
|
|
10
|
+
* loadProvider("vertex_ai") must now ALWAYS construct the provider via
|
|
11
|
+
* createVertex() with explicitly resolved settings:
|
|
12
|
+
* - mesh-standard names map through,
|
|
13
|
+
* - the vendor-specific GOOGLE_VERTEX_* name wins when both are set,
|
|
14
|
+
* - settings that resolve to nothing are OMITTED (the SDK surfaces its own
|
|
15
|
+
* clear error), and the debug warn mentions BOTH accepted names.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=llm-provider-vertex-settings.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider-vertex-settings.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/llm-provider-vertex-settings.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vertex AI provider settings resolution — issue #1181.
|
|
3
|
+
*
|
|
4
|
+
* The mesh contract (#834) is GOOGLE_CLOUD_PROJECT / GOOGLE_CLOUD_LOCATION
|
|
5
|
+
* (honored by the Python runtime). @ai-sdk/google-vertex's default `vertex`
|
|
6
|
+
* instance only reads GOOGLE_VERTEX_PROJECT / GOOGLE_VERTEX_LOCATION at call
|
|
7
|
+
* time, so identically-configured environments worked on Python and threw
|
|
8
|
+
* `AI_LoadSettingError` on TS.
|
|
9
|
+
*
|
|
10
|
+
* loadProvider("vertex_ai") must now ALWAYS construct the provider via
|
|
11
|
+
* createVertex() with explicitly resolved settings:
|
|
12
|
+
* - mesh-standard names map through,
|
|
13
|
+
* - the vendor-specific GOOGLE_VERTEX_* name wins when both are set,
|
|
14
|
+
* - settings that resolve to nothing are OMITTED (the SDK surfaces its own
|
|
15
|
+
* clear error), and the debug warn mentions BOTH accepted names.
|
|
16
|
+
*/
|
|
17
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
18
|
+
const createVertexMock = vi.fn((options) => {
|
|
19
|
+
// Mimic the real factory: returns a callable provider that resolves models.
|
|
20
|
+
return (modelId) => ({ modelId, options });
|
|
21
|
+
});
|
|
22
|
+
vi.mock("@ai-sdk/google-vertex", () => ({
|
|
23
|
+
createVertex: (options) => createVertexMock(options),
|
|
24
|
+
// The default instance reads GOOGLE_VERTEX_* env vars at call time and must
|
|
25
|
+
// never be used by the mesh provider path (#1181 regression guard).
|
|
26
|
+
vertex: () => {
|
|
27
|
+
throw new Error("default `vertex` instance must not be used");
|
|
28
|
+
},
|
|
29
|
+
}));
|
|
30
|
+
import { loadProvider, resolveVertexSettings } from "../llm-provider.js";
|
|
31
|
+
const ENV_KEYS = [
|
|
32
|
+
"GOOGLE_VERTEX_PROJECT",
|
|
33
|
+
"GOOGLE_VERTEX_LOCATION",
|
|
34
|
+
"GOOGLE_CLOUD_PROJECT",
|
|
35
|
+
"GOOGLE_CLOUD_LOCATION",
|
|
36
|
+
"MCP_MESH_DEBUG_MODE",
|
|
37
|
+
"MCP_MESH_LOG_LEVEL",
|
|
38
|
+
];
|
|
39
|
+
describe("vertex_ai provider settings resolution (#1181)", () => {
|
|
40
|
+
let savedEnv;
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
createVertexMock.mockClear();
|
|
43
|
+
// Capture-and-restore: save current values, clear for a clean slate.
|
|
44
|
+
savedEnv = {};
|
|
45
|
+
for (const key of ENV_KEYS) {
|
|
46
|
+
savedEnv[key] = process.env[key];
|
|
47
|
+
delete process.env[key];
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
afterEach(() => {
|
|
51
|
+
for (const key of ENV_KEYS) {
|
|
52
|
+
if (savedEnv[key] === undefined) {
|
|
53
|
+
delete process.env[key];
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
process.env[key] = savedEnv[key];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
vi.restoreAllMocks();
|
|
60
|
+
});
|
|
61
|
+
it("maps mesh-standard GOOGLE_CLOUD_PROJECT/GOOGLE_CLOUD_LOCATION through to createVertex", async () => {
|
|
62
|
+
process.env.GOOGLE_CLOUD_PROJECT = "mesh-project";
|
|
63
|
+
process.env.GOOGLE_CLOUD_LOCATION = "us-central1";
|
|
64
|
+
const provider = await loadProvider("vertex_ai");
|
|
65
|
+
expect(createVertexMock).toHaveBeenCalledTimes(1);
|
|
66
|
+
expect(createVertexMock).toHaveBeenCalledWith({
|
|
67
|
+
project: "mesh-project",
|
|
68
|
+
location: "us-central1",
|
|
69
|
+
});
|
|
70
|
+
// The swap must be seamless: loadProvider returns the factory's provider,
|
|
71
|
+
// which resolves model IDs exactly like the previous default instance.
|
|
72
|
+
expect(typeof provider).toBe("function");
|
|
73
|
+
const model = provider("gemini-2.5-flash");
|
|
74
|
+
expect(model.modelId).toBe("gemini-2.5-flash");
|
|
75
|
+
expect(model.options).toEqual({
|
|
76
|
+
project: "mesh-project",
|
|
77
|
+
location: "us-central1",
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
it("prefers vendor-specific GOOGLE_VERTEX_* when both names are set", async () => {
|
|
81
|
+
process.env.GOOGLE_VERTEX_PROJECT = "vertex-project";
|
|
82
|
+
process.env.GOOGLE_VERTEX_LOCATION = "europe-west4";
|
|
83
|
+
process.env.GOOGLE_CLOUD_PROJECT = "cloud-project";
|
|
84
|
+
process.env.GOOGLE_CLOUD_LOCATION = "us-central1";
|
|
85
|
+
await loadProvider("vertex_ai");
|
|
86
|
+
expect(createVertexMock).toHaveBeenCalledWith({
|
|
87
|
+
project: "vertex-project",
|
|
88
|
+
location: "europe-west4",
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it("resolves each setting independently (mixed naming)", async () => {
|
|
92
|
+
process.env.GOOGLE_VERTEX_PROJECT = "vertex-project";
|
|
93
|
+
process.env.GOOGLE_CLOUD_LOCATION = "us-east1";
|
|
94
|
+
await loadProvider("vertex_ai");
|
|
95
|
+
expect(createVertexMock).toHaveBeenCalledWith({
|
|
96
|
+
project: "vertex-project",
|
|
97
|
+
location: "us-east1",
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
it("omits unresolved settings and warns mentioning BOTH accepted names", async () => {
|
|
101
|
+
process.env.MCP_MESH_DEBUG_MODE = "true";
|
|
102
|
+
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
103
|
+
await loadProvider("vertex_ai");
|
|
104
|
+
// Factory still called (single code path), but without project/location
|
|
105
|
+
// keys — the SDK throws its own clear LoadSettingError at call time.
|
|
106
|
+
expect(createVertexMock).toHaveBeenCalledTimes(1);
|
|
107
|
+
const opts = createVertexMock.mock.calls[0][0];
|
|
108
|
+
expect(opts).not.toHaveProperty("project");
|
|
109
|
+
expect(opts).not.toHaveProperty("location");
|
|
110
|
+
const logged = logSpy.mock.calls.map((call) => call.join(" ")).join("\n");
|
|
111
|
+
expect(logged).toContain("GOOGLE_VERTEX_PROJECT");
|
|
112
|
+
expect(logged).toContain("GOOGLE_CLOUD_PROJECT");
|
|
113
|
+
expect(logged).toContain("GOOGLE_VERTEX_LOCATION");
|
|
114
|
+
expect(logged).toContain("GOOGLE_CLOUD_LOCATION");
|
|
115
|
+
});
|
|
116
|
+
it("resolveVertexSettings treats empty string as unset (falls through, never blank)", () => {
|
|
117
|
+
process.env.GOOGLE_VERTEX_PROJECT = "";
|
|
118
|
+
process.env.GOOGLE_CLOUD_PROJECT = "cloud-project";
|
|
119
|
+
process.env.GOOGLE_VERTEX_LOCATION = "";
|
|
120
|
+
const settings = resolveVertexSettings();
|
|
121
|
+
// An empty vendor-specific name must not shadow-and-blank the setting: it
|
|
122
|
+
// falls through to the mesh-standard name, and a setting with no non-empty
|
|
123
|
+
// source is omitted entirely.
|
|
124
|
+
expect(settings).toEqual({ project: "cloud-project" });
|
|
125
|
+
expect(settings).not.toHaveProperty("location");
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=llm-provider-vertex-settings.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider-vertex-settings.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider-vertex-settings.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-conflict-fallback.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/port-conflict-fallback.spec.ts"],"names":[],"mappings":""}
|