@apollo/client-ai-apps 0.3.3 → 0.5.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/.github/CODEOWNERS +1 -0
- package/.github/workflows/pr.yaml +23 -1
- package/.github/workflows/release.yaml +1 -5
- package/.github/workflows/verify-changeset.yml +112 -21
- package/CHANGELOG.md +416 -0
- package/__mocks__/fs/promises.cjs +3 -0
- package/__mocks__/fs.cjs +3 -0
- package/dist/config/defineConfig.d.ts +26 -0
- package/dist/config/defineConfig.d.ts.map +1 -0
- package/dist/config/defineConfig.js +7 -0
- package/dist/config/defineConfig.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +29 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +51 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/types.d.ts +7 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/ApolloClient.d.ts +4 -3
- package/dist/core/ApolloClient.d.ts.map +1 -1
- package/dist/core/ApolloClient.js +6 -59
- package/dist/core/ApolloClient.js.map +1 -1
- package/dist/core/Platform.d.ts +8 -0
- package/dist/core/Platform.d.ts.map +1 -0
- package/dist/core/Platform.js +20 -0
- package/dist/core/Platform.js.map +1 -0
- package/dist/core/types.d.ts +13 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +2 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mcp.d.ts +5 -0
- package/dist/index.mcp.d.ts.map +1 -0
- package/dist/index.mcp.js +5 -0
- package/dist/index.mcp.js.map +1 -0
- package/dist/index.openai.d.ts +5 -0
- package/dist/index.openai.d.ts.map +1 -0
- package/dist/index.openai.js +5 -0
- package/dist/index.openai.js.map +1 -0
- package/dist/link/ToolCallLink.d.ts +3 -3
- package/dist/link/ToolCallLink.d.ts.map +1 -1
- package/dist/link/ToolCallLink.js +5 -14
- package/dist/link/ToolCallLink.js.map +1 -1
- package/dist/mcp/core/ApolloClient.d.ts +21 -0
- package/dist/mcp/core/ApolloClient.d.ts.map +1 -0
- package/dist/mcp/core/ApolloClient.js +65 -0
- package/dist/mcp/core/ApolloClient.js.map +1 -0
- package/dist/mcp/core/McpAppManager.d.ts +34 -0
- package/dist/mcp/core/McpAppManager.d.ts.map +1 -0
- package/dist/mcp/core/McpAppManager.js +63 -0
- package/dist/mcp/core/McpAppManager.js.map +1 -0
- package/dist/mcp/core/Platform.d.ts +8 -0
- package/dist/mcp/core/Platform.d.ts.map +1 -0
- package/dist/mcp/core/Platform.js +8 -0
- package/dist/mcp/core/Platform.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/link/ToolCallLink.d.ts +28 -0
- package/dist/mcp/link/ToolCallLink.d.ts.map +1 -0
- package/dist/mcp/link/ToolCallLink.js +35 -0
- package/dist/mcp/link/ToolCallLink.js.map +1 -0
- package/dist/mcp/react/hooks/useApolloClient.d.ts +3 -0
- package/dist/mcp/react/hooks/useApolloClient.d.ts.map +1 -0
- package/dist/mcp/react/hooks/useApolloClient.js +9 -0
- package/dist/mcp/react/hooks/useApolloClient.js.map +1 -0
- package/dist/mcp/react/hooks/useApp.d.ts +2 -0
- package/dist/mcp/react/hooks/useApp.d.ts.map +1 -0
- package/dist/mcp/react/hooks/useApp.js +5 -0
- package/dist/mcp/react/hooks/useApp.js.map +1 -0
- package/dist/mcp/react/hooks/useToolInput.d.ts +2 -0
- package/dist/mcp/react/hooks/useToolInput.d.ts.map +1 -0
- package/dist/mcp/react/hooks/useToolInput.js +5 -0
- package/dist/mcp/react/hooks/useToolInput.js.map +1 -0
- package/dist/mcp/react/hooks/useToolMetadata.d.ts +8 -0
- package/dist/mcp/react/hooks/useToolMetadata.d.ts.map +1 -0
- package/dist/mcp/react/hooks/useToolMetadata.js +5 -0
- package/dist/mcp/react/hooks/useToolMetadata.js.map +1 -0
- package/dist/mcp/react/hooks/useToolName.d.ts +2 -0
- package/dist/mcp/react/hooks/useToolName.d.ts.map +1 -0
- package/dist/mcp/react/hooks/useToolName.js +5 -0
- package/dist/mcp/react/hooks/useToolName.js.map +1 -0
- package/dist/mcp/react/index.d.ts +5 -0
- package/dist/mcp/react/index.d.ts.map +1 -0
- package/dist/mcp/react/index.js +5 -0
- package/dist/mcp/react/index.js.map +1 -0
- package/dist/openai/core/ApolloClient.d.ts +21 -0
- package/dist/openai/core/ApolloClient.d.ts.map +1 -0
- package/dist/openai/core/ApolloClient.js +66 -0
- package/dist/openai/core/ApolloClient.js.map +1 -0
- package/dist/openai/core/McpAppManager.d.ts +28 -0
- package/dist/openai/core/McpAppManager.d.ts.map +1 -0
- package/dist/openai/core/McpAppManager.js +73 -0
- package/dist/openai/core/McpAppManager.js.map +1 -0
- package/dist/openai/core/Platform.d.ts +8 -0
- package/dist/openai/core/Platform.d.ts.map +1 -0
- package/dist/openai/core/Platform.js +8 -0
- package/dist/openai/core/Platform.js.map +1 -0
- package/dist/openai/globals.d.ts +12 -0
- package/dist/openai/globals.d.ts.map +1 -0
- package/dist/openai/globals.js +2 -0
- package/dist/openai/globals.js.map +1 -0
- package/dist/openai/index.d.ts +3 -0
- package/dist/openai/index.d.ts.map +1 -0
- package/dist/openai/index.js +3 -0
- package/dist/openai/index.js.map +1 -0
- package/dist/openai/link/ToolCallLink.d.ts +28 -0
- package/dist/openai/link/ToolCallLink.d.ts.map +1 -0
- package/dist/openai/link/ToolCallLink.js +35 -0
- package/dist/openai/link/ToolCallLink.js.map +1 -0
- package/dist/openai/react/hooks/useApolloClient.d.ts +3 -0
- package/dist/openai/react/hooks/useApolloClient.d.ts.map +1 -0
- package/dist/openai/react/hooks/useApolloClient.js +9 -0
- package/dist/openai/react/hooks/useApolloClient.js.map +1 -0
- package/dist/openai/react/hooks/useApp.d.ts +2 -0
- package/dist/openai/react/hooks/useApp.d.ts.map +1 -0
- package/dist/openai/react/hooks/useApp.js +5 -0
- package/dist/openai/react/hooks/useApp.js.map +1 -0
- package/dist/openai/react/hooks/useOpenAiGlobal.d.ts +3 -0
- package/dist/openai/react/hooks/useOpenAiGlobal.d.ts.map +1 -0
- package/dist/{react → openai/react}/hooks/useOpenAiGlobal.js +1 -1
- package/dist/openai/react/hooks/useOpenAiGlobal.js.map +1 -0
- package/dist/openai/react/hooks/useToolInput.d.ts +2 -0
- package/dist/openai/react/hooks/useToolInput.d.ts.map +1 -0
- package/dist/openai/react/hooks/useToolInput.js +5 -0
- package/dist/openai/react/hooks/useToolInput.js.map +1 -0
- package/dist/openai/react/hooks/useToolMetadata.d.ts +2 -0
- package/dist/openai/react/hooks/useToolMetadata.d.ts.map +1 -0
- package/dist/openai/react/hooks/useToolMetadata.js +5 -0
- package/dist/openai/react/hooks/useToolMetadata.js.map +1 -0
- package/dist/openai/react/hooks/useToolName.d.ts.map +1 -0
- package/dist/openai/react/hooks/useToolName.js +5 -0
- package/dist/openai/react/hooks/useToolName.js.map +1 -0
- package/dist/{react → openai/react}/hooks/useWidgetState.d.ts +1 -1
- package/dist/openai/react/hooks/useWidgetState.d.ts.map +1 -0
- package/dist/openai/react/hooks/useWidgetState.js.map +1 -0
- package/dist/openai/react/index.d.ts +6 -0
- package/dist/openai/react/index.d.ts.map +1 -0
- package/dist/openai/react/index.js +6 -0
- package/dist/openai/react/index.js.map +1 -0
- package/dist/{types/openai.d.ts → openai/types.d.ts} +7 -11
- package/dist/openai/types.d.ts.map +1 -0
- package/dist/{types/openai.js → openai/types.js} +1 -1
- package/dist/openai/types.js.map +1 -0
- package/dist/react/ApolloProvider.d.ts +6 -2
- package/dist/react/ApolloProvider.d.ts.map +1 -1
- package/dist/react/ApolloProvider.js +12 -27
- package/dist/react/ApolloProvider.js.map +1 -1
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +9 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mcp.d.ts +3 -0
- package/dist/react/index.mcp.d.ts.map +1 -0
- package/dist/react/index.mcp.js +3 -0
- package/dist/react/index.mcp.js.map +1 -0
- package/dist/react/index.openai.d.ts +3 -0
- package/dist/react/index.openai.d.ts.map +1 -0
- package/dist/react/index.openai.js +3 -0
- package/dist/react/index.openai.js.map +1 -0
- package/dist/react/missingHook.d.ts +2 -0
- package/dist/react/missingHook.d.ts.map +1 -0
- package/dist/react/missingHook.js +6 -0
- package/dist/react/missingHook.js.map +1 -0
- package/dist/tsconfig/core/tsconfig.json +5 -0
- package/dist/tsconfig/mcp/tsconfig.json +6 -0
- package/dist/tsconfig/openai/tsconfig.json +7 -0
- package/dist/types/application-manifest.d.ts +13 -1
- package/dist/types/application-manifest.d.ts.map +1 -1
- package/dist/types/application-manifest.js.map +1 -1
- package/dist/utilities/cacheAsync.d.ts +4 -0
- package/dist/utilities/cacheAsync.d.ts.map +1 -0
- package/dist/utilities/cacheAsync.js +19 -0
- package/dist/utilities/cacheAsync.js.map +1 -0
- package/dist/utilities/constants.d.ts +6 -0
- package/dist/utilities/constants.d.ts.map +1 -0
- package/dist/utilities/constants.js +6 -0
- package/dist/utilities/constants.js.map +1 -0
- package/dist/utilities/emptyModule.d.ts +2 -0
- package/dist/utilities/emptyModule.d.ts.map +1 -0
- package/dist/utilities/emptyModule.js +2 -0
- package/dist/utilities/emptyModule.js.map +1 -0
- package/dist/utilities/getVariablesForOperationFromToolInput.d.ts +5 -0
- package/dist/utilities/getVariablesForOperationFromToolInput.d.ts.map +1 -0
- package/dist/utilities/getVariablesForOperationFromToolInput.js +18 -0
- package/dist/utilities/getVariablesForOperationFromToolInput.js.map +1 -0
- package/dist/utilities/index.d.ts +6 -0
- package/dist/utilities/index.d.ts.map +1 -0
- package/dist/utilities/index.js +6 -0
- package/dist/utilities/index.js.map +1 -0
- package/dist/utilities/invariant.d.ts +2 -0
- package/dist/utilities/invariant.d.ts.map +1 -0
- package/dist/utilities/invariant.js +6 -0
- package/dist/utilities/invariant.js.map +1 -0
- package/dist/utilities/promiseWithResolvers.d.ts +7 -0
- package/dist/utilities/promiseWithResolvers.d.ts.map +1 -0
- package/dist/utilities/promiseWithResolvers.js +16 -0
- package/dist/utilities/promiseWithResolvers.js.map +1 -0
- package/dist/vite/__tests__/utilities/build.d.ts +41 -0
- package/dist/vite/__tests__/utilities/build.d.ts.map +1 -0
- package/dist/vite/__tests__/utilities/build.js +63 -0
- package/dist/vite/__tests__/utilities/build.js.map +1 -0
- package/dist/vite/apolloClientAiApps.d.ts +14 -0
- package/dist/vite/apolloClientAiApps.d.ts.map +1 -0
- package/dist/vite/apolloClientAiApps.js +350 -0
- package/dist/vite/apolloClientAiApps.js.map +1 -0
- package/dist/vite/index.d.ts +1 -2
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +1 -2
- package/dist/vite/index.js.map +1 -1
- package/dist/vite/utilities/config.d.ts +2 -0
- package/dist/vite/utilities/config.d.ts.map +1 -0
- package/dist/vite/utilities/config.js +11 -0
- package/dist/vite/utilities/config.js.map +1 -0
- package/dist/vite/utilities/graphql.d.ts +20 -0
- package/dist/vite/utilities/graphql.d.ts.map +1 -0
- package/dist/vite/utilities/graphql.js +42 -0
- package/dist/vite/utilities/graphql.js.map +1 -0
- package/knope.toml +1 -1
- package/package.json +109 -12
- package/src/config/defineConfig.ts +8 -0
- package/src/config/index.ts +2 -0
- package/src/config/schema.ts +73 -0
- package/src/config/types.ts +7 -0
- package/src/core/ApolloClient.ts +7 -95
- package/src/core/Platform.ts +27 -0
- package/src/core/types.ts +14 -0
- package/src/index.mcp.ts +5 -0
- package/src/index.openai.ts +5 -0
- package/src/index.ts +4 -28
- package/src/link/ToolCallLink.ts +6 -22
- package/src/mcp/core/ApolloClient.ts +102 -0
- package/src/mcp/core/McpAppManager.ts +98 -0
- package/src/mcp/core/Platform.ts +11 -0
- package/src/mcp/core/__tests__/ApolloClient.test.ts +464 -0
- package/src/mcp/index.ts +2 -0
- package/src/mcp/link/ToolCallLink.ts +40 -0
- package/src/mcp/link/__tests__/ToolCallLink.test.ts +53 -0
- package/src/mcp/react/hooks/__tests__/useApp.test.tsx +46 -0
- package/src/mcp/react/hooks/__tests__/useToolInput.test.tsx +50 -0
- package/src/mcp/react/hooks/__tests__/useToolMetadata.test.tsx +53 -0
- package/src/mcp/react/hooks/__tests__/useToolName.test.tsx +50 -0
- package/src/mcp/react/hooks/useApolloClient.ts +14 -0
- package/src/mcp/react/hooks/useApp.ts +5 -0
- package/src/mcp/react/hooks/useToolInput.ts +5 -0
- package/src/mcp/react/hooks/useToolMetadata.ts +5 -0
- package/src/mcp/react/hooks/useToolName.ts +5 -0
- package/src/mcp/react/index.ts +4 -0
- package/src/openai/core/ApolloClient.ts +100 -0
- package/src/openai/core/McpAppManager.ts +110 -0
- package/src/openai/core/Platform.ts +11 -0
- package/src/openai/core/__tests__/ApolloClient.test.ts +537 -0
- package/src/openai/globals.ts +14 -0
- package/src/openai/index.ts +2 -0
- package/src/openai/link/ToolCallLink.ts +40 -0
- package/src/{react → openai/react}/hooks/__tests__/useOpenAiGlobal.test.ts +1 -1
- package/src/openai/react/hooks/__tests__/useToolInput.test.tsx +85 -0
- package/src/openai/react/hooks/__tests__/useToolMetadata.test.tsx +86 -0
- package/src/openai/react/hooks/__tests__/useToolName.test.tsx +50 -0
- package/src/{react → openai/react}/hooks/__tests__/useWidgetState.test.tsx +1 -1
- package/src/openai/react/hooks/useApolloClient.ts +14 -0
- package/src/openai/react/hooks/useApp.ts +5 -0
- package/src/{react → openai/react}/hooks/useOpenAiGlobal.ts +2 -2
- package/src/openai/react/hooks/useToolInput.ts +5 -0
- package/src/openai/react/hooks/useToolMetadata.ts +5 -0
- package/src/openai/react/hooks/useToolName.ts +5 -0
- package/src/{react → openai/react}/hooks/useWidgetState.ts +1 -1
- package/src/openai/react/index.ts +5 -0
- package/src/{types/openai.ts → openai/types.ts} +9 -13
- package/src/react/ApolloProvider.tsx +23 -31
- package/src/react/__tests__/ApolloProvider/mcp.test.tsx +74 -0
- package/src/react/__tests__/ApolloProvider/openai.test.tsx +146 -0
- package/src/react/index.mcp.ts +7 -0
- package/src/react/index.openai.ts +7 -0
- package/src/react/index.ts +19 -0
- package/src/react/missingHook.ts +9 -0
- package/src/testing/internal/index.ts +8 -0
- package/src/testing/internal/matchers/index.ts +2 -0
- package/src/testing/internal/matchers/toComplete.ts +46 -0
- package/src/testing/internal/matchers/toEmitValue.ts +71 -0
- package/src/testing/internal/matchers/types.ts +3 -0
- package/src/testing/internal/mcp/graphqlToolResult.ts +31 -0
- package/src/testing/internal/mcp/minimalHostContextWithToolName.ts +9 -0
- package/src/testing/internal/mcp/mockMcpHost.ts +188 -0
- package/src/testing/internal/openai/dispatchStateChange.ts +1 -1
- package/src/testing/internal/openai/stubOpenAiGlobals.ts +22 -9
- package/src/testing/internal/react/renderAsync.ts +7 -0
- package/src/testing/internal/utilities/ObservableStream.ts +172 -0
- package/src/testing/internal/utilities/getSerializableProperties.ts +55 -0
- package/src/testing/internal/utilities/mockApplicationManifest.ts +39 -0
- package/src/testing/internal/utilities/spyOnConsole.ts +29 -0
- package/src/testing/internal/utilities/wait.ts +3 -0
- package/src/tsconfig/core/tsconfig.json +5 -0
- package/src/tsconfig/mcp/tsconfig.json +6 -0
- package/src/tsconfig/openai/tsconfig.json +7 -0
- package/src/types/application-manifest.ts +16 -1
- package/src/utilities/__tests__/cacheAsync.test.ts +64 -0
- package/src/utilities/cacheAsync.ts +25 -0
- package/src/utilities/constants.ts +5 -0
- package/src/utilities/emptyModule.ts +1 -0
- package/src/utilities/getVariablesForOperationFromToolInput.ts +27 -0
- package/src/utilities/index.ts +5 -0
- package/src/utilities/invariant.ts +5 -0
- package/src/utilities/promiseWithResolvers.ts +18 -0
- package/src/vite/__tests__/apolloClientAiApps.test.ts +1521 -0
- package/src/vite/__tests__/utilities/build.ts +72 -0
- package/src/vite/apolloClientAiApps.ts +515 -0
- package/src/vite/index.ts +1 -2
- package/src/vite/utilities/config.ts +13 -0
- package/src/vite/utilities/graphql.ts +123 -0
- package/tsconfig.base.json +2 -2
- package/tsconfig.vite.build.json +4 -1
- package/tsconfig.vite.json +8 -2
- package/vitest-setup.ts +28 -0
- package/dist/react/context/ToolUseContext.d.ts +0 -16
- package/dist/react/context/ToolUseContext.d.ts.map +0 -1
- package/dist/react/context/ToolUseContext.js +0 -11
- package/dist/react/context/ToolUseContext.js.map +0 -1
- package/dist/react/hooks/useCallTool.d.ts +0 -4
- package/dist/react/hooks/useCallTool.d.ts.map +0 -1
- package/dist/react/hooks/useCallTool.js +0 -5
- package/dist/react/hooks/useCallTool.js.map +0 -1
- package/dist/react/hooks/useOpenAiGlobal.d.ts +0 -3
- package/dist/react/hooks/useOpenAiGlobal.d.ts.map +0 -1
- package/dist/react/hooks/useOpenAiGlobal.js.map +0 -1
- package/dist/react/hooks/useOpenExternal.d.ts +0 -4
- package/dist/react/hooks/useOpenExternal.d.ts.map +0 -1
- package/dist/react/hooks/useOpenExternal.js +0 -5
- package/dist/react/hooks/useOpenExternal.js.map +0 -1
- package/dist/react/hooks/useRequestDisplayMode.d.ts +0 -7
- package/dist/react/hooks/useRequestDisplayMode.d.ts.map +0 -1
- package/dist/react/hooks/useRequestDisplayMode.js +0 -6
- package/dist/react/hooks/useRequestDisplayMode.js.map +0 -1
- package/dist/react/hooks/useSendFollowUpMessage.d.ts +0 -2
- package/dist/react/hooks/useSendFollowUpMessage.d.ts.map +0 -1
- package/dist/react/hooks/useSendFollowUpMessage.js +0 -8
- package/dist/react/hooks/useSendFollowUpMessage.js.map +0 -1
- package/dist/react/hooks/useToolEffect.d.ts +0 -3
- package/dist/react/hooks/useToolEffect.d.ts.map +0 -1
- package/dist/react/hooks/useToolEffect.js +0 -28
- package/dist/react/hooks/useToolEffect.js.map +0 -1
- package/dist/react/hooks/useToolInput.d.ts +0 -2
- package/dist/react/hooks/useToolInput.d.ts.map +0 -1
- package/dist/react/hooks/useToolInput.js +0 -6
- package/dist/react/hooks/useToolInput.js.map +0 -1
- package/dist/react/hooks/useToolName.d.ts.map +0 -1
- package/dist/react/hooks/useToolName.js +0 -6
- package/dist/react/hooks/useToolName.js.map +0 -1
- package/dist/react/hooks/useToolOutput.d.ts +0 -2
- package/dist/react/hooks/useToolOutput.d.ts.map +0 -1
- package/dist/react/hooks/useToolOutput.js +0 -5
- package/dist/react/hooks/useToolOutput.js.map +0 -1
- package/dist/react/hooks/useToolResponseMetadata.d.ts +0 -2
- package/dist/react/hooks/useToolResponseMetadata.d.ts.map +0 -1
- package/dist/react/hooks/useToolResponseMetadata.js +0 -5
- package/dist/react/hooks/useToolResponseMetadata.js.map +0 -1
- package/dist/react/hooks/useWidgetState.d.ts.map +0 -1
- package/dist/react/hooks/useWidgetState.js.map +0 -1
- package/dist/types/openai.d.ts.map +0 -1
- package/dist/types/openai.js.map +0 -1
- package/dist/vite/absolute_asset_imports_plugin.d.ts +0 -5
- package/dist/vite/absolute_asset_imports_plugin.d.ts.map +0 -1
- package/dist/vite/absolute_asset_imports_plugin.js +0 -17
- package/dist/vite/absolute_asset_imports_plugin.js.map +0 -1
- package/dist/vite/application_manifest_plugin.d.ts +0 -10
- package/dist/vite/application_manifest_plugin.d.ts.map +0 -1
- package/dist/vite/application_manifest_plugin.js +0 -274
- package/dist/vite/application_manifest_plugin.js.map +0 -1
- package/src/core/__tests__/ApolloClient.test.ts +0 -626
- package/src/react/__tests__/ApolloProvider.test.tsx +0 -41
- package/src/react/context/ToolUseContext.tsx +0 -31
- package/src/react/hooks/__tests__/useCallTool.test.ts +0 -46
- package/src/react/hooks/__tests__/useOpenExternal.test.tsx +0 -24
- package/src/react/hooks/__tests__/useRequestDisplayMode.test.ts +0 -17
- package/src/react/hooks/__tests__/useSendFollowUpMessage.test.ts +0 -15
- package/src/react/hooks/__tests__/useToolEffect.test.tsx +0 -67
- package/src/react/hooks/__tests__/useToolInput.test.ts +0 -13
- package/src/react/hooks/__tests__/useToolName.test.ts +0 -13
- package/src/react/hooks/__tests__/useToolOutput.test.tsx +0 -49
- package/src/react/hooks/__tests__/useToolResponseMetadata.test.tsx +0 -49
- package/src/react/hooks/useCallTool.ts +0 -13
- package/src/react/hooks/useOpenExternal.ts +0 -11
- package/src/react/hooks/useRequestDisplayMode.ts +0 -7
- package/src/react/hooks/useSendFollowUpMessage.ts +0 -7
- package/src/react/hooks/useToolEffect.tsx +0 -37
- package/src/react/hooks/useToolInput.ts +0 -7
- package/src/react/hooks/useToolName.ts +0 -7
- package/src/react/hooks/useToolOutput.ts +0 -5
- package/src/react/hooks/useToolResponseMetadata.ts +0 -5
- package/src/vite/__tests__/absolute_asset_imports_plugin.test.ts +0 -102
- package/src/vite/__tests__/application_manifest_plugin.test.ts +0 -1038
- package/src/vite/absolute_asset_imports_plugin.ts +0 -22
- package/src/vite/application_manifest_plugin.ts +0 -443
- /package/dist/{react → openai/react}/hooks/useToolName.d.ts +0 -0
- /package/dist/{react → openai/react}/hooks/useWidgetState.js +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { build, createServer, type InlineConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
type Plugins = NonNullable<InlineConfig["plugins"]>;
|
|
6
|
+
|
|
7
|
+
export async function setupServer(config: InlineConfig & { plugins: Plugins }) {
|
|
8
|
+
const server = await createServer({
|
|
9
|
+
configFile: false,
|
|
10
|
+
server: {
|
|
11
|
+
port: 3333,
|
|
12
|
+
...config.server,
|
|
13
|
+
},
|
|
14
|
+
...config,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
...server,
|
|
19
|
+
[Symbol.asyncDispose]() {
|
|
20
|
+
return server.close();
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function buildApp(
|
|
26
|
+
config: Omit<InlineConfig, "configFile" | "plugins"> & {
|
|
27
|
+
plugins: Plugins;
|
|
28
|
+
}
|
|
29
|
+
) {
|
|
30
|
+
await build({
|
|
31
|
+
configFile: false,
|
|
32
|
+
logLevel: "silent",
|
|
33
|
+
...config,
|
|
34
|
+
build: {
|
|
35
|
+
emptyOutDir: false,
|
|
36
|
+
outDir: "dist",
|
|
37
|
+
...config.build,
|
|
38
|
+
rollupOptions: {
|
|
39
|
+
input: config.build?.rollupOptions?.input ?? "virtual:entry",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
plugins: [
|
|
43
|
+
...config.plugins,
|
|
44
|
+
|
|
45
|
+
// We need to use `fs` to resolve modules to ensure vite uses memfs when
|
|
46
|
+
// building, otherwise we get an ENOENT error for any files written to the
|
|
47
|
+
// virtual filesystem.
|
|
48
|
+
{
|
|
49
|
+
name: "test:virtual-entry",
|
|
50
|
+
resolveId(id) {
|
|
51
|
+
if (id === "virtual:entry") return id;
|
|
52
|
+
if (id.endsWith(".html")) return path.resolve(id);
|
|
53
|
+
|
|
54
|
+
if (id.startsWith("/")) {
|
|
55
|
+
const resolved = path.resolve(id.slice(1));
|
|
56
|
+
|
|
57
|
+
if (fs.existsSync(resolved)) {
|
|
58
|
+
return resolved;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
load(id) {
|
|
63
|
+
if (id === "virtual:entry") return "export default {};";
|
|
64
|
+
|
|
65
|
+
if (fs.existsSync(id)) {
|
|
66
|
+
return fs.readFileSync(id, "utf8");
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defaultClientConditions,
|
|
3
|
+
type Environment,
|
|
4
|
+
type Plugin,
|
|
5
|
+
type ResolvedConfig,
|
|
6
|
+
} from "vite";
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import { ApolloClient, ApolloLink, type DocumentNode } from "@apollo/client";
|
|
11
|
+
import { InMemoryCache } from "@apollo/client";
|
|
12
|
+
import { gqlPluckFromCodeStringSync } from "@graphql-tools/graphql-tag-pluck";
|
|
13
|
+
import { glob } from "glob";
|
|
14
|
+
import { print } from "@apollo/client/utilities";
|
|
15
|
+
import { removeDirectivesFromDocument } from "@apollo/client/utilities/internal";
|
|
16
|
+
import { of } from "rxjs";
|
|
17
|
+
import { Kind, parse, type OperationDefinitionNode } from "graphql";
|
|
18
|
+
import {
|
|
19
|
+
getArgumentValue,
|
|
20
|
+
getDirectiveArgument,
|
|
21
|
+
getTypeName,
|
|
22
|
+
maybeGetArgumentValue,
|
|
23
|
+
} from "./utilities/graphql.js";
|
|
24
|
+
import type {
|
|
25
|
+
ApplicationManifest,
|
|
26
|
+
ManifestOperation,
|
|
27
|
+
} from "../types/application-manifest";
|
|
28
|
+
import { invariant } from "../utilities/invariant.js";
|
|
29
|
+
import { explorer } from "./utilities/config.js";
|
|
30
|
+
import type { ApolloClientAiAppsConfig } from "../config/index.js";
|
|
31
|
+
import { ApolloClientAiAppsConfigSchema } from "../config/schema.js";
|
|
32
|
+
import { z } from "zod";
|
|
33
|
+
|
|
34
|
+
export declare namespace apolloClientAiApps {
|
|
35
|
+
export type Target = ApolloClientAiAppsConfig.AppTarget;
|
|
36
|
+
|
|
37
|
+
export interface Options {
|
|
38
|
+
targets: Target[];
|
|
39
|
+
devTarget?: Target | undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const root = process.cwd();
|
|
44
|
+
|
|
45
|
+
const VALID_TARGETS: apolloClientAiApps.Target[] = ["openai", "mcp"];
|
|
46
|
+
|
|
47
|
+
function isValidTarget(target: unknown): target is apolloClientAiApps.Target {
|
|
48
|
+
return VALID_TARGETS.includes(target as apolloClientAiApps.Target);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function buildExtensions(target: apolloClientAiApps.Target) {
|
|
52
|
+
return [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json"].flatMap(
|
|
53
|
+
(ext) => [`.${target}${ext}`, ext]
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function devTarget(target: string | undefined) {
|
|
58
|
+
invariant(
|
|
59
|
+
target === undefined || isValidTarget(target),
|
|
60
|
+
`devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(", ")}.`
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return target;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface FileCache {
|
|
67
|
+
file: string;
|
|
68
|
+
hash: string;
|
|
69
|
+
operations: ManifestOperation[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function apolloClientAiApps(
|
|
73
|
+
options: apolloClientAiApps.Options
|
|
74
|
+
): Plugin {
|
|
75
|
+
const targets = Array.from(new Set(options.targets));
|
|
76
|
+
const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;
|
|
77
|
+
const cache = new Map<string, FileCache>();
|
|
78
|
+
|
|
79
|
+
let packageJson!: Record<string, any>;
|
|
80
|
+
let config!: ResolvedConfig;
|
|
81
|
+
|
|
82
|
+
invariant(
|
|
83
|
+
Array.isArray(targets) && targets.length > 0,
|
|
84
|
+
"The `targets` option must be a non-empty array"
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
invariant(
|
|
88
|
+
targets.every(isValidTarget),
|
|
89
|
+
`All targets must be one of: ${VALID_TARGETS.join(", ")}`
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const client = new ApolloClient({
|
|
93
|
+
cache: new InMemoryCache(),
|
|
94
|
+
link: processQueryLink,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
async function processFile(file: string) {
|
|
98
|
+
const code = fs.readFileSync(file, "utf-8");
|
|
99
|
+
|
|
100
|
+
if (!code.includes("gql")) return;
|
|
101
|
+
|
|
102
|
+
const fileHash = createHash("md5").update(code).digest("hex");
|
|
103
|
+
if (cache.get(file)?.hash === fileHash) return;
|
|
104
|
+
const sources = gqlPluckFromCodeStringSync(file, code, {
|
|
105
|
+
modules: [
|
|
106
|
+
{ name: "graphql-tag", identifier: "gql" },
|
|
107
|
+
{ name: "@apollo/client", identifier: "gql" },
|
|
108
|
+
],
|
|
109
|
+
}).map((source) => ({
|
|
110
|
+
node: parse(source.body),
|
|
111
|
+
file,
|
|
112
|
+
location: source.locationOffset,
|
|
113
|
+
}));
|
|
114
|
+
|
|
115
|
+
const operations: ManifestOperation[] = [];
|
|
116
|
+
for (const source of sources) {
|
|
117
|
+
const type = (
|
|
118
|
+
source.node.definitions.find(
|
|
119
|
+
(d) => d.kind === "OperationDefinition"
|
|
120
|
+
) as OperationDefinitionNode
|
|
121
|
+
).operation;
|
|
122
|
+
|
|
123
|
+
let result;
|
|
124
|
+
if (type === "query") {
|
|
125
|
+
result = await client.query({
|
|
126
|
+
query: source.node,
|
|
127
|
+
fetchPolicy: "no-cache",
|
|
128
|
+
});
|
|
129
|
+
} else if (type === "mutation") {
|
|
130
|
+
result = await client.mutate({
|
|
131
|
+
mutation: source.node,
|
|
132
|
+
fetchPolicy: "no-cache",
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
throw new Error(
|
|
136
|
+
"Found an unsupported operation type. Only Query and Mutation are supported."
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
operations.push(result.data as ManifestOperation);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
cache.set(file, {
|
|
143
|
+
file: file,
|
|
144
|
+
hash: fileHash,
|
|
145
|
+
operations,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function generateManifest(environment?: Environment) {
|
|
150
|
+
const appsConfig = await getAppsConfig();
|
|
151
|
+
const operations = Array.from(cache.values()).flatMap(
|
|
152
|
+
(entry) => entry.operations
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
invariant(
|
|
156
|
+
operations.filter((o) => o.prefetch).length <= 1,
|
|
157
|
+
"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`."
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
function getBuildResourceForTarget(target: apolloClientAiApps.Target) {
|
|
161
|
+
const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);
|
|
162
|
+
|
|
163
|
+
if (entryPoint) {
|
|
164
|
+
return entryPoint;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (config.mode === "production") {
|
|
168
|
+
return `${target}/index.html`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
throw new Error(
|
|
172
|
+
`No entry point found for mode "${config.mode}". Entry points other than "development" and "production" must be defined in package.json file.`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
let resource: ApplicationManifest["resource"];
|
|
177
|
+
if (config.command === "serve") {
|
|
178
|
+
// Dev mode: resource is a string (dev server URL)
|
|
179
|
+
resource =
|
|
180
|
+
getResourceFromConfig(appsConfig, config.mode, devTarget!) ??
|
|
181
|
+
`http${config.server.https ? "s" : ""}://${config.server.host ?? "localhost"}:${config.server.port}`;
|
|
182
|
+
} else {
|
|
183
|
+
resource = Object.fromEntries(
|
|
184
|
+
targets.map((target) => [target, getBuildResourceForTarget(target)])
|
|
185
|
+
) as { mcp?: string; openai?: string };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const manifest: ApplicationManifest = {
|
|
189
|
+
format: "apollo-ai-app-manifest",
|
|
190
|
+
version: "1",
|
|
191
|
+
appVersion: appsConfig.version ?? packageJson.version,
|
|
192
|
+
name: appsConfig.name ?? packageJson.name,
|
|
193
|
+
description: appsConfig.description ?? packageJson.description,
|
|
194
|
+
hash: createHash("sha256").update(Date.now().toString()).digest("hex"),
|
|
195
|
+
operations: Array.from(cache.values()).flatMap(
|
|
196
|
+
(entry) => entry.operations
|
|
197
|
+
),
|
|
198
|
+
resource,
|
|
199
|
+
csp: {
|
|
200
|
+
connectDomains: appsConfig.csp?.connectDomains ?? [],
|
|
201
|
+
frameDomains: appsConfig.csp?.frameDomains ?? [],
|
|
202
|
+
redirectDomains: appsConfig.csp?.redirectDomains ?? [],
|
|
203
|
+
resourceDomains: appsConfig.csp?.resourceDomains ?? [],
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
if (isNonEmptyObject(appsConfig.widgetSettings)) {
|
|
208
|
+
manifest.widgetSettings = appsConfig.widgetSettings;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (isNonEmptyObject(appsConfig.labels)) {
|
|
212
|
+
manifest.labels = appsConfig.labels;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// We create mcp and openai environments in order to write to
|
|
216
|
+
// subdirectories, but we want the manifest to be in the root outDir. If we
|
|
217
|
+
// are running in a different environment, we'll put it in the configured
|
|
218
|
+
// outDir directly instead.
|
|
219
|
+
const outDir =
|
|
220
|
+
environment?.name === "mcp" || environment?.name === "openai" ?
|
|
221
|
+
path.resolve(config.build.outDir, "../")
|
|
222
|
+
: config.build.outDir;
|
|
223
|
+
|
|
224
|
+
// Always write to build directory so the MCP server picks it up
|
|
225
|
+
const dest = path.resolve(root, outDir, ".application-manifest.json");
|
|
226
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
227
|
+
fs.writeFileSync(dest, JSON.stringify(manifest));
|
|
228
|
+
|
|
229
|
+
// Always write to the dev location so that the app can bundle the manifest content
|
|
230
|
+
fs.writeFileSync(".application-manifest.json", JSON.stringify(manifest));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
name: "@apollo/client-ai-apps/vite",
|
|
235
|
+
async buildStart() {
|
|
236
|
+
// Read package.json on start
|
|
237
|
+
packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
|
|
238
|
+
|
|
239
|
+
// Scan all files on startup
|
|
240
|
+
const files = await glob("./src/**/*.{ts,tsx,js,jsx}", { fs });
|
|
241
|
+
|
|
242
|
+
for (const file of files) {
|
|
243
|
+
const fullPath = path.resolve(root, file);
|
|
244
|
+
await processFile(fullPath);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.
|
|
248
|
+
if (config.command === "serve") {
|
|
249
|
+
await generateManifest(this.environment);
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
configResolved(resolvedConfig) {
|
|
253
|
+
config = resolvedConfig;
|
|
254
|
+
},
|
|
255
|
+
configEnvironment(name, { build }) {
|
|
256
|
+
if (!targets.includes(name as any)) return;
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
build: {
|
|
260
|
+
outDir: path.join(build?.outDir ?? "dist", name),
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
},
|
|
264
|
+
configureServer(server) {
|
|
265
|
+
server.watcher.on("change", async (file) => {
|
|
266
|
+
if (file.endsWith("package.json")) {
|
|
267
|
+
packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
|
|
268
|
+
await generateManifest();
|
|
269
|
+
} else if (file.match(/\.?apollo-client-ai-apps\.config\.\w+$/)) {
|
|
270
|
+
explorer.clearCaches();
|
|
271
|
+
await generateManifest();
|
|
272
|
+
} else if (file.match(/\.(jsx?|tsx?)$/)) {
|
|
273
|
+
await processFile(file);
|
|
274
|
+
await generateManifest();
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
config(_, { command }) {
|
|
280
|
+
if (command === "serve") {
|
|
281
|
+
invariant(
|
|
282
|
+
isValidTarget(devTarget) || targets.length === 1,
|
|
283
|
+
"`devTarget` must be set for development when using multiple targets."
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const target = devTarget ?? targets[0];
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
resolve: {
|
|
290
|
+
extensions: buildExtensions(target),
|
|
291
|
+
conditions: [target, ...defaultClientConditions],
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
environments: Object.fromEntries(
|
|
298
|
+
targets.map((target) => [
|
|
299
|
+
target,
|
|
300
|
+
{
|
|
301
|
+
consumer: "client",
|
|
302
|
+
webCompatible: true,
|
|
303
|
+
resolve: {
|
|
304
|
+
extensions: buildExtensions(target),
|
|
305
|
+
conditions: [target, ...defaultClientConditions],
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
])
|
|
309
|
+
),
|
|
310
|
+
builder: {
|
|
311
|
+
buildApp: async (builder) => {
|
|
312
|
+
await Promise.all(
|
|
313
|
+
targets.map((target) =>
|
|
314
|
+
builder.build(builder.environments[target])
|
|
315
|
+
)
|
|
316
|
+
);
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
transformIndexHtml(html, ctx) {
|
|
322
|
+
if (!ctx.server) return html;
|
|
323
|
+
|
|
324
|
+
let baseUrl = (
|
|
325
|
+
ctx.server.config?.server?.origin ??
|
|
326
|
+
ctx.server.resolvedUrls?.local[0] ??
|
|
327
|
+
""
|
|
328
|
+
).replace(/\/$/, "");
|
|
329
|
+
baseUrl = baseUrl.replace(/\/$/, "");
|
|
330
|
+
|
|
331
|
+
return (
|
|
332
|
+
html
|
|
333
|
+
// import "/@vite/..." or "/@react-refresh"
|
|
334
|
+
.replace(/(from\s+["'])\/([^"']+)/g, `$1${baseUrl}/$2`)
|
|
335
|
+
// src="/src/..."
|
|
336
|
+
.replace(/(src=["'])\/([^"']+)/gi, `$1${baseUrl}/$2`)
|
|
337
|
+
);
|
|
338
|
+
},
|
|
339
|
+
async writeBundle() {
|
|
340
|
+
await generateManifest(this.environment);
|
|
341
|
+
},
|
|
342
|
+
} satisfies Plugin;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const processQueryLink = new ApolloLink((operation) => {
|
|
346
|
+
const body = print(
|
|
347
|
+
removeManifestDirectives(sortTopLevelDefinitions(operation.query))
|
|
348
|
+
);
|
|
349
|
+
const name = operation.operationName;
|
|
350
|
+
const definition = operation.query.definitions.find(
|
|
351
|
+
(d) => d.kind === "OperationDefinition"
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
// Use `operation.query` so that the error reflects the end-user defined
|
|
355
|
+
// document, not our sorted one
|
|
356
|
+
invariant(
|
|
357
|
+
definition,
|
|
358
|
+
`Document does not contain an operation:\n${print(operation.query)}`
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
const { directives, operation: type } = definition;
|
|
362
|
+
|
|
363
|
+
const variables = definition.variableDefinitions?.reduce(
|
|
364
|
+
(obj, varDef) => ({
|
|
365
|
+
...obj,
|
|
366
|
+
[varDef.variable.name.value]: getTypeName(varDef.type),
|
|
367
|
+
}),
|
|
368
|
+
{}
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
const prefetch = directives?.some((d) => d.name.value === "prefetch");
|
|
372
|
+
const id = createHash("sha256").update(body).digest("hex");
|
|
373
|
+
// 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
|
|
374
|
+
const prefetchID = prefetch ? "__anonymous" : undefined;
|
|
375
|
+
|
|
376
|
+
const tools = directives
|
|
377
|
+
?.filter((d) => d.name.value === "tool")
|
|
378
|
+
.map((directive) => {
|
|
379
|
+
const result = ToolDirectiveSchema.safeParse({
|
|
380
|
+
name: getArgumentValue(
|
|
381
|
+
getDirectiveArgument("name", directive, { required: true }),
|
|
382
|
+
Kind.STRING
|
|
383
|
+
),
|
|
384
|
+
description: getArgumentValue(
|
|
385
|
+
getDirectiveArgument("description", directive, { required: true }),
|
|
386
|
+
Kind.STRING
|
|
387
|
+
),
|
|
388
|
+
extraInputs: maybeGetArgumentValue(
|
|
389
|
+
getDirectiveArgument("extraInputs", directive),
|
|
390
|
+
Kind.LIST
|
|
391
|
+
),
|
|
392
|
+
labels: maybeGetArgumentValue(
|
|
393
|
+
getDirectiveArgument("labels", directive),
|
|
394
|
+
Kind.OBJECT
|
|
395
|
+
),
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
if (result.error) {
|
|
399
|
+
throw z.prettifyError(result.error);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return result.data;
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// TODO: Make this object satisfy the `ManifestOperation` type. Currently
|
|
406
|
+
// it errors because we need more validation on a few of these fields
|
|
407
|
+
return of({
|
|
408
|
+
data: { id, name, type, body, variables, prefetch, prefetchID, tools },
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
function removeManifestDirectives(doc: DocumentNode) {
|
|
413
|
+
return removeDirectivesFromDocument(
|
|
414
|
+
[{ name: "prefetch" }, { name: "tool" }],
|
|
415
|
+
doc
|
|
416
|
+
)!;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Sort the definitions in this document so that operations come before fragments,
|
|
420
|
+
// and so that each kind of definition is sorted by name.
|
|
421
|
+
export function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {
|
|
422
|
+
const definitions = [...query.definitions];
|
|
423
|
+
// We want to avoid unnecessary dependencies, so write out a comparison
|
|
424
|
+
// function instead of using _.orderBy.
|
|
425
|
+
definitions.sort((a, b) => {
|
|
426
|
+
// This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.
|
|
427
|
+
if (a.kind > b.kind) {
|
|
428
|
+
return -1;
|
|
429
|
+
}
|
|
430
|
+
if (a.kind < b.kind) {
|
|
431
|
+
return 1;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Extract the name from each definition. Jump through some hoops because
|
|
435
|
+
// non-executable definitions don't have to have names (even though any
|
|
436
|
+
// DocumentNode actually passed here should only have executable
|
|
437
|
+
// definitions).
|
|
438
|
+
const aName =
|
|
439
|
+
a.kind === "OperationDefinition" || a.kind === "FragmentDefinition" ?
|
|
440
|
+
(a.name?.value ?? "")
|
|
441
|
+
: "";
|
|
442
|
+
const bName =
|
|
443
|
+
b.kind === "OperationDefinition" || b.kind === "FragmentDefinition" ?
|
|
444
|
+
(b.name?.value ?? "")
|
|
445
|
+
: "";
|
|
446
|
+
|
|
447
|
+
// Sort by name ascending.
|
|
448
|
+
if (aName < bName) {
|
|
449
|
+
return -1;
|
|
450
|
+
}
|
|
451
|
+
if (aName > bName) {
|
|
452
|
+
return 1;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Assuming that the document is "valid", no operation or fragment name can appear
|
|
456
|
+
// more than once, so we don't need to differentiate further to have a deterministic
|
|
457
|
+
// sort.
|
|
458
|
+
return 0;
|
|
459
|
+
});
|
|
460
|
+
return {
|
|
461
|
+
...query,
|
|
462
|
+
definitions,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function isNonEmptyObject<T extends object>(
|
|
467
|
+
obj: T | null | undefined
|
|
468
|
+
): obj is T {
|
|
469
|
+
return !!obj && Object.keys(obj).length > 0;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
async function getAppsConfig(): Promise<ApolloClientAiAppsConfig.Config> {
|
|
473
|
+
const result = await explorer.search();
|
|
474
|
+
const config = (result?.config ??
|
|
475
|
+
{}) as Partial<ApolloClientAiAppsConfig.Config>;
|
|
476
|
+
|
|
477
|
+
const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);
|
|
478
|
+
|
|
479
|
+
if (parsed.error) {
|
|
480
|
+
throw z.prettifyError(parsed.error);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return parsed.data;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function getResourceFromConfig(
|
|
487
|
+
appsConfig: ApolloClientAiAppsConfig.Config,
|
|
488
|
+
mode: string,
|
|
489
|
+
target: apolloClientAiApps.Target
|
|
490
|
+
) {
|
|
491
|
+
if (!appsConfig.entry || !appsConfig.entry[mode]) {
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const config = appsConfig.entry[mode];
|
|
496
|
+
|
|
497
|
+
return typeof config === "string" ? config : config[target];
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const ToolDirectiveSchema = z.strictObject({
|
|
501
|
+
name: z.stringFormat("toolName", (value) => value.indexOf(" ") === -1, {
|
|
502
|
+
error: (iss) => `Tool with name "${iss.input}" must not contain spaces`,
|
|
503
|
+
}),
|
|
504
|
+
description: z.string(),
|
|
505
|
+
extraInputs: z.optional(
|
|
506
|
+
z.array(
|
|
507
|
+
z.strictObject({
|
|
508
|
+
name: z.string(),
|
|
509
|
+
description: z.string(),
|
|
510
|
+
type: z.literal(["string", "boolean", "number"]),
|
|
511
|
+
})
|
|
512
|
+
)
|
|
513
|
+
),
|
|
514
|
+
labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),
|
|
515
|
+
});
|
package/src/vite/index.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from "./absolute_asset_imports_plugin.js";
|
|
1
|
+
export { apolloClientAiApps, devTarget } from "./apolloClientAiApps.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cosmiconfig } from "cosmiconfig";
|
|
2
|
+
|
|
3
|
+
const moduleName = "apollo-client-ai-apps";
|
|
4
|
+
|
|
5
|
+
const supportedExtensions = ["json", "yml", "yaml", "js", "ts", "cjs", "mjs"];
|
|
6
|
+
const searchPlaces = supportedExtensions
|
|
7
|
+
.flatMap((extension) => [
|
|
8
|
+
`.${moduleName}.config.${extension}`,
|
|
9
|
+
`${moduleName}.config.${extension}`,
|
|
10
|
+
])
|
|
11
|
+
.concat("package.json");
|
|
12
|
+
|
|
13
|
+
export const explorer = cosmiconfig(moduleName, { searchPlaces });
|