mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 02:03:16 +00:00
web-ui package
This commit is contained in:
parent
7159c9734e
commit
f2eecb78d2
55 changed files with 10932 additions and 13 deletions
3
packages/web-ui/example/.gitignore
vendored
Normal file
3
packages/web-ui/example/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
dist
|
||||
.DS_Store
|
||||
61
packages/web-ui/example/README.md
Normal file
61
packages/web-ui/example/README.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Pi Web UI - Example
|
||||
|
||||
This is a minimal example showing how to use `@mariozechner/pi-web-ui` in a web application.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) in your browser.
|
||||
|
||||
## What's Included
|
||||
|
||||
This example demonstrates:
|
||||
|
||||
- **ChatPanel** - The main chat interface component
|
||||
- **System Prompt** - Custom configuration for the AI assistant
|
||||
- **Tools** - JavaScript REPL and artifacts tool
|
||||
|
||||
## Configuration
|
||||
|
||||
### API Keys
|
||||
|
||||
The example uses **Direct Mode** by default, which means it calls AI provider APIs directly from the browser.
|
||||
|
||||
To use the chat:
|
||||
|
||||
1. Click the settings icon (⚙️) in the chat interface
|
||||
2. Click "Manage API Keys"
|
||||
3. Add your API key for your preferred provider:
|
||||
- **Anthropic**: Get a key from [console.anthropic.com](https://console.anthropic.com/)
|
||||
- **OpenAI**: Get a key from [platform.openai.com](https://platform.openai.com/)
|
||||
- **Google**: Get a key from [makersuite.google.com](https://makersuite.google.com/)
|
||||
|
||||
API keys are stored in your browser's localStorage and never sent to any server except the AI provider's API.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
example/
|
||||
├── src/
|
||||
│ ├── main.ts # Main application entry point
|
||||
│ └── app.css # Tailwind CSS configuration
|
||||
├── index.html # HTML entry point
|
||||
├── package.json # Dependencies
|
||||
├── vite.config.ts # Vite configuration
|
||||
└── tsconfig.json # TypeScript configuration
|
||||
```
|
||||
|
||||
## Learn More
|
||||
|
||||
- [Pi Web UI Documentation](../README.md)
|
||||
- [Pi AI Documentation](../../ai/README.md)
|
||||
- [Mini Lit Documentation](https://github.com/mariozechner/mini-lit)
|
||||
13
packages/web-ui/example/index.html
Normal file
13
packages/web-ui/example/index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Pi Web UI - Example</title>
|
||||
<meta name="description" content="Example usage of @mariozechner/pi-web-ui - Reusable AI chat interface" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
1965
packages/web-ui/example/package-lock.json
generated
Normal file
1965
packages/web-ui/example/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
22
packages/web-ui/example/package.json
Normal file
22
packages/web-ui/example/package.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "pi-web-ui-example",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mariozechner/mini-lit": "^0.1.7",
|
||||
"@mariozechner/pi-ai": "file:../../ai",
|
||||
"@mariozechner/pi-web-ui": "file:../",
|
||||
"@tailwindcss/vite": "^4.1.13",
|
||||
"lit": "^3.3.1",
|
||||
"lucide": "^0.544.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^7.1.6"
|
||||
}
|
||||
}
|
||||
1
packages/web-ui/example/src/app.css
Normal file
1
packages/web-ui/example/src/app.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import "../../dist/app.css";
|
||||
51
packages/web-ui/example/src/main.ts
Normal file
51
packages/web-ui/example/src/main.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { Button, icon } from "@mariozechner/mini-lit";
|
||||
import "@mariozechner/mini-lit/dist/ThemeToggle.js";
|
||||
import { ChatPanel, ApiKeysDialog } from "@mariozechner/pi-web-ui";
|
||||
import { html, render } from "lit";
|
||||
import { Settings } from "lucide";
|
||||
import "./app.css";
|
||||
|
||||
const systemPrompt = `You are a helpful AI assistant with access to various tools.
|
||||
|
||||
Available tools:
|
||||
- JavaScript REPL: Execute JavaScript code in a sandboxed browser environment (can do calculations, get time, process data, create visualizations, etc.)
|
||||
- Artifacts: Create interactive HTML, SVG, Markdown, and text artifacts
|
||||
|
||||
Feel free to use these tools when needed to provide accurate and helpful responses.`;
|
||||
|
||||
// Create and configure the chat panel
|
||||
const chatPanel = new ChatPanel();
|
||||
chatPanel.systemPrompt = systemPrompt;
|
||||
chatPanel.additionalTools = [];
|
||||
|
||||
// Render the app structure
|
||||
const appHtml = html`
|
||||
<div class="w-full h-screen flex flex-col bg-background text-foreground overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between border-b border-border shrink-0">
|
||||
<div class="px-4 py-3">
|
||||
<span class="text-base font-semibold text-foreground">Pi Web UI Example</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 px-2">
|
||||
<theme-toggle></theme-toggle>
|
||||
${Button({
|
||||
variant: "ghost",
|
||||
size: "sm",
|
||||
children: icon(Settings, "sm"),
|
||||
onClick: () => ApiKeysDialog.open(),
|
||||
title: "API Keys Settings",
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat Panel -->
|
||||
${chatPanel}
|
||||
</div>
|
||||
`;
|
||||
|
||||
const app = document.getElementById("app");
|
||||
if (!app) {
|
||||
throw new Error("App container not found");
|
||||
}
|
||||
|
||||
render(appHtml, app);
|
||||
104
packages/web-ui/example/src/test-sessions.ts
Normal file
104
packages/web-ui/example/src/test-sessions.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
const simpleHtml = {
|
||||
"systemPrompt": "You are a helpful AI assistant with access to various tools.\n\nAvailable tools:\n- Calculator: Perform mathematical calculations\n- Current Time: Get the current date and time in any timezone\n- Artifacts: Create interactive HTML, SVG, Markdown, and text artifacts\n\nFeel free to use these tools when needed to provide accurate and helpful responses.",
|
||||
"model": {
|
||||
"id": "claude-sonnet-4-5-20250929",
|
||||
"name": "Claude Sonnet 4.5",
|
||||
"api": "anthropic-messages",
|
||||
"provider": "anthropic",
|
||||
"baseUrl": "https://api.anthropic.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 3,
|
||||
"output": 15,
|
||||
"cacheRead": 0.3,
|
||||
"cacheWrite": 3.75
|
||||
},
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 64000
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "simple html"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "I'll create a simple HTML page for you!"
|
||||
},
|
||||
{
|
||||
"type": "toolCall",
|
||||
"id": "toolu_01JXaq9rMAUt1goJ5tMQXgLh",
|
||||
"name": "artifacts",
|
||||
"arguments": {
|
||||
"command": "create",
|
||||
"filename": "index.html",
|
||||
"title": "Simple HTML Page",
|
||||
"content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Simple HTML Page</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n max-width: 800px;\n margin: 0 auto;\n padding: 20px;\n background-color: #f5f5f5;\n }\n \n header {\n background-color: #4CAF50;\n color: white;\n padding: 20px;\n text-align: center;\n border-radius: 8px;\n }\n \n main {\n background-color: white;\n padding: 20px;\n margin-top: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n \n button {\n background-color: #4CAF50;\n color: white;\n padding: 10px 20px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 16px;\n }\n \n button:hover {\n background-color: #45a049;\n }\n </style>\n</head>\n<body>\n <header>\n <h1>Welcome to My Simple Page</h1>\n </header>\n \n <main>\n <h2>Hello!</h2>\n <p>This is a simple HTML page with some basic styling.</p>\n \n <h3>Features:</h3>\n <ul>\n <li>Clean design</li>\n <li>Responsive layout</li>\n <li>Interactive button</li>\n </ul>\n \n <button onclick=\"showMessage()\">Click Me!</button>\n <p id=\"message\"></p>\n </main>\n \n <script>\n function showMessage() {\n document.getElementById('message').textContent = '✨ Thanks for clicking!';\n }\n </script>\n</body>\n</html>"
|
||||
}
|
||||
}
|
||||
],
|
||||
"api": "anthropic-messages",
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-4-5-20250929",
|
||||
"usage": {
|
||||
"input": 2108,
|
||||
"output": 666,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"cost": {
|
||||
"input": 0.006324,
|
||||
"output": 0.00999,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.016314000000000002
|
||||
}
|
||||
},
|
||||
"stopReason": "toolUse"
|
||||
},
|
||||
{
|
||||
"role": "toolResult",
|
||||
"toolCallId": "toolu_01JXaq9rMAUt1goJ5tMQXgLh",
|
||||
"toolName": "artifacts",
|
||||
"output": "Created file index.html\n\nExecution timed out. Partial logs:\nKeine Logs für index.html",
|
||||
"isError": false
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "I've created a simple HTML page for you! It includes:\n\n- **Clean header** with a green background\n- **Main content area** with a white card-style design\n- **A list** showing some features\n- **An interactive button** that displays a message when clicked\n- **Responsive styling** that looks good on different screen sizes\n\nThe page has a light gray background and uses simple, clean styling. Try clicking the button to see it in action! \n\nWould you like me to modify anything or add more features?"
|
||||
}
|
||||
],
|
||||
"api": "anthropic-messages",
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-4-5-20250929",
|
||||
"usage": {
|
||||
"input": 2811,
|
||||
"output": 115,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"cost": {
|
||||
"input": 0.008433,
|
||||
"output": 0.001725,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.010158
|
||||
}
|
||||
},
|
||||
"stopReason": "stop"
|
||||
}
|
||||
]
|
||||
};
|
||||
15
packages/web-ui/example/tsconfig.json
Normal file
15
packages/web-ui/example/tsconfig.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
6
packages/web-ui/example/vite.config.ts
Normal file
6
packages/web-ui/example/vite.config.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import tailwindcss from "@tailwindcss/vite";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss()],
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue