Spaces:
Running
Running
remove default tools and make the get started page dynamic. Added public folder
Browse files- .gitignore +1 -0
- public/liquidai-logo.svg +1 -0
- public/thumbnail.png +3 -0
- src/App.tsx +19 -22
- src/components/ExamplePrompts.tsx +38 -25
- src/tools/get_location.js +0 -84
- src/tools/get_time.js +0 -51
- src/tools/math_eval.js +0 -54
- src/tools/open_webpage.js +0 -49
- src/tools/random_number.js +0 -51
- src/tools/sleep.js +0 -45
- src/tools/speak.js +0 -58
- src/tools/template.js +0 -47
.gitignore
CHANGED
@@ -22,3 +22,4 @@ dist-ssr
|
|
22 |
*.njsproj
|
23 |
*.sln
|
24 |
*.sw?
|
|
|
|
22 |
*.njsproj
|
23 |
*.sln
|
24 |
*.sw?
|
25 |
+
package-lock.json
|
public/liquidai-logo.svg
ADDED
|
public/thumbnail.png
ADDED
![]() |
Git LFS Details
|
src/App.tsx
CHANGED
@@ -35,7 +35,7 @@ import {
|
|
35 |
import { DEFAULT_SYSTEM_PROMPT } from "./constants/systemPrompt";
|
36 |
import { DB_NAME, STORE_NAME, SETTINGS_STORE_NAME } from "./constants/db";
|
37 |
|
38 |
-
import {
|
39 |
import ToolResultRenderer from "./components/ToolResultRenderer";
|
40 |
import ToolCallIndicator from "./components/ToolCallIndicator";
|
41 |
import ToolItem from "./components/ToolItem";
|
@@ -123,23 +123,7 @@ const App: React.FC = () => {
|
|
123 |
const loadTools = useCallback(async (): Promise<void> => {
|
124 |
const db = await getDB();
|
125 |
const allTools: Tool[] = await db.getAll(STORE_NAME);
|
126 |
-
|
127 |
-
const defaultTools: Tool[] = Object.entries(DEFAULT_TOOLS).map(
|
128 |
-
([name, code], id) => ({
|
129 |
-
id,
|
130 |
-
name,
|
131 |
-
code,
|
132 |
-
enabled: true,
|
133 |
-
isCollapsed: false,
|
134 |
-
})
|
135 |
-
);
|
136 |
-
const tx = db.transaction(STORE_NAME, "readwrite");
|
137 |
-
await Promise.all(defaultTools.map((tool) => tx.store.put(tool)));
|
138 |
-
await tx.done;
|
139 |
-
setTools(defaultTools);
|
140 |
-
} else {
|
141 |
-
setTools(allTools.map((t) => ({ ...t, isCollapsed: false })));
|
142 |
-
}
|
143 |
|
144 |
// Load MCP tools and merge them
|
145 |
const mcpTools = getMCPToolsAsOriginalTools();
|
@@ -386,12 +370,15 @@ const App: React.FC = () => {
|
|
386 |
);
|
387 |
}
|
388 |
|
389 |
-
|
390 |
call,
|
391 |
result: parsedResult,
|
392 |
renderer: rendererCode,
|
393 |
-
|
394 |
-
|
|
|
|
|
|
|
395 |
} catch (error) {
|
396 |
const errorMessage = getErrorMessage(error);
|
397 |
results.push({ call, error: errorMessage });
|
@@ -720,7 +707,17 @@ const App: React.FC = () => {
|
|
720 |
className="flex-grow bg-gray-800 rounded-lg p-4 overflow-y-auto mb-4 space-y-4"
|
721 |
>
|
722 |
{messages.length === 0 && isReady ? (
|
723 |
-
<ExamplePrompts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
724 |
) : (
|
725 |
messages.map((msg, index) => {
|
726 |
const key = `${msg.role}-${index}`;
|
|
|
35 |
import { DEFAULT_SYSTEM_PROMPT } from "./constants/systemPrompt";
|
36 |
import { DB_NAME, STORE_NAME, SETTINGS_STORE_NAME } from "./constants/db";
|
37 |
|
38 |
+
import { TEMPLATE } from "./tools";
|
39 |
import ToolResultRenderer from "./components/ToolResultRenderer";
|
40 |
import ToolCallIndicator from "./components/ToolCallIndicator";
|
41 |
import ToolItem from "./components/ToolItem";
|
|
|
123 |
const loadTools = useCallback(async (): Promise<void> => {
|
124 |
const db = await getDB();
|
125 |
const allTools: Tool[] = await db.getAll(STORE_NAME);
|
126 |
+
setTools(allTools.map((t) => ({ ...t, isCollapsed: false })));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
|
128 |
// Load MCP tools and merge them
|
129 |
const mcpTools = getMCPToolsAsOriginalTools();
|
|
|
370 |
);
|
371 |
}
|
372 |
|
373 |
+
const renderInfo: RenderInfo = {
|
374 |
call,
|
375 |
result: parsedResult,
|
376 |
renderer: rendererCode,
|
377 |
+
};
|
378 |
+
if (namedParams && Object.keys(namedParams).length > 0) {
|
379 |
+
renderInfo.input = namedParams;
|
380 |
+
}
|
381 |
+
results.push(renderInfo);
|
382 |
} catch (error) {
|
383 |
const errorMessage = getErrorMessage(error);
|
384 |
results.push({ call, error: errorMessage });
|
|
|
707 |
className="flex-grow bg-gray-800 rounded-lg p-4 overflow-y-auto mb-4 space-y-4"
|
708 |
>
|
709 |
{messages.length === 0 && isReady ? (
|
710 |
+
<ExamplePrompts
|
711 |
+
examples={tools
|
712 |
+
.filter((tool) => tool.enabled)
|
713 |
+
.map((tool) => ({
|
714 |
+
icon: "🛠️",
|
715 |
+
displayText: tool.name,
|
716 |
+
messageText: `${tool.name}()`,
|
717 |
+
}))
|
718 |
+
.filter((ex) => ex.displayText)}
|
719 |
+
onExampleClick={handleExampleClick}
|
720 |
+
/>
|
721 |
) : (
|
722 |
messages.map((msg, index) => {
|
723 |
const key = `${msg.role}-${index}`;
|
src/components/ExamplePrompts.tsx
CHANGED
@@ -9,32 +9,45 @@ interface ExamplePromptsProps {
|
|
9 |
const ExamplePrompts: React.FC<ExamplePromptsProps> = ({
|
10 |
examples,
|
11 |
onExampleClick,
|
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 |
</div>
|
37 |
-
|
38 |
-
|
39 |
|
40 |
export default ExamplePrompts;
|
|
|
9 |
const ExamplePrompts: React.FC<ExamplePromptsProps> = ({
|
10 |
examples,
|
11 |
onExampleClick,
|
12 |
+
}) => {
|
13 |
+
// If examples are provided, use them. Otherwise, generate from enabled tools.
|
14 |
+
let dynamicExamples = examples;
|
15 |
+
if (!dynamicExamples) {
|
16 |
+
// Try to get tools from props (if passed as examples)
|
17 |
+
dynamicExamples = undefined;
|
18 |
+
}
|
19 |
+
// If still undefined, fallback to DEFAULT_EXAMPLES
|
20 |
+
if (!dynamicExamples) {
|
21 |
+
dynamicExamples = DEFAULT_EXAMPLES;
|
22 |
+
}
|
23 |
+
|
24 |
+
return (
|
25 |
+
<div className="flex flex-col items-center justify-center h-full space-y-6">
|
26 |
+
<div className="text-center mb-6">
|
27 |
+
<h2 className="text-2xl font-semibold text-gray-300 mb-1">
|
28 |
+
Try an example
|
29 |
+
</h2>
|
30 |
+
<p className="text-sm text-gray-500">Click one to get started</p>
|
31 |
+
</div>
|
32 |
|
33 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 max-w-2xl w-full px-4">
|
34 |
+
{dynamicExamples.map((example, index) => (
|
35 |
+
<button
|
36 |
+
key={index}
|
37 |
+
onClick={() => onExampleClick(example.messageText)}
|
38 |
+
className="flex items-center gap-3 p-4 bg-gray-700 hover:bg-gray-600 rounded-lg transition-colors text-left group cursor-pointer"
|
39 |
+
>
|
40 |
+
<span className="text-xl flex-shrink-0 group-hover:scale-110 transition-transform">
|
41 |
+
{example.icon}
|
42 |
+
</span>
|
43 |
+
<span className="text-sm text-gray-200 group-hover:text-white transition-colors">
|
44 |
+
{example.displayText}
|
45 |
+
</span>
|
46 |
+
</button>
|
47 |
+
))}
|
48 |
+
</div>
|
49 |
</div>
|
50 |
+
);
|
51 |
+
};
|
52 |
|
53 |
export default ExamplePrompts;
|
src/tools/get_location.js
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Get the user's current location using the browser's geolocation API.
|
3 |
-
* @returns {Promise<{ latitude: number, longitude: number }>} The current position { latitude, longitude }.
|
4 |
-
*/
|
5 |
-
export async function get_location() {
|
6 |
-
return new Promise((resolve, reject) => {
|
7 |
-
if (!navigator.geolocation) {
|
8 |
-
reject("Geolocation not supported.");
|
9 |
-
return;
|
10 |
-
}
|
11 |
-
navigator.geolocation.getCurrentPosition(
|
12 |
-
(pos) =>
|
13 |
-
resolve({
|
14 |
-
latitude: pos.coords.latitude,
|
15 |
-
longitude: pos.coords.longitude,
|
16 |
-
}),
|
17 |
-
(err) => reject(err.message || "Geolocation error"),
|
18 |
-
);
|
19 |
-
});
|
20 |
-
}
|
21 |
-
|
22 |
-
export default (input, output) =>
|
23 |
-
React.createElement(
|
24 |
-
"div",
|
25 |
-
{ className: "bg-green-50 border border-green-200 rounded-lg p-4" },
|
26 |
-
React.createElement(
|
27 |
-
"div",
|
28 |
-
{ className: "flex items-center mb-2" },
|
29 |
-
React.createElement(
|
30 |
-
"div",
|
31 |
-
{
|
32 |
-
className:
|
33 |
-
"w-8 h-8 bg-green-100 rounded-full flex items-center justify-center mr-3",
|
34 |
-
},
|
35 |
-
"📍",
|
36 |
-
),
|
37 |
-
React.createElement(
|
38 |
-
"h3",
|
39 |
-
{ className: "text-green-900 font-semibold" },
|
40 |
-
"Location",
|
41 |
-
),
|
42 |
-
),
|
43 |
-
output?.latitude && output?.longitude
|
44 |
-
? React.createElement(
|
45 |
-
"div",
|
46 |
-
{ className: "space-y-1 text-sm" },
|
47 |
-
React.createElement(
|
48 |
-
"p",
|
49 |
-
{ className: "text-green-700" },
|
50 |
-
React.createElement(
|
51 |
-
"span",
|
52 |
-
{ className: "font-medium" },
|
53 |
-
"Latitude: ",
|
54 |
-
),
|
55 |
-
output.latitude.toFixed(6),
|
56 |
-
),
|
57 |
-
React.createElement(
|
58 |
-
"p",
|
59 |
-
{ className: "text-green-700" },
|
60 |
-
React.createElement(
|
61 |
-
"span",
|
62 |
-
{ className: "font-medium" },
|
63 |
-
"Longitude: ",
|
64 |
-
),
|
65 |
-
output.longitude.toFixed(6),
|
66 |
-
),
|
67 |
-
React.createElement(
|
68 |
-
"a",
|
69 |
-
{
|
70 |
-
href: `https://maps.google.com?q=${output.latitude},${output.longitude}`,
|
71 |
-
target: "_blank",
|
72 |
-
rel: "noopener noreferrer",
|
73 |
-
className:
|
74 |
-
"inline-block mt-2 text-green-600 hover:text-green-800 underline text-xs",
|
75 |
-
},
|
76 |
-
"View on Google Maps",
|
77 |
-
),
|
78 |
-
)
|
79 |
-
: React.createElement(
|
80 |
-
"p",
|
81 |
-
{ className: "text-green-700 text-sm" },
|
82 |
-
JSON.stringify(output),
|
83 |
-
),
|
84 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/get_time.js
DELETED
@@ -1,51 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Get the current date and time.
|
3 |
-
* @returns {{ iso: string, local: string }} The current date and time as ISO and local time strings.
|
4 |
-
*/
|
5 |
-
export function get_time() {
|
6 |
-
const now = new Date();
|
7 |
-
return {
|
8 |
-
iso: now.toISOString(),
|
9 |
-
local: now.toLocaleString(undefined, {
|
10 |
-
dateStyle: "full",
|
11 |
-
timeStyle: "long",
|
12 |
-
}),
|
13 |
-
};
|
14 |
-
}
|
15 |
-
|
16 |
-
export default (input, output) =>
|
17 |
-
React.createElement(
|
18 |
-
"div",
|
19 |
-
{ className: "bg-amber-50 border border-amber-200 rounded-lg p-4" },
|
20 |
-
React.createElement(
|
21 |
-
"div",
|
22 |
-
{ className: "flex items-center mb-2" },
|
23 |
-
React.createElement(
|
24 |
-
"div",
|
25 |
-
{
|
26 |
-
className:
|
27 |
-
"w-8 h-8 bg-amber-100 rounded-full flex items-center justify-center mr-3",
|
28 |
-
},
|
29 |
-
"🕐",
|
30 |
-
),
|
31 |
-
React.createElement(
|
32 |
-
"h3",
|
33 |
-
{ className: "text-amber-900 font-semibold" },
|
34 |
-
"Current Time",
|
35 |
-
),
|
36 |
-
),
|
37 |
-
React.createElement(
|
38 |
-
"div",
|
39 |
-
{ className: "text-sm space-y-1" },
|
40 |
-
React.createElement(
|
41 |
-
"p",
|
42 |
-
{ className: "text-amber-700 font-mono" },
|
43 |
-
output.local,
|
44 |
-
),
|
45 |
-
React.createElement(
|
46 |
-
"p",
|
47 |
-
{ className: "text-amber-600 text-xs" },
|
48 |
-
new Date(output.iso).toLocaleString(),
|
49 |
-
),
|
50 |
-
),
|
51 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/math_eval.js
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Evaluate a math expression.
|
3 |
-
* @param {string} expression - The math expression (e.g., "2 + 2 * (3 - 1)").
|
4 |
-
* @returns {number} The result of the expression.
|
5 |
-
*/
|
6 |
-
export function math_eval(expression) {
|
7 |
-
// Only allow numbers, spaces, and math symbols: + - * / % ( ) .
|
8 |
-
if (!/^[\d\s+\-*/%.()]+$/.test(expression)) {
|
9 |
-
throw new Error("Invalid characters in expression.");
|
10 |
-
}
|
11 |
-
return Function('"use strict";return (' + expression + ")")();
|
12 |
-
}
|
13 |
-
|
14 |
-
export default (input, output) =>
|
15 |
-
React.createElement(
|
16 |
-
"div",
|
17 |
-
{ className: "bg-emerald-50 border border-emerald-200 rounded-lg p-4" },
|
18 |
-
React.createElement(
|
19 |
-
"div",
|
20 |
-
{ className: "flex items-center mb-2" },
|
21 |
-
React.createElement(
|
22 |
-
"div",
|
23 |
-
{
|
24 |
-
className:
|
25 |
-
"w-8 h-8 bg-emerald-100 rounded-full flex items-center justify-center mr-3",
|
26 |
-
},
|
27 |
-
"🧮",
|
28 |
-
),
|
29 |
-
React.createElement(
|
30 |
-
"h3",
|
31 |
-
{ className: "text-emerald-900 font-semibold" },
|
32 |
-
"Math Evaluation",
|
33 |
-
),
|
34 |
-
),
|
35 |
-
React.createElement(
|
36 |
-
"div",
|
37 |
-
{ className: "text-center" },
|
38 |
-
React.createElement(
|
39 |
-
"div",
|
40 |
-
{ className: "text-lg font-mono text-emerald-700 mb-1" },
|
41 |
-
input.expression || "Unknown expression",
|
42 |
-
),
|
43 |
-
React.createElement(
|
44 |
-
"div",
|
45 |
-
{ className: "text-2xl font-bold text-emerald-600 mb-1" },
|
46 |
-
`= ${output}`,
|
47 |
-
),
|
48 |
-
React.createElement(
|
49 |
-
"p",
|
50 |
-
{ className: "text-emerald-500 text-xs" },
|
51 |
-
"Calculation result",
|
52 |
-
),
|
53 |
-
),
|
54 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/open_webpage.js
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Open a webpage
|
3 |
-
* @param {string} src - The URL of the webpage.
|
4 |
-
* @returns {string} The validated URL.
|
5 |
-
*/
|
6 |
-
export function open_webpage(src) {
|
7 |
-
try {
|
8 |
-
const urlObj = new URL(src);
|
9 |
-
if (!["http:", "https:"].includes(urlObj.protocol)) {
|
10 |
-
throw new Error("Only HTTP and HTTPS URLs are allowed.");
|
11 |
-
}
|
12 |
-
return urlObj.href;
|
13 |
-
} catch (error) {
|
14 |
-
throw new Error("Invalid URL provided.");
|
15 |
-
}
|
16 |
-
}
|
17 |
-
|
18 |
-
export default (input, output) => {
|
19 |
-
return React.createElement(
|
20 |
-
"div",
|
21 |
-
{ className: "bg-blue-50 border border-blue-200 rounded-lg p-4" },
|
22 |
-
React.createElement(
|
23 |
-
"div",
|
24 |
-
{ className: "flex items-center mb-2" },
|
25 |
-
React.createElement(
|
26 |
-
"div",
|
27 |
-
{
|
28 |
-
className:
|
29 |
-
"w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center mr-3",
|
30 |
-
},
|
31 |
-
"🌐",
|
32 |
-
),
|
33 |
-
React.createElement(
|
34 |
-
"h3",
|
35 |
-
{ className: "text-blue-900 font-semibold" },
|
36 |
-
"Web Page",
|
37 |
-
),
|
38 |
-
),
|
39 |
-
React.createElement("iframe", {
|
40 |
-
src: output,
|
41 |
-
className: "w-full border border-blue-300 rounded",
|
42 |
-
width: 480,
|
43 |
-
height: 360,
|
44 |
-
title: "Embedded content",
|
45 |
-
allow: "autoplay",
|
46 |
-
frameBorder: "0",
|
47 |
-
}),
|
48 |
-
);
|
49 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/random_number.js
DELETED
@@ -1,51 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Generate a random integer between min and max (inclusive).
|
3 |
-
* @param {number} min - Minimum value (inclusive).
|
4 |
-
* @param {number} max - Maximum value (inclusive).
|
5 |
-
* @returns {number} A random integer.
|
6 |
-
*/
|
7 |
-
export function random_number(min, max) {
|
8 |
-
min = Math.ceil(Number(min));
|
9 |
-
max = Math.floor(Number(max));
|
10 |
-
if (isNaN(min) || isNaN(max) || min > max) {
|
11 |
-
throw new Error("Invalid min or max value.");
|
12 |
-
}
|
13 |
-
return Math.floor(Math.random() * (max - min + 1)) + min;
|
14 |
-
}
|
15 |
-
|
16 |
-
export default (input, output) =>
|
17 |
-
React.createElement(
|
18 |
-
"div",
|
19 |
-
{ className: "bg-indigo-50 border border-indigo-200 rounded-lg p-4" },
|
20 |
-
React.createElement(
|
21 |
-
"div",
|
22 |
-
{ className: "flex items-center mb-2" },
|
23 |
-
React.createElement(
|
24 |
-
"div",
|
25 |
-
{
|
26 |
-
className:
|
27 |
-
"w-8 h-8 bg-indigo-100 rounded-full flex items-center justify-center mr-3",
|
28 |
-
},
|
29 |
-
"🎲",
|
30 |
-
),
|
31 |
-
React.createElement(
|
32 |
-
"h3",
|
33 |
-
{ className: "text-indigo-900 font-semibold" },
|
34 |
-
"Random Number",
|
35 |
-
),
|
36 |
-
),
|
37 |
-
React.createElement(
|
38 |
-
"div",
|
39 |
-
{ className: "text-center" },
|
40 |
-
React.createElement(
|
41 |
-
"div",
|
42 |
-
{ className: "text-3xl font-bold text-indigo-600 mb-1" },
|
43 |
-
output,
|
44 |
-
),
|
45 |
-
React.createElement(
|
46 |
-
"p",
|
47 |
-
{ className: "text-indigo-500 text-xs" },
|
48 |
-
`Range: ${input.min || "?"} - ${input.max || "?"}`,
|
49 |
-
),
|
50 |
-
),
|
51 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/sleep.js
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Sleep for a given number of seconds.
|
3 |
-
* @param {number} seconds - The number of seconds to sleep.
|
4 |
-
* @return {void}
|
5 |
-
*/
|
6 |
-
export async function sleep(seconds) {
|
7 |
-
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
8 |
-
}
|
9 |
-
|
10 |
-
export default (input, output) =>
|
11 |
-
React.createElement(
|
12 |
-
"div",
|
13 |
-
{ className: "bg-purple-50 border border-purple-200 rounded-lg p-4" },
|
14 |
-
React.createElement(
|
15 |
-
"div",
|
16 |
-
{ className: "flex items-center mb-2" },
|
17 |
-
React.createElement(
|
18 |
-
"div",
|
19 |
-
{
|
20 |
-
className:
|
21 |
-
"w-8 h-8 bg-purple-100 rounded-full flex items-center justify-center mr-3",
|
22 |
-
},
|
23 |
-
"😴",
|
24 |
-
),
|
25 |
-
React.createElement(
|
26 |
-
"h3",
|
27 |
-
{ className: "text-purple-900 font-semibold" },
|
28 |
-
"Sleep",
|
29 |
-
),
|
30 |
-
),
|
31 |
-
React.createElement(
|
32 |
-
"div",
|
33 |
-
{ className: "text-sm space-y-1" },
|
34 |
-
React.createElement(
|
35 |
-
"p",
|
36 |
-
{ className: "text-purple-700 font-medium" },
|
37 |
-
`Slept for ${input.seconds || "unknown"} seconds`,
|
38 |
-
),
|
39 |
-
React.createElement(
|
40 |
-
"p",
|
41 |
-
{ className: "text-purple-600 text-xs" },
|
42 |
-
output,
|
43 |
-
),
|
44 |
-
),
|
45 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/speak.js
DELETED
@@ -1,58 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Speak text using the browser's speech synthesis API.
|
3 |
-
* @param {string} text - The text to speak.
|
4 |
-
* @param {string} [voice] - The name of the voice to use (optional).
|
5 |
-
* @return {void}
|
6 |
-
*/
|
7 |
-
export function speak(text, voice = undefined) {
|
8 |
-
const utter = new window.SpeechSynthesisUtterance(text);
|
9 |
-
if (voice) {
|
10 |
-
const voices = window.speechSynthesis.getVoices();
|
11 |
-
const match = voices.find((v) => v.name === voice);
|
12 |
-
if (match) utter.voice = match;
|
13 |
-
}
|
14 |
-
window.speechSynthesis.speak(utter);
|
15 |
-
}
|
16 |
-
|
17 |
-
export default (input, output) =>
|
18 |
-
React.createElement(
|
19 |
-
"div",
|
20 |
-
{ className: "bg-blue-50 border border-blue-200 rounded-lg p-4" },
|
21 |
-
React.createElement(
|
22 |
-
"div",
|
23 |
-
{ className: "flex items-center mb-2" },
|
24 |
-
React.createElement(
|
25 |
-
"div",
|
26 |
-
{
|
27 |
-
className:
|
28 |
-
"w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center mr-3",
|
29 |
-
},
|
30 |
-
"🔊",
|
31 |
-
),
|
32 |
-
React.createElement(
|
33 |
-
"h3",
|
34 |
-
{ className: "text-blue-900 font-semibold" },
|
35 |
-
"Speech Synthesis",
|
36 |
-
),
|
37 |
-
),
|
38 |
-
React.createElement(
|
39 |
-
"div",
|
40 |
-
{ className: "text-sm space-y-1" },
|
41 |
-
React.createElement(
|
42 |
-
"p",
|
43 |
-
{ className: "text-blue-700 font-medium" },
|
44 |
-
`Speaking: "${input.text || "Unknown text"}"`,
|
45 |
-
),
|
46 |
-
input.voice &&
|
47 |
-
React.createElement(
|
48 |
-
"p",
|
49 |
-
{ className: "text-blue-600 text-xs" },
|
50 |
-
`Voice: ${input.voice}`,
|
51 |
-
),
|
52 |
-
React.createElement(
|
53 |
-
"p",
|
54 |
-
{ className: "text-blue-600 text-xs" },
|
55 |
-
typeof output === "string" ? output : "Speech completed successfully",
|
56 |
-
),
|
57 |
-
),
|
58 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/tools/template.js
DELETED
@@ -1,47 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Description of the tool.
|
3 |
-
* @param {any} parameter1 - Description of the first parameter.
|
4 |
-
* @param {any} parameter2 - Description of the second parameter.
|
5 |
-
* @returns {any} Description of the return value.
|
6 |
-
*/
|
7 |
-
export function new_tool(parameter1, parameter2) {
|
8 |
-
// TODO: Implement the tool logic here
|
9 |
-
return true; // Placeholder return value
|
10 |
-
}
|
11 |
-
|
12 |
-
export default (input, output) =>
|
13 |
-
React.createElement(
|
14 |
-
"div",
|
15 |
-
{ className: "bg-amber-50 border border-amber-200 rounded-lg p-4" },
|
16 |
-
React.createElement(
|
17 |
-
"div",
|
18 |
-
{ className: "flex items-center mb-2" },
|
19 |
-
React.createElement(
|
20 |
-
"div",
|
21 |
-
{
|
22 |
-
className:
|
23 |
-
"w-8 h-8 bg-amber-100 rounded-full flex items-center justify-center mr-3",
|
24 |
-
},
|
25 |
-
"🛠️",
|
26 |
-
),
|
27 |
-
React.createElement(
|
28 |
-
"h3",
|
29 |
-
{ className: "text-amber-900 font-semibold" },
|
30 |
-
"Tool Name",
|
31 |
-
),
|
32 |
-
),
|
33 |
-
React.createElement(
|
34 |
-
"div",
|
35 |
-
{ className: "text-sm space-y-1" },
|
36 |
-
React.createElement(
|
37 |
-
"p",
|
38 |
-
{ className: "text-amber-700 font-medium" },
|
39 |
-
`Input: ${JSON.stringify(input)}`,
|
40 |
-
),
|
41 |
-
React.createElement(
|
42 |
-
"p",
|
43 |
-
{ className: "text-amber-600 text-xs" },
|
44 |
-
`Output: ${output}`,
|
45 |
-
),
|
46 |
-
),
|
47 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|