feat(prototypes): add pi-web-ui-lan prototype
LAN-accessible web UI for pi agent interaction.
This commit is contained in:
parent
1e1965dc17
commit
131fb86852
26
prototypes/pi-web-ui-lan/README.md
Normal file
26
prototypes/pi-web-ui-lan/README.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Pi Web UI (LAN prototype)
|
||||
|
||||
Minimal LAN-only web UI using `@mariozechner/pi-web-ui`.
|
||||
|
||||
## Run (LAN)
|
||||
|
||||
```bash
|
||||
cd /home/dan/proj/skills/prototypes/pi-web-ui-lan
|
||||
npm install
|
||||
npm run dev:lan
|
||||
```
|
||||
|
||||
Vite will print a LAN URL (e.g., `http://192.168.1.20:5173`). Open it on your phone connected to the same Wi‑Fi.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Start the dev server (`npm run dev:lan`).
|
||||
2. Open the LAN URL on the phone.
|
||||
3. Open Settings → Manage API Keys and add your provider key.
|
||||
4. Chat in the UI.
|
||||
|
||||
## Notes / Limitations
|
||||
|
||||
- This prototype runs in **direct mode** (browser calls provider APIs directly).
|
||||
- It does **not** access the local filesystem or repo yet.
|
||||
- Next step for repo access: add a local RPC/agent backend and bridge it to the UI.
|
||||
12
prototypes/pi-web-ui-lan/index.html
Normal file
12
prototypes/pi-web-ui-lan/index.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!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 (LAN)</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
22
prototypes/pi-web-ui-lan/package.json
Normal file
22
prototypes/pi-web-ui-lan/package.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "pi-web-ui-lan",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev:lan": "vite --host 0.0.0.0 --port 5173",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --host 0.0.0.0 --port 5173"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mariozechner/pi-agent-core": "^0.49.3",
|
||||
"@mariozechner/pi-ai": "^0.49.3",
|
||||
"@mariozechner/pi-web-ui": "^0.49.3",
|
||||
"lit": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^7.1.6"
|
||||
}
|
||||
}
|
||||
2938
prototypes/pi-web-ui-lan/pnpm-lock.yaml
Normal file
2938
prototypes/pi-web-ui-lan/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
49
prototypes/pi-web-ui-lan/src/main.ts
Normal file
49
prototypes/pi-web-ui-lan/src/main.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import { Agent } from "@mariozechner/pi-agent-core";
|
||||
import { getModel } from "@mariozechner/pi-ai";
|
||||
import {
|
||||
ApiKeyPromptDialog,
|
||||
AppStorage,
|
||||
ChatPanel,
|
||||
IndexedDBStorageBackend,
|
||||
ProviderKeysStore,
|
||||
SessionsStore,
|
||||
SettingsStore,
|
||||
defaultConvertToLlm,
|
||||
setAppStorage,
|
||||
} from "@mariozechner/pi-web-ui";
|
||||
import "@mariozechner/pi-web-ui/app.css";
|
||||
|
||||
const settings = new SettingsStore();
|
||||
const providerKeys = new ProviderKeysStore();
|
||||
const sessions = new SessionsStore();
|
||||
|
||||
const backend = new IndexedDBStorageBackend({
|
||||
dbName: "pi-web-ui-lan",
|
||||
version: 1,
|
||||
stores: [settings.getConfig(), providerKeys.getConfig(), sessions.getConfig(), SessionsStore.getMetadataConfig()],
|
||||
});
|
||||
|
||||
settings.setBackend(backend);
|
||||
providerKeys.setBackend(backend);
|
||||
sessions.setBackend(backend);
|
||||
|
||||
const storage = new AppStorage(settings, providerKeys, sessions, undefined, backend);
|
||||
setAppStorage(storage);
|
||||
|
||||
const agent = new Agent({
|
||||
initialState: {
|
||||
systemPrompt: "You are a helpful assistant.",
|
||||
model: getModel("google", "gemini-3-flash-preview"),
|
||||
thinkingLevel: "off",
|
||||
messages: [],
|
||||
tools: [],
|
||||
},
|
||||
convertToLlm: defaultConvertToLlm,
|
||||
});
|
||||
|
||||
const chatPanel = new ChatPanel();
|
||||
await chatPanel.setAgent(agent, {
|
||||
onApiKeyRequired: async (provider) => ApiKeyPromptDialog.prompt(provider),
|
||||
});
|
||||
|
||||
document.getElementById("app")?.appendChild(chatPanel);
|
||||
15
prototypes/pi-web-ui-lan/tsconfig.json
Normal file
15
prototypes/pi-web-ui-lan/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/**/*"]
|
||||
}
|
||||
10
prototypes/pi-web-ui-lan/vite.config.ts
Normal file
10
prototypes/pi-web-ui-lan/vite.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
conditions: ["production", "browser", "module", "default"],
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
},
|
||||
});
|
||||
Loading…
Reference in a new issue