@apollo/client-ai-apps 0.6.4 → 0.7.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/CHANGELOG.md +100 -0
- package/CONTRIBUTING.md +195 -0
- package/README.md +74 -0
- package/dist/core/AbstractApolloClient.d.ts +33 -0
- package/dist/core/AbstractApolloClient.d.ts.map +1 -0
- package/dist/core/AbstractApolloClient.js +129 -0
- package/dist/core/AbstractApolloClient.js.map +1 -0
- package/dist/core/ApolloClient.d.ts +3 -7
- package/dist/core/ApolloClient.d.ts.map +1 -1
- package/dist/core/ApolloClient.js +5 -4
- package/dist/core/ApolloClient.js.map +1 -1
- package/dist/core/McpAppManager.d.ts +42 -0
- package/dist/core/McpAppManager.d.ts.map +1 -0
- package/dist/core/McpAppManager.js +56 -0
- package/dist/core/McpAppManager.js.map +1 -0
- package/dist/core/typeRegistration.d.ts +0 -14
- package/dist/core/typeRegistration.d.ts.map +1 -1
- package/dist/core/typeRegistration.js.map +1 -1
- package/dist/core/types.d.ts +2 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mcp.d.ts +0 -1
- package/dist/index.mcp.d.ts.map +1 -1
- package/dist/index.mcp.js +0 -1
- package/dist/index.mcp.js.map +1 -1
- package/dist/index.openai.d.ts +0 -1
- package/dist/index.openai.d.ts.map +1 -1
- package/dist/index.openai.js +0 -1
- package/dist/index.openai.js.map +1 -1
- package/dist/link/ToolCallLink.d.ts +6 -1
- package/dist/link/ToolCallLink.d.ts.map +1 -1
- package/dist/link/ToolCallLink.js +17 -4
- package/dist/link/ToolCallLink.js.map +1 -1
- package/dist/link/ToolHydrationLink.d.ts +21 -0
- package/dist/link/ToolHydrationLink.d.ts.map +1 -0
- package/dist/link/ToolHydrationLink.js +57 -0
- package/dist/link/ToolHydrationLink.js.map +1 -0
- package/dist/mcp/core/ApolloClient.d.ts +3 -20
- package/dist/mcp/core/ApolloClient.d.ts.map +1 -1
- package/dist/mcp/core/ApolloClient.js +20 -98
- package/dist/mcp/core/ApolloClient.js.map +1 -1
- package/dist/mcp/index.d.ts +0 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +0 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/openai/core/ApolloClient.d.ts +3 -20
- package/dist/openai/core/ApolloClient.d.ts.map +1 -1
- package/dist/openai/core/ApolloClient.js +36 -98
- package/dist/openai/core/ApolloClient.js.map +1 -1
- package/dist/openai/index.d.ts +0 -1
- package/dist/openai/index.d.ts.map +1 -1
- package/dist/openai/index.js +0 -1
- package/dist/openai/index.js.map +1 -1
- package/dist/openai/react/index.d.ts +0 -7
- package/dist/openai/react/index.d.ts.map +1 -1
- package/dist/openai/react/index.js +0 -7
- package/dist/openai/react/index.js.map +1 -1
- package/dist/react/ApolloProvider.d.ts.map +1 -1
- package/dist/react/ApolloProvider.js +1 -1
- package/dist/react/ApolloProvider.js.map +1 -1
- package/dist/{mcp/react/hooks → react}/createHydrationUtils.d.ts +1 -1
- package/dist/react/createHydrationUtils.d.ts.map +1 -0
- package/dist/{mcp/react/hooks → react}/createHydrationUtils.js +7 -9
- package/dist/react/createHydrationUtils.js.map +1 -0
- package/dist/react/hooks/internal/useApolloClient.d.ts +3 -0
- package/dist/react/hooks/internal/useApolloClient.d.ts.map +1 -0
- package/dist/{mcp/react/hooks → react/hooks/internal}/useApolloClient.js +3 -3
- package/dist/react/hooks/internal/useApolloClient.js.map +1 -0
- package/dist/react/hooks/useApp.d.ts.map +1 -0
- package/dist/react/hooks/useApp.js +5 -0
- package/dist/react/hooks/useApp.js.map +1 -0
- package/dist/react/hooks/useHostContext.d.ts.map +1 -0
- package/dist/{openai/react → react}/hooks/useHostContext.js +1 -1
- package/dist/react/hooks/useHostContext.js.map +1 -0
- package/dist/react/hooks/useToolInfo.d.ts +3 -0
- package/dist/react/hooks/useToolInfo.d.ts.map +1 -0
- package/dist/react/hooks/useToolInfo.js +5 -0
- package/dist/react/hooks/useToolInfo.js.map +1 -0
- package/dist/react/hooks/useToolMetadata.d.ts +2 -0
- package/dist/react/hooks/useToolMetadata.d.ts.map +1 -0
- package/dist/react/hooks/useToolMetadata.js +5 -0
- package/dist/react/hooks/useToolMetadata.js.map +1 -0
- package/dist/react/index.d.ts +5 -16
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -19
- package/dist/react/index.js.map +1 -1
- package/dist/types/application-manifest.d.ts +1 -0
- package/dist/types/application-manifest.d.ts.map +1 -1
- package/dist/types/application-manifest.js.map +1 -1
- package/dist/utilities/connectToHost.d.ts +3 -0
- package/dist/utilities/connectToHost.d.ts.map +1 -0
- package/dist/utilities/connectToHost.js +11 -0
- package/dist/utilities/connectToHost.js.map +1 -0
- package/dist/utilities/index.d.ts +1 -0
- package/dist/utilities/index.d.ts.map +1 -1
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/index.js.map +1 -1
- package/dist/vite/apolloClientAiApps.d.ts.map +1 -1
- package/dist/vite/apolloClientAiApps.js +2 -0
- package/dist/vite/apolloClientAiApps.js.map +1 -1
- package/package.json +5 -22
- package/src/core/AbstractApolloClient.ts +217 -0
- package/src/core/ApolloClient.ts +8 -10
- package/src/core/McpAppManager.ts +106 -0
- package/src/core/typeRegistration.ts +0 -15
- package/src/core/types.ts +2 -1
- package/src/index.mcp.ts +0 -1
- package/src/index.openai.ts +0 -1
- package/src/index.ts +1 -6
- package/src/link/ToolCallLink.ts +27 -5
- package/src/link/ToolHydrationLink.ts +90 -0
- package/src/link/__tests__/ToolCallLink.test.ts +99 -0
- package/src/mcp/core/ApolloClient.ts +32 -165
- package/src/mcp/core/__tests__/ApolloClient.test.ts +571 -71
- package/src/mcp/index.ts +0 -1
- package/src/openai/core/ApolloClient.ts +48 -161
- package/src/openai/core/__tests__/ApolloClient.test.ts +916 -118
- package/src/openai/index.ts +0 -1
- package/src/openai/react/index.ts +0 -7
- package/src/react/ApolloProvider.tsx +1 -6
- package/src/react/__tests__/ApolloProvider/mcp.test.tsx +66 -29
- package/src/react/__tests__/ApolloProvider/openai.test.tsx +16 -41
- package/src/react/__tests__/createHydrationUtils.test.tsx +1260 -0
- package/src/{mcp/react/hooks → react}/createHydrationUtils.ts +7 -10
- package/src/react/hooks/__tests__/useApp.test.tsx +46 -0
- package/src/react/hooks/__tests__/useHostContext.test.tsx +99 -0
- package/src/react/hooks/__tests__/useToolInfo.test.tsx +98 -0
- package/src/react/hooks/__tests__/useToolMetadata.test.tsx +58 -0
- package/src/{mcp/react/hooks → react/hooks/internal}/useApolloClient.ts +3 -3
- package/src/{mcp/react → react}/hooks/useApp.ts +1 -1
- package/src/{openai/react → react}/hooks/useHostContext.ts +1 -1
- package/src/react/hooks/useToolInfo.ts +6 -0
- package/src/react/hooks/useToolMetadata.ts +5 -0
- package/src/react/index.ts +5 -36
- package/src/testing/internal/graphql/parseManifestOperation.ts +87 -0
- package/src/testing/internal/index.ts +3 -0
- package/src/testing/internal/matchers/index.ts +1 -0
- package/src/testing/internal/matchers/toEmitAnything.ts +43 -0
- package/src/testing/internal/matchers/types.ts +1 -0
- package/src/testing/internal/mcp/mockMcpHost.ts +25 -4
- package/src/testing/internal/tests/eachHostEnv.ts +22 -0
- package/src/testing/internal/utilities/createHostEnv.ts +117 -0
- package/src/types/application-manifest.ts +1 -0
- package/src/utilities/connectToHost.ts +13 -0
- package/src/utilities/index.ts +1 -0
- package/src/vite/__tests__/apolloClientAiApps.test.ts +56 -0
- package/src/vite/apolloClientAiApps.ts +5 -0
- package/tsconfig.vite.json +1 -1
- package/vitest.config.ts +13 -0
- package/dist/mcp/core/McpAppManager.d.ts +0 -30
- package/dist/mcp/core/McpAppManager.d.ts.map +0 -1
- package/dist/mcp/core/McpAppManager.js +0 -82
- package/dist/mcp/core/McpAppManager.js.map +0 -1
- package/dist/mcp/link/ToolCallLink.d.ts +0 -28
- package/dist/mcp/link/ToolCallLink.d.ts.map +0 -1
- package/dist/mcp/link/ToolCallLink.js +0 -35
- package/dist/mcp/link/ToolCallLink.js.map +0 -1
- package/dist/mcp/react/hooks/createHydrationUtils.d.ts.map +0 -1
- package/dist/mcp/react/hooks/createHydrationUtils.js.map +0 -1
- package/dist/mcp/react/hooks/useApolloClient.d.ts +0 -3
- package/dist/mcp/react/hooks/useApolloClient.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useApolloClient.js.map +0 -1
- package/dist/mcp/react/hooks/useApp.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useApp.js +0 -5
- package/dist/mcp/react/hooks/useApp.js.map +0 -1
- package/dist/mcp/react/hooks/useHostContext.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useHostContext.js +0 -7
- package/dist/mcp/react/hooks/useHostContext.js.map +0 -1
- package/dist/mcp/react/hooks/useToolInfo.d.ts +0 -3
- package/dist/mcp/react/hooks/useToolInfo.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useToolInfo.js +0 -10
- package/dist/mcp/react/hooks/useToolInfo.js.map +0 -1
- package/dist/mcp/react/hooks/useToolInput.d.ts +0 -7
- package/dist/mcp/react/hooks/useToolInput.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useToolInput.js +0 -9
- package/dist/mcp/react/hooks/useToolInput.js.map +0 -1
- package/dist/mcp/react/hooks/useToolMetadata.d.ts +0 -2
- package/dist/mcp/react/hooks/useToolMetadata.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useToolMetadata.js +0 -5
- package/dist/mcp/react/hooks/useToolMetadata.js.map +0 -1
- package/dist/mcp/react/hooks/useToolName.d.ts +0 -7
- package/dist/mcp/react/hooks/useToolName.d.ts.map +0 -1
- package/dist/mcp/react/hooks/useToolName.js +0 -9
- package/dist/mcp/react/hooks/useToolName.js.map +0 -1
- package/dist/mcp/react/index.d.ts +0 -8
- package/dist/mcp/react/index.d.ts.map +0 -1
- package/dist/mcp/react/index.js +0 -8
- package/dist/mcp/react/index.js.map +0 -1
- package/dist/openai/core/McpAppManager.d.ts +0 -29
- package/dist/openai/core/McpAppManager.d.ts.map +0 -1
- package/dist/openai/core/McpAppManager.js +0 -91
- package/dist/openai/core/McpAppManager.js.map +0 -1
- package/dist/openai/link/ToolCallLink.d.ts +0 -28
- package/dist/openai/link/ToolCallLink.d.ts.map +0 -1
- package/dist/openai/link/ToolCallLink.js +0 -35
- package/dist/openai/link/ToolCallLink.js.map +0 -1
- package/dist/openai/react/hooks/createHydrationUtils.d.ts +0 -15
- package/dist/openai/react/hooks/createHydrationUtils.d.ts.map +0 -1
- package/dist/openai/react/hooks/createHydrationUtils.js +0 -113
- package/dist/openai/react/hooks/createHydrationUtils.js.map +0 -1
- package/dist/openai/react/hooks/useApp.d.ts +0 -2
- package/dist/openai/react/hooks/useApp.d.ts.map +0 -1
- package/dist/openai/react/hooks/useApp.js +0 -5
- package/dist/openai/react/hooks/useApp.js.map +0 -1
- package/dist/openai/react/hooks/useHostContext.d.ts +0 -2
- package/dist/openai/react/hooks/useHostContext.d.ts.map +0 -1
- package/dist/openai/react/hooks/useHostContext.js.map +0 -1
- package/dist/openai/react/hooks/useToolInfo.d.ts +0 -3
- package/dist/openai/react/hooks/useToolInfo.d.ts.map +0 -1
- package/dist/openai/react/hooks/useToolInfo.js +0 -10
- package/dist/openai/react/hooks/useToolInfo.js.map +0 -1
- package/dist/openai/react/hooks/useToolInput.d.ts +0 -7
- package/dist/openai/react/hooks/useToolInput.d.ts.map +0 -1
- package/dist/openai/react/hooks/useToolInput.js +0 -9
- package/dist/openai/react/hooks/useToolInput.js.map +0 -1
- package/dist/openai/react/hooks/useToolMetadata.d.ts +0 -2
- package/dist/openai/react/hooks/useToolMetadata.d.ts.map +0 -1
- package/dist/openai/react/hooks/useToolMetadata.js +0 -5
- package/dist/openai/react/hooks/useToolMetadata.js.map +0 -1
- package/dist/openai/react/hooks/useToolName.d.ts +0 -7
- package/dist/openai/react/hooks/useToolName.d.ts.map +0 -1
- package/dist/openai/react/hooks/useToolName.js +0 -9
- package/dist/openai/react/hooks/useToolName.js.map +0 -1
- package/dist/react/index.mcp.d.ts +0 -3
- package/dist/react/index.mcp.d.ts.map +0 -1
- package/dist/react/index.mcp.js +0 -3
- package/dist/react/index.mcp.js.map +0 -1
- package/dist/react/index.openai.d.ts +0 -3
- package/dist/react/index.openai.d.ts.map +0 -1
- package/dist/react/index.openai.js +0 -3
- package/dist/react/index.openai.js.map +0 -1
- package/dist/react/missingHook.d.ts +0 -2
- package/dist/react/missingHook.d.ts.map +0 -1
- package/dist/react/missingHook.js +0 -6
- package/dist/react/missingHook.js.map +0 -1
- package/src/mcp/core/McpAppManager.ts +0 -129
- package/src/mcp/link/ToolCallLink.ts +0 -40
- package/src/mcp/link/__tests__/ToolCallLink.test.ts +0 -62
- package/src/mcp/react/hooks/__tests__/createHydrationUtils.test.tsx +0 -1228
- package/src/mcp/react/hooks/__tests__/useApp.test.tsx +0 -46
- package/src/mcp/react/hooks/__tests__/useHostContext.test.tsx +0 -95
- package/src/mcp/react/hooks/__tests__/useToolInfo.test.tsx +0 -53
- package/src/mcp/react/hooks/__tests__/useToolInput.test.tsx +0 -50
- package/src/mcp/react/hooks/__tests__/useToolMetadata.test.tsx +0 -53
- package/src/mcp/react/hooks/__tests__/useToolName.test.tsx +0 -50
- package/src/mcp/react/hooks/useHostContext.ts +0 -14
- package/src/mcp/react/hooks/useToolInfo.ts +0 -13
- package/src/mcp/react/hooks/useToolInput.ts +0 -10
- package/src/mcp/react/hooks/useToolMetadata.ts +0 -5
- package/src/mcp/react/hooks/useToolName.ts +0 -10
- package/src/mcp/react/index.ts +0 -7
- package/src/openai/core/McpAppManager.ts +0 -139
- package/src/openai/link/ToolCallLink.ts +0 -40
- package/src/openai/react/hooks/__tests__/createHydrationUtils.test.tsx +0 -1333
- package/src/openai/react/hooks/__tests__/useToolInfo.test.tsx +0 -92
- package/src/openai/react/hooks/__tests__/useToolInput.test.tsx +0 -85
- package/src/openai/react/hooks/__tests__/useToolMetadata.test.tsx +0 -86
- package/src/openai/react/hooks/__tests__/useToolName.test.tsx +0 -50
- package/src/openai/react/hooks/createHydrationUtils.ts +0 -182
- package/src/openai/react/hooks/useApp.ts +0 -5
- package/src/openai/react/hooks/useToolInfo.ts +0 -13
- package/src/openai/react/hooks/useToolInput.ts +0 -10
- package/src/openai/react/hooks/useToolMetadata.ts +0 -5
- package/src/openai/react/hooks/useToolName.ts +0 -10
- package/src/react/index.mcp.ts +0 -10
- package/src/react/index.openai.ts +0 -10
- package/src/react/missingHook.ts +0 -9
- /package/dist/{mcp/react → react}/hooks/useApp.d.ts +0 -0
- /package/dist/{mcp/react → react}/hooks/useHostContext.d.ts +0 -0
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { afterEach, expect, test, vi } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
graphqlToolResult,
|
|
4
|
-
minimalHostContextWithToolName,
|
|
5
|
-
mockApplicationManifest,
|
|
6
|
-
mockMcpHost,
|
|
7
|
-
spyOnConsole,
|
|
8
|
-
stubOpenAiGlobals,
|
|
9
|
-
} from "../../../../testing/internal/index.js";
|
|
10
|
-
import {
|
|
11
|
-
disableActEnvironment,
|
|
12
|
-
renderHookToSnapshotStream,
|
|
13
|
-
} from "@testing-library/react-render-stream";
|
|
14
|
-
import { useToolInfo } from "../useToolInfo.js";
|
|
15
|
-
import { ApolloClient } from "../../../core/ApolloClient.js";
|
|
16
|
-
import { InMemoryCache } from "@apollo/client";
|
|
17
|
-
import { Suspense } from "react";
|
|
18
|
-
import { ApolloProvider } from "../../../../react/ApolloProvider.js";
|
|
19
|
-
|
|
20
|
-
afterEach(() => {
|
|
21
|
-
vi.unstubAllGlobals();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("returns tool name and input combined", async () => {
|
|
25
|
-
using _ = spyOnConsole("debug");
|
|
26
|
-
stubOpenAiGlobals({ toolResponseMetadata: {}, toolInput: { id: "1" } });
|
|
27
|
-
const client = new ApolloClient({
|
|
28
|
-
cache: new InMemoryCache(),
|
|
29
|
-
manifest: mockApplicationManifest(),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
using host = await mockMcpHost({
|
|
33
|
-
hostContext: minimalHostContextWithToolName("GetProduct"),
|
|
34
|
-
});
|
|
35
|
-
host.onCleanup(() => client.stop());
|
|
36
|
-
|
|
37
|
-
host.sendToolInput({ arguments: { id: "1" } });
|
|
38
|
-
host.sendToolResult(graphqlToolResult({ data: { product: null } }));
|
|
39
|
-
|
|
40
|
-
using _disabledAct = disableActEnvironment();
|
|
41
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
42
|
-
() => useToolInfo(),
|
|
43
|
-
{
|
|
44
|
-
wrapper: ({ children }) => (
|
|
45
|
-
<Suspense>
|
|
46
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
47
|
-
</Suspense>
|
|
48
|
-
),
|
|
49
|
-
}
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
await expect(takeSnapshot()).resolves.toEqual({
|
|
53
|
-
toolName: "GetProduct",
|
|
54
|
-
toolInput: { id: "1" },
|
|
55
|
-
});
|
|
56
|
-
await expect(takeSnapshot).not.toRerender();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test("returns undefined toolInput when toolInput is not provided", async () => {
|
|
60
|
-
using _ = spyOnConsole("debug");
|
|
61
|
-
stubOpenAiGlobals({ toolResponseMetadata: {} });
|
|
62
|
-
const client = new ApolloClient({
|
|
63
|
-
cache: new InMemoryCache(),
|
|
64
|
-
manifest: mockApplicationManifest(),
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
using host = await mockMcpHost({
|
|
68
|
-
hostContext: minimalHostContextWithToolName("GetProduct"),
|
|
69
|
-
});
|
|
70
|
-
host.onCleanup(() => client.stop());
|
|
71
|
-
|
|
72
|
-
host.sendToolInput({ arguments: {} });
|
|
73
|
-
host.sendToolResult(graphqlToolResult({ data: { product: null } }));
|
|
74
|
-
|
|
75
|
-
using _disabledAct = disableActEnvironment();
|
|
76
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
77
|
-
() => useToolInfo(),
|
|
78
|
-
{
|
|
79
|
-
wrapper: ({ children }) => (
|
|
80
|
-
<Suspense>
|
|
81
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
82
|
-
</Suspense>
|
|
83
|
-
),
|
|
84
|
-
}
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
await expect(takeSnapshot()).resolves.toEqual({
|
|
88
|
-
toolName: "GetProduct",
|
|
89
|
-
toolInput: undefined,
|
|
90
|
-
});
|
|
91
|
-
await expect(takeSnapshot).not.toRerender();
|
|
92
|
-
});
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { afterEach, expect, test, vi } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
mockApplicationManifest,
|
|
4
|
-
mockMcpHost,
|
|
5
|
-
spyOnConsole,
|
|
6
|
-
stubOpenAiGlobals,
|
|
7
|
-
} from "../../../../testing/internal/index.js";
|
|
8
|
-
import {
|
|
9
|
-
disableActEnvironment,
|
|
10
|
-
renderHookToSnapshotStream,
|
|
11
|
-
} from "@testing-library/react-render-stream";
|
|
12
|
-
import { useToolInput } from "../useToolInput.js";
|
|
13
|
-
import { ApolloClient } from "../../../core/ApolloClient.js";
|
|
14
|
-
import { InMemoryCache } from "@apollo/client";
|
|
15
|
-
import { Suspense } from "react";
|
|
16
|
-
import { ApolloProvider } from "../../../../react/ApolloProvider.js";
|
|
17
|
-
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
vi.unstubAllGlobals();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("returns the tool input from the MCP host", async () => {
|
|
23
|
-
using _ = spyOnConsole("debug");
|
|
24
|
-
stubOpenAiGlobals({ toolResponseMetadata: {}, toolInput: { id: "1" } });
|
|
25
|
-
const client = new ApolloClient({
|
|
26
|
-
cache: new InMemoryCache(),
|
|
27
|
-
manifest: mockApplicationManifest(),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
using host = await mockMcpHost();
|
|
31
|
-
host.onCleanup(() => client.stop());
|
|
32
|
-
|
|
33
|
-
host.sendToolInput({ arguments: { id: "1" } });
|
|
34
|
-
host.sendToolResult({
|
|
35
|
-
content: [],
|
|
36
|
-
structuredContent: {},
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
using _disabledAct = disableActEnvironment();
|
|
40
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
41
|
-
() => useToolInput(),
|
|
42
|
-
{
|
|
43
|
-
wrapper: ({ children }) => (
|
|
44
|
-
<Suspense>
|
|
45
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
46
|
-
</Suspense>
|
|
47
|
-
),
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
await expect(takeSnapshot()).resolves.toEqual({ id: "1" });
|
|
52
|
-
await expect(takeSnapshot).not.toRerender();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test("returns undefined when ontoolinput is not fired", async () => {
|
|
56
|
-
using _ = spyOnConsole("debug");
|
|
57
|
-
stubOpenAiGlobals({ toolResponseMetadata: {} });
|
|
58
|
-
const client = new ApolloClient({
|
|
59
|
-
cache: new InMemoryCache(),
|
|
60
|
-
manifest: mockApplicationManifest(),
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
using host = await mockMcpHost();
|
|
64
|
-
host.onCleanup(() => client.stop());
|
|
65
|
-
|
|
66
|
-
host.sendToolResult({
|
|
67
|
-
content: [],
|
|
68
|
-
structuredContent: {},
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
using _disabledAct = disableActEnvironment();
|
|
72
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
73
|
-
() => useToolInput(),
|
|
74
|
-
{
|
|
75
|
-
wrapper: ({ children }) => (
|
|
76
|
-
<Suspense>
|
|
77
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
78
|
-
</Suspense>
|
|
79
|
-
),
|
|
80
|
-
}
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
await expect(takeSnapshot()).resolves.toBeUndefined();
|
|
84
|
-
await expect(takeSnapshot).not.toRerender();
|
|
85
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { afterEach, expect, test, vi } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
mockApplicationManifest,
|
|
4
|
-
mockMcpHost,
|
|
5
|
-
spyOnConsole,
|
|
6
|
-
stubOpenAiGlobals,
|
|
7
|
-
} from "../../../../testing/internal/index.js";
|
|
8
|
-
import {
|
|
9
|
-
disableActEnvironment,
|
|
10
|
-
renderHookToSnapshotStream,
|
|
11
|
-
} from "@testing-library/react-render-stream";
|
|
12
|
-
import { useToolMetadata } from "../useToolMetadata.js";
|
|
13
|
-
import { ApolloClient } from "../../../core/ApolloClient.js";
|
|
14
|
-
import { InMemoryCache } from "@apollo/client";
|
|
15
|
-
import { Suspense } from "react";
|
|
16
|
-
import { ApolloProvider } from "../../../../react/ApolloProvider.js";
|
|
17
|
-
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
vi.unstubAllGlobals();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("returns the tool metadata from window.openai", async () => {
|
|
23
|
-
using _ = spyOnConsole("debug");
|
|
24
|
-
stubOpenAiGlobals({ toolResponseMetadata: { foo: true } });
|
|
25
|
-
const client = new ApolloClient({
|
|
26
|
-
cache: new InMemoryCache(),
|
|
27
|
-
manifest: mockApplicationManifest(),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
using host = await mockMcpHost();
|
|
31
|
-
host.onCleanup(() => client.stop());
|
|
32
|
-
|
|
33
|
-
host.sendToolInput({ arguments: {} });
|
|
34
|
-
host.sendToolResult({
|
|
35
|
-
content: [],
|
|
36
|
-
structuredContent: {},
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
using _disabledAct = disableActEnvironment();
|
|
40
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
41
|
-
() => useToolMetadata(),
|
|
42
|
-
{
|
|
43
|
-
wrapper: ({ children }) => (
|
|
44
|
-
<Suspense>
|
|
45
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
46
|
-
</Suspense>
|
|
47
|
-
),
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
await expect(takeSnapshot()).resolves.toEqual({ foo: true });
|
|
52
|
-
await expect(takeSnapshot).not.toRerender();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test("returns null when not set", async () => {
|
|
56
|
-
using _ = spyOnConsole("debug");
|
|
57
|
-
stubOpenAiGlobals();
|
|
58
|
-
const client = new ApolloClient({
|
|
59
|
-
cache: new InMemoryCache(),
|
|
60
|
-
manifest: mockApplicationManifest(),
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
using host = await mockMcpHost();
|
|
64
|
-
host.onCleanup(() => client.stop());
|
|
65
|
-
|
|
66
|
-
host.sendToolInput({ arguments: {} });
|
|
67
|
-
host.sendToolResult({
|
|
68
|
-
content: [],
|
|
69
|
-
structuredContent: {},
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
using _disabledAct = disableActEnvironment();
|
|
73
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
74
|
-
() => useToolMetadata(),
|
|
75
|
-
{
|
|
76
|
-
wrapper: ({ children }) => (
|
|
77
|
-
<Suspense>
|
|
78
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
79
|
-
</Suspense>
|
|
80
|
-
),
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
await expect(takeSnapshot()).resolves.toBeNull();
|
|
85
|
-
await expect(takeSnapshot).not.toRerender();
|
|
86
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
2
|
-
import { useToolName } from "../useToolName.js";
|
|
3
|
-
import {
|
|
4
|
-
graphqlToolResult,
|
|
5
|
-
minimalHostContextWithToolName,
|
|
6
|
-
mockApplicationManifest,
|
|
7
|
-
mockMcpHost,
|
|
8
|
-
spyOnConsole,
|
|
9
|
-
stubOpenAiGlobals,
|
|
10
|
-
} from "../../../../testing/internal/index.js";
|
|
11
|
-
import { ApolloClient } from "../../../core/ApolloClient.js";
|
|
12
|
-
import { InMemoryCache } from "@apollo/client";
|
|
13
|
-
import {
|
|
14
|
-
disableActEnvironment,
|
|
15
|
-
renderHookToSnapshotStream,
|
|
16
|
-
} from "@testing-library/react-render-stream";
|
|
17
|
-
import { Suspense } from "react";
|
|
18
|
-
import { ApolloProvider } from "../../../../react/ApolloProvider.js";
|
|
19
|
-
|
|
20
|
-
test("returns the tool name from the MCP host", async () => {
|
|
21
|
-
using _ = spyOnConsole("debug");
|
|
22
|
-
stubOpenAiGlobals({ toolResponseMetadata: {} });
|
|
23
|
-
const client = new ApolloClient({
|
|
24
|
-
cache: new InMemoryCache(),
|
|
25
|
-
manifest: mockApplicationManifest(),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
using host = await mockMcpHost({
|
|
29
|
-
hostContext: minimalHostContextWithToolName("GetProduct"),
|
|
30
|
-
});
|
|
31
|
-
host.onCleanup(() => client.stop());
|
|
32
|
-
|
|
33
|
-
host.sendToolInput({ arguments: {} });
|
|
34
|
-
host.sendToolResult(graphqlToolResult({ data: { product: null } }));
|
|
35
|
-
|
|
36
|
-
using _disabledAct = disableActEnvironment();
|
|
37
|
-
const { takeSnapshot } = await renderHookToSnapshotStream(
|
|
38
|
-
() => useToolName(),
|
|
39
|
-
{
|
|
40
|
-
wrapper: ({ children }) => (
|
|
41
|
-
<Suspense>
|
|
42
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
43
|
-
</Suspense>
|
|
44
|
-
),
|
|
45
|
-
}
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
await expect(takeSnapshot()).resolves.toBe("GetProduct");
|
|
49
|
-
await expect(takeSnapshot).not.toRerender();
|
|
50
|
-
});
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useRef, useMemo, useLayoutEffect } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
DocumentNode,
|
|
4
|
-
OperationVariables,
|
|
5
|
-
TypedDocumentNode,
|
|
6
|
-
} from "@apollo/client";
|
|
7
|
-
import { useApolloClient } from "./useApolloClient.js";
|
|
8
|
-
import { useToolName } from "./useToolName.js";
|
|
9
|
-
import { isReactive } from "../../../react/reactive.js";
|
|
10
|
-
import type { Reactive } from "../../../react/reactive.js";
|
|
11
|
-
import { equal } from "@wry/equality";
|
|
12
|
-
import { __DEV__ } from "@apollo/client/utilities/environment";
|
|
13
|
-
import {
|
|
14
|
-
getToolNamesFromDocument,
|
|
15
|
-
getVariableNamesFromDocument,
|
|
16
|
-
} from "../../../utilities/index.js";
|
|
17
|
-
|
|
18
|
-
type HydratedVariablesInput<TVariables> = {
|
|
19
|
-
[K in keyof TVariables]: TVariables[K] | Reactive<TVariables[K]>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
type StateVariables<TVariables, Input> = {
|
|
23
|
-
[K in keyof TVariables as K extends keyof Input ?
|
|
24
|
-
Input[K] extends Reactive<any> ?
|
|
25
|
-
never
|
|
26
|
-
: K
|
|
27
|
-
: K]: K extends keyof TVariables ? TVariables[K] : never;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
type SetVariables<TState> = (
|
|
31
|
-
update: Partial<TState> | ((prev: TState) => Partial<TState>)
|
|
32
|
-
) => void;
|
|
33
|
-
|
|
34
|
-
/** @experimental */
|
|
35
|
-
export function createHydrationUtils<
|
|
36
|
-
TVariables extends OperationVariables = OperationVariables,
|
|
37
|
-
>(document: TypedDocumentNode<any, TVariables> | DocumentNode) {
|
|
38
|
-
const documentToolNames = getToolNamesFromDocument(document);
|
|
39
|
-
const variableNames = getVariableNamesFromDocument(document);
|
|
40
|
-
|
|
41
|
-
function useHydratedVariables<
|
|
42
|
-
TInputVariables extends HydratedVariablesInput<TVariables>,
|
|
43
|
-
>(
|
|
44
|
-
variables: TInputVariables &
|
|
45
|
-
Record<Exclude<keyof TInputVariables, keyof TVariables>, never>
|
|
46
|
-
): [
|
|
47
|
-
variables: TVariables,
|
|
48
|
-
setVariables: SetVariables<StateVariables<TVariables, TInputVariables>>,
|
|
49
|
-
] {
|
|
50
|
-
const client = useApolloClient();
|
|
51
|
-
const toolName = useToolName();
|
|
52
|
-
const [toolInput] = useState(() => client.toolInput);
|
|
53
|
-
|
|
54
|
-
const toolMatches =
|
|
55
|
-
toolInput !== undefined &&
|
|
56
|
-
toolName !== undefined &&
|
|
57
|
-
documentToolNames.has(toolName);
|
|
58
|
-
|
|
59
|
-
const [stateVars, setStateVars] = useState<Record<string, unknown>>(() => {
|
|
60
|
-
const values: Record<string, unknown> = {};
|
|
61
|
-
|
|
62
|
-
for (const [key, value] of Object.entries(
|
|
63
|
-
toolMatches ? toolInput : variables
|
|
64
|
-
)) {
|
|
65
|
-
if (variableNames.has(key) && !isReactive(value)) {
|
|
66
|
-
values[key] = value;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return values;
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
const [initialReactiveValues] = useState<Record<string, unknown>>(() => {
|
|
74
|
-
const values: Record<string, unknown> = {};
|
|
75
|
-
|
|
76
|
-
for (const [key, value] of Object.entries(variables)) {
|
|
77
|
-
if (variableNames.has(key) && isReactive(value)) {
|
|
78
|
-
values[key] = value.value;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return values;
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
const [reactiveVars, setReactiveVars] = useState(() => {
|
|
86
|
-
const values: Record<string, unknown> = {};
|
|
87
|
-
|
|
88
|
-
for (const [key, value] of Object.entries(initialReactiveValues)) {
|
|
89
|
-
if (toolMatches && key in toolInput) {
|
|
90
|
-
values[key] = toolInput[key];
|
|
91
|
-
} else if (!toolMatches) {
|
|
92
|
-
values[key] = value;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return values;
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const changedKeysRef = useRef(new Set<string>());
|
|
100
|
-
const nextReactiveVars: Record<string, unknown> = {};
|
|
101
|
-
|
|
102
|
-
for (const [key, value] of Object.entries(variables)) {
|
|
103
|
-
if (!variableNames.has(key) || !isReactive(value)) continue;
|
|
104
|
-
|
|
105
|
-
const hasChanged =
|
|
106
|
-
changedKeysRef.current.has(key) ||
|
|
107
|
-
!equal(value.value, initialReactiveValues[key]);
|
|
108
|
-
|
|
109
|
-
if (toolMatches && !hasChanged) {
|
|
110
|
-
if (key in toolInput) {
|
|
111
|
-
nextReactiveVars[key] = toolInput[key];
|
|
112
|
-
}
|
|
113
|
-
} else {
|
|
114
|
-
nextReactiveVars[key] = value.value;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (!equal(nextReactiveVars, reactiveVars)) {
|
|
119
|
-
setReactiveVars(nextReactiveVars);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Clear the tool input after first mount so that remounting the component
|
|
123
|
-
// uses the user-provided variables rather than the hydrated tool input.
|
|
124
|
-
// This runs once on mount; watchQuery also clears it when useQuery is
|
|
125
|
-
// present, so both paths are idempotent.
|
|
126
|
-
useLayoutEffect(() => {
|
|
127
|
-
if (toolMatches) {
|
|
128
|
-
client.clearToolInput();
|
|
129
|
-
}
|
|
130
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
131
|
-
}, []);
|
|
132
|
-
|
|
133
|
-
useLayoutEffect(() => {
|
|
134
|
-
for (const [key, value] of Object.entries(variables)) {
|
|
135
|
-
if (
|
|
136
|
-
variableNames.has(key) &&
|
|
137
|
-
isReactive(value) &&
|
|
138
|
-
!changedKeysRef.current.has(key) &&
|
|
139
|
-
!equal(value.value, initialReactiveValues[key])
|
|
140
|
-
) {
|
|
141
|
-
changedKeysRef.current.add(key);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
const resolvedVariables = useMemo(() => {
|
|
147
|
-
return { ...stateVars, ...reactiveVars } as TVariables;
|
|
148
|
-
}, [stateVars, reactiveVars]);
|
|
149
|
-
|
|
150
|
-
const setVariables = useCallback<
|
|
151
|
-
SetVariables<StateVariables<TVariables, TInputVariables>>
|
|
152
|
-
>((update) => {
|
|
153
|
-
setStateVars((prev) => {
|
|
154
|
-
const updates =
|
|
155
|
-
typeof update === "function" ? update(prev as any) : update;
|
|
156
|
-
|
|
157
|
-
const filtered = Object.fromEntries(
|
|
158
|
-
Object.entries(updates).filter(([key]) => {
|
|
159
|
-
if (key in initialReactiveValues) {
|
|
160
|
-
if (__DEV__) {
|
|
161
|
-
console.warn(
|
|
162
|
-
`Attempted to set reactive variable "${key}" via setVariables. ` +
|
|
163
|
-
`Reactive variables are read-only and are ignored. `
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
return true;
|
|
169
|
-
})
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
if (Object.keys(filtered).length === 0) return prev;
|
|
173
|
-
|
|
174
|
-
return { ...prev, ...filtered };
|
|
175
|
-
});
|
|
176
|
-
}, []);
|
|
177
|
-
|
|
178
|
-
return [resolvedVariables, setVariables];
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return { useHydratedVariables };
|
|
182
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ToolInfo } from "../../../core/typeRegistration.js";
|
|
2
|
-
import { useApolloClient } from "./useApolloClient.js";
|
|
3
|
-
|
|
4
|
-
export function useToolInfo(): ToolInfo | undefined {
|
|
5
|
-
const appManager = useApolloClient()["appManager"];
|
|
6
|
-
const toolName = appManager.toolName;
|
|
7
|
-
|
|
8
|
-
if (!toolName) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return { toolName, toolInput: appManager.toolInput };
|
|
13
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ToolInput } from "../../../core/typeRegistration.js";
|
|
2
|
-
import { useApolloClient } from "./useApolloClient.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated Please use the `useToolInfo` hook. `useToolInput` will be removed
|
|
6
|
-
* in the next major version.
|
|
7
|
-
*/
|
|
8
|
-
export function useToolInput(): ToolInput | undefined {
|
|
9
|
-
return useApolloClient()["appManager"].toolInput;
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ToolName } from "../../../core/typeRegistration.js";
|
|
2
|
-
import { useApolloClient } from "./useApolloClient.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated Please use the `useToolInfo` hook. `useToolName` will be removed
|
|
6
|
-
* in the next major version.
|
|
7
|
-
*/
|
|
8
|
-
export const useToolName = (): ToolName | undefined => {
|
|
9
|
-
return useApolloClient()["appManager"].toolName;
|
|
10
|
-
};
|
package/src/react/index.mcp.ts
DELETED
package/src/react/missingHook.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export function missingHook<HookFn extends (...args: any[]) => any>(
|
|
2
|
-
name: string
|
|
3
|
-
) {
|
|
4
|
-
return (() => {
|
|
5
|
-
throw new Error(
|
|
6
|
-
`Cannot use the '${name}' hook without export conditions. Please set export conditions or import from the \`/openai\` or \`/mcp\` subpath directly.`
|
|
7
|
-
);
|
|
8
|
-
}) as unknown as HookFn;
|
|
9
|
-
}
|
|
File without changes
|
|
File without changes
|