@apollo/client-ai-apps 0.2.4 → 0.3.1
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/.git-blame-ignore-revs +2 -0
- package/.github/workflows/compare-build-output.yml +28 -0
- package/.github/workflows/pr.yaml +23 -15
- package/.github/workflows/release.yaml +46 -46
- package/.prettierrc +9 -0
- package/config/compare-build-output-to.sh +90 -0
- package/dist/core/ApolloClient.d.ts +14 -0
- package/dist/index.d.ts +17 -10
- package/dist/index.js +164 -62
- package/dist/link/ToolCallLink.d.ts +26 -0
- package/dist/react/ApolloProvider.d.ts +9 -0
- package/dist/react/context/ToolUseContext.d.ts +15 -0
- package/dist/{hooks → react/hooks}/useOpenAiGlobal.d.ts +1 -1
- package/dist/react/hooks/useOpenExternal.d.ts +3 -0
- package/dist/{hooks → react/hooks}/useRequestDisplayMode.d.ts +1 -1
- package/dist/{hooks → react/hooks}/useToolEffect.d.ts +0 -4
- package/dist/react/hooks/useToolOutput.d.ts +1 -0
- package/dist/react/hooks/useToolResponseMetadata.d.ts +1 -0
- package/dist/react/hooks/useWidgetState.d.ts +4 -0
- package/dist/types/openai.d.ts +1 -2
- package/dist/vite/index.js +74 -21
- package/package.json +9 -2
- package/scripts/dev.mjs +3 -1
- package/src/core/ApolloClient.ts +108 -0
- package/src/{apollo_client/client.test.ts → core/__tests__/ApolloClient.test.ts} +232 -20
- package/src/index.ts +36 -10
- package/src/link/ToolCallLink.ts +49 -0
- package/src/{apollo_client/provider.tsx → react/ApolloProvider.tsx} +19 -9
- package/src/{apollo_client/provider.test.tsx → react/__tests__/ApolloProvider.test.tsx} +9 -9
- package/src/react/context/ToolUseContext.tsx +30 -0
- package/src/{hooks → react/hooks/__tests__}/useCallTool.test.ts +1 -1
- package/src/{hooks → react/hooks/__tests__}/useOpenAiGlobal.test.ts +5 -3
- package/src/react/hooks/__tests__/useOpenExternal.test.tsx +24 -0
- package/src/{hooks → react/hooks/__tests__}/useRequestDisplayMode.test.ts +2 -2
- package/src/{hooks → react/hooks/__tests__}/useSendFollowUpMessage.test.ts +4 -2
- package/src/{hooks → react/hooks/__tests__}/useToolEffect.test.tsx +27 -10
- package/src/{hooks → react/hooks/__tests__}/useToolInput.test.ts +1 -1
- package/src/{hooks → react/hooks/__tests__}/useToolName.test.ts +1 -1
- package/src/react/hooks/__tests__/useToolOutput.test.tsx +49 -0
- package/src/react/hooks/__tests__/useToolResponseMetadata.test.tsx +49 -0
- package/src/react/hooks/__tests__/useWidgetState.test.tsx +158 -0
- package/src/react/hooks/useCallTool.ts +13 -0
- package/src/{hooks → react/hooks}/useOpenAiGlobal.ts +11 -5
- package/src/react/hooks/useOpenExternal.ts +11 -0
- package/src/{hooks → react/hooks}/useRequestDisplayMode.ts +1 -1
- package/src/react/hooks/useToolEffect.tsx +37 -0
- package/src/{hooks → react/hooks}/useToolName.ts +1 -1
- package/src/react/hooks/useToolOutput.ts +5 -0
- package/src/react/hooks/useToolResponseMetadata.ts +5 -0
- package/src/react/hooks/useWidgetState.ts +48 -0
- package/src/testing/internal/index.ts +2 -0
- package/src/testing/internal/matchers/index.d.ts +9 -0
- package/src/testing/internal/matchers/index.ts +1 -0
- package/src/testing/internal/matchers/toRerender.ts +49 -0
- package/src/testing/internal/openai/dispatchStateChange.ts +9 -0
- package/src/testing/internal/openai/stubOpenAiGlobals.ts +13 -0
- package/src/types/openai.ts +6 -3
- package/src/vite/{absolute_asset_imports_plugin.test.ts → __tests__/absolute_asset_imports_plugin.test.ts} +4 -2
- package/src/vite/{application_manifest_plugin.test.ts → __tests__/application_manifest_plugin.test.ts} +176 -53
- package/src/vite/absolute_asset_imports_plugin.ts +3 -1
- package/src/vite/application_manifest_plugin.ts +84 -24
- package/vitest-setup.ts +1 -0
- package/dist/apollo_client/client.d.ts +0 -14
- package/dist/apollo_client/provider.d.ts +0 -5
- package/src/apollo_client/client.ts +0 -90
- package/src/hooks/useCallTool.ts +0 -8
- package/src/hooks/useToolEffect.tsx +0 -41
- /package/dist/{hooks → react/hooks}/useSendFollowUpMessage.d.ts +0 -0
- /package/dist/{hooks → react/hooks}/useToolInput.d.ts +0 -0
- /package/dist/{hooks → react/hooks}/useToolName.d.ts +0 -0
- /package/src/{hooks → react/hooks}/useSendFollowUpMessage.ts +0 -0
- /package/src/{hooks → react/hooks}/useToolInput.ts +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Compare Build Output
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
|
|
5
|
+
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
comparebuildoutput:
|
|
9
|
+
name: Compare Build Output
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout repo
|
|
13
|
+
uses: actions/checkout@v5
|
|
14
|
+
with:
|
|
15
|
+
# Fetch entire git history so we have the parent commit to compare against
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
- name: Setup Node.js
|
|
18
|
+
uses: actions/setup-node@v6
|
|
19
|
+
with:
|
|
20
|
+
node-version: ">=23.6.0"
|
|
21
|
+
- name: Install dependencies (with cache)
|
|
22
|
+
uses: bahmutov/npm-install@v1
|
|
23
|
+
|
|
24
|
+
- name: Run comparison script
|
|
25
|
+
id: attw
|
|
26
|
+
run: ./config/compare-build-output-to.sh $(git merge-base HEAD origin/${{ github.base_ref }}) | tee $GITHUB_STEP_SUMMARY
|
|
27
|
+
env:
|
|
28
|
+
RUNNER_TEMP: ${{ runner.temp }}
|
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
name: Build on PR
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened]
|
|
6
6
|
|
|
7
7
|
jobs:
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout code
|
|
13
|
+
uses: actions/checkout@v4
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
- name: Set up Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: 20.x
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: npm ci
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
- name: Run build
|
|
24
|
+
run: npm run build
|
|
25
|
+
|
|
26
|
+
- name: Test
|
|
27
|
+
shell: bash
|
|
28
|
+
run: npm run test
|
|
29
|
+
|
|
30
|
+
- name: Check formatting
|
|
31
|
+
shell: bash
|
|
32
|
+
run: npm run format:check
|
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
name: Release new Version
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
4
|
+
workflow_dispatch:
|
|
5
5
|
|
|
6
6
|
permissions:
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
contents: write
|
|
8
|
+
id-token: write # Required for OIDC
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
11
|
+
release:
|
|
12
|
+
name: Release
|
|
13
|
+
if: github.repository == 'apollographql/apollo-ai-apps-client'
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Setup Node.js 20.x
|
|
19
|
+
uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: ">=23.6.0"
|
|
22
|
+
registry-url: "https://registry.npmjs.org/"
|
|
23
|
+
env:
|
|
24
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
shell: bash
|
|
28
|
+
run: npm ci
|
|
29
|
+
|
|
30
|
+
- name: Build
|
|
31
|
+
shell: bash
|
|
32
|
+
run: npm run build
|
|
33
|
+
|
|
34
|
+
- name: Test
|
|
35
|
+
shell: bash
|
|
36
|
+
run: npm run test
|
|
37
|
+
|
|
38
|
+
- name: Configure Git
|
|
39
|
+
run: |
|
|
40
|
+
git config --global user.name GitHub Actions
|
|
41
|
+
git config user.email github-actions@github.com
|
|
42
|
+
|
|
43
|
+
- uses: knope-dev/action@v2.1.0
|
|
44
|
+
with:
|
|
45
|
+
version: 0.21.5
|
|
46
|
+
|
|
47
|
+
- run: knope release
|
|
48
|
+
env:
|
|
49
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
+
|
|
51
|
+
- name: Publish to npm
|
|
52
|
+
shell: bash
|
|
53
|
+
run: npm publish --provenance --access public
|
package/.prettierrc
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
upstream=$1
|
|
4
|
+
comparison="${RUNNER_TEMP:-/tmp}/comparison_checkout"
|
|
5
|
+
root=$(git rev-parse --show-toplevel)
|
|
6
|
+
|
|
7
|
+
temp=$(mktemp --tmpdir="${RUNNER_TEMP:-/tmp}")
|
|
8
|
+
trap 'rm -f "$temp"' EXIT
|
|
9
|
+
|
|
10
|
+
patterndiff(){
|
|
11
|
+
cd dist || { echo "dist folder not found"; exit 1; }
|
|
12
|
+
count=0
|
|
13
|
+
while IFS= read -r -d '' file
|
|
14
|
+
do
|
|
15
|
+
if ! filediff="$(diff <(tr "'" '"' < "$comparison/dist/$file") <(tr "'" '"' < "$root/dist/$file"))"; then
|
|
16
|
+
(( count++ ))
|
|
17
|
+
echo "$file"
|
|
18
|
+
if [[ "$file" == *.min.* ]]; then
|
|
19
|
+
echo "> Minified file differs."
|
|
20
|
+
else
|
|
21
|
+
echo "$filediff"
|
|
22
|
+
fi
|
|
23
|
+
fi
|
|
24
|
+
done >"$temp" < <(find . -name "$1" -print0)
|
|
25
|
+
|
|
26
|
+
output="$(cat <"$temp")"
|
|
27
|
+
|
|
28
|
+
cat <<EOF
|
|
29
|
+
|
|
30
|
+
## differences in $1 files
|
|
31
|
+
|
|
32
|
+
<details>
|
|
33
|
+
<summary>
|
|
34
|
+
|
|
35
|
+
### $count files with differences
|
|
36
|
+
|
|
37
|
+
</summary>
|
|
38
|
+
|
|
39
|
+
\`\`\`diff
|
|
40
|
+
|
|
41
|
+
$output
|
|
42
|
+
|
|
43
|
+
\`\`\`
|
|
44
|
+
|
|
45
|
+
</details>
|
|
46
|
+
EOF
|
|
47
|
+
|
|
48
|
+
cd ..
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
[ -z "$upstream" ] && { echo "need upstream argument"; exit 1; }
|
|
52
|
+
|
|
53
|
+
git worktree add --force --detach --checkout "$comparison" "$upstream" || { cd "$comparison" && git checkout "$upstream"; } || exit 1
|
|
54
|
+
|
|
55
|
+
cd "$comparison" || { echo "checkout failed"; exit 1; }
|
|
56
|
+
[ -d node_modules ] || cp -r "$root/node_modules" .
|
|
57
|
+
npm i >&2
|
|
58
|
+
git status >&2
|
|
59
|
+
npm run build >&2
|
|
60
|
+
cd "$root" || exit 1
|
|
61
|
+
git status >&2
|
|
62
|
+
npm run build >&2
|
|
63
|
+
|
|
64
|
+
set +e
|
|
65
|
+
|
|
66
|
+
patterndiff "*.js"
|
|
67
|
+
patterndiff "*.cjs"
|
|
68
|
+
patterndiff "*.d.ts"
|
|
69
|
+
patterndiff "*.d.cts"
|
|
70
|
+
|
|
71
|
+
cat <<EOF
|
|
72
|
+
|
|
73
|
+
## differences in other files
|
|
74
|
+
|
|
75
|
+
<details>
|
|
76
|
+
<summary>
|
|
77
|
+
|
|
78
|
+
### $(diff -qr "$comparison/dist" "dist" -x "*.map" -x "*.native.*" -x "*.js" -x "*.cjs" -x "*.d.ts" -x "*.d.cts" -w | wc -l) files with differences
|
|
79
|
+
|
|
80
|
+
</summary>
|
|
81
|
+
|
|
82
|
+
\`\`\`diff
|
|
83
|
+
|
|
84
|
+
$(diff -r "$comparison/dist" "dist" -x "*.map" -x "*.native.*" -x "*.js" -x "*.cjs" -x "*.d.ts" -x "*.d.cts" -w)
|
|
85
|
+
|
|
86
|
+
\`\`\`
|
|
87
|
+
|
|
88
|
+
</details>
|
|
89
|
+
EOF
|
|
90
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ApolloClient as BaseApolloClient } from "@apollo/client";
|
|
2
|
+
import "../types/openai";
|
|
3
|
+
import { ApplicationManifest } from "../types/application-manifest";
|
|
4
|
+
export declare namespace ApolloClient {
|
|
5
|
+
interface Options extends Omit<BaseApolloClient.Options, "link"> {
|
|
6
|
+
link?: BaseApolloClient.Options["link"];
|
|
7
|
+
manifest: ApplicationManifest;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export declare class ApolloClient extends BaseApolloClient {
|
|
11
|
+
manifest: ApplicationManifest;
|
|
12
|
+
constructor(options: ApolloClient.Options);
|
|
13
|
+
prefetchData(): Promise<void>;
|
|
14
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
1
|
+
export type { API, CallTool, DeviceType, DisplayMode, OpenAiGlobals, SafeArea, SafeAreaInsets, Theme, UserAgent, UnknownObject, } from "./types/openai";
|
|
2
|
+
export { SET_GLOBALS_EVENT_TYPE, SetGlobalsEvent } from "./types/openai";
|
|
3
|
+
export type { ApplicationManifest, ManifestOperation, ManifestTool, ManifestExtraInput, ManifestCsp, } from "./types/application-manifest";
|
|
4
|
+
export { ToolUseProvider } from "./react/context/ToolUseContext";
|
|
5
|
+
export { useOpenAiGlobal } from "./react/hooks/useOpenAiGlobal";
|
|
6
|
+
export { useToolName } from "./react/hooks/useToolName";
|
|
7
|
+
export { useToolInput } from "./react/hooks/useToolInput";
|
|
8
|
+
export { useSendFollowUpMessage } from "./react/hooks/useSendFollowUpMessage";
|
|
9
|
+
export { useRequestDisplayMode } from "./react/hooks/useRequestDisplayMode";
|
|
10
|
+
export { useToolEffect } from "./react/hooks/useToolEffect";
|
|
11
|
+
export { useOpenExternal } from "./react/hooks/useOpenExternal";
|
|
12
|
+
export { useToolOutput } from "./react/hooks/useToolOutput";
|
|
13
|
+
export { useToolResponseMetadata } from "./react/hooks/useToolResponseMetadata";
|
|
14
|
+
export { useWidgetState } from "./react/hooks/useWidgetState";
|
|
9
15
|
export * from "@apollo/client";
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
16
|
+
export { ApolloClient } from "./core/ApolloClient";
|
|
17
|
+
export { ApolloProvider } from "./react/ApolloProvider";
|
|
18
|
+
export { ToolCallLink } from "./link/ToolCallLink";
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,22 @@ var SetGlobalsEvent = class extends CustomEvent {
|
|
|
4
4
|
type = SET_GLOBALS_EVENT_TYPE;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
// src/
|
|
8
|
-
import {
|
|
7
|
+
// src/react/context/ToolUseContext.tsx
|
|
8
|
+
import React, { createContext, useContext, useState } from "react";
|
|
9
|
+
var ToolUseContext = createContext(null);
|
|
10
|
+
function ToolUseProvider({ children, appName }) {
|
|
11
|
+
const [hasNavigated, setHasNavigated] = useState(false);
|
|
12
|
+
return /* @__PURE__ */ React.createElement(ToolUseContext.Provider, { value: { hasNavigated, setHasNavigated, appName } }, children);
|
|
13
|
+
}
|
|
14
|
+
function useToolUseState() {
|
|
15
|
+
return useContext(ToolUseContext);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/react/hooks/useOpenAiGlobal.ts
|
|
19
|
+
import { useSyncExternalStore, useCallback } from "react";
|
|
9
20
|
function useOpenAiGlobal(key) {
|
|
10
21
|
return useSyncExternalStore(
|
|
11
|
-
(onChange) => {
|
|
22
|
+
useCallback((onChange) => {
|
|
12
23
|
const handleSetGlobal = (event) => {
|
|
13
24
|
const value = event.detail.globals[key];
|
|
14
25
|
if (value === void 0) {
|
|
@@ -22,24 +33,24 @@ function useOpenAiGlobal(key) {
|
|
|
22
33
|
return () => {
|
|
23
34
|
window.removeEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal);
|
|
24
35
|
};
|
|
25
|
-
},
|
|
36
|
+
}, []),
|
|
26
37
|
() => window.openai[key]
|
|
27
38
|
);
|
|
28
39
|
}
|
|
29
40
|
|
|
30
|
-
// src/hooks/useToolName.ts
|
|
41
|
+
// src/react/hooks/useToolName.ts
|
|
31
42
|
var useToolName = () => {
|
|
32
43
|
const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
|
|
33
44
|
return toolResponseMetadata?.toolName;
|
|
34
45
|
};
|
|
35
46
|
|
|
36
|
-
// src/hooks/useToolInput.ts
|
|
47
|
+
// src/react/hooks/useToolInput.ts
|
|
37
48
|
var useToolInput = () => {
|
|
38
49
|
const toolInput = useOpenAiGlobal("toolInput");
|
|
39
50
|
return toolInput;
|
|
40
51
|
};
|
|
41
52
|
|
|
42
|
-
// src/hooks/useSendFollowUpMessage.ts
|
|
53
|
+
// src/react/hooks/useSendFollowUpMessage.ts
|
|
43
54
|
var useSendFollowUpMessage = () => {
|
|
44
55
|
return async (prompt) => {
|
|
45
56
|
await window.openai?.sendFollowUpMessage({
|
|
@@ -48,105 +59,188 @@ var useSendFollowUpMessage = () => {
|
|
|
48
59
|
};
|
|
49
60
|
};
|
|
50
61
|
|
|
51
|
-
// src/hooks/useRequestDisplayMode.ts
|
|
62
|
+
// src/react/hooks/useRequestDisplayMode.ts
|
|
52
63
|
var useRequestDisplayMode = () => {
|
|
53
64
|
return async (args) => {
|
|
54
65
|
return await window.openai?.requestDisplayMode(args);
|
|
55
66
|
};
|
|
56
67
|
};
|
|
57
68
|
|
|
58
|
-
// src/hooks/useToolEffect.tsx
|
|
59
|
-
import
|
|
60
|
-
var ToolUseContext = React.createContext(null);
|
|
61
|
-
function ToolUseProvider({ children, appName }) {
|
|
62
|
-
const [hasNavigated, setHasNavigated] = useState(false);
|
|
63
|
-
return /* @__PURE__ */ React.createElement(ToolUseContext.Provider, { value: { hasNavigated, setHasNavigated, appName } }, children);
|
|
64
|
-
}
|
|
69
|
+
// src/react/hooks/useToolEffect.tsx
|
|
70
|
+
import { useEffect } from "react";
|
|
65
71
|
var useToolEffect = (toolName, effect, deps = []) => {
|
|
66
|
-
const ctx =
|
|
72
|
+
const ctx = useToolUseState();
|
|
67
73
|
const fullToolName = useToolName();
|
|
68
74
|
const toolInput = useToolInput();
|
|
69
|
-
if (!ctx)
|
|
75
|
+
if (!ctx)
|
|
76
|
+
throw new Error("useToolEffect must be used within ToolUseProvider");
|
|
70
77
|
const toolNames = Array.isArray(toolName) ? toolName : [toolName];
|
|
71
78
|
useEffect(() => {
|
|
72
|
-
const matches = toolNames.some(
|
|
79
|
+
const matches = toolNames.some(
|
|
80
|
+
(name) => fullToolName === `${ctx.appName}--${name}`
|
|
81
|
+
);
|
|
73
82
|
if (!ctx.hasNavigated && matches) {
|
|
74
83
|
effect(toolInput);
|
|
75
84
|
ctx.setHasNavigated(true);
|
|
76
85
|
}
|
|
77
|
-
}, [
|
|
86
|
+
}, [
|
|
87
|
+
ctx.hasNavigated,
|
|
88
|
+
ctx.setHasNavigated,
|
|
89
|
+
ctx.appName,
|
|
90
|
+
toolNames,
|
|
91
|
+
fullToolName,
|
|
92
|
+
toolInput,
|
|
93
|
+
...deps
|
|
94
|
+
]);
|
|
78
95
|
};
|
|
79
96
|
|
|
97
|
+
// src/react/hooks/useOpenExternal.ts
|
|
98
|
+
import { useCallback as useCallback2 } from "react";
|
|
99
|
+
function useOpenExternal() {
|
|
100
|
+
return useCallback2(
|
|
101
|
+
(...args) => window.openai.openExternal(...args),
|
|
102
|
+
[]
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/react/hooks/useToolOutput.ts
|
|
107
|
+
function useToolOutput() {
|
|
108
|
+
return useOpenAiGlobal("toolOutput") ?? null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/react/hooks/useToolResponseMetadata.ts
|
|
112
|
+
function useToolResponseMetadata() {
|
|
113
|
+
return useOpenAiGlobal("toolResponseMetadata") ?? null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/react/hooks/useWidgetState.ts
|
|
117
|
+
import { useCallback as useCallback3, useState as useState2 } from "react";
|
|
118
|
+
function useWidgetState(defaultState) {
|
|
119
|
+
const widgetStateFromWindow = useOpenAiGlobal("widgetState");
|
|
120
|
+
const [previousWidgetStateFromWindow, setPreviousWidgetStateFromWindow] = useState2(widgetStateFromWindow);
|
|
121
|
+
let [widgetState, _setWidgetState] = useState2(() => {
|
|
122
|
+
if (widgetStateFromWindow != null) {
|
|
123
|
+
return widgetStateFromWindow;
|
|
124
|
+
}
|
|
125
|
+
return typeof defaultState === "function" ? defaultState() : defaultState ?? null;
|
|
126
|
+
});
|
|
127
|
+
if (previousWidgetStateFromWindow !== widgetStateFromWindow) {
|
|
128
|
+
_setWidgetState(widgetState = widgetStateFromWindow);
|
|
129
|
+
setPreviousWidgetStateFromWindow(widgetStateFromWindow);
|
|
130
|
+
}
|
|
131
|
+
const setWidgetState = useCallback3((state) => {
|
|
132
|
+
_setWidgetState((prevState) => {
|
|
133
|
+
const newState = typeof state === "function" ? state(prevState) : state;
|
|
134
|
+
if (newState != null && typeof window !== "undefined") {
|
|
135
|
+
void window.openai?.setWidgetState?.(newState);
|
|
136
|
+
}
|
|
137
|
+
return newState;
|
|
138
|
+
});
|
|
139
|
+
}, []);
|
|
140
|
+
return [widgetState, setWidgetState];
|
|
141
|
+
}
|
|
142
|
+
|
|
80
143
|
// src/index.ts
|
|
81
144
|
export * from "@apollo/client";
|
|
82
145
|
|
|
83
|
-
// src/
|
|
84
|
-
import { ApolloClient
|
|
85
|
-
import * as Observable from "rxjs";
|
|
86
|
-
import { selectHttpOptionsAndBody } from "@apollo/client/link/http";
|
|
87
|
-
import { fallbackHttpConfig } from "@apollo/client/link/http";
|
|
146
|
+
// src/core/ApolloClient.ts
|
|
147
|
+
import { ApolloClient as BaseApolloClient } from "@apollo/client";
|
|
88
148
|
import { DocumentTransform } from "@apollo/client";
|
|
89
149
|
import { removeDirectivesFromDocument } from "@apollo/client/utilities/internal";
|
|
90
150
|
import { parse } from "graphql";
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
151
|
+
import { __DEV__ } from "@apollo/client/utilities/environment";
|
|
152
|
+
|
|
153
|
+
// src/link/ToolCallLink.ts
|
|
154
|
+
import { ApolloLink } from "@apollo/client";
|
|
155
|
+
import { from, map } from "rxjs";
|
|
156
|
+
import {
|
|
157
|
+
fallbackHttpConfig,
|
|
158
|
+
selectHttpOptionsAndBody
|
|
159
|
+
} from "@apollo/client/link/http";
|
|
160
|
+
var ToolCallLink = class extends ApolloLink {
|
|
161
|
+
request(operation) {
|
|
162
|
+
const context = operation.getContext();
|
|
163
|
+
const contextConfig = {
|
|
164
|
+
http: context.http,
|
|
165
|
+
options: context.fetchOptions,
|
|
166
|
+
credentials: context.credentials,
|
|
167
|
+
headers: context.headers
|
|
168
|
+
};
|
|
169
|
+
const { query, variables } = selectHttpOptionsAndBody(
|
|
170
|
+
operation,
|
|
171
|
+
fallbackHttpConfig,
|
|
172
|
+
contextConfig
|
|
173
|
+
).body;
|
|
174
|
+
return from(window.openai.callTool("execute", { query, variables })).pipe(
|
|
175
|
+
map((result) => ({ data: result.structuredContent.data }))
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// src/core/ApolloClient.ts
|
|
181
|
+
var ApolloClient = class extends BaseApolloClient {
|
|
105
182
|
manifest;
|
|
106
183
|
constructor(options) {
|
|
184
|
+
const link = options.link ?? new ToolCallLink();
|
|
185
|
+
if (__DEV__) {
|
|
186
|
+
validateTerminatingLink(link);
|
|
187
|
+
}
|
|
107
188
|
super({
|
|
108
|
-
|
|
109
|
-
|
|
189
|
+
...options,
|
|
190
|
+
link,
|
|
110
191
|
// Strip out the prefetch/tool directives so they don't get sent with the operation to the server
|
|
111
192
|
documentTransform: new DocumentTransform((document) => {
|
|
112
|
-
return removeDirectivesFromDocument(
|
|
193
|
+
return removeDirectivesFromDocument(
|
|
194
|
+
[{ name: "prefetch" }, { name: "tool" }],
|
|
195
|
+
document
|
|
196
|
+
);
|
|
113
197
|
})
|
|
114
198
|
});
|
|
115
199
|
this.manifest = options.manifest;
|
|
116
200
|
}
|
|
117
201
|
async prefetchData() {
|
|
118
202
|
this.manifest.operations.forEach((operation) => {
|
|
119
|
-
if (operation.prefetch && operation.prefetchID && window.openai.toolOutput
|
|
203
|
+
if (operation.prefetch && operation.prefetchID && window.openai.toolOutput?.prefetch?.[operation.prefetchID]) {
|
|
120
204
|
this.writeQuery({
|
|
121
205
|
query: parse(operation.body),
|
|
122
206
|
data: window.openai.toolOutput.prefetch[operation.prefetchID].data
|
|
123
207
|
});
|
|
124
208
|
}
|
|
125
209
|
if (operation.tools?.find(
|
|
126
|
-
(tool) => `${this.manifest.name}--${tool.name}` === window.openai.toolResponseMetadata
|
|
210
|
+
(tool) => `${this.manifest.name}--${tool.name}` === window.openai.toolResponseMetadata?.toolName
|
|
127
211
|
)) {
|
|
128
212
|
const variables = Object.keys(window.openai.toolInput).reduce(
|
|
129
|
-
(obj, key) => operation.variables[key] ? { ...obj, [key]: window.openai.toolInput[key] } : obj,
|
|
213
|
+
(obj, key) => operation.variables?.[key] ? { ...obj, [key]: window.openai.toolInput[key] } : obj,
|
|
130
214
|
{}
|
|
131
215
|
);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
216
|
+
if (window.openai.toolOutput) {
|
|
217
|
+
this.writeQuery({
|
|
218
|
+
query: parse(operation.body),
|
|
219
|
+
data: window.openai.toolOutput.result.data,
|
|
220
|
+
variables
|
|
221
|
+
});
|
|
222
|
+
}
|
|
137
223
|
}
|
|
138
224
|
});
|
|
139
225
|
}
|
|
140
226
|
};
|
|
227
|
+
function validateTerminatingLink(link) {
|
|
228
|
+
let terminatingLink = link;
|
|
229
|
+
while (terminatingLink.right) {
|
|
230
|
+
terminatingLink = terminatingLink.right;
|
|
231
|
+
}
|
|
232
|
+
if (terminatingLink.constructor.name !== "ToolCallLink") {
|
|
233
|
+
throw new Error(
|
|
234
|
+
"The terminating link must be a `ToolCallLink`. If you are using a `split` link, ensure the `right` branch uses a `ToolCallLink` as the terminating link."
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
141
238
|
|
|
142
|
-
// src/
|
|
143
|
-
import
|
|
144
|
-
import { ApolloProvider } from "@apollo/client/react";
|
|
145
|
-
var
|
|
146
|
-
|
|
147
|
-
client
|
|
148
|
-
}) => {
|
|
149
|
-
const [hasPreloaded, setHasPreloaded] = useState2(false);
|
|
239
|
+
// src/react/ApolloProvider.tsx
|
|
240
|
+
import React3, { useEffect as useEffect2, useState as useState3 } from "react";
|
|
241
|
+
import { ApolloProvider as BaseApolloProvider } from "@apollo/client/react";
|
|
242
|
+
var ApolloProvider = ({ children, client }) => {
|
|
243
|
+
const [hasPreloaded, setHasPreloaded] = useState3(false);
|
|
150
244
|
useEffect2(() => {
|
|
151
245
|
const prefetchData = async () => {
|
|
152
246
|
await client.prefetchData();
|
|
@@ -159,19 +253,27 @@ var ExtendedApolloProvider = ({
|
|
|
159
253
|
if (window.openai?.toolOutput) {
|
|
160
254
|
window.dispatchEvent(new CustomEvent(SET_GLOBALS_EVENT_TYPE));
|
|
161
255
|
}
|
|
162
|
-
|
|
163
|
-
|
|
256
|
+
return () => {
|
|
257
|
+
window.removeEventListener(SET_GLOBALS_EVENT_TYPE, prefetchData);
|
|
258
|
+
};
|
|
259
|
+
}, []);
|
|
260
|
+
return hasPreloaded ? /* @__PURE__ */ React3.createElement(BaseApolloProvider, { client }, children) : null;
|
|
164
261
|
};
|
|
165
262
|
export {
|
|
166
|
-
|
|
167
|
-
|
|
263
|
+
ApolloClient,
|
|
264
|
+
ApolloProvider,
|
|
168
265
|
SET_GLOBALS_EVENT_TYPE,
|
|
169
266
|
SetGlobalsEvent,
|
|
267
|
+
ToolCallLink,
|
|
170
268
|
ToolUseProvider,
|
|
171
269
|
useOpenAiGlobal,
|
|
270
|
+
useOpenExternal,
|
|
172
271
|
useRequestDisplayMode,
|
|
173
272
|
useSendFollowUpMessage,
|
|
174
273
|
useToolEffect,
|
|
175
274
|
useToolInput,
|
|
176
|
-
useToolName
|
|
275
|
+
useToolName,
|
|
276
|
+
useToolOutput,
|
|
277
|
+
useToolResponseMetadata,
|
|
278
|
+
useWidgetState
|
|
177
279
|
};
|