@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.
Files changed (272) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/CONTRIBUTING.md +195 -0
  3. package/README.md +74 -0
  4. package/dist/core/AbstractApolloClient.d.ts +33 -0
  5. package/dist/core/AbstractApolloClient.d.ts.map +1 -0
  6. package/dist/core/AbstractApolloClient.js +129 -0
  7. package/dist/core/AbstractApolloClient.js.map +1 -0
  8. package/dist/core/ApolloClient.d.ts +3 -7
  9. package/dist/core/ApolloClient.d.ts.map +1 -1
  10. package/dist/core/ApolloClient.js +5 -4
  11. package/dist/core/ApolloClient.js.map +1 -1
  12. package/dist/core/McpAppManager.d.ts +42 -0
  13. package/dist/core/McpAppManager.d.ts.map +1 -0
  14. package/dist/core/McpAppManager.js +56 -0
  15. package/dist/core/McpAppManager.js.map +1 -0
  16. package/dist/core/typeRegistration.d.ts +0 -14
  17. package/dist/core/typeRegistration.d.ts.map +1 -1
  18. package/dist/core/typeRegistration.js.map +1 -1
  19. package/dist/core/types.d.ts +2 -1
  20. package/dist/core/types.d.ts.map +1 -1
  21. package/dist/core/types.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/index.mcp.d.ts +0 -1
  26. package/dist/index.mcp.d.ts.map +1 -1
  27. package/dist/index.mcp.js +0 -1
  28. package/dist/index.mcp.js.map +1 -1
  29. package/dist/index.openai.d.ts +0 -1
  30. package/dist/index.openai.d.ts.map +1 -1
  31. package/dist/index.openai.js +0 -1
  32. package/dist/index.openai.js.map +1 -1
  33. package/dist/link/ToolCallLink.d.ts +6 -1
  34. package/dist/link/ToolCallLink.d.ts.map +1 -1
  35. package/dist/link/ToolCallLink.js +17 -4
  36. package/dist/link/ToolCallLink.js.map +1 -1
  37. package/dist/link/ToolHydrationLink.d.ts +21 -0
  38. package/dist/link/ToolHydrationLink.d.ts.map +1 -0
  39. package/dist/link/ToolHydrationLink.js +57 -0
  40. package/dist/link/ToolHydrationLink.js.map +1 -0
  41. package/dist/mcp/core/ApolloClient.d.ts +3 -20
  42. package/dist/mcp/core/ApolloClient.d.ts.map +1 -1
  43. package/dist/mcp/core/ApolloClient.js +20 -98
  44. package/dist/mcp/core/ApolloClient.js.map +1 -1
  45. package/dist/mcp/index.d.ts +0 -1
  46. package/dist/mcp/index.d.ts.map +1 -1
  47. package/dist/mcp/index.js +0 -1
  48. package/dist/mcp/index.js.map +1 -1
  49. package/dist/openai/core/ApolloClient.d.ts +3 -20
  50. package/dist/openai/core/ApolloClient.d.ts.map +1 -1
  51. package/dist/openai/core/ApolloClient.js +36 -98
  52. package/dist/openai/core/ApolloClient.js.map +1 -1
  53. package/dist/openai/index.d.ts +0 -1
  54. package/dist/openai/index.d.ts.map +1 -1
  55. package/dist/openai/index.js +0 -1
  56. package/dist/openai/index.js.map +1 -1
  57. package/dist/openai/react/index.d.ts +0 -7
  58. package/dist/openai/react/index.d.ts.map +1 -1
  59. package/dist/openai/react/index.js +0 -7
  60. package/dist/openai/react/index.js.map +1 -1
  61. package/dist/react/ApolloProvider.d.ts.map +1 -1
  62. package/dist/react/ApolloProvider.js +1 -1
  63. package/dist/react/ApolloProvider.js.map +1 -1
  64. package/dist/{mcp/react/hooks → react}/createHydrationUtils.d.ts +1 -1
  65. package/dist/react/createHydrationUtils.d.ts.map +1 -0
  66. package/dist/{mcp/react/hooks → react}/createHydrationUtils.js +7 -9
  67. package/dist/react/createHydrationUtils.js.map +1 -0
  68. package/dist/react/hooks/internal/useApolloClient.d.ts +3 -0
  69. package/dist/react/hooks/internal/useApolloClient.d.ts.map +1 -0
  70. package/dist/{mcp/react/hooks → react/hooks/internal}/useApolloClient.js +3 -3
  71. package/dist/react/hooks/internal/useApolloClient.js.map +1 -0
  72. package/dist/react/hooks/useApp.d.ts.map +1 -0
  73. package/dist/react/hooks/useApp.js +5 -0
  74. package/dist/react/hooks/useApp.js.map +1 -0
  75. package/dist/react/hooks/useHostContext.d.ts.map +1 -0
  76. package/dist/{openai/react → react}/hooks/useHostContext.js +1 -1
  77. package/dist/react/hooks/useHostContext.js.map +1 -0
  78. package/dist/react/hooks/useToolInfo.d.ts +3 -0
  79. package/dist/react/hooks/useToolInfo.d.ts.map +1 -0
  80. package/dist/react/hooks/useToolInfo.js +5 -0
  81. package/dist/react/hooks/useToolInfo.js.map +1 -0
  82. package/dist/react/hooks/useToolMetadata.d.ts +2 -0
  83. package/dist/react/hooks/useToolMetadata.d.ts.map +1 -0
  84. package/dist/react/hooks/useToolMetadata.js +5 -0
  85. package/dist/react/hooks/useToolMetadata.js.map +1 -0
  86. package/dist/react/index.d.ts +5 -16
  87. package/dist/react/index.d.ts.map +1 -1
  88. package/dist/react/index.js +5 -19
  89. package/dist/react/index.js.map +1 -1
  90. package/dist/types/application-manifest.d.ts +1 -0
  91. package/dist/types/application-manifest.d.ts.map +1 -1
  92. package/dist/types/application-manifest.js.map +1 -1
  93. package/dist/utilities/connectToHost.d.ts +3 -0
  94. package/dist/utilities/connectToHost.d.ts.map +1 -0
  95. package/dist/utilities/connectToHost.js +11 -0
  96. package/dist/utilities/connectToHost.js.map +1 -0
  97. package/dist/utilities/index.d.ts +1 -0
  98. package/dist/utilities/index.d.ts.map +1 -1
  99. package/dist/utilities/index.js +1 -0
  100. package/dist/utilities/index.js.map +1 -1
  101. package/dist/vite/apolloClientAiApps.d.ts.map +1 -1
  102. package/dist/vite/apolloClientAiApps.js +2 -0
  103. package/dist/vite/apolloClientAiApps.js.map +1 -1
  104. package/package.json +5 -22
  105. package/src/core/AbstractApolloClient.ts +217 -0
  106. package/src/core/ApolloClient.ts +8 -10
  107. package/src/core/McpAppManager.ts +106 -0
  108. package/src/core/typeRegistration.ts +0 -15
  109. package/src/core/types.ts +2 -1
  110. package/src/index.mcp.ts +0 -1
  111. package/src/index.openai.ts +0 -1
  112. package/src/index.ts +1 -6
  113. package/src/link/ToolCallLink.ts +27 -5
  114. package/src/link/ToolHydrationLink.ts +90 -0
  115. package/src/link/__tests__/ToolCallLink.test.ts +99 -0
  116. package/src/mcp/core/ApolloClient.ts +32 -165
  117. package/src/mcp/core/__tests__/ApolloClient.test.ts +571 -71
  118. package/src/mcp/index.ts +0 -1
  119. package/src/openai/core/ApolloClient.ts +48 -161
  120. package/src/openai/core/__tests__/ApolloClient.test.ts +916 -118
  121. package/src/openai/index.ts +0 -1
  122. package/src/openai/react/index.ts +0 -7
  123. package/src/react/ApolloProvider.tsx +1 -6
  124. package/src/react/__tests__/ApolloProvider/mcp.test.tsx +66 -29
  125. package/src/react/__tests__/ApolloProvider/openai.test.tsx +16 -41
  126. package/src/react/__tests__/createHydrationUtils.test.tsx +1260 -0
  127. package/src/{mcp/react/hooks → react}/createHydrationUtils.ts +7 -10
  128. package/src/react/hooks/__tests__/useApp.test.tsx +46 -0
  129. package/src/react/hooks/__tests__/useHostContext.test.tsx +99 -0
  130. package/src/react/hooks/__tests__/useToolInfo.test.tsx +98 -0
  131. package/src/react/hooks/__tests__/useToolMetadata.test.tsx +58 -0
  132. package/src/{mcp/react/hooks → react/hooks/internal}/useApolloClient.ts +3 -3
  133. package/src/{mcp/react → react}/hooks/useApp.ts +1 -1
  134. package/src/{openai/react → react}/hooks/useHostContext.ts +1 -1
  135. package/src/react/hooks/useToolInfo.ts +6 -0
  136. package/src/react/hooks/useToolMetadata.ts +5 -0
  137. package/src/react/index.ts +5 -36
  138. package/src/testing/internal/graphql/parseManifestOperation.ts +87 -0
  139. package/src/testing/internal/index.ts +3 -0
  140. package/src/testing/internal/matchers/index.ts +1 -0
  141. package/src/testing/internal/matchers/toEmitAnything.ts +43 -0
  142. package/src/testing/internal/matchers/types.ts +1 -0
  143. package/src/testing/internal/mcp/mockMcpHost.ts +25 -4
  144. package/src/testing/internal/tests/eachHostEnv.ts +22 -0
  145. package/src/testing/internal/utilities/createHostEnv.ts +117 -0
  146. package/src/types/application-manifest.ts +1 -0
  147. package/src/utilities/connectToHost.ts +13 -0
  148. package/src/utilities/index.ts +1 -0
  149. package/src/vite/__tests__/apolloClientAiApps.test.ts +56 -0
  150. package/src/vite/apolloClientAiApps.ts +5 -0
  151. package/tsconfig.vite.json +1 -1
  152. package/vitest.config.ts +13 -0
  153. package/dist/mcp/core/McpAppManager.d.ts +0 -30
  154. package/dist/mcp/core/McpAppManager.d.ts.map +0 -1
  155. package/dist/mcp/core/McpAppManager.js +0 -82
  156. package/dist/mcp/core/McpAppManager.js.map +0 -1
  157. package/dist/mcp/link/ToolCallLink.d.ts +0 -28
  158. package/dist/mcp/link/ToolCallLink.d.ts.map +0 -1
  159. package/dist/mcp/link/ToolCallLink.js +0 -35
  160. package/dist/mcp/link/ToolCallLink.js.map +0 -1
  161. package/dist/mcp/react/hooks/createHydrationUtils.d.ts.map +0 -1
  162. package/dist/mcp/react/hooks/createHydrationUtils.js.map +0 -1
  163. package/dist/mcp/react/hooks/useApolloClient.d.ts +0 -3
  164. package/dist/mcp/react/hooks/useApolloClient.d.ts.map +0 -1
  165. package/dist/mcp/react/hooks/useApolloClient.js.map +0 -1
  166. package/dist/mcp/react/hooks/useApp.d.ts.map +0 -1
  167. package/dist/mcp/react/hooks/useApp.js +0 -5
  168. package/dist/mcp/react/hooks/useApp.js.map +0 -1
  169. package/dist/mcp/react/hooks/useHostContext.d.ts.map +0 -1
  170. package/dist/mcp/react/hooks/useHostContext.js +0 -7
  171. package/dist/mcp/react/hooks/useHostContext.js.map +0 -1
  172. package/dist/mcp/react/hooks/useToolInfo.d.ts +0 -3
  173. package/dist/mcp/react/hooks/useToolInfo.d.ts.map +0 -1
  174. package/dist/mcp/react/hooks/useToolInfo.js +0 -10
  175. package/dist/mcp/react/hooks/useToolInfo.js.map +0 -1
  176. package/dist/mcp/react/hooks/useToolInput.d.ts +0 -7
  177. package/dist/mcp/react/hooks/useToolInput.d.ts.map +0 -1
  178. package/dist/mcp/react/hooks/useToolInput.js +0 -9
  179. package/dist/mcp/react/hooks/useToolInput.js.map +0 -1
  180. package/dist/mcp/react/hooks/useToolMetadata.d.ts +0 -2
  181. package/dist/mcp/react/hooks/useToolMetadata.d.ts.map +0 -1
  182. package/dist/mcp/react/hooks/useToolMetadata.js +0 -5
  183. package/dist/mcp/react/hooks/useToolMetadata.js.map +0 -1
  184. package/dist/mcp/react/hooks/useToolName.d.ts +0 -7
  185. package/dist/mcp/react/hooks/useToolName.d.ts.map +0 -1
  186. package/dist/mcp/react/hooks/useToolName.js +0 -9
  187. package/dist/mcp/react/hooks/useToolName.js.map +0 -1
  188. package/dist/mcp/react/index.d.ts +0 -8
  189. package/dist/mcp/react/index.d.ts.map +0 -1
  190. package/dist/mcp/react/index.js +0 -8
  191. package/dist/mcp/react/index.js.map +0 -1
  192. package/dist/openai/core/McpAppManager.d.ts +0 -29
  193. package/dist/openai/core/McpAppManager.d.ts.map +0 -1
  194. package/dist/openai/core/McpAppManager.js +0 -91
  195. package/dist/openai/core/McpAppManager.js.map +0 -1
  196. package/dist/openai/link/ToolCallLink.d.ts +0 -28
  197. package/dist/openai/link/ToolCallLink.d.ts.map +0 -1
  198. package/dist/openai/link/ToolCallLink.js +0 -35
  199. package/dist/openai/link/ToolCallLink.js.map +0 -1
  200. package/dist/openai/react/hooks/createHydrationUtils.d.ts +0 -15
  201. package/dist/openai/react/hooks/createHydrationUtils.d.ts.map +0 -1
  202. package/dist/openai/react/hooks/createHydrationUtils.js +0 -113
  203. package/dist/openai/react/hooks/createHydrationUtils.js.map +0 -1
  204. package/dist/openai/react/hooks/useApp.d.ts +0 -2
  205. package/dist/openai/react/hooks/useApp.d.ts.map +0 -1
  206. package/dist/openai/react/hooks/useApp.js +0 -5
  207. package/dist/openai/react/hooks/useApp.js.map +0 -1
  208. package/dist/openai/react/hooks/useHostContext.d.ts +0 -2
  209. package/dist/openai/react/hooks/useHostContext.d.ts.map +0 -1
  210. package/dist/openai/react/hooks/useHostContext.js.map +0 -1
  211. package/dist/openai/react/hooks/useToolInfo.d.ts +0 -3
  212. package/dist/openai/react/hooks/useToolInfo.d.ts.map +0 -1
  213. package/dist/openai/react/hooks/useToolInfo.js +0 -10
  214. package/dist/openai/react/hooks/useToolInfo.js.map +0 -1
  215. package/dist/openai/react/hooks/useToolInput.d.ts +0 -7
  216. package/dist/openai/react/hooks/useToolInput.d.ts.map +0 -1
  217. package/dist/openai/react/hooks/useToolInput.js +0 -9
  218. package/dist/openai/react/hooks/useToolInput.js.map +0 -1
  219. package/dist/openai/react/hooks/useToolMetadata.d.ts +0 -2
  220. package/dist/openai/react/hooks/useToolMetadata.d.ts.map +0 -1
  221. package/dist/openai/react/hooks/useToolMetadata.js +0 -5
  222. package/dist/openai/react/hooks/useToolMetadata.js.map +0 -1
  223. package/dist/openai/react/hooks/useToolName.d.ts +0 -7
  224. package/dist/openai/react/hooks/useToolName.d.ts.map +0 -1
  225. package/dist/openai/react/hooks/useToolName.js +0 -9
  226. package/dist/openai/react/hooks/useToolName.js.map +0 -1
  227. package/dist/react/index.mcp.d.ts +0 -3
  228. package/dist/react/index.mcp.d.ts.map +0 -1
  229. package/dist/react/index.mcp.js +0 -3
  230. package/dist/react/index.mcp.js.map +0 -1
  231. package/dist/react/index.openai.d.ts +0 -3
  232. package/dist/react/index.openai.d.ts.map +0 -1
  233. package/dist/react/index.openai.js +0 -3
  234. package/dist/react/index.openai.js.map +0 -1
  235. package/dist/react/missingHook.d.ts +0 -2
  236. package/dist/react/missingHook.d.ts.map +0 -1
  237. package/dist/react/missingHook.js +0 -6
  238. package/dist/react/missingHook.js.map +0 -1
  239. package/src/mcp/core/McpAppManager.ts +0 -129
  240. package/src/mcp/link/ToolCallLink.ts +0 -40
  241. package/src/mcp/link/__tests__/ToolCallLink.test.ts +0 -62
  242. package/src/mcp/react/hooks/__tests__/createHydrationUtils.test.tsx +0 -1228
  243. package/src/mcp/react/hooks/__tests__/useApp.test.tsx +0 -46
  244. package/src/mcp/react/hooks/__tests__/useHostContext.test.tsx +0 -95
  245. package/src/mcp/react/hooks/__tests__/useToolInfo.test.tsx +0 -53
  246. package/src/mcp/react/hooks/__tests__/useToolInput.test.tsx +0 -50
  247. package/src/mcp/react/hooks/__tests__/useToolMetadata.test.tsx +0 -53
  248. package/src/mcp/react/hooks/__tests__/useToolName.test.tsx +0 -50
  249. package/src/mcp/react/hooks/useHostContext.ts +0 -14
  250. package/src/mcp/react/hooks/useToolInfo.ts +0 -13
  251. package/src/mcp/react/hooks/useToolInput.ts +0 -10
  252. package/src/mcp/react/hooks/useToolMetadata.ts +0 -5
  253. package/src/mcp/react/hooks/useToolName.ts +0 -10
  254. package/src/mcp/react/index.ts +0 -7
  255. package/src/openai/core/McpAppManager.ts +0 -139
  256. package/src/openai/link/ToolCallLink.ts +0 -40
  257. package/src/openai/react/hooks/__tests__/createHydrationUtils.test.tsx +0 -1333
  258. package/src/openai/react/hooks/__tests__/useToolInfo.test.tsx +0 -92
  259. package/src/openai/react/hooks/__tests__/useToolInput.test.tsx +0 -85
  260. package/src/openai/react/hooks/__tests__/useToolMetadata.test.tsx +0 -86
  261. package/src/openai/react/hooks/__tests__/useToolName.test.tsx +0 -50
  262. package/src/openai/react/hooks/createHydrationUtils.ts +0 -182
  263. package/src/openai/react/hooks/useApp.ts +0 -5
  264. package/src/openai/react/hooks/useToolInfo.ts +0 -13
  265. package/src/openai/react/hooks/useToolInput.ts +0 -10
  266. package/src/openai/react/hooks/useToolMetadata.ts +0 -5
  267. package/src/openai/react/hooks/useToolName.ts +0 -10
  268. package/src/react/index.mcp.ts +0 -10
  269. package/src/react/index.openai.ts +0 -10
  270. package/src/react/missingHook.ts +0 -9
  271. /package/dist/{mcp/react → react}/hooks/useApp.d.ts +0 -0
  272. /package/dist/{mcp/react → react}/hooks/useHostContext.d.ts +0 -0
@@ -1,2 +1 @@
1
1
  export { ApolloClient } from "./core/ApolloClient.js";
2
- export { ToolCallLink } from "./link/ToolCallLink.js";
@@ -1,8 +1 @@
1
- export { useApp } from "./hooks/useApp.js";
2
- export { useHostContext } from "./hooks/useHostContext.js";
3
- export { useToolName } from "./hooks/useToolName.js";
4
- export { useToolMetadata } from "./hooks/useToolMetadata.js";
5
- export { useToolInput } from "./hooks/useToolInput.js";
6
- export { useToolInfo } from "./hooks/useToolInfo.js";
7
- export { createHydrationUtils } from "./hooks/createHydrationUtils.js";
8
1
  export { useWidgetState } from "./hooks/useWidgetState.js";
@@ -1,7 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  import { use } from "react";
3
3
  import { ApolloProvider as BaseApolloProvider } from "@apollo/client/react";
4
- import type { ApolloClient as BaseApolloClient } from "@apollo/client";
5
4
  import { ApolloClient as OpenAiApolloClient } from "../openai/core/ApolloClient.js";
6
5
  import { ApolloClient as McpApolloClient } from "../mcp/core/ApolloClient.js";
7
6
  import type { ApolloClient as FallbackApolloClient } from "../core/ApolloClient.js";
@@ -27,9 +26,5 @@ export function ApolloProvider({ children, client }: ApolloProvider.Props) {
27
26
 
28
27
  use(client.connect());
29
28
 
30
- return (
31
- <BaseApolloProvider client={client as BaseApolloClient}>
32
- {children}
33
- </BaseApolloProvider>
34
- );
29
+ return <BaseApolloProvider client={client}>{children}</BaseApolloProvider>;
35
30
  }
@@ -4,48 +4,80 @@ import { ApolloProvider } from "../../ApolloProvider.js";
4
4
  import { waitFor } from "@testing-library/react";
5
5
  import { ApolloClient } from "../../../mcp/core/ApolloClient.js";
6
6
  import { gql, InMemoryCache } from "@apollo/client";
7
- import { print } from "@apollo/client/utilities";
8
7
  import {
9
8
  minimalHostContextWithToolName,
10
9
  mockApplicationManifest,
11
10
  mockMcpHost,
11
+ parseManifestOperation,
12
12
  renderAsync,
13
13
  spyOnConsole,
14
14
  } from "../../../testing/internal/index.js";
15
15
 
16
- test("writes to the cache as soon as toolOutput is available", async () => {
16
+ test("writes prefetch data to the cache when immediately available", async () => {
17
+ using _ = spyOnConsole("debug");
18
+
19
+ const query = gql`
20
+ query GreetingQuery @tool(description: "Fetches a greeting") @prefetch {
21
+ greeting
22
+ }
23
+ `;
24
+
25
+ const client = new ApolloClient({
26
+ cache: new InMemoryCache(),
27
+ manifest: mockApplicationManifest({
28
+ operations: [parseManifestOperation(query)],
29
+ }),
30
+ });
31
+
32
+ using host = await mockMcpHost({
33
+ hostContext: minimalHostContextWithToolName("OtherTool"),
34
+ });
35
+ host.onCleanup(() => client.stop());
36
+
37
+ host.sendToolInput({ arguments: {} });
38
+ host.sendToolResult({
39
+ structuredContent: {
40
+ result: {
41
+ data: null,
42
+ },
43
+ prefetch: {
44
+ __anonymous: { data: { greeting: "hello" } },
45
+ },
46
+ },
47
+ });
48
+
49
+ await renderAsync(<ApolloProvider client={client} />, {
50
+ wrapper: ({ children }) => <Suspense>{children}</Suspense>,
51
+ });
52
+
53
+ await waitFor(() => {
54
+ expect(client.extract()).toStrictEqual({
55
+ ROOT_QUERY: {
56
+ __typename: "Query",
57
+ greeting: "hello",
58
+ },
59
+ });
60
+ });
61
+ });
62
+
63
+ test("hydrates the tool result and writes to the cache when query first executes", async () => {
17
64
  using _ = spyOnConsole("debug");
18
65
 
19
- const toolName = "GreetingQuery";
20
66
  using host = await mockMcpHost({
21
- hostContext: minimalHostContextWithToolName(toolName),
67
+ hostContext: minimalHostContextWithToolName("GreetingQuery"),
22
68
  });
23
69
  host.onCleanup(() => client.stop());
24
70
 
25
71
  const query = gql`
26
- query GreetingQuery {
72
+ query GreetingQuery @tool(description: "Fetches a greeting") {
27
73
  greeting
28
74
  }
29
75
  `;
30
- const data = {
31
- greeting: "hello",
32
- };
33
76
 
34
77
  const client = new ApolloClient({
35
78
  cache: new InMemoryCache(),
36
79
  manifest: mockApplicationManifest({
37
- operations: [
38
- {
39
- id: "1",
40
- name: "GreetingQuery",
41
- body: print(query),
42
- prefetch: true,
43
- prefetchID: "__anonymous",
44
- type: "query",
45
- variables: {},
46
- tools: [{ name: toolName, description: "Fetches a greeting" }],
47
- },
48
- ],
80
+ operations: [parseManifestOperation(query)],
49
81
  }),
50
82
  });
51
83
 
@@ -59,16 +91,21 @@ test("writes to the cache as soon as toolOutput is available", async () => {
59
91
 
60
92
  host.sendToolInput({ arguments: {} });
61
93
  host.sendToolResult({
62
- content: [{ type: "text", text: JSON.stringify({ result: { data } }) }],
63
- structuredContent: { result: { data } },
94
+ structuredContent: { result: { data: { greeting: "hello" } } },
64
95
  });
65
96
 
66
- await waitFor(() => {
67
- expect(client.extract()).toEqual({
68
- ROOT_QUERY: {
69
- __typename: "Query",
70
- greeting: "hello",
71
- },
72
- });
97
+ await expect(
98
+ waitFor(() => expect(client.extract()).not.toEqual({}))
99
+ ).rejects.toThrow();
100
+
101
+ await expect(client.query({ query })).resolves.toStrictEqual({
102
+ data: { greeting: "hello" },
103
+ });
104
+
105
+ expect(client.extract()).toStrictEqual({
106
+ ROOT_QUERY: {
107
+ __typename: "Query",
108
+ greeting: "hello",
109
+ },
73
110
  });
74
111
  });
@@ -4,22 +4,22 @@ import { ApolloProvider } from "../../ApolloProvider.js";
4
4
  import { waitFor } from "@testing-library/react";
5
5
  import { ApolloClient } from "../../../openai/core/ApolloClient.js";
6
6
  import { gql, InMemoryCache } from "@apollo/client";
7
- import { print } from "@apollo/client/utilities";
8
7
  import {
9
8
  minimalHostContextWithToolName,
10
9
  mockApplicationManifest,
11
10
  mockMcpHost,
11
+ parseManifestOperation,
12
12
  renderAsync,
13
13
  spyOnConsole,
14
14
  stubOpenAiGlobals,
15
15
  } from "../../../testing/internal/index.js";
16
16
 
17
- test("writes data to the cache when immediately available", async () => {
17
+ test("writes prefetch data to the cache when immediately available", async () => {
18
18
  stubOpenAiGlobals();
19
19
  using _ = spyOnConsole("debug");
20
20
 
21
21
  const query = gql`
22
- query GreetingQuery {
22
+ query GreetingQuery @tool(description: "Fetches a greeting") @prefetch {
23
23
  greeting
24
24
  }
25
25
  `;
@@ -31,18 +31,7 @@ test("writes data to the cache when immediately available", async () => {
31
31
  const client = new ApolloClient({
32
32
  cache: new InMemoryCache(),
33
33
  manifest: mockApplicationManifest({
34
- operations: [
35
- {
36
- id: "1",
37
- name: "GreetingQuery",
38
- body: print(query),
39
- prefetch: true,
40
- prefetchID: "__anonymous",
41
- type: "query",
42
- variables: {},
43
- tools: [],
44
- },
45
- ],
34
+ operations: [parseManifestOperation(query)],
46
35
  }),
47
36
  });
48
37
 
@@ -53,7 +42,6 @@ test("writes data to the cache when immediately available", async () => {
53
42
 
54
43
  host.sendToolInput({ arguments: {} });
55
44
  host.sendToolResult({
56
- content: [],
57
45
  structuredContent: {
58
46
  result: {
59
47
  data: null,
@@ -78,36 +66,20 @@ test("writes data to the cache when immediately available", async () => {
78
66
  });
79
67
  });
80
68
 
81
- test("writes to the cache as soon as toolOutput is available", async () => {
69
+ test("hydrates the tool result and writes to the cache when query first executes", async () => {
82
70
  stubOpenAiGlobals();
83
71
  using _ = spyOnConsole("debug");
84
72
 
85
- stubOpenAiGlobals();
86
-
87
73
  const query = gql`
88
- query GreetingQuery {
74
+ query GreetingQuery @tool(description: "Fetches a greeting") {
89
75
  greeting
90
76
  }
91
77
  `;
92
- const data = {
93
- greeting: "hello",
94
- };
95
78
 
96
79
  const client = new ApolloClient({
97
80
  cache: new InMemoryCache(),
98
81
  manifest: mockApplicationManifest({
99
- operations: [
100
- {
101
- id: "1",
102
- name: "GreetingQuery",
103
- body: print(query),
104
- prefetch: true,
105
- prefetchID: "__anonymous",
106
- type: "query",
107
- variables: {},
108
- tools: [],
109
- },
110
- ],
82
+ operations: [parseManifestOperation(query)],
111
83
  }),
112
84
  });
113
85
 
@@ -127,12 +99,15 @@ test("writes to the cache as soon as toolOutput is available", async () => {
127
99
  ).rejects.toThrow();
128
100
 
129
101
  host.sendToolResult({
130
- content: [],
131
- structuredContent: {
132
- prefetch: {
133
- __anonymous: { data },
134
- },
135
- },
102
+ structuredContent: { result: { data: { greeting: "hello" } } },
103
+ });
104
+
105
+ await expect(
106
+ waitFor(() => expect(client.extract()).not.toEqual({}))
107
+ ).rejects.toThrow();
108
+
109
+ await expect(client.query({ query })).resolves.toStrictEqual({
110
+ data: { greeting: "hello" },
136
111
  });
137
112
 
138
113
  await waitFor(() => {