@copilotkit/react-core 1.51.3-next.8 → 1.51.3
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 +15 -0
- package/dist/{chunk-BUSWSDYO.mjs → chunk-7JTI6ZL4.mjs} +2 -2
- package/dist/{chunk-GPEJNVE5.mjs → chunk-RBGVEVWY.mjs} +2 -2
- package/dist/{chunk-E7SE25ZU.mjs → chunk-SRJT5VVY.mjs} +2 -2
- package/dist/{chunk-CDUIA2WM.mjs → chunk-VGL3DGUW.mjs} +16 -13
- package/dist/chunk-VGL3DGUW.mjs.map +1 -0
- package/dist/hooks/index.js +14 -11
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +4 -4
- package/dist/hooks/use-copilot-action.js +14 -11
- package/dist/hooks/use-copilot-action.js.map +1 -1
- package/dist/hooks/use-copilot-action.mjs +2 -2
- package/dist/hooks/use-copilot-authenticated-action.js +14 -11
- package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
- package/dist/hooks/use-copilot-authenticated-action.mjs +3 -3
- package/dist/hooks/use-default-tool.js +14 -11
- package/dist/hooks/use-default-tool.js.map +1 -1
- package/dist/hooks/use-default-tool.mjs +3 -3
- package/dist/hooks/use-frontend-tool.js +14 -11
- package/dist/hooks/use-frontend-tool.js.map +1 -1
- package/dist/hooks/use-frontend-tool.mjs +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/setupTests.js +2 -0
- package/dist/setupTests.js.map +1 -1
- package/dist/setupTests.mjs +2 -0
- package/dist/setupTests.mjs.map +1 -1
- package/package.json +7 -7
- package/src/hooks/__tests__/use-frontend-tool-remount.e2e.test.tsx +92 -0
- package/src/hooks/use-frontend-tool.ts +20 -14
- package/src/setupTests.ts +3 -0
- package/dist/chunk-CDUIA2WM.mjs.map +0 -1
- /package/dist/{chunk-BUSWSDYO.mjs.map → chunk-7JTI6ZL4.mjs.map} +0 -0
- /package/dist/{chunk-GPEJNVE5.mjs.map → chunk-RBGVEVWY.mjs.map} +0 -0
- /package/dist/{chunk-E7SE25ZU.mjs.map → chunk-SRJT5VVY.mjs.map} +0 -0
package/dist/setupTests.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
// src/setupTests.ts
|
|
4
|
+
var import_zod = require("zod");
|
|
4
5
|
jest.mock("@segment/analytics-node", () => ({
|
|
5
6
|
Analytics: jest.fn().mockImplementation(() => ({
|
|
6
7
|
track: jest.fn(),
|
|
@@ -19,6 +20,7 @@ jest.mock("@copilotkit/shared", () => ({
|
|
|
19
20
|
}
|
|
20
21
|
}),
|
|
21
22
|
dataToUUID: jest.fn((data) => JSON.stringify(data)),
|
|
23
|
+
getZodParameters: jest.fn(() => import_zod.z.object({})),
|
|
22
24
|
randomId: jest.fn(() => "test-random-id"),
|
|
23
25
|
CopilotKitAgentDiscoveryError: jest.fn(),
|
|
24
26
|
randomUUID: jest.fn(() => "mock-thread-id")
|
package/dist/setupTests.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/setupTests.ts"],"sourcesContent":["// Mock modules that cause ES module issues\njest.mock(\"@segment/analytics-node\", () => ({\n Analytics: jest.fn().mockImplementation(() => ({\n track: jest.fn(),\n identify: jest.fn(),\n page: jest.fn(),\n group: jest.fn(),\n alias: jest.fn(),\n })),\n}));\n\njest.mock(\"@copilotkit/shared\", () => ({\n parseJson: jest.fn((jsonString, defaultValue) => {\n try {\n return JSON.parse(jsonString);\n } catch {\n return defaultValue;\n }\n }),\n dataToUUID: jest.fn((data) => JSON.stringify(data)),\n randomId: jest.fn(() => \"test-random-id\"),\n CopilotKitAgentDiscoveryError: jest.fn(),\n randomUUID: jest.fn(() => \"mock-thread-id\"),\n}));\n\n// Mock react-dom/test-utils to avoid compatibility issues\njest.mock(\"react-dom/test-utils\", () => ({\n act: jest.fn((fn) => fn()),\n}));\n"],"mappings":";;;
|
|
1
|
+
{"version":3,"sources":["../src/setupTests.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// Mock modules that cause ES module issues\njest.mock(\"@segment/analytics-node\", () => ({\n Analytics: jest.fn().mockImplementation(() => ({\n track: jest.fn(),\n identify: jest.fn(),\n page: jest.fn(),\n group: jest.fn(),\n alias: jest.fn(),\n })),\n}));\n\njest.mock(\"@copilotkit/shared\", () => ({\n parseJson: jest.fn((jsonString, defaultValue) => {\n try {\n return JSON.parse(jsonString);\n } catch {\n return defaultValue;\n }\n }),\n dataToUUID: jest.fn((data) => JSON.stringify(data)),\n getZodParameters: jest.fn(() => z.object({})),\n randomId: jest.fn(() => \"test-random-id\"),\n CopilotKitAgentDiscoveryError: jest.fn(),\n randomUUID: jest.fn(() => \"mock-thread-id\"),\n}));\n\n// Mock react-dom/test-utils to avoid compatibility issues\njest.mock(\"react-dom/test-utils\", () => ({\n act: jest.fn((fn) => fn()),\n}));\n"],"mappings":";;;AAAA,iBAAkB;AAGlB,KAAK,KAAK,2BAA2B,OAAO;AAAA,EAC1C,WAAW,KAAK,GAAG,EAAE,mBAAmB,OAAO;AAAA,IAC7C,OAAO,KAAK,GAAG;AAAA,IACf,UAAU,KAAK,GAAG;AAAA,IAClB,MAAM,KAAK,GAAG;AAAA,IACd,OAAO,KAAK,GAAG;AAAA,IACf,OAAO,KAAK,GAAG;AAAA,EACjB,EAAE;AACJ,EAAE;AAEF,KAAK,KAAK,sBAAsB,OAAO;AAAA,EACrC,WAAW,KAAK,GAAG,CAAC,YAAY,iBAAiB;AAC/C,QAAI;AACF,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B,SAAQ,GAAN;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,YAAY,KAAK,GAAG,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA,EAClD,kBAAkB,KAAK,GAAG,MAAM,aAAE,OAAO,CAAC,CAAC,CAAC;AAAA,EAC5C,UAAU,KAAK,GAAG,MAAM,gBAAgB;AAAA,EACxC,+BAA+B,KAAK,GAAG;AAAA,EACvC,YAAY,KAAK,GAAG,MAAM,gBAAgB;AAC5C,EAAE;AAGF,KAAK,KAAK,wBAAwB,OAAO;AAAA,EACvC,KAAK,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC;AAC3B,EAAE;","names":[]}
|
package/dist/setupTests.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/setupTests.ts
|
|
2
|
+
import { z } from "zod";
|
|
2
3
|
jest.mock("@segment/analytics-node", () => ({
|
|
3
4
|
Analytics: jest.fn().mockImplementation(() => ({
|
|
4
5
|
track: jest.fn(),
|
|
@@ -17,6 +18,7 @@ jest.mock("@copilotkit/shared", () => ({
|
|
|
17
18
|
}
|
|
18
19
|
}),
|
|
19
20
|
dataToUUID: jest.fn((data) => JSON.stringify(data)),
|
|
21
|
+
getZodParameters: jest.fn(() => z.object({})),
|
|
20
22
|
randomId: jest.fn(() => "test-random-id"),
|
|
21
23
|
CopilotKitAgentDiscoveryError: jest.fn(),
|
|
22
24
|
randomUUID: jest.fn(() => "mock-thread-id")
|
package/dist/setupTests.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/setupTests.ts"],"sourcesContent":["// Mock modules that cause ES module issues\njest.mock(\"@segment/analytics-node\", () => ({\n Analytics: jest.fn().mockImplementation(() => ({\n track: jest.fn(),\n identify: jest.fn(),\n page: jest.fn(),\n group: jest.fn(),\n alias: jest.fn(),\n })),\n}));\n\njest.mock(\"@copilotkit/shared\", () => ({\n parseJson: jest.fn((jsonString, defaultValue) => {\n try {\n return JSON.parse(jsonString);\n } catch {\n return defaultValue;\n }\n }),\n dataToUUID: jest.fn((data) => JSON.stringify(data)),\n randomId: jest.fn(() => \"test-random-id\"),\n CopilotKitAgentDiscoveryError: jest.fn(),\n randomUUID: jest.fn(() => \"mock-thread-id\"),\n}));\n\n// Mock react-dom/test-utils to avoid compatibility issues\njest.mock(\"react-dom/test-utils\", () => ({\n act: jest.fn((fn) => fn()),\n}));\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/setupTests.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// Mock modules that cause ES module issues\njest.mock(\"@segment/analytics-node\", () => ({\n Analytics: jest.fn().mockImplementation(() => ({\n track: jest.fn(),\n identify: jest.fn(),\n page: jest.fn(),\n group: jest.fn(),\n alias: jest.fn(),\n })),\n}));\n\njest.mock(\"@copilotkit/shared\", () => ({\n parseJson: jest.fn((jsonString, defaultValue) => {\n try {\n return JSON.parse(jsonString);\n } catch {\n return defaultValue;\n }\n }),\n dataToUUID: jest.fn((data) => JSON.stringify(data)),\n getZodParameters: jest.fn(() => z.object({})),\n randomId: jest.fn(() => \"test-random-id\"),\n CopilotKitAgentDiscoveryError: jest.fn(),\n randomUUID: jest.fn(() => \"mock-thread-id\"),\n}));\n\n// Mock react-dom/test-utils to avoid compatibility issues\njest.mock(\"react-dom/test-utils\", () => ({\n act: jest.fn((fn) => fn()),\n}));\n"],"mappings":";AAAA,SAAS,SAAS;AAGlB,KAAK,KAAK,2BAA2B,OAAO;AAAA,EAC1C,WAAW,KAAK,GAAG,EAAE,mBAAmB,OAAO;AAAA,IAC7C,OAAO,KAAK,GAAG;AAAA,IACf,UAAU,KAAK,GAAG;AAAA,IAClB,MAAM,KAAK,GAAG;AAAA,IACd,OAAO,KAAK,GAAG;AAAA,IACf,OAAO,KAAK,GAAG;AAAA,EACjB,EAAE;AACJ,EAAE;AAEF,KAAK,KAAK,sBAAsB,OAAO;AAAA,EACrC,WAAW,KAAK,GAAG,CAAC,YAAY,iBAAiB;AAC/C,QAAI;AACF,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B,SAAQ,GAAN;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,YAAY,KAAK,GAAG,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA,EAClD,kBAAkB,KAAK,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAAA,EAC5C,UAAU,KAAK,GAAG,MAAM,gBAAgB;AAAA,EACxC,+BAA+B,KAAK,GAAG;AAAA,EACvC,YAAY,KAAK,GAAG,MAAM,gBAAgB;AAC5C,EAAE;AAGF,KAAK,KAAK,wBAAwB,OAAO;AAAA,EACvC,KAAK,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC;AAC3B,EAAE;","names":[]}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"version": "1.51.3
|
|
12
|
+
"version": "1.51.3",
|
|
13
13
|
"sideEffects": [
|
|
14
14
|
"**/*.css"
|
|
15
15
|
],
|
|
@@ -53,18 +53,18 @@
|
|
|
53
53
|
"tsup": "^6.7.0",
|
|
54
54
|
"typescript": "^5.2.3",
|
|
55
55
|
"zod": ">=3.0.0",
|
|
56
|
-
"eslint-config-custom": "1.4.
|
|
57
|
-
"tsconfig": "1.4.
|
|
56
|
+
"eslint-config-custom": "1.4.7",
|
|
57
|
+
"tsconfig": "1.4.7"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@ag-ui/client": "^0.0.43",
|
|
61
61
|
"@scarf/scarf": "^1.3.0",
|
|
62
62
|
"react-markdown": "^8.0.7",
|
|
63
63
|
"untruncate-json": "^0.0.1",
|
|
64
|
-
"@copilotkit/runtime-client-gql": "1.51.3
|
|
65
|
-
"@copilotkit/shared": "1.51.3
|
|
66
|
-
"@copilotkitnext/core": "1.51.3
|
|
67
|
-
"@copilotkitnext/react": "1.51.3
|
|
64
|
+
"@copilotkit/runtime-client-gql": "1.51.3",
|
|
65
|
+
"@copilotkit/shared": "1.51.3",
|
|
66
|
+
"@copilotkitnext/core": "1.51.3",
|
|
67
|
+
"@copilotkitnext/react": "1.51.3"
|
|
68
68
|
},
|
|
69
69
|
"keywords": [
|
|
70
70
|
"copilotkit",
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { render, waitFor } from "@testing-library/react";
|
|
3
|
+
import { ToolCallStatus } from "@copilotkitnext/core";
|
|
4
|
+
import { useFrontendTool } from "../use-frontend-tool";
|
|
5
|
+
|
|
6
|
+
jest.mock("@copilotkitnext/react", () => {
|
|
7
|
+
let currentRender: any = null;
|
|
8
|
+
const listeners = new Set<() => void>();
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
useFrontendTool: jest.fn((tool: { render?: any }) => {
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
currentRender = tool.render ?? null;
|
|
14
|
+
listeners.forEach((listener) => listener());
|
|
15
|
+
}, [tool.render]);
|
|
16
|
+
}),
|
|
17
|
+
__getCurrentRender: () => currentRender,
|
|
18
|
+
__subscribeRender: (listener: () => void) => {
|
|
19
|
+
listeners.add(listener);
|
|
20
|
+
return () => listeners.delete(listener);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const toolRenderModule = jest.requireMock("@copilotkitnext/react") as {
|
|
26
|
+
__getCurrentRender: () => any;
|
|
27
|
+
__subscribeRender: (listener: () => void) => () => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function ToolRenderHost() {
|
|
31
|
+
const render = React.useSyncExternalStore(
|
|
32
|
+
toolRenderModule.__subscribeRender,
|
|
33
|
+
toolRenderModule.__getCurrentRender,
|
|
34
|
+
toolRenderModule.__getCurrentRender,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
if (!render) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const RenderComponent = render;
|
|
42
|
+
return (
|
|
43
|
+
<RenderComponent
|
|
44
|
+
name="actionOne"
|
|
45
|
+
args={{}}
|
|
46
|
+
status={ToolCallStatus.InProgress}
|
|
47
|
+
result={undefined}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function RunActionButton({ onMount, onUnmount }: { onMount: jest.Mock; onUnmount: jest.Mock }) {
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
onMount();
|
|
55
|
+
return () => onUnmount();
|
|
56
|
+
}, [onMount, onUnmount]);
|
|
57
|
+
|
|
58
|
+
return <div data-testid="run-action">Run</div>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
describe("useFrontendTool dependency changes", () => {
|
|
62
|
+
it("should not remount rendered tool UI when deps change", async () => {
|
|
63
|
+
const mounted = jest.fn();
|
|
64
|
+
const unmounted = jest.fn();
|
|
65
|
+
|
|
66
|
+
const ToolUser = ({ version }: { version: number }) => {
|
|
67
|
+
useFrontendTool(
|
|
68
|
+
{
|
|
69
|
+
name: "actionOne",
|
|
70
|
+
description: "Execute action one",
|
|
71
|
+
render: () => <RunActionButton onMount={mounted} onUnmount={unmounted} />,
|
|
72
|
+
},
|
|
73
|
+
[version],
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return <ToolRenderHost />;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const ui = render(<ToolUser version={0} />);
|
|
80
|
+
|
|
81
|
+
await waitFor(() => {
|
|
82
|
+
expect(mounted).toHaveBeenCalledTimes(1);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
ui.rerender(<ToolUser version={1} />);
|
|
86
|
+
|
|
87
|
+
await waitFor(() => {
|
|
88
|
+
expect(unmounted).toHaveBeenCalledTimes(0);
|
|
89
|
+
expect(mounted).toHaveBeenCalledTimes(1);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useRef } from "react";
|
|
1
|
+
import React, { useEffect, useMemo, useRef } from "react";
|
|
2
2
|
import { ActionRenderProps, FrontendAction } from "../types/frontend-action";
|
|
3
3
|
import { Parameter, getZodParameters, MappedParameterTypes } from "@copilotkit/shared";
|
|
4
4
|
import { parseJson } from "@copilotkit/shared";
|
|
@@ -43,28 +43,34 @@ export function useFrontendTool<const T extends Parameter[] = []>(
|
|
|
43
43
|
const { name, description, parameters, render, followUp } = tool;
|
|
44
44
|
const zodParameters = getZodParameters(parameters);
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const renderRef = useRef<typeof render>(render);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
renderRef.current = render;
|
|
50
|
+
}, [render, ...(dependencies ?? [])]);
|
|
51
|
+
|
|
52
|
+
const normalizedRender: FrontendToolOptions<T>["render"] | undefined = useMemo(() => {
|
|
47
53
|
if (typeof render === "undefined") {
|
|
48
54
|
return undefined;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
if (typeof render === "string") {
|
|
52
|
-
const staticRender = render;
|
|
53
|
-
return (() =>
|
|
54
|
-
React.createElement(
|
|
55
|
-
React.Fragment,
|
|
56
|
-
null,
|
|
57
|
-
staticRender,
|
|
58
|
-
)) as FrontendToolOptions<T>["render"];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
57
|
return ((args: FrontendToolRenderArgs<T>) => {
|
|
58
|
+
const currentRender = renderRef.current;
|
|
59
|
+
|
|
60
|
+
if (typeof currentRender === "undefined") {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (typeof currentRender === "string") {
|
|
65
|
+
return React.createElement(React.Fragment, null, currentRender);
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
const renderArgs = {
|
|
63
69
|
...args,
|
|
64
70
|
result: typeof args.result === "string" ? parseJson(args.result, args.result) : args.result,
|
|
65
71
|
} as ActionRenderProps<T>;
|
|
66
72
|
|
|
67
|
-
const rendered =
|
|
73
|
+
const rendered = currentRender(renderArgs);
|
|
68
74
|
|
|
69
75
|
if (typeof rendered === "string") {
|
|
70
76
|
return React.createElement(React.Fragment, null, rendered);
|
|
@@ -72,7 +78,7 @@ export function useFrontendTool<const T extends Parameter[] = []>(
|
|
|
72
78
|
|
|
73
79
|
return rendered ?? null;
|
|
74
80
|
}) as FrontendToolOptions<T>["render"];
|
|
75
|
-
})
|
|
81
|
+
}, []);
|
|
76
82
|
|
|
77
83
|
// Handler ref to avoid stale closures
|
|
78
84
|
const handlerRef = useRef<typeof tool.handler>(tool.handler);
|
package/src/setupTests.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
1
3
|
// Mock modules that cause ES module issues
|
|
2
4
|
jest.mock("@segment/analytics-node", () => ({
|
|
3
5
|
Analytics: jest.fn().mockImplementation(() => ({
|
|
@@ -18,6 +20,7 @@ jest.mock("@copilotkit/shared", () => ({
|
|
|
18
20
|
}
|
|
19
21
|
}),
|
|
20
22
|
dataToUUID: jest.fn((data) => JSON.stringify(data)),
|
|
23
|
+
getZodParameters: jest.fn(() => z.object({})),
|
|
21
24
|
randomId: jest.fn(() => "test-random-id"),
|
|
22
25
|
CopilotKitAgentDiscoveryError: jest.fn(),
|
|
23
26
|
randomUUID: jest.fn(() => "mock-thread-id"),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-frontend-tool.ts"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { ActionRenderProps, FrontendAction } from \"../types/frontend-action\";\nimport { Parameter, getZodParameters, MappedParameterTypes } from \"@copilotkit/shared\";\nimport { parseJson } from \"@copilotkit/shared\";\nimport { ToolCallStatus } from \"@copilotkitnext/core\";\nimport {\n type ReactFrontendTool,\n useFrontendTool as useFrontendToolVNext,\n} from \"@copilotkitnext/react\";\n\ntype FrontendToolOptions<T extends Parameter[] | []> = ReactFrontendTool<MappedParameterTypes<T>>;\ntype FrontendToolRenderArgs<T extends Parameter[] | []> =\n | {\n name: string;\n args: Partial<MappedParameterTypes<T>>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n args: MappedParameterTypes<T>;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n args: MappedParameterTypes<T>;\n status: ToolCallStatus.Complete;\n result: string;\n };\n\nexport type UseFrontendToolArgs<T extends Parameter[] | [] = []> = {\n available?: \"disabled\" | \"enabled\";\n} & Pick<\n FrontendAction<T>,\n \"name\" | \"description\" | \"parameters\" | \"handler\" | \"followUp\" | \"render\"\n>;\n\nexport function useFrontendTool<const T extends Parameter[] = []>(\n tool: UseFrontendToolArgs<T>,\n dependencies?: any[],\n) {\n const { name, description, parameters, render, followUp } = tool;\n const zodParameters = getZodParameters(parameters);\n\n const normalizedRender: FrontendToolOptions<T>[\"render\"] | undefined = (() => {\n if (typeof render === \"undefined\") {\n return undefined;\n }\n\n if (typeof render === \"string\") {\n const staticRender = render;\n return (() =>\n React.createElement(\n React.Fragment,\n null,\n staticRender,\n )) as FrontendToolOptions<T>[\"render\"];\n }\n\n return ((args: FrontendToolRenderArgs<T>) => {\n const renderArgs = {\n ...args,\n result: typeof args.result === \"string\" ? parseJson(args.result, args.result) : args.result,\n } as ActionRenderProps<T>;\n\n const rendered = render(renderArgs);\n\n if (typeof rendered === \"string\") {\n return React.createElement(React.Fragment, null, rendered);\n }\n\n return rendered ?? null;\n }) as FrontendToolOptions<T>[\"render\"];\n })();\n\n // Handler ref to avoid stale closures\n const handlerRef = useRef<typeof tool.handler>(tool.handler);\n\n useEffect(() => {\n handlerRef.current = tool.handler;\n }, [tool.handler, ...(dependencies ?? [])]);\n\n const normalizedHandler = tool.handler\n ? (args: MappedParameterTypes<T>) => handlerRef.current?.(args)\n : undefined;\n\n useFrontendToolVNext<MappedParameterTypes<T>>({\n name,\n description,\n parameters: zodParameters,\n handler: normalizedHandler,\n followUp,\n render: normalizedRender,\n });\n}\n"],"mappings":";;;;;;AAAA,OAAO,SAAS,WAAW,cAAc;AAEzC,SAAoB,wBAA8C;AAClE,SAAS,iBAAiB;AAE1B;AAAA,EAEE,mBAAmB;AAAA,OACd;AA8BA,SAAS,gBACd,MACA,cACA;AACA,QAAM,EAAE,MAAM,aAAa,YAAY,QAAQ,SAAS,IAAI;AAC5D,QAAM,gBAAgB,iBAAiB,UAAU;AAEjD,QAAM,oBAAkE,MAAM;AAC5E,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,WAAW,UAAU;AAC9B,YAAM,eAAe;AACrB,aAAQ,MACN,MAAM;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACJ;AAEA,WAAQ,CAAC,SAAoC;AAC3C,YAAM,aAAa,iCACd,OADc;AAAA,QAEjB,QAAQ,OAAO,KAAK,WAAW,WAAW,UAAU,KAAK,QAAQ,KAAK,MAAM,IAAI,KAAK;AAAA,MACvF;AAEA,YAAM,WAAW,OAAO,UAAU;AAElC,UAAI,OAAO,aAAa,UAAU;AAChC,eAAO,MAAM,cAAc,MAAM,UAAU,MAAM,QAAQ;AAAA,MAC3D;AAEA,aAAO,8BAAY;AAAA,IACrB;AAAA,EACF,GAAG;AAGH,QAAM,aAAa,OAA4B,KAAK,OAAO;AAE3D,YAAU,MAAM;AACd,eAAW,UAAU,KAAK;AAAA,EAC5B,GAAG,CAAC,KAAK,SAAS,GAAI,sCAAgB,CAAC,CAAE,CAAC;AAE1C,QAAM,oBAAoB,KAAK,UAC3B,CAAC,SAA+B;AApFtC;AAoFyC,4BAAW,YAAX,oCAAqB;AAAA,MACxD;AAEJ,uBAA8C;AAAA,IAC5C;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,SAAS;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|