@apollo/client-ai-apps 0.5.0 → 0.5.2
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 +22 -0
- package/dist/config/defineConfig.d.ts +5 -3
- package/dist/config/defineConfig.d.ts.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/core/types.d.ts +6 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/mcp/core/McpAppManager.d.ts +2 -7
- package/dist/mcp/core/McpAppManager.d.ts.map +1 -1
- package/dist/mcp/core/McpAppManager.js +10 -1
- package/dist/mcp/core/McpAppManager.js.map +1 -1
- package/dist/mcp/react/hooks/useToolMetadata.d.ts +1 -7
- package/dist/mcp/react/hooks/useToolMetadata.d.ts.map +1 -1
- package/dist/openai/core/McpAppManager.d.ts.map +1 -1
- package/dist/openai/core/McpAppManager.js +13 -15
- package/dist/openai/core/McpAppManager.js.map +1 -1
- package/dist/vite/apolloClientAiApps.js.map +1 -1
- package/package.json +1 -1
- package/src/config/types.ts +1 -1
- package/src/core/types.ts +7 -0
- package/src/mcp/core/McpAppManager.ts +11 -2
- package/src/mcp/link/__tests__/ToolCallLink.test.ts +12 -3
- package/src/openai/core/McpAppManager.ts +14 -17
- package/src/openai/core/__tests__/ApolloClient.test.ts +4 -4
- package/src/openai/react/hooks/__tests__/useToolInput.test.tsx +1 -1
- package/src/vite/apolloClientAiApps.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
## 0.5.2 (2026-02-23)
|
|
2
|
+
|
|
3
|
+
### Fixes
|
|
4
|
+
|
|
5
|
+
#### Add fallback when `toolName` is not available from host context
|
|
6
|
+
|
|
7
|
+
Provides a fallback in MCP apps to get the executed tool name from `_meta.toolName` when the host does not provide `toolInfo` from host context, or `structuredContent.toolName` when the host does not forward `_meta` to the connected application.
|
|
8
|
+
|
|
9
|
+
#### Always use `window.openai.toolInput` to initialize the tool input value
|
|
10
|
+
|
|
11
|
+
ChatGPT doesn't always send the `ui/notifications/tool-input` notification before we get `ui/notifications/tool-result`. Other times it sends the notification more than once. Because of the inconsistency, we can't always accurately get the correct tool input value using the notification by the time we get the `ui/notifications/tool-result` notification. This results in the wrong value for `variables` and incorrectly writes the query data to the cache.
|
|
12
|
+
|
|
13
|
+
This fix falls back to get `toolInput` from `window.openai.toolInput` in ChatGPT apps after we receive the `ui/notification/tool-result` notification to ensure we have the correct tool input value.
|
|
14
|
+
|
|
15
|
+
## 0.5.1 (2026-02-19)
|
|
16
|
+
|
|
17
|
+
### Fixes
|
|
18
|
+
|
|
19
|
+
#### Fixes the type of `ApolloClientAiAppsConfig.Config`
|
|
20
|
+
|
|
21
|
+
The `ApolloClientAiAppsConfig.Config` is mistakenly set as the output type instead of the input type. This primarily affected the `labels` config which expected a different input shape than the output shape.
|
|
22
|
+
|
|
1
23
|
## 0.5.0 (2026-02-19)
|
|
2
24
|
|
|
3
25
|
### Breaking Changes
|
|
@@ -6,7 +6,7 @@ export declare function defineConfig(config: ApolloClientAiAppsConfig.Config): {
|
|
|
6
6
|
name?: string;
|
|
7
7
|
description?: string;
|
|
8
8
|
version?: string;
|
|
9
|
-
entry?: Partial<Record<
|
|
9
|
+
entry?: Partial<Record<string, string | Partial<Record<"mcp" | "openai", string>>>>;
|
|
10
10
|
csp?: {
|
|
11
11
|
connectDomains?: string[];
|
|
12
12
|
frameDomains?: string[];
|
|
@@ -19,8 +19,10 @@ export declare function defineConfig(config: ApolloClientAiAppsConfig.Config): {
|
|
|
19
19
|
domain?: string;
|
|
20
20
|
};
|
|
21
21
|
labels?: {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
toolInvocation?: {
|
|
23
|
+
invoking?: string;
|
|
24
|
+
invoked?: string;
|
|
25
|
+
};
|
|
24
26
|
};
|
|
25
27
|
};
|
|
26
28
|
//# sourceMappingURL=defineConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineConfig.d.ts","sourceRoot":"","sources":["../../src/config/defineConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,wBAAwB,CAAC,MAAM
|
|
1
|
+
{"version":3,"file":"defineConfig.d.ts","sourceRoot":"","sources":["../../src/config/defineConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,wBAAwB,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;EAEnE"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import { z } from "zod";
|
|
|
2
2
|
import type { ApolloClientAiAppsConfigSchema, AppTarget } from "./schema.js";
|
|
3
3
|
export declare namespace ApolloClientAiAppsConfig {
|
|
4
4
|
type AppTarget = z.infer<typeof AppTarget>;
|
|
5
|
-
type Config = z.
|
|
5
|
+
type Config = z.input<typeof ApolloClientAiAppsConfigSchema>;
|
|
6
6
|
}
|
|
7
7
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/config/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { ApolloClientAiAppsConfigSchema, AppTarget } from \"./schema.js\";\n\nexport declare namespace ApolloClientAiAppsConfig {\n export type AppTarget = z.infer<typeof AppTarget>;\n export type Config = z.
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { ApolloClientAiAppsConfigSchema, AppTarget } from \"./schema.js\";\n\nexport declare namespace ApolloClientAiAppsConfig {\n export type AppTarget = z.infer<typeof AppTarget>;\n export type Config = z.input<typeof ApolloClientAiAppsConfigSchema>;\n}\n"]}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { CallToolResult as McpCallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import type { FormattedExecutionResult } from "graphql";
|
|
3
3
|
export declare namespace ApolloMcpServerApps {
|
|
4
|
+
interface Meta {
|
|
5
|
+
toolName: string;
|
|
6
|
+
[x: string]: unknown;
|
|
7
|
+
}
|
|
4
8
|
interface StructuredContent {
|
|
5
9
|
result: FormattedExecutionResult;
|
|
6
10
|
prefetch?: Record<string, FormattedExecutionResult>;
|
|
11
|
+
toolName?: string;
|
|
7
12
|
[x: string]: unknown;
|
|
8
13
|
}
|
|
9
14
|
interface CallToolResult extends McpCallToolResult {
|
|
15
|
+
_meta?: ApolloMcpServerApps.Meta;
|
|
10
16
|
structuredContent: ApolloMcpServerApps.StructuredContent;
|
|
11
17
|
}
|
|
12
18
|
}
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAExD,yBAAiB,mBAAmB,CAAC;IACnC,UAAiB,iBAAiB;QAChC,MAAM,EAAE,wBAAwB,CAAC;QACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;QACpD,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB;IAED,UAAiB,cAAe,SAAQ,iBAAiB;QACvD,iBAAiB,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;KAC1D;CACF"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAExD,yBAAiB,mBAAmB,CAAC;IACnC,UAAiB,IAAI;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB;IAED,UAAiB,iBAAiB;QAChC,MAAM,EAAE,wBAAwB,CAAC;QACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;QACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB;IAED,UAAiB,cAAe,SAAQ,iBAAiB;QACvD,KAAK,CAAC,EAAE,mBAAmB,CAAC,IAAI,CAAC;QACjC,iBAAiB,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;KAC1D;CACF"}
|
package/dist/core/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CallToolResult as McpCallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { FormattedExecutionResult } from \"graphql\";\n\nexport namespace ApolloMcpServerApps {\n export interface StructuredContent {\n result: FormattedExecutionResult;\n prefetch?: Record<string, FormattedExecutionResult>;\n [x: string]: unknown;\n }\n\n export interface CallToolResult extends McpCallToolResult {\n structuredContent: ApolloMcpServerApps.StructuredContent;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CallToolResult as McpCallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { FormattedExecutionResult } from \"graphql\";\n\nexport namespace ApolloMcpServerApps {\n export interface Meta {\n toolName: string;\n [x: string]: unknown;\n }\n\n export interface StructuredContent {\n result: FormattedExecutionResult;\n prefetch?: Record<string, FormattedExecutionResult>;\n toolName?: string;\n [x: string]: unknown;\n }\n\n export interface CallToolResult extends McpCallToolResult {\n _meta?: ApolloMcpServerApps.Meta;\n structuredContent: ApolloMcpServerApps.StructuredContent;\n }\n}\n"]}
|
|
@@ -2,19 +2,14 @@ import { App } from "@modelcontextprotocol/ext-apps";
|
|
|
2
2
|
import type { ApplicationManifest } from "../../types/application-manifest";
|
|
3
3
|
import type { FormattedExecutionResult } from "graphql";
|
|
4
4
|
import type { DocumentNode, OperationVariables } from "@apollo/client";
|
|
5
|
+
import type { ApolloMcpServerApps } from "../../core/types";
|
|
5
6
|
/** @internal */
|
|
6
7
|
export declare class McpAppManager {
|
|
7
8
|
#private;
|
|
8
9
|
readonly app: App;
|
|
9
10
|
constructor(manifest: ApplicationManifest);
|
|
10
11
|
get toolName(): string | undefined;
|
|
11
|
-
get toolMetadata():
|
|
12
|
-
[x: string]: unknown;
|
|
13
|
-
progressToken?: string | number | undefined;
|
|
14
|
-
"io.modelcontextprotocol/related-task"?: {
|
|
15
|
-
taskId: string;
|
|
16
|
-
} | undefined;
|
|
17
|
-
} | undefined;
|
|
12
|
+
get toolMetadata(): ApolloMcpServerApps.Meta | undefined;
|
|
18
13
|
get toolInput(): Record<string, unknown> | undefined;
|
|
19
14
|
waitForInitialization: (() => Promise<{
|
|
20
15
|
toolName: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppManager.d.ts","sourceRoot":"","sources":["../../../src/mcp/core/McpAppManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAwB,MAAM,gCAAgC,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"McpAppManager.d.ts","sourceRoot":"","sources":["../../../src/mcp/core/McpAppManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAwB,MAAM,gCAAgC,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAM5D,gBAAgB;AAChB,qBAAa,aAAa;;IACxB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;gBAMN,QAAQ,EAAE,mBAAmB;IAIzC,IAAI,QAAQ,uBAEX;IAED,IAAI,YAAY,yCAEf;IAED,IAAI,SAAS,wCAEZ;IAED,qBAAqB;;;;;;;MAqClB;IAEH,KAAK;IAIC,YAAY,CAAC,EACjB,KAAK,EACL,SAAS,GACV,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,SAAS,EAAE,kBAAkB,GAAG,SAAS,CAAC;KAC3C;YASa,OAAO;CAWtB"}
|
|
@@ -31,7 +31,16 @@ export class McpAppManager {
|
|
|
31
31
|
await this.connect();
|
|
32
32
|
const { structuredContent, _meta } = await toolResult.promise;
|
|
33
33
|
const { arguments: args } = await toolInput.promise;
|
|
34
|
-
|
|
34
|
+
// Some hosts do not provide toolInfo in the ui/initialize response, so we
|
|
35
|
+
// fallback to `_meta.toolName` provided by Apollo MCP server if the value
|
|
36
|
+
// is not available.
|
|
37
|
+
this.#toolName =
|
|
38
|
+
this.app.getHostContext()?.toolInfo?.tool.name ??
|
|
39
|
+
_meta?.toolName ??
|
|
40
|
+
// Some hosts do not forward `_meta` nor do they provide `toolInfo`. Our
|
|
41
|
+
// MCP server provides `toolName` in `structuredContent` as a workaround
|
|
42
|
+
// that we can use if all else fails
|
|
43
|
+
structuredContent.toolName;
|
|
35
44
|
this.#toolMetadata = _meta;
|
|
36
45
|
this.#toolInput = args;
|
|
37
46
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppManager.js","sourceRoot":"","sources":["../../../src/mcp/core/McpAppManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAK3E,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAOnE,gBAAgB;AAChB,MAAM,OAAO,aAAa;IACf,GAAG,CAAM;IAElB,SAAS,CAAqB;IAC9B,aAAa,
|
|
1
|
+
{"version":3,"file":"McpAppManager.js","sourceRoot":"","sources":["../../../src/mcp/core/McpAppManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { App, PostMessageTransport } from \"@modelcontextprotocol/ext-apps\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ApplicationManifest } from \"../../types/application-manifest\";\nimport type { FormattedExecutionResult } from \"graphql\";\nimport type { DocumentNode, OperationVariables } from \"@apollo/client\";\nimport { print } from \"@apollo/client/utilities\";\nimport { cacheAsync, promiseWithResolvers } from \"../../utilities\";\nimport type { ApolloMcpServerApps } from \"../../core/types\";\n\ntype ExecuteQueryCallToolResult = Omit<CallToolResult, \"structuredContent\"> & {\n structuredContent: FormattedExecutionResult;\n};\n\n/** @internal */\nexport class McpAppManager {\n readonly app: App;\n\n #toolName: string | undefined;\n #toolMetadata: ApolloMcpServerApps.CallToolResult[\"_meta\"] | undefined;\n #toolInput: Record<string, unknown> | undefined;\n\n constructor(manifest: ApplicationManifest) {\n this.app = new App({ name: manifest.name, version: manifest.appVersion });\n }\n\n get toolName() {\n return this.#toolName;\n }\n\n get toolMetadata() {\n return this.#toolMetadata;\n }\n\n get toolInput() {\n return this.#toolInput;\n }\n\n waitForInitialization = cacheAsync(async () => {\n let toolResult = promiseWithResolvers<ApolloMcpServerApps.CallToolResult>();\n let toolInput = promiseWithResolvers<Parameters<App[\"ontoolinput\"]>[0]>();\n\n this.app.ontoolresult = (params) => {\n toolResult.resolve(\n params as unknown as ApolloMcpServerApps.CallToolResult\n );\n };\n\n this.app.ontoolinput = (params) => {\n toolInput.resolve(params);\n };\n\n await this.connect();\n\n const { structuredContent, _meta } = await toolResult.promise;\n const { arguments: args } = await toolInput.promise;\n\n // Some hosts do not provide toolInfo in the ui/initialize response, so we\n // fallback to `_meta.toolName` provided by Apollo MCP server if the value\n // is not available.\n this.#toolName =\n this.app.getHostContext()?.toolInfo?.tool.name ??\n _meta?.toolName ??\n // Some hosts do not forward `_meta` nor do they provide `toolInfo`. Our\n // MCP server provides `toolName` in `structuredContent` as a workaround\n // that we can use if all else fails\n structuredContent.toolName;\n this.#toolMetadata = _meta;\n this.#toolInput = args;\n\n return {\n ...structuredContent,\n toolName: this.toolName,\n args,\n };\n });\n\n close() {\n return this.app.close();\n }\n\n async executeQuery({\n query,\n variables,\n }: {\n query: DocumentNode;\n variables: OperationVariables | undefined;\n }) {\n const result = (await this.app.callServerTool({\n name: \"execute\",\n arguments: { query: print(query), variables },\n })) as ExecuteQueryCallToolResult;\n\n return result.structuredContent;\n }\n\n private async connect() {\n try {\n return await this.app.connect(\n new PostMessageTransport(window.parent, window.parent)\n );\n } catch (e) {\n const error = e instanceof Error ? e : new Error(\"Failed to connect\");\n\n throw error;\n }\n }\n}\n"]}
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
export declare function useToolMetadata():
|
|
2
|
-
[x: string]: unknown;
|
|
3
|
-
progressToken?: string | number | undefined;
|
|
4
|
-
"io.modelcontextprotocol/related-task"?: {
|
|
5
|
-
taskId: string;
|
|
6
|
-
} | undefined;
|
|
7
|
-
} | undefined;
|
|
1
|
+
export declare function useToolMetadata(): import("../../../core/types.js").ApolloMcpServerApps.Meta | undefined;
|
|
8
2
|
//# sourceMappingURL=useToolMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToolMetadata.d.ts","sourceRoot":"","sources":["../../../../src/mcp/react/hooks/useToolMetadata.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe
|
|
1
|
+
{"version":3,"file":"useToolMetadata.d.ts","sourceRoot":"","sources":["../../../../src/mcp/react/hooks/useToolMetadata.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,0EAE9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppManager.d.ts","sourceRoot":"","sources":["../../../src/openai/core/McpAppManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAwB,MAAM,gCAAgC,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AASvE,gBAAgB;AAChB,qBAAa,aAAa;;IACxB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;gBAMN,QAAQ,EAAE,mBAAmB;IAIzC,IAAI,QAAQ,uBAEX;IAED,IAAI,YAAY,mCAEf;IAED,IAAI,SAAS,wCAEZ;IAED,qBAAqB;;;;;;;
|
|
1
|
+
{"version":3,"file":"McpAppManager.d.ts","sourceRoot":"","sources":["../../../src/openai/core/McpAppManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAwB,MAAM,gCAAgC,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AASvE,gBAAgB;AAChB,qBAAa,aAAa;;IACxB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;gBAMN,QAAQ,EAAE,mBAAmB;IAIzC,IAAI,QAAQ,uBAEX;IAED,IAAI,YAAY,mCAEf;IAED,IAAI,SAAS,wCAEZ;IAED,qBAAqB;;;;;;;MAqClB;IAEH,KAAK;IAIC,YAAY,CAAC,EACjB,KAAK,EACL,SAAS,GACV,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,SAAS,EAAE,kBAAkB,GAAG,SAAS,CAAC;KAC3C;YASa,OAAO;CAWtB"}
|
|
@@ -21,33 +21,31 @@ export class McpAppManager {
|
|
|
21
21
|
}
|
|
22
22
|
waitForInitialization = cacheAsync(async () => {
|
|
23
23
|
let toolResult = promiseWithResolvers();
|
|
24
|
-
let toolInput = promiseWithResolvers();
|
|
25
24
|
this.app.ontoolresult = (params) => {
|
|
26
25
|
toolResult.resolve(params);
|
|
27
|
-
// OpenAI is not consistent about sending `ui/notifications/tool-input`
|
|
28
|
-
// before we get the rool result (which should happen according to the
|
|
29
|
-
// spec). We resolve this promise in case it wasn't sent to avoid stalling
|
|
30
|
-
// initialization indefinitely.
|
|
31
|
-
//
|
|
32
|
-
// When OpenAI fixes this issue and sends `ui/notifications/tool-input`
|
|
33
|
-
// consistently, this can be removed.
|
|
34
|
-
toolInput.resolve({});
|
|
35
|
-
};
|
|
36
|
-
this.app.ontoolinput = (params) => {
|
|
37
|
-
toolInput.resolve(params);
|
|
38
26
|
};
|
|
39
27
|
await this.connect();
|
|
40
28
|
const { structuredContent } = await toolResult.promise;
|
|
41
|
-
const { arguments: args } = await toolInput.promise;
|
|
42
29
|
this.#toolName = this.app.getHostContext()?.toolInfo?.tool.name;
|
|
43
|
-
|
|
30
|
+
// OpenAI is not consistent about sending `ui/notifications/tool-input`.
|
|
31
|
+
// Sometimes it doesn't send at all, other times it sends more than once
|
|
32
|
+
// before we get the tool result (which should always happen and at most
|
|
33
|
+
// once according to the spec). Rather than relying on the
|
|
34
|
+
// `ui/notifications/tool-input` notification to set the tool input value,
|
|
35
|
+
// we read from `window.openai.toolInput so that we hvae the most recent
|
|
36
|
+
// set value.
|
|
37
|
+
//
|
|
38
|
+
// When OpenAI fixes this issue and sends `ui/notifications/tool-input`
|
|
39
|
+
// consistently according to the MCP Apps specification, this can be
|
|
40
|
+
// reverrted to use the `app.ontoolinput` callback.
|
|
41
|
+
this.#toolInput = window.openai.toolInput;
|
|
44
42
|
// OpenAI doesn't provide access to `_meta`, so we need to use
|
|
45
43
|
// window.openai.toolResponseMetadata directly
|
|
46
44
|
this.#toolMetadata = window.openai.toolResponseMetadata;
|
|
47
45
|
return {
|
|
48
46
|
...structuredContent,
|
|
49
47
|
toolName: this.toolName,
|
|
50
|
-
args,
|
|
48
|
+
args: this.toolInput,
|
|
51
49
|
};
|
|
52
50
|
});
|
|
53
51
|
close() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppManager.js","sourceRoot":"","sources":["../../../src/openai/core/McpAppManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAK3E,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAOnE,gBAAgB;AAChB,MAAM,OAAO,aAAa;IACf,GAAG,CAAM;IAElB,SAAS,CAAqB;IAC9B,aAAa,GAAmC,IAAI,CAAC;IACrD,UAAU,CAAsC;IAEhD,YAAY,QAA6B;QACvC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,qBAAqB,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;QAC5C,IAAI,UAAU,GAAG,oBAAoB,EAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"McpAppManager.js","sourceRoot":"","sources":["../../../src/openai/core/McpAppManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { App, PostMessageTransport } from \"@modelcontextprotocol/ext-apps\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ApplicationManifest } from \"../../types/application-manifest\";\nimport type { FormattedExecutionResult } from \"graphql\";\nimport type { DocumentNode, OperationVariables } from \"@apollo/client\";\nimport { print } from \"@apollo/client/utilities\";\nimport { cacheAsync, promiseWithResolvers } from \"../../utilities\";\nimport type { ApolloMcpServerApps } from \"../../core/types\";\n\ntype ExecuteQueryCallToolResult = Omit<CallToolResult, \"structuredContent\"> & {\n structuredContent: FormattedExecutionResult;\n};\n\n/** @internal */\nexport class McpAppManager {\n readonly app: App;\n\n #toolName: string | undefined;\n #toolMetadata: Record<string, unknown> | null = null;\n #toolInput: Record<string, unknown> | undefined;\n\n constructor(manifest: ApplicationManifest) {\n this.app = new App({ name: manifest.name, version: manifest.appVersion });\n }\n\n get toolName() {\n return this.#toolName;\n }\n\n get toolMetadata() {\n return this.#toolMetadata;\n }\n\n get toolInput() {\n return this.#toolInput;\n }\n\n waitForInitialization = cacheAsync(async () => {\n let toolResult = promiseWithResolvers<ApolloMcpServerApps.CallToolResult>();\n\n this.app.ontoolresult = (params) => {\n toolResult.resolve(\n params as unknown as ApolloMcpServerApps.CallToolResult\n );\n };\n\n await this.connect();\n\n const { structuredContent } = await toolResult.promise;\n\n this.#toolName = this.app.getHostContext()?.toolInfo?.tool.name;\n\n // OpenAI is not consistent about sending `ui/notifications/tool-input`.\n // Sometimes it doesn't send at all, other times it sends more than once\n // before we get the tool result (which should always happen and at most\n // once according to the spec). Rather than relying on the\n // `ui/notifications/tool-input` notification to set the tool input value,\n // we read from `window.openai.toolInput so that we hvae the most recent\n // set value.\n //\n // When OpenAI fixes this issue and sends `ui/notifications/tool-input`\n // consistently according to the MCP Apps specification, this can be\n // reverrted to use the `app.ontoolinput` callback.\n this.#toolInput = window.openai.toolInput;\n\n // OpenAI doesn't provide access to `_meta`, so we need to use\n // window.openai.toolResponseMetadata directly\n this.#toolMetadata = window.openai.toolResponseMetadata;\n\n return {\n ...structuredContent,\n toolName: this.toolName,\n args: this.toolInput,\n };\n });\n\n close() {\n return this.app.close();\n }\n\n async executeQuery({\n query,\n variables,\n }: {\n query: DocumentNode;\n variables: OperationVariables | undefined;\n }) {\n const result = (await this.app.callServerTool({\n name: \"execute\",\n arguments: { query: print(query), variables },\n })) as ExecuteQueryCallToolResult;\n\n return result.structuredContent;\n }\n\n private async connect() {\n try {\n return await this.app.connect(\n new PostMessageTransport(window.parent, window.parent)\n );\n } catch (e) {\n const error = e instanceof Error ? e : new Error(\"Failed to connect\");\n\n throw error;\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apolloClientAiApps.js","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defaultClientConditions,\n type Environment,\n type Plugin,\n type ResolvedConfig,\n} from \"vite\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { ApolloClient, ApolloLink, type DocumentNode } from \"@apollo/client\";\nimport { InMemoryCache } from \"@apollo/client\";\nimport { gqlPluckFromCodeStringSync } from \"@graphql-tools/graphql-tag-pluck\";\nimport { glob } from \"glob\";\nimport { print } from \"@apollo/client/utilities\";\nimport { removeDirectivesFromDocument } from \"@apollo/client/utilities/internal\";\nimport { of } from \"rxjs\";\nimport { Kind, parse, type OperationDefinitionNode } from \"graphql\";\nimport {\n getArgumentValue,\n getDirectiveArgument,\n getTypeName,\n maybeGetArgumentValue,\n} from \"./utilities/graphql.js\";\nimport type {\n ApplicationManifest,\n ManifestOperation,\n} from \"../types/application-manifest\";\nimport { invariant } from \"../utilities/invariant.js\";\nimport { explorer } from \"./utilities/config.js\";\nimport type { ApolloClientAiAppsConfig } from \"../config/index.js\";\nimport { ApolloClientAiAppsConfigSchema } from \"../config/schema.js\";\nimport { z } from \"zod\";\n\nexport declare namespace apolloClientAiApps {\n export type Target = ApolloClientAiAppsConfig.AppTarget;\n\n export interface Options {\n targets: Target[];\n devTarget?: Target | undefined;\n }\n}\n\nconst root = process.cwd();\n\nconst VALID_TARGETS: apolloClientAiApps.Target[] = [\"openai\", \"mcp\"];\n\nfunction isValidTarget(target: unknown): target is apolloClientAiApps.Target {\n return VALID_TARGETS.includes(target as apolloClientAiApps.Target);\n}\n\nfunction buildExtensions(target: apolloClientAiApps.Target) {\n return [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\", \".json\"].flatMap(\n (ext) => [`.${target}${ext}`, ext]\n );\n}\n\nexport function devTarget(target: string | undefined) {\n invariant(\n target === undefined || isValidTarget(target),\n `devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(\", \")}.`\n );\n\n return target;\n}\n\ninterface FileCache {\n file: string;\n hash: string;\n operations: ManifestOperation[];\n}\n\nexport function apolloClientAiApps(\n options: apolloClientAiApps.Options\n): Plugin {\n const targets = Array.from(new Set(options.targets));\n const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;\n const cache = new Map<string, FileCache>();\n\n let packageJson!: Record<string, any>;\n let config!: ResolvedConfig;\n\n invariant(\n Array.isArray(targets) && targets.length > 0,\n \"The `targets` option must be a non-empty array\"\n );\n\n invariant(\n targets.every(isValidTarget),\n `All targets must be one of: ${VALID_TARGETS.join(\", \")}`\n );\n\n const client = new ApolloClient({\n cache: new InMemoryCache(),\n link: processQueryLink,\n });\n\n async function processFile(file: string) {\n const code = fs.readFileSync(file, \"utf-8\");\n\n if (!code.includes(\"gql\")) return;\n\n const fileHash = createHash(\"md5\").update(code).digest(\"hex\");\n if (cache.get(file)?.hash === fileHash) return;\n const sources = gqlPluckFromCodeStringSync(file, code, {\n modules: [\n { name: \"graphql-tag\", identifier: \"gql\" },\n { name: \"@apollo/client\", identifier: \"gql\" },\n ],\n }).map((source) => ({\n node: parse(source.body),\n file,\n location: source.locationOffset,\n }));\n\n const operations: ManifestOperation[] = [];\n for (const source of sources) {\n const type = (\n source.node.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n ) as OperationDefinitionNode\n ).operation;\n\n let result;\n if (type === \"query\") {\n result = await client.query({\n query: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else if (type === \"mutation\") {\n result = await client.mutate({\n mutation: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else {\n throw new Error(\n \"Found an unsupported operation type. Only Query and Mutation are supported.\"\n );\n }\n operations.push(result.data as ManifestOperation);\n }\n\n cache.set(file, {\n file: file,\n hash: fileHash,\n operations,\n });\n }\n\n async function generateManifest(environment?: Environment) {\n const appsConfig = await getAppsConfig();\n const operations = Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n );\n\n invariant(\n operations.filter((o) => o.prefetch).length <= 1,\n \"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.\"\n );\n\n function getBuildResourceForTarget(target: apolloClientAiApps.Target) {\n const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);\n\n if (entryPoint) {\n return entryPoint;\n }\n\n if (config.mode === \"production\") {\n return `${target}/index.html`;\n }\n\n throw new Error(\n `No entry point found for mode \"${config.mode}\". Entry points other than \"development\" and \"production\" must be defined in package.json file.`\n );\n }\n\n let resource: ApplicationManifest[\"resource\"];\n if (config.command === \"serve\") {\n // Dev mode: resource is a string (dev server URL)\n resource =\n getResourceFromConfig(appsConfig, config.mode, devTarget!) ??\n `http${config.server.https ? \"s\" : \"\"}://${config.server.host ?? \"localhost\"}:${config.server.port}`;\n } else {\n resource = Object.fromEntries(\n targets.map((target) => [target, getBuildResourceForTarget(target)])\n ) as { mcp?: string; openai?: string };\n }\n\n const manifest: ApplicationManifest = {\n format: \"apollo-ai-app-manifest\",\n version: \"1\",\n appVersion: appsConfig.version ?? packageJson.version,\n name: appsConfig.name ?? packageJson.name,\n description: appsConfig.description ?? packageJson.description,\n hash: createHash(\"sha256\").update(Date.now().toString()).digest(\"hex\"),\n operations: Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n ),\n resource,\n csp: {\n connectDomains: appsConfig.csp?.connectDomains ?? [],\n frameDomains: appsConfig.csp?.frameDomains ?? [],\n redirectDomains: appsConfig.csp?.redirectDomains ?? [],\n resourceDomains: appsConfig.csp?.resourceDomains ?? [],\n },\n };\n\n if (isNonEmptyObject(appsConfig.widgetSettings)) {\n manifest.widgetSettings = appsConfig.widgetSettings;\n }\n\n if (isNonEmptyObject(appsConfig.labels)) {\n manifest.labels = appsConfig.labels;\n }\n\n // We create mcp and openai environments in order to write to\n // subdirectories, but we want the manifest to be in the root outDir. If we\n // are running in a different environment, we'll put it in the configured\n // outDir directly instead.\n const outDir =\n environment?.name === \"mcp\" || environment?.name === \"openai\" ?\n path.resolve(config.build.outDir, \"../\")\n : config.build.outDir;\n\n // Always write to build directory so the MCP server picks it up\n const dest = path.resolve(root, outDir, \".application-manifest.json\");\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, JSON.stringify(manifest));\n\n // Always write to the dev location so that the app can bundle the manifest content\n fs.writeFileSync(\".application-manifest.json\", JSON.stringify(manifest));\n }\n\n return {\n name: \"@apollo/client-ai-apps/vite\",\n async buildStart() {\n // Read package.json on start\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n\n // Scan all files on startup\n const files = await glob(\"./src/**/*.{ts,tsx,js,jsx}\", { fs });\n\n for (const file of files) {\n const fullPath = path.resolve(root, file);\n await processFile(fullPath);\n }\n\n // We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.\n if (config.command === \"serve\") {\n await generateManifest(this.environment);\n }\n },\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n configEnvironment(name, { build }) {\n if (!targets.includes(name as any)) return;\n\n return {\n build: {\n outDir: path.join(build?.outDir ?? \"dist\", name),\n },\n };\n },\n configureServer(server) {\n server.watcher.on(\"change\", async (file) => {\n if (file.endsWith(\"package.json\")) {\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n await generateManifest();\n } else if (file.match(/\\.?apollo-client-ai-apps\\.config\\.\\w+$/)) {\n explorer.clearCaches();\n await generateManifest();\n } else if (file.match(/\\.(jsx?|tsx?)$/)) {\n await processFile(file);\n await generateManifest();\n }\n });\n },\n\n config(_, { command }) {\n if (command === \"serve\") {\n invariant(\n isValidTarget(devTarget) || targets.length === 1,\n \"`devTarget` must be set for development when using multiple targets.\"\n );\n\n const target = devTarget ?? targets[0];\n\n return {\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n };\n }\n\n return {\n environments: Object.fromEntries(\n targets.map((target) => [\n target,\n {\n consumer: \"client\",\n webCompatible: true,\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n },\n ])\n ),\n builder: {\n buildApp: async (builder) => {\n await Promise.all(\n targets.map((target) =>\n builder.build(builder.environments[target])\n )\n );\n },\n },\n };\n },\n transformIndexHtml(html, ctx) {\n if (!ctx.server) return html;\n\n let baseUrl = (\n ctx.server.config?.server?.origin ??\n ctx.server.resolvedUrls?.local[0] ??\n \"\"\n ).replace(/\\/$/, \"\");\n baseUrl = baseUrl.replace(/\\/$/, \"\");\n\n return (\n html\n // import \"/@vite/...\" or \"/@react-refresh\"\n .replace(/(from\\s+[\"'])\\/([^\"']+)/g, `$1${baseUrl}/$2`)\n // src=\"/src/...\"\n .replace(/(src=[\"'])\\/([^\"']+)/gi, `$1${baseUrl}/$2`)\n );\n },\n async writeBundle() {\n await generateManifest(this.environment);\n },\n } satisfies Plugin;\n}\n\nconst processQueryLink = new ApolloLink((operation) => {\n const body = print(\n removeManifestDirectives(sortTopLevelDefinitions(operation.query))\n );\n const name = operation.operationName;\n const definition = operation.query.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n );\n\n // Use `operation.query` so that the error reflects the end-user defined\n // document, not our sorted one\n invariant(\n definition,\n `Document does not contain an operation:\\n${print(operation.query)}`\n );\n\n const { directives, operation: type } = definition;\n\n const variables = definition.variableDefinitions?.reduce(\n (obj, varDef) => ({\n ...obj,\n [varDef.variable.name.value]: getTypeName(varDef.type),\n }),\n {}\n );\n\n const prefetch = directives?.some((d) => d.name.value === \"prefetch\");\n const id = createHash(\"sha256\").update(body).digest(\"hex\");\n // TODO: For now, you can only have 1 operation marked as prefetch. In the future, we'll likely support more than 1, and the \"prefetchId\" will be defined on the `@prefetch` itself as an argument\n const prefetchID = prefetch ? \"__anonymous\" : undefined;\n\n const tools = directives\n ?.filter((d) => d.name.value === \"tool\")\n .map((directive) => {\n const result = ToolDirectiveSchema.safeParse({\n name: getArgumentValue(\n getDirectiveArgument(\"name\", directive, { required: true }),\n Kind.STRING\n ),\n description: getArgumentValue(\n getDirectiveArgument(\"description\", directive, { required: true }),\n Kind.STRING\n ),\n extraInputs: maybeGetArgumentValue(\n getDirectiveArgument(\"extraInputs\", directive),\n Kind.LIST\n ),\n labels: maybeGetArgumentValue(\n getDirectiveArgument(\"labels\", directive),\n Kind.OBJECT\n ),\n });\n\n if (result.error) {\n throw z.prettifyError(result.error);\n }\n\n return result.data;\n });\n\n // TODO: Make this object satisfy the `ManifestOperation` type. Currently\n // it errors because we need more validation on a few of these fields\n return of({\n data: { id, name, type, body, variables, prefetch, prefetchID, tools },\n });\n});\n\nfunction removeManifestDirectives(doc: DocumentNode) {\n return removeDirectivesFromDocument(\n [{ name: \"prefetch\" }, { name: \"tool\" }],\n doc\n )!;\n}\n\n// Sort the definitions in this document so that operations come before fragments,\n// and so that each kind of definition is sorted by name.\nexport function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {\n const definitions = [...query.definitions];\n // We want to avoid unnecessary dependencies, so write out a comparison\n // function instead of using _.orderBy.\n definitions.sort((a, b) => {\n // This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.\n if (a.kind > b.kind) {\n return -1;\n }\n if (a.kind < b.kind) {\n return 1;\n }\n\n // Extract the name from each definition. Jump through some hoops because\n // non-executable definitions don't have to have names (even though any\n // DocumentNode actually passed here should only have executable\n // definitions).\n const aName =\n a.kind === \"OperationDefinition\" || a.kind === \"FragmentDefinition\" ?\n (a.name?.value ?? \"\")\n : \"\";\n const bName =\n b.kind === \"OperationDefinition\" || b.kind === \"FragmentDefinition\" ?\n (b.name?.value ?? \"\")\n : \"\";\n\n // Sort by name ascending.\n if (aName < bName) {\n return -1;\n }\n if (aName > bName) {\n return 1;\n }\n\n // Assuming that the document is \"valid\", no operation or fragment name can appear\n // more than once, so we don't need to differentiate further to have a deterministic\n // sort.\n return 0;\n });\n return {\n ...query,\n definitions,\n };\n}\n\nfunction isNonEmptyObject<T extends object>(\n obj: T | null | undefined\n): obj is T {\n return !!obj && Object.keys(obj).length > 0;\n}\n\nasync function getAppsConfig(): Promise<ApolloClientAiAppsConfig.Config> {\n const result = await explorer.search();\n const config = (result?.config ??\n {}) as Partial<ApolloClientAiAppsConfig.Config>;\n\n const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);\n\n if (parsed.error) {\n throw z.prettifyError(parsed.error);\n }\n\n return parsed.data;\n}\n\nfunction getResourceFromConfig(\n appsConfig: ApolloClientAiAppsConfig.Config,\n mode: string,\n target: apolloClientAiApps.Target\n) {\n if (!appsConfig.entry || !appsConfig.entry[mode]) {\n return;\n }\n\n const config = appsConfig.entry[mode];\n\n return typeof config === \"string\" ? config : config[target];\n}\n\nconst ToolDirectiveSchema = z.strictObject({\n name: z.stringFormat(\"toolName\", (value) => value.indexOf(\" \") === -1, {\n error: (iss) => `Tool with name \"${iss.input}\" must not contain spaces`,\n }),\n description: z.string(),\n extraInputs: z.optional(\n z.array(\n z.strictObject({\n name: z.string(),\n description: z.string(),\n type: z.literal([\"string\", \"boolean\", \"number\"]),\n })\n )\n ),\n labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),\n});\n"]}
|
|
1
|
+
{"version":3,"file":"apolloClientAiApps.js","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defaultClientConditions,\n type Environment,\n type Plugin,\n type ResolvedConfig,\n} from \"vite\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { ApolloClient, ApolloLink, type DocumentNode } from \"@apollo/client\";\nimport { InMemoryCache } from \"@apollo/client\";\nimport { gqlPluckFromCodeStringSync } from \"@graphql-tools/graphql-tag-pluck\";\nimport { glob } from \"glob\";\nimport { print } from \"@apollo/client/utilities\";\nimport { removeDirectivesFromDocument } from \"@apollo/client/utilities/internal\";\nimport { of } from \"rxjs\";\nimport { Kind, parse, type OperationDefinitionNode } from \"graphql\";\nimport {\n getArgumentValue,\n getDirectiveArgument,\n getTypeName,\n maybeGetArgumentValue,\n} from \"./utilities/graphql.js\";\nimport type {\n ApplicationManifest,\n ManifestOperation,\n} from \"../types/application-manifest\";\nimport { invariant } from \"../utilities/invariant.js\";\nimport { explorer } from \"./utilities/config.js\";\nimport type { ApolloClientAiAppsConfig } from \"../config/index.js\";\nimport { ApolloClientAiAppsConfigSchema } from \"../config/schema.js\";\nimport { z } from \"zod\";\n\nexport declare namespace apolloClientAiApps {\n export type Target = ApolloClientAiAppsConfig.AppTarget;\n\n export interface Options {\n targets: Target[];\n devTarget?: Target | undefined;\n }\n}\n\nconst root = process.cwd();\n\nconst VALID_TARGETS: apolloClientAiApps.Target[] = [\"openai\", \"mcp\"];\n\nfunction isValidTarget(target: unknown): target is apolloClientAiApps.Target {\n return VALID_TARGETS.includes(target as apolloClientAiApps.Target);\n}\n\nfunction buildExtensions(target: apolloClientAiApps.Target) {\n return [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\", \".json\"].flatMap(\n (ext) => [`.${target}${ext}`, ext]\n );\n}\n\nexport function devTarget(target: string | undefined) {\n invariant(\n target === undefined || isValidTarget(target),\n `devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(\", \")}.`\n );\n\n return target;\n}\n\ninterface FileCache {\n file: string;\n hash: string;\n operations: ManifestOperation[];\n}\n\nexport function apolloClientAiApps(\n options: apolloClientAiApps.Options\n): Plugin {\n const targets = Array.from(new Set(options.targets));\n const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;\n const cache = new Map<string, FileCache>();\n\n let packageJson!: Record<string, any>;\n let config!: ResolvedConfig;\n\n invariant(\n Array.isArray(targets) && targets.length > 0,\n \"The `targets` option must be a non-empty array\"\n );\n\n invariant(\n targets.every(isValidTarget),\n `All targets must be one of: ${VALID_TARGETS.join(\", \")}`\n );\n\n const client = new ApolloClient({\n cache: new InMemoryCache(),\n link: processQueryLink,\n });\n\n async function processFile(file: string) {\n const code = fs.readFileSync(file, \"utf-8\");\n\n if (!code.includes(\"gql\")) return;\n\n const fileHash = createHash(\"md5\").update(code).digest(\"hex\");\n if (cache.get(file)?.hash === fileHash) return;\n const sources = gqlPluckFromCodeStringSync(file, code, {\n modules: [\n { name: \"graphql-tag\", identifier: \"gql\" },\n { name: \"@apollo/client\", identifier: \"gql\" },\n ],\n }).map((source) => ({\n node: parse(source.body),\n file,\n location: source.locationOffset,\n }));\n\n const operations: ManifestOperation[] = [];\n for (const source of sources) {\n const type = (\n source.node.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n ) as OperationDefinitionNode\n ).operation;\n\n let result;\n if (type === \"query\") {\n result = await client.query({\n query: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else if (type === \"mutation\") {\n result = await client.mutate({\n mutation: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else {\n throw new Error(\n \"Found an unsupported operation type. Only Query and Mutation are supported.\"\n );\n }\n operations.push(result.data as ManifestOperation);\n }\n\n cache.set(file, {\n file: file,\n hash: fileHash,\n operations,\n });\n }\n\n async function generateManifest(environment?: Environment) {\n const appsConfig = await getAppsConfig();\n const operations = Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n );\n\n invariant(\n operations.filter((o) => o.prefetch).length <= 1,\n \"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.\"\n );\n\n function getBuildResourceForTarget(target: apolloClientAiApps.Target) {\n const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);\n\n if (entryPoint) {\n return entryPoint;\n }\n\n if (config.mode === \"production\") {\n return `${target}/index.html`;\n }\n\n throw new Error(\n `No entry point found for mode \"${config.mode}\". Entry points other than \"development\" and \"production\" must be defined in package.json file.`\n );\n }\n\n let resource: ApplicationManifest[\"resource\"];\n if (config.command === \"serve\") {\n // Dev mode: resource is a string (dev server URL)\n resource =\n getResourceFromConfig(appsConfig, config.mode, devTarget!) ??\n `http${config.server.https ? \"s\" : \"\"}://${config.server.host ?? \"localhost\"}:${config.server.port}`;\n } else {\n resource = Object.fromEntries(\n targets.map((target) => [target, getBuildResourceForTarget(target)])\n ) as { mcp?: string; openai?: string };\n }\n\n const manifest: ApplicationManifest = {\n format: \"apollo-ai-app-manifest\",\n version: \"1\",\n appVersion: appsConfig.version ?? packageJson.version,\n name: appsConfig.name ?? packageJson.name,\n description: appsConfig.description ?? packageJson.description,\n hash: createHash(\"sha256\").update(Date.now().toString()).digest(\"hex\"),\n operations: Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n ),\n resource,\n csp: {\n connectDomains: appsConfig.csp?.connectDomains ?? [],\n frameDomains: appsConfig.csp?.frameDomains ?? [],\n redirectDomains: appsConfig.csp?.redirectDomains ?? [],\n resourceDomains: appsConfig.csp?.resourceDomains ?? [],\n },\n };\n\n if (isNonEmptyObject(appsConfig.widgetSettings)) {\n manifest.widgetSettings = appsConfig.widgetSettings;\n }\n\n if (isNonEmptyObject(appsConfig.labels)) {\n manifest.labels = appsConfig.labels;\n }\n\n // We create mcp and openai environments in order to write to\n // subdirectories, but we want the manifest to be in the root outDir. If we\n // are running in a different environment, we'll put it in the configured\n // outDir directly instead.\n const outDir =\n environment?.name === \"mcp\" || environment?.name === \"openai\" ?\n path.resolve(config.build.outDir, \"../\")\n : config.build.outDir;\n\n // Always write to build directory so the MCP server picks it up\n const dest = path.resolve(root, outDir, \".application-manifest.json\");\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, JSON.stringify(manifest));\n\n // Always write to the dev location so that the app can bundle the manifest content\n fs.writeFileSync(\".application-manifest.json\", JSON.stringify(manifest));\n }\n\n return {\n name: \"@apollo/client-ai-apps/vite\",\n async buildStart() {\n // Read package.json on start\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n\n // Scan all files on startup\n const files = await glob(\"./src/**/*.{ts,tsx,js,jsx}\", { fs });\n\n for (const file of files) {\n const fullPath = path.resolve(root, file);\n await processFile(fullPath);\n }\n\n // We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.\n if (config.command === \"serve\") {\n await generateManifest(this.environment);\n }\n },\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n configEnvironment(name, { build }) {\n if (!targets.includes(name as any)) return;\n\n return {\n build: {\n outDir: path.join(build?.outDir ?? \"dist\", name),\n },\n };\n },\n configureServer(server) {\n server.watcher.on(\"change\", async (file) => {\n if (file.endsWith(\"package.json\")) {\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n await generateManifest();\n } else if (file.match(/\\.?apollo-client-ai-apps\\.config\\.\\w+$/)) {\n explorer.clearCaches();\n await generateManifest();\n } else if (file.match(/\\.(jsx?|tsx?)$/)) {\n await processFile(file);\n await generateManifest();\n }\n });\n },\n\n config(_, { command }) {\n if (command === \"serve\") {\n invariant(\n isValidTarget(devTarget) || targets.length === 1,\n \"`devTarget` must be set for development when using multiple targets.\"\n );\n\n const target = devTarget ?? targets[0];\n\n return {\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n };\n }\n\n return {\n environments: Object.fromEntries(\n targets.map((target) => [\n target,\n {\n consumer: \"client\",\n webCompatible: true,\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n },\n ])\n ),\n builder: {\n buildApp: async (builder) => {\n await Promise.all(\n targets.map((target) =>\n builder.build(builder.environments[target])\n )\n );\n },\n },\n };\n },\n transformIndexHtml(html, ctx) {\n if (!ctx.server) return html;\n\n let baseUrl = (\n ctx.server.config?.server?.origin ??\n ctx.server.resolvedUrls?.local[0] ??\n \"\"\n ).replace(/\\/$/, \"\");\n baseUrl = baseUrl.replace(/\\/$/, \"\");\n\n return (\n html\n // import \"/@vite/...\" or \"/@react-refresh\"\n .replace(/(from\\s+[\"'])\\/([^\"']+)/g, `$1${baseUrl}/$2`)\n // src=\"/src/...\"\n .replace(/(src=[\"'])\\/([^\"']+)/gi, `$1${baseUrl}/$2`)\n );\n },\n async writeBundle() {\n await generateManifest(this.environment);\n },\n } satisfies Plugin;\n}\n\nconst processQueryLink = new ApolloLink((operation) => {\n const body = print(\n removeManifestDirectives(sortTopLevelDefinitions(operation.query))\n );\n const name = operation.operationName;\n const definition = operation.query.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n );\n\n // Use `operation.query` so that the error reflects the end-user defined\n // document, not our sorted one\n invariant(\n definition,\n `Document does not contain an operation:\\n${print(operation.query)}`\n );\n\n const { directives, operation: type } = definition;\n\n const variables = definition.variableDefinitions?.reduce(\n (obj, varDef) => ({\n ...obj,\n [varDef.variable.name.value]: getTypeName(varDef.type),\n }),\n {}\n );\n\n const prefetch = directives?.some((d) => d.name.value === \"prefetch\");\n const id = createHash(\"sha256\").update(body).digest(\"hex\");\n // TODO: For now, you can only have 1 operation marked as prefetch. In the future, we'll likely support more than 1, and the \"prefetchId\" will be defined on the `@prefetch` itself as an argument\n const prefetchID = prefetch ? \"__anonymous\" : undefined;\n\n const tools = directives\n ?.filter((d) => d.name.value === \"tool\")\n .map((directive) => {\n const result = ToolDirectiveSchema.safeParse({\n name: getArgumentValue(\n getDirectiveArgument(\"name\", directive, { required: true }),\n Kind.STRING\n ),\n description: getArgumentValue(\n getDirectiveArgument(\"description\", directive, { required: true }),\n Kind.STRING\n ),\n extraInputs: maybeGetArgumentValue(\n getDirectiveArgument(\"extraInputs\", directive),\n Kind.LIST\n ),\n labels: maybeGetArgumentValue(\n getDirectiveArgument(\"labels\", directive),\n Kind.OBJECT\n ),\n });\n\n if (result.error) {\n throw z.prettifyError(result.error);\n }\n\n return result.data;\n });\n\n // TODO: Make this object satisfy the `ManifestOperation` type. Currently\n // it errors because we need more validation on a few of these fields\n return of({\n data: { id, name, type, body, variables, prefetch, prefetchID, tools },\n });\n});\n\nfunction removeManifestDirectives(doc: DocumentNode) {\n return removeDirectivesFromDocument(\n [{ name: \"prefetch\" }, { name: \"tool\" }],\n doc\n )!;\n}\n\n// Sort the definitions in this document so that operations come before fragments,\n// and so that each kind of definition is sorted by name.\nexport function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {\n const definitions = [...query.definitions];\n // We want to avoid unnecessary dependencies, so write out a comparison\n // function instead of using _.orderBy.\n definitions.sort((a, b) => {\n // This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.\n if (a.kind > b.kind) {\n return -1;\n }\n if (a.kind < b.kind) {\n return 1;\n }\n\n // Extract the name from each definition. Jump through some hoops because\n // non-executable definitions don't have to have names (even though any\n // DocumentNode actually passed here should only have executable\n // definitions).\n const aName =\n a.kind === \"OperationDefinition\" || a.kind === \"FragmentDefinition\" ?\n (a.name?.value ?? \"\")\n : \"\";\n const bName =\n b.kind === \"OperationDefinition\" || b.kind === \"FragmentDefinition\" ?\n (b.name?.value ?? \"\")\n : \"\";\n\n // Sort by name ascending.\n if (aName < bName) {\n return -1;\n }\n if (aName > bName) {\n return 1;\n }\n\n // Assuming that the document is \"valid\", no operation or fragment name can appear\n // more than once, so we don't need to differentiate further to have a deterministic\n // sort.\n return 0;\n });\n return {\n ...query,\n definitions,\n };\n}\n\nfunction isNonEmptyObject<T extends object>(\n obj: T | null | undefined\n): obj is T {\n return !!obj && Object.keys(obj).length > 0;\n}\n\nasync function getAppsConfig() {\n const result = await explorer.search();\n const config = (result?.config ??\n {}) as Partial<ApolloClientAiAppsConfig.Config>;\n\n const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);\n\n if (parsed.error) {\n throw z.prettifyError(parsed.error);\n }\n\n return parsed.data;\n}\n\nfunction getResourceFromConfig(\n appsConfig: z.infer<typeof ApolloClientAiAppsConfigSchema>,\n mode: string,\n target: apolloClientAiApps.Target\n) {\n if (!appsConfig.entry || !appsConfig.entry[mode]) {\n return;\n }\n\n const config = appsConfig.entry[mode];\n\n return typeof config === \"string\" ? config : config[target];\n}\n\nconst ToolDirectiveSchema = z.strictObject({\n name: z.stringFormat(\"toolName\", (value) => value.indexOf(\" \") === -1, {\n error: (iss) => `Tool with name \"${iss.input}\" must not contain spaces`,\n }),\n description: z.string(),\n extraInputs: z.optional(\n z.array(\n z.strictObject({\n name: z.string(),\n description: z.string(),\n type: z.literal([\"string\", \"boolean\", \"number\"]),\n })\n )\n ),\n labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),\n});\n"]}
|
package/package.json
CHANGED
package/src/config/types.ts
CHANGED
|
@@ -3,5 +3,5 @@ import type { ApolloClientAiAppsConfigSchema, AppTarget } from "./schema.js";
|
|
|
3
3
|
|
|
4
4
|
export declare namespace ApolloClientAiAppsConfig {
|
|
5
5
|
export type AppTarget = z.infer<typeof AppTarget>;
|
|
6
|
-
export type Config = z.
|
|
6
|
+
export type Config = z.input<typeof ApolloClientAiAppsConfigSchema>;
|
|
7
7
|
}
|
package/src/core/types.ts
CHANGED
|
@@ -2,13 +2,20 @@ import type { CallToolResult as McpCallToolResult } from "@modelcontextprotocol/
|
|
|
2
2
|
import type { FormattedExecutionResult } from "graphql";
|
|
3
3
|
|
|
4
4
|
export namespace ApolloMcpServerApps {
|
|
5
|
+
export interface Meta {
|
|
6
|
+
toolName: string;
|
|
7
|
+
[x: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
export interface StructuredContent {
|
|
6
11
|
result: FormattedExecutionResult;
|
|
7
12
|
prefetch?: Record<string, FormattedExecutionResult>;
|
|
13
|
+
toolName?: string;
|
|
8
14
|
[x: string]: unknown;
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
export interface CallToolResult extends McpCallToolResult {
|
|
18
|
+
_meta?: ApolloMcpServerApps.Meta;
|
|
12
19
|
structuredContent: ApolloMcpServerApps.StructuredContent;
|
|
13
20
|
}
|
|
14
21
|
}
|
|
@@ -16,7 +16,7 @@ export class McpAppManager {
|
|
|
16
16
|
readonly app: App;
|
|
17
17
|
|
|
18
18
|
#toolName: string | undefined;
|
|
19
|
-
#toolMetadata: ApolloMcpServerApps.CallToolResult["_meta"];
|
|
19
|
+
#toolMetadata: ApolloMcpServerApps.CallToolResult["_meta"] | undefined;
|
|
20
20
|
#toolInput: Record<string, unknown> | undefined;
|
|
21
21
|
|
|
22
22
|
constructor(manifest: ApplicationManifest) {
|
|
@@ -54,7 +54,16 @@ export class McpAppManager {
|
|
|
54
54
|
const { structuredContent, _meta } = await toolResult.promise;
|
|
55
55
|
const { arguments: args } = await toolInput.promise;
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// Some hosts do not provide toolInfo in the ui/initialize response, so we
|
|
58
|
+
// fallback to `_meta.toolName` provided by Apollo MCP server if the value
|
|
59
|
+
// is not available.
|
|
60
|
+
this.#toolName =
|
|
61
|
+
this.app.getHostContext()?.toolInfo?.tool.name ??
|
|
62
|
+
_meta?.toolName ??
|
|
63
|
+
// Some hosts do not forward `_meta` nor do they provide `toolInfo`. Our
|
|
64
|
+
// MCP server provides `toolName` in `structuredContent` as a workaround
|
|
65
|
+
// that we can use if all else fails
|
|
66
|
+
structuredContent.toolName;
|
|
58
67
|
this.#toolMetadata = _meta;
|
|
59
68
|
this.#toolInput = args;
|
|
60
69
|
|
|
@@ -3,6 +3,7 @@ import { gql, InMemoryCache } from "@apollo/client";
|
|
|
3
3
|
import { execute } from "@apollo/client/link";
|
|
4
4
|
import { ApolloClient } from "../../core/ApolloClient.js";
|
|
5
5
|
import {
|
|
6
|
+
minimalHostContextWithToolName,
|
|
6
7
|
mockApplicationManifest,
|
|
7
8
|
mockMcpHost,
|
|
8
9
|
ObservableStream,
|
|
@@ -23,15 +24,23 @@ test("delegates query execution to MCP host", async () => {
|
|
|
23
24
|
manifest: mockApplicationManifest(),
|
|
24
25
|
});
|
|
25
26
|
|
|
26
|
-
using host = await mockMcpHost(
|
|
27
|
+
using host = await mockMcpHost({
|
|
28
|
+
hostContext: minimalHostContextWithToolName("GetProduct"),
|
|
29
|
+
});
|
|
27
30
|
host.onCleanup(() => client.stop());
|
|
28
31
|
|
|
32
|
+
host.sendToolInput({ arguments: {} });
|
|
29
33
|
host.sendToolResult({
|
|
30
34
|
_meta: { toolName: "GetProduct" },
|
|
31
35
|
content: [],
|
|
32
|
-
structuredContent: {
|
|
36
|
+
structuredContent: {
|
|
37
|
+
result: {
|
|
38
|
+
data: {
|
|
39
|
+
product: null,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
33
43
|
});
|
|
34
|
-
host.sendToolInput({ arguments: {} });
|
|
35
44
|
|
|
36
45
|
host.mockToolCall("execute", () => ({
|
|
37
46
|
content: [],
|
|
@@ -37,34 +37,31 @@ export class McpAppManager {
|
|
|
37
37
|
|
|
38
38
|
waitForInitialization = cacheAsync(async () => {
|
|
39
39
|
let toolResult = promiseWithResolvers<ApolloMcpServerApps.CallToolResult>();
|
|
40
|
-
let toolInput = promiseWithResolvers<Parameters<App["ontoolinput"]>[0]>();
|
|
41
40
|
|
|
42
41
|
this.app.ontoolresult = (params) => {
|
|
43
42
|
toolResult.resolve(
|
|
44
43
|
params as unknown as ApolloMcpServerApps.CallToolResult
|
|
45
44
|
);
|
|
46
|
-
|
|
47
|
-
// OpenAI is not consistent about sending `ui/notifications/tool-input`
|
|
48
|
-
// before we get the rool result (which should happen according to the
|
|
49
|
-
// spec). We resolve this promise in case it wasn't sent to avoid stalling
|
|
50
|
-
// initialization indefinitely.
|
|
51
|
-
//
|
|
52
|
-
// When OpenAI fixes this issue and sends `ui/notifications/tool-input`
|
|
53
|
-
// consistently, this can be removed.
|
|
54
|
-
toolInput.resolve({});
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
this.app.ontoolinput = (params) => {
|
|
58
|
-
toolInput.resolve(params);
|
|
59
45
|
};
|
|
60
46
|
|
|
61
47
|
await this.connect();
|
|
62
48
|
|
|
63
49
|
const { structuredContent } = await toolResult.promise;
|
|
64
|
-
const { arguments: args } = await toolInput.promise;
|
|
65
50
|
|
|
66
51
|
this.#toolName = this.app.getHostContext()?.toolInfo?.tool.name;
|
|
67
|
-
|
|
52
|
+
|
|
53
|
+
// OpenAI is not consistent about sending `ui/notifications/tool-input`.
|
|
54
|
+
// Sometimes it doesn't send at all, other times it sends more than once
|
|
55
|
+
// before we get the tool result (which should always happen and at most
|
|
56
|
+
// once according to the spec). Rather than relying on the
|
|
57
|
+
// `ui/notifications/tool-input` notification to set the tool input value,
|
|
58
|
+
// we read from `window.openai.toolInput so that we hvae the most recent
|
|
59
|
+
// set value.
|
|
60
|
+
//
|
|
61
|
+
// When OpenAI fixes this issue and sends `ui/notifications/tool-input`
|
|
62
|
+
// consistently according to the MCP Apps specification, this can be
|
|
63
|
+
// reverrted to use the `app.ontoolinput` callback.
|
|
64
|
+
this.#toolInput = window.openai.toolInput;
|
|
68
65
|
|
|
69
66
|
// OpenAI doesn't provide access to `_meta`, so we need to use
|
|
70
67
|
// window.openai.toolResponseMetadata directly
|
|
@@ -73,7 +70,7 @@ export class McpAppManager {
|
|
|
73
70
|
return {
|
|
74
71
|
...structuredContent,
|
|
75
72
|
toolName: this.toolName,
|
|
76
|
-
args,
|
|
73
|
+
args: this.toolInput,
|
|
77
74
|
};
|
|
78
75
|
});
|
|
79
76
|
|
|
@@ -92,7 +92,7 @@ describe("Client Basics", () => {
|
|
|
92
92
|
|
|
93
93
|
describe("prefetchData", () => {
|
|
94
94
|
test("caches tool response when data is provided", async () => {
|
|
95
|
-
stubOpenAiGlobals();
|
|
95
|
+
stubOpenAiGlobals({ toolInput: { id: 1 } });
|
|
96
96
|
using _ = spyOnConsole("debug");
|
|
97
97
|
const client = new ApolloClient({
|
|
98
98
|
cache: new InMemoryCache(),
|
|
@@ -148,7 +148,7 @@ describe("prefetchData", () => {
|
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
test("caches prefetched data when prefetched data is provided", async () => {
|
|
151
|
-
stubOpenAiGlobals();
|
|
151
|
+
stubOpenAiGlobals({ toolInput: { id: 1 } });
|
|
152
152
|
using _ = spyOnConsole("debug");
|
|
153
153
|
const client = new ApolloClient({
|
|
154
154
|
cache: new InMemoryCache(),
|
|
@@ -226,7 +226,7 @@ describe("prefetchData", () => {
|
|
|
226
226
|
});
|
|
227
227
|
|
|
228
228
|
test("caches both prefetch and tool response when both are provided", async () => {
|
|
229
|
-
stubOpenAiGlobals();
|
|
229
|
+
stubOpenAiGlobals({ toolInput: { id: 1 } });
|
|
230
230
|
using _ = spyOnConsole("debug");
|
|
231
231
|
const client = new ApolloClient({
|
|
232
232
|
cache: new InMemoryCache(),
|
|
@@ -343,7 +343,7 @@ describe("prefetchData", () => {
|
|
|
343
343
|
});
|
|
344
344
|
|
|
345
345
|
test("excludes extra inputs when writing to cache", async () => {
|
|
346
|
-
stubOpenAiGlobals();
|
|
346
|
+
stubOpenAiGlobals({ toolInput: { id: 1, myOtherThing: 2 } });
|
|
347
347
|
using _ = spyOnConsole("debug");
|
|
348
348
|
const client = new ApolloClient({
|
|
349
349
|
cache: new InMemoryCache(),
|
|
@@ -21,7 +21,7 @@ afterEach(() => {
|
|
|
21
21
|
|
|
22
22
|
test("returns the tool input from the MCP host", async () => {
|
|
23
23
|
using _ = spyOnConsole("debug");
|
|
24
|
-
stubOpenAiGlobals({ toolResponseMetadata: {} });
|
|
24
|
+
stubOpenAiGlobals({ toolResponseMetadata: {}, toolInput: { id: "1" } });
|
|
25
25
|
const client = new ApolloClient({
|
|
26
26
|
cache: new InMemoryCache(),
|
|
27
27
|
manifest: mockApplicationManifest(),
|
|
@@ -469,7 +469,7 @@ function isNonEmptyObject<T extends object>(
|
|
|
469
469
|
return !!obj && Object.keys(obj).length > 0;
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
-
async function getAppsConfig()
|
|
472
|
+
async function getAppsConfig() {
|
|
473
473
|
const result = await explorer.search();
|
|
474
474
|
const config = (result?.config ??
|
|
475
475
|
{}) as Partial<ApolloClientAiAppsConfig.Config>;
|
|
@@ -484,7 +484,7 @@ async function getAppsConfig(): Promise<ApolloClientAiAppsConfig.Config> {
|
|
|
484
484
|
}
|
|
485
485
|
|
|
486
486
|
function getResourceFromConfig(
|
|
487
|
-
appsConfig:
|
|
487
|
+
appsConfig: z.infer<typeof ApolloClientAiAppsConfigSchema>,
|
|
488
488
|
mode: string,
|
|
489
489
|
target: apolloClientAiApps.Target
|
|
490
490
|
) {
|