@skybridge/test 0.0.0-dev.c19b437 → 0.0.0-dev.dbab7df

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,19 +4,17 @@ Evals for [Skybridge](https://skybridge.tech) MCP apps: they answer whether a
4
4
  prompt reaches the right tool with the right arguments, which no unit test can
5
5
  check.
6
6
 
7
- **Beta.** The API is still settling, so it publishes under the `beta`
8
- dist-tag and may change between releases.
9
-
10
7
  Add the `evals` option to the Skybridge Vite plugin, then write scenarios with
11
8
  vitest's own `it` and `expect`.
12
9
 
13
10
  ```ts
11
+ import { anthropic } from "@ai-sdk/anthropic";
14
12
  import { expect, it } from "vitest";
15
13
  import { start } from "@skybridge/test";
16
14
  import type { AppType } from "../src/server.js";
17
15
 
18
16
  it("finds products by category", async () => {
19
- const chat = await start<AppType>();
17
+ const chat = await start<AppType>({ model: anthropic("claude-sonnet-4-5") });
20
18
  await chat.send("I am looking for ski goggles");
21
19
 
22
20
  expect.chat(chat).toHaveCalledToolWith("search-products", {
@@ -25,68 +23,95 @@ it("finds products by category", async () => {
25
23
  });
26
24
  ```
27
25
 
28
- ## Choosing a model
26
+ ## In-process mode
27
+
28
+ Pass the app itself instead of booting a server. `start` then dials
29
+ `app.fetchHandler` directly, and the tool names and argument shapes come from
30
+ the app value, so no type parameter is needed.
31
+
32
+ ```ts
33
+ import { anthropic } from "@ai-sdk/anthropic";
34
+ import { expect, it } from "vitest";
35
+ import { start } from "@skybridge/test";
36
+ import { app } from "../src/server.js";
37
+
38
+ it("finds products by category", async () => {
39
+ const chat = await start({ app, model: anthropic("claude-sonnet-4-5") });
40
+ await chat.send("I am looking for ski goggles");
41
+
42
+ expect.chat(chat).toHaveCalledToolWith("search-products", {
43
+ category: "goggles",
44
+ });
45
+ });
46
+ ```
29
47
 
30
- `model` is a `provider/model-id` string. Only the provider you name is
31
- imported, so install just that one as a dev dependency, and the key is read
32
- from its own environment variable.
48
+ Prefer it whenever you can: there is no child process and no plugin config, so
49
+ it runs anywhere vitest does. The caveat is that it bypasses the Express layer,
50
+ so nothing verifies a bearer token; pass `authInfo` to claim an identity, or use
51
+ the process mode above when the evals must go through real tokens.
33
52
 
34
- | prefix | package | key |
35
- | --- | --- | --- |
36
- | `anthropic` | `@ai-sdk/anthropic` | `ANTHROPIC_API_KEY` |
37
- | `openai` | `@ai-sdk/openai` | `OPENAI_API_KEY` |
38
- | `mistral` | `@ai-sdk/mistral` | `MISTRAL_API_KEY` |
39
- | `google` | `@ai-sdk/google` | `GOOGLE_GENERATIVE_AI_API_KEY` |
53
+ ### Authenticated evals
40
54
 
41
55
  ```ts
42
- skybridge({
43
- evals: {
44
- model: "anthropic/claude-sonnet-4-5",
45
- project: { cwd: ".", command: ["node", "dist/server.js"] },
56
+ const chat = await start({
57
+ app,
58
+ model: anthropic("claude-sonnet-4-5"),
59
+ authInfo: {
60
+ token: "eval-token",
61
+ clientId: "eval-client",
62
+ scopes: ["checkout"],
63
+ extra: { sub: "user_123", email: "ada@example.com" },
46
64
  },
47
65
  });
48
66
  ```
49
67
 
50
- `command` has to start the server process directly, since wrappers such as
51
- `pnpm run` do not forward the channel the runner uses to learn the port.
68
+ `authInfo` injects a claimed identity: the app's own scheme and scope
69
+ enforcement runs for real, in-band challenges included, and only token
70
+ signature verification is skipped. Omit it to eval the anonymous path, which is
71
+ how you assert that a protected tool challenges instead of running.
52
72
 
53
- Scenarios wait on a real model, so raise vitest's `testTimeout` well above its
54
- default: `test: { testTimeout: 120_000 }`.
73
+ ## Choosing a model
55
74
 
56
- Any other prefix is passed to the AI SDK untouched, so a string such as
57
- `openai/gpt-5` also resolves through the Vercel AI Gateway if you have
58
- `AI_GATEWAY_API_KEY` set and no provider package installed.
75
+ `start` takes any AI SDK model instance, so the provider and its credentials
76
+ are the project's own. Install the provider package you want alongside `ai`.
59
77
 
60
- ## Models the prefixes cannot reach
78
+ ```ts
79
+ import { anthropic } from "@ai-sdk/anthropic";
80
+ import { start } from "@skybridge/test";
61
81
 
62
- For a local runtime, a company gateway, or a model that needs middleware,
63
- build the model yourself and register it from a vitest setup file. It takes
64
- precedence over `model`, which can then be left out.
82
+ const chat = await start<AppType>({ model: anthropic("claude-sonnet-4-5") });
83
+ ```
84
+
85
+ A local runtime or a company gateway works the same way, through the AI SDK's
86
+ own `createOpenAICompatible` or `customProvider`.
65
87
 
66
88
  ```ts
67
- // eval-model.ts
68
89
  import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
69
- import { defineEvalModel } from "@skybridge/test";
70
90
 
71
- defineEvalModel(
72
- createOpenAICompatible({ baseURL: "http://localhost:11434/v1" })("llama3.1"),
73
- );
91
+ const ollama = createOpenAICompatible({
92
+ name: "ollama",
93
+ baseURL: "http://localhost:11434/v1",
94
+ });
95
+ const chat = await start<AppType>({ model: ollama("llama3.1") });
74
96
  ```
75
97
 
98
+ ## Booting the server
99
+
76
100
  ```ts
77
- // vitest.config.ts
78
- export default defineConfig({
79
- plugins: [skybridge({ evals: { project: { ... } } })],
80
- test: { setupFiles: ["./eval-model.ts"] },
101
+ skybridge({
102
+ evals: { project: { cwd: ".", command: ["node", "dist/index.js"] } },
81
103
  });
82
104
  ```
83
105
 
84
- Tool calls the server rejected do not count towards a positive assertion, so a
85
- scenario cannot pass on a call that errored. To assert an error on purpose, use
86
- `toHaveFailedToolCall`.
106
+ `command` has to start the server process directly, since wrappers such as
107
+ `pnpm run` do not forward the channel the runner uses to learn the port.
108
+
109
+ Assertions on what the assistant said work the same way, though model prose
110
+ varies between runs, so keep them loose.
87
111
 
88
112
  ```ts
89
- expect.chat(chat).toHaveFailedToolCall("create-checkout");
113
+ expect.chat(chat).toHaveSaid("in stock");
114
+ expect.chat(chat).not.toHaveSaid("refund");
90
115
  ```
91
116
 
92
117
  See the [documentation](https://docs.skybridge.tech) for setup and the full
package/dist/chat.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ToolCall, ToolDefinition } from "@skybridge/vite-plugin/evals";
1
+ import type { ToolCall } from "@skybridge/vite-plugin/evals";
2
2
  import { type LanguageModel } from "ai";
3
3
  interface HostConfig {
4
4
  model: LanguageModel;
@@ -6,13 +6,22 @@ interface HostConfig {
6
6
  systemPrompt?: string;
7
7
  maxSteps?: number;
8
8
  }
9
+ /**
10
+ * A `fetch` replacement the transport dials instead of the network. Mirrors the
11
+ * MCP client's own `fetch` option so an in-process app can serve the session.
12
+ */
13
+ export type TransportFetch = (url: string | URL, init?: RequestInit) => Promise<Response>;
9
14
  /**
10
15
  * One conversation against one MCP session. A scenario asserts on
11
16
  * {@link Chat.toolCalls}, the sequence of calls the model made.
12
17
  */
13
18
  export declare class Chat<App = unknown> {
19
+ /** Type-only anchor so `expect.chat` infers `App` from the conversation. */
20
+ readonly $app: App;
14
21
  /** Every call the model made, in order, as it crossed the wire. */
15
22
  readonly toolCalls: ToolCall<App>[];
23
+ /** What the assistant said, one entry per turn, intermediate ones included. */
24
+ readonly assistantTurns: string[];
16
25
  private readonly messages;
17
26
  private readonly failures;
18
27
  private readonly client;
@@ -20,11 +29,9 @@ export declare class Chat<App = unknown> {
20
29
  private readonly host;
21
30
  private tools;
22
31
  private constructor();
23
- static open<App>(serverUrl: string, host: HostConfig): Promise<Chat<App>>;
24
- /** The tool definitions the model was looking at, for failure reports. */
25
- get toolDefinitions(): ToolDefinition[];
26
- /** Takes a turn and returns the model's answer. */
27
- send(prompt: string): Promise<string>;
32
+ static open<App>(serverUrl: string, host: HostConfig, fetchImpl?: TransportFetch): Promise<Chat<App>>;
33
+ /** Takes a turn. Assert on the result with `expect.chat`. */
34
+ send(prompt: string): Promise<void>;
28
35
  close(): Promise<void>;
29
36
  private failureFor;
30
37
  private toolSet;
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAIL,KAAK,aAAa,EAGnB,MAAM,IAAI,CAAC;AAEZ,UAAU,UAAU;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,qBAAa,IAAI,CAAC,GAAG,GAAG,OAAO;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAM;IAEzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,KAAK,CAAwB;IAErC,OAAO;WAUM,IAAI,CAAC,GAAG,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAerB,0EAA0E;IAC1E,IAAI,eAAe,IAAI,cAAc,EAAE,CAEtC;IAED,mDAAmD;IAC7C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,OAAO;CAmChB"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAIL,KAAK,aAAa,EAGnB,MAAM,IAAI,CAAC;AAEZ,UAAU,UAAU;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB;;;GAGG;AACH,qBAAa,IAAI,CAAC,GAAG,GAAG,OAAO;IAC7B,4EAA4E;IAC5E,SAAiB,IAAI,EAAE,GAAG,CAAC;IAE3B,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAM;IAEzC,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,CAAM;IAEvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,KAAK,CAAc;IAE3B,OAAO;WAUM,IAAI,CAAC,GAAG,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,UAAU,EAChB,SAAS,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAkBrB,6DAA6D;IACvD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,OAAO;CAqChB"}
package/dist/chat.js CHANGED
@@ -1,5 +1,4 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
1
+ import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
3
2
  import { dynamicTool, generateText, jsonSchema, stepCountIs, } from "ai";
4
3
  const DEFAULT_MAX_STEPS = 8;
5
4
  /**
@@ -9,6 +8,8 @@ const DEFAULT_MAX_STEPS = 8;
9
8
  export class Chat {
10
9
  /** Every call the model made, in order, as it crossed the wire. */
11
10
  toolCalls = [];
11
+ /** What the assistant said, one entry per turn, intermediate ones included. */
12
+ assistantTurns = [];
12
13
  messages = [];
13
14
  failures = new Map();
14
15
  client;
@@ -20,9 +21,9 @@ export class Chat {
20
21
  this.transport = transport;
21
22
  this.host = host;
22
23
  }
23
- static async open(serverUrl, host) {
24
+ static async open(serverUrl, host, fetchImpl) {
24
25
  const client = new Client({ name: "skybridge-eval", version: "0" });
25
- const transport = new StreamableHTTPClientTransport(new URL(serverUrl));
26
+ const transport = new StreamableHTTPClientTransport(new URL(serverUrl), fetchImpl === undefined ? undefined : { fetch: fetchImpl });
26
27
  await client.connect(transport);
27
28
  const chat = new Chat(client, transport, host);
28
29
  try {
@@ -35,11 +36,7 @@ export class Chat {
35
36
  }
36
37
  return chat;
37
38
  }
38
- /** The tool definitions the model was looking at, for failure reports. */
39
- get toolDefinitions() {
40
- return this.tools;
41
- }
42
- /** Takes a turn and returns the model's answer. */
39
+ /** Takes a turn. Assert on the result with `expect.chat`. */
43
40
  async send(prompt) {
44
41
  this.messages.push({ role: "user", content: prompt });
45
42
  const result = await generateText({
@@ -61,8 +58,12 @@ export class Chat {
61
58
  });
62
59
  }
63
60
  }
61
+ for (const step of result.steps) {
62
+ if (step.text !== "") {
63
+ this.assistantTurns.push(step.text);
64
+ }
65
+ }
64
66
  this.messages.push(...result.response.messages);
65
- return result.text;
66
67
  }
67
68
  async close() {
68
69
  await this.transport.close();
package/dist/chat.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { ChatAssertion, ChatMatchers, } from "@skybridge/vite-plugin/evals";
2
2
  export type { Chat } from "./chat.js";
3
- export { defineEvalModel } from "./model.js";
3
+ export type { EvalApp, EvalIdentity } from "./session-registry.js";
4
4
  export { start } from "./session-registry.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,YAAY,GACb,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,YAAY,GACb,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,2 @@
1
- export { defineEvalModel } from "./model.js";
2
1
  export { start } from "./session-registry.js";
3
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,16 +1,70 @@
1
+ import type { LanguageModel } from "ai";
1
2
  import { Chat } from "./chat.js";
2
3
  /**
3
- * Opens a fresh MCP session and conversation against the server the plugin
4
- * started. The session is closed when the current test finishes, so scenarios
5
- * never leak sessions and never write teardown, and tests that run
4
+ * The minimum a Skybridge app has to expose to be served in-process: the
5
+ * `$types` marker the assertions infer tool names from, and the fetch handler
6
+ * the session is dialed through. Structural on purpose, so this package needs
7
+ * no runtime dependency on `skybridge`.
8
+ */
9
+ export interface EvalApp {
10
+ readonly $types: {
11
+ readonly tools: object;
12
+ };
13
+ readonly fetchHandler: {
14
+ fetch: (request: Request, options?: {
15
+ authInfo?: EvalIdentity;
16
+ }) => Promise<Response>;
17
+ };
18
+ }
19
+ /**
20
+ * The identity an in-process session claims, handed to the app as the
21
+ * request's `authInfo`. Mirrors the SDK's `AuthInfo` structurally; `extra`
22
+ * carries whatever claims the app's verifier would have produced.
23
+ */
24
+ export interface EvalIdentity {
25
+ token: string;
26
+ clientId: string;
27
+ scopes: string[];
28
+ expiresAt?: number;
29
+ resource?: URL;
30
+ extra?: Record<string, unknown>;
31
+ }
32
+ interface StartOptions {
33
+ /** Any AI SDK model instance, built by the project. */
34
+ model: LanguageModel;
35
+ systemPrompt?: string;
36
+ temperature?: number;
37
+ maxSteps?: number;
38
+ }
39
+ /**
40
+ * Opens a fresh MCP session and conversation against the app under test. Pass
41
+ * `app` to serve it in-process, or omit it to reach the server the Vite plugin
42
+ * started. Either way the session is closed when the current test finishes, so
43
+ * scenarios never leak sessions and never write teardown, and tests that run
6
44
  * concurrently cannot close each other's sessions.
7
45
  *
46
+ * In-process mode infers the assertions from the app value itself, so
47
+ * `expect.chat` gets the project's tool names and argument shapes with no type
48
+ * parameter. It talks straight to `app.fetchHandler`, which never closes: the
49
+ * handler is memoized on the app and shared by every test.
50
+ *
51
+ * `authInfo` claims an identity for the session: the app's per-tool scheme and
52
+ * scope enforcement runs against it for real, only token verification is
53
+ * skipped. Omit it to exercise the anonymous path, challenges included. It is
54
+ * in-process only, since a server reached over HTTP takes real tokens instead.
55
+ */
56
+ export declare function start<App extends EvalApp>(options: StartOptions & {
57
+ app: App;
58
+ authInfo?: EvalIdentity;
59
+ }): Promise<Chat<App>>;
60
+ /**
8
61
  * The type parameter pins the assertions to the project's registry:
9
62
  * `start<AppType>()` returns a `Chat<AppType>`, and `expect.chat` infers the
10
63
  * tool names and argument shapes from it.
11
64
  */
12
- export declare function start<App>(overrides?: {
13
- systemPrompt?: string;
14
- temperature?: number;
65
+ export declare function start<App>(options: StartOptions & {
66
+ app?: never;
67
+ authInfo?: never;
15
68
  }): Promise<Chat<App>>;
69
+ export {};
16
70
  //# sourceMappingURL=session-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-registry.d.ts","sourceRoot":"","sources":["../src/session-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAgBrB"}
1
+ {"version":3,"file":"session-registry.d.ts","sourceRoot":"","sources":["../src/session-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE;QACrB,KAAK,EAAE,CACL,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,YAAY,CAAA;SAAE,KAClC,OAAO,CAAC,QAAQ,CAAC,CAAC;KACxB,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,UAAU,YAAY;IACpB,uDAAuD;IACvD,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,KAAK,CAAC,GAAG,SAAS,OAAO,EAC7C,OAAO,EAAE,YAAY,GAAG;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;CAAE,GAC5D,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACtB;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAC7B,OAAO,EAAE,YAAY,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACxD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC"}
@@ -1,29 +1,36 @@
1
1
  import { inject, onTestFinished } from "vitest";
2
2
  import { Chat } from "./chat.js";
3
- import { resolveModel } from "./model.js";
4
- /**
5
- * Opens a fresh MCP session and conversation against the server the plugin
6
- * started. The session is closed when the current test finishes, so scenarios
7
- * never leak sessions and never write teardown, and tests that run
8
- * concurrently cannot close each other's sessions.
9
- *
10
- * The type parameter pins the assertions to the project's registry:
11
- * `start<AppType>()` returns a `Chat<AppType>`, and `expect.chat` infers the
12
- * tool names and argument shapes from it.
13
- */
14
- export async function start(overrides) {
15
- const config = inject("skybridgeEvals");
16
- const url = inject("skybridgeEvalsUrl");
17
- if (config === undefined || url === undefined) {
18
- throw new Error("No eval server is running. Add `skybridge({ evals: {...} })` to the vitest config.");
3
+ const IN_PROCESS_URL = "http://in-process.skybridge.test/mcp";
4
+ function sharedDefaults() {
5
+ try {
6
+ return inject("skybridgeEvals");
7
+ }
8
+ catch {
9
+ return undefined;
19
10
  }
20
- const chat = await Chat.open(url, {
21
- model: await resolveModel(config.model),
22
- temperature: overrides?.temperature ?? config.temperature,
23
- systemPrompt: overrides?.systemPrompt ?? config.systemPrompt,
24
- maxSteps: config.maxSteps,
25
- });
11
+ }
12
+ export async function start(options) {
13
+ const config = sharedDefaults();
14
+ const host = {
15
+ model: options.model,
16
+ temperature: options.temperature ?? config?.temperature,
17
+ systemPrompt: options.systemPrompt ?? config?.systemPrompt,
18
+ maxSteps: options.maxSteps ?? config?.maxSteps,
19
+ };
20
+ const chat = await (options.app === undefined
21
+ ? Chat.open(urlFromPlugin(), host)
22
+ : inProcessChat(options.app, host, options.authInfo));
26
23
  onTestFinished(() => chat.close());
27
24
  return chat;
28
25
  }
26
+ function urlFromPlugin() {
27
+ const url = inject("skybridgeEvalsUrl");
28
+ if (url === undefined) {
29
+ throw new Error("No eval server is running. Pass `app` to `start` to serve the app in-process, or add `skybridge({ evals: {...} })` to the vitest config.");
30
+ }
31
+ return url;
32
+ }
33
+ function inProcessChat(app, host, authInfo) {
34
+ return Chat.open(IN_PROCESS_URL, host, (url, init) => app.fetchHandler.fetch(new Request(url, init), authInfo === undefined ? undefined : { authInfo }));
35
+ }
29
36
  //# sourceMappingURL=session-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-registry.js","sourceRoot":"","sources":["../src/session-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAM,SAGhC;IACC,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAM,GAAG,EAAE;QACrC,KAAK,EAAE,MAAM,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;QACvC,WAAW,EAAE,SAAS,EAAE,WAAW,IAAI,MAAM,CAAC,WAAW;QACzD,YAAY,EAAE,SAAS,EAAE,YAAY,IAAI,MAAM,CAAC,YAAY;QAC5D,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CAAC;IACH,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"session-registry.js","sourceRoot":"","sources":["../src/session-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAwCjC,MAAM,cAAc,GAAG,sCAAsC,CAAC;AAE9D,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AA8BD,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAAkE;IAElE,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG;QACX,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,MAAM,EAAE,WAAW;QACvD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,MAAM,EAAE,YAAY;QAC1D,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM,EAAE,QAAQ;KAC/C,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS;QAC3C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAM,aAAa,EAAE,EAAE,IAAI,CAAC;QACvC,CAAC,CAAC,aAAa,CAAM,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE7D,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa;IACpB,MAAM,GAAG,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACxC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,0IAA0I,CAC3I,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CACpB,GAAY,EACZ,IAAqC,EACrC,QAAkC;IAElC,OAAO,IAAI,CAAC,IAAI,CAAM,cAAc,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CACxD,GAAG,CAAC,YAAY,CAAC,KAAK,CACpB,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EACtB,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAClD,CACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skybridge/test",
3
- "version": "0.0.0-dev.c19b437",
3
+ "version": "0.0.0-dev.dbab7df",
4
4
  "description": "Eval runner for Skybridge MCP apps: does a prompt reach the right tool with the right arguments",
5
5
  "license": "ISC",
6
6
  "type": "module",
@@ -12,58 +12,31 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "default": "./dist/index.js"
15
- },
16
- "./vitest-config": {
17
- "types": "./dist/vitest-config.d.ts",
18
- "default": "./dist/vitest-config.js"
19
15
  }
20
16
  },
21
17
  "files": [
22
18
  "dist"
23
19
  ],
24
20
  "dependencies": {
25
- "@modelcontextprotocol/sdk": "^1.29.0",
26
- "ai": "^5.0.0",
27
- "@skybridge/vite-plugin": "0.0.0-dev.c19b437"
21
+ "@modelcontextprotocol/client": "^2.0.0",
22
+ "@skybridge/vite-plugin": "0.0.0-dev.dbab7df"
28
23
  },
29
24
  "peerDependencies": {
30
- "@ai-sdk/anthropic": "^2.0.0",
31
- "@ai-sdk/google": "^2.0.0",
32
- "@ai-sdk/mistral": "^2.0.0",
33
- "@ai-sdk/openai": "^2.0.0",
25
+ "ai": "^5.0.0",
34
26
  "skybridge": "^2.0.0",
35
27
  "vitest": "^4.1.0"
36
28
  },
37
- "peerDependenciesMeta": {
38
- "@ai-sdk/anthropic": {
39
- "optional": true
40
- },
41
- "@ai-sdk/google": {
42
- "optional": true
43
- },
44
- "@ai-sdk/mistral": {
45
- "optional": true
46
- },
47
- "@ai-sdk/openai": {
48
- "optional": true
49
- }
50
- },
51
29
  "devDependencies": {
52
- "@ai-sdk/anthropic": "^2.0.0",
53
- "@ai-sdk/google": "^2.0.0",
54
- "@ai-sdk/mistral": "^2.0.0",
55
- "@ai-sdk/openai": "^2.0.0",
56
30
  "@types/node": "^24.13.3",
31
+ "ai": "^5.0.0",
57
32
  "typescript": "^5.9.3",
58
33
  "vitest": "^4.1.10",
59
- "skybridge": "0.0.0-dev.c19b437"
34
+ "zod": "^4.4.3",
35
+ "skybridge": "0.0.0-dev.dbab7df"
60
36
  },
61
37
  "engines": {
62
38
  "node": ">=22.23.1"
63
39
  },
64
- "publishConfig": {
65
- "tag": "beta"
66
- },
67
40
  "scripts": {
68
41
  "build": "tsc -p tsconfig.json",
69
42
  "format": "biome check --write --error-on-warnings",
package/dist/model.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import type { LanguageModel } from "ai";
2
- /**
3
- * Registers a model instance from a setup file, taking precedence over the
4
- * configured `model` string. The escape hatch for anything the provider
5
- * prefixes cannot express, such as a local runtime or a company LLM gateway.
6
- */
7
- export declare function defineEvalModel(model: LanguageModel): void;
8
- /**
9
- * Turns a `provider/model-id` string into a model instance, importing only the
10
- * provider named. Each provider package reads its own conventional API key
11
- * variable, so no key configuration is needed. An unrecognised prefix is
12
- * returned untouched for the AI SDK's default provider to resolve.
13
- */
14
- export declare function resolveModel(spec: string | undefined): Promise<LanguageModel>;
15
- //# sourceMappingURL=model.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAaxC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAE1D;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAAC,aAAa,CAAC,CAwBxB"}
package/dist/model.js DELETED
@@ -1,43 +0,0 @@
1
- const PROVIDERS = {
2
- anthropic: () => import("@ai-sdk/anthropic").then((m) => m.anthropic),
3
- google: () => import("@ai-sdk/google").then((m) => m.google),
4
- mistral: () => import("@ai-sdk/mistral").then((m) => m.mistral),
5
- openai: () => import("@ai-sdk/openai").then((m) => m.openai),
6
- };
7
- let registered;
8
- /**
9
- * Registers a model instance from a setup file, taking precedence over the
10
- * configured `model` string. The escape hatch for anything the provider
11
- * prefixes cannot express, such as a local runtime or a company LLM gateway.
12
- */
13
- export function defineEvalModel(model) {
14
- registered = model;
15
- }
16
- /**
17
- * Turns a `provider/model-id` string into a model instance, importing only the
18
- * provider named. Each provider package reads its own conventional API key
19
- * variable, so no key configuration is needed. An unrecognised prefix is
20
- * returned untouched for the AI SDK's default provider to resolve.
21
- */
22
- export async function resolveModel(spec) {
23
- if (registered !== undefined) {
24
- return registered;
25
- }
26
- if (spec === undefined) {
27
- throw new Error("No model configured. Set `model` on the evals plugin, or call defineEvalModel() from a setup file.");
28
- }
29
- const separator = spec.indexOf("/");
30
- if (separator === -1) {
31
- return spec;
32
- }
33
- const name = spec.slice(0, separator);
34
- const load = PROVIDERS[name];
35
- if (load === undefined) {
36
- return spec;
37
- }
38
- const provider = await load().catch(() => {
39
- throw new Error(`The model "${spec}" needs @ai-sdk/${name}@^2. Install it as a dev dependency.`);
40
- });
41
- return provider(spec.slice(separator + 1));
42
- }
43
- //# sourceMappingURL=model.js.map
package/dist/model.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAIA,MAAM,SAAS,GAAmD;IAChE,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5D,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/D,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;CAC7D,CAAC;AAEF,IAAI,UAAqC,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAwB;IAExB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,KAAK,CACb,cAAc,IAAI,mBAAmB,IAAI,sCAAsC,CAChF,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC"}