Commit 1ba0c9c3edc6
2026-02-16 14:31:17
1 parent
e3b2504
Changed files (4)
src/pi/main-test.ts
@@ -0,0 +1,126 @@
+#!/usr/bin/env node
+/**
+ * Temporary test runner for Pi-based Daneel
+ * This is a quick integration to test current progress
+ * Will be replaced by proper XMPP integration in Phase 6
+ */
+
+import { XmppClient } from "../xmpp/client.js";
+import { XmppAgent } from "./agent-wrapper.js";
+import { getModel } from "@mariozechner/pi-ai";
+import { statusTool } from "./tools/status.js";
+import { bareJid } from "../xmpp/types.js";
+
+interface XmppConfig {
+ jid: string;
+ password: string;
+ ownerJid: string;
+}
+
+function loadConfig(): XmppConfig {
+ const jid = process.env.DANEEL_XMPP_JID;
+ const password = process.env.DANEEL_XMPP_PASSWORD;
+ const ownerJid = process.env.DANEEL_OWNER_JID;
+
+ if (!jid || !password || !ownerJid) {
+ console.error("Missing required environment variables:");
+ console.error(" DANEEL_XMPP_JID");
+ console.error(" DANEEL_XMPP_PASSWORD");
+ console.error(" DANEEL_OWNER_JID");
+ process.exit(1);
+ }
+
+ return { jid, password, ownerJid };
+}
+
+async function main() {
+ console.log("Daneel - XMPP Research Bot (Pi Edition)");
+ console.log("=========================================\n");
+
+ const config = loadConfig();
+
+ // Determine default model
+ const defaultModel = getModel("google", "gemini-2.0-flash");
+ console.log("Using default model: Google Gemini 2.0 Flash");
+
+ // Map of JID -> XmppAgent
+ const agents = new Map<string, XmppAgent>();
+
+ function getOrCreateAgent(jid: string): XmppAgent {
+ const bare = bareJid(jid);
+ let agent = agents.get(bare);
+
+ if (!agent) {
+ console.log(`Creating new agent for JID: ${bare}`);
+ agent = new XmppAgent(bare, defaultModel);
+
+ // Add status tool
+ // TODO: This will be properly integrated in Phase 4 refactor
+ // For now, the agent doesn't use tools yet (empty tools array in agent-wrapper.ts)
+
+ agents.set(bare, agent);
+ }
+
+ return agent;
+ }
+
+ // Create XMPP client
+ const xmpp = new XmppClient({
+ xmpp: {
+ jid: config.jid,
+ password: config.password,
+ ownerJid: config.ownerJid,
+ },
+ llm: {
+ defaultModel: { provider: "google" as any, model: "gemini-2.0-flash" },
+ providers: {},
+ },
+ paths: {
+ dataDir: "./data",
+ inboxPath: process.env.DANEEL_INBOX_PATH || "~/desktop/org/inbox.org",
+ },
+ debug: process.env.DANEEL_DEBUG === "true",
+ });
+
+ // Set up message handler
+ xmpp.onMessage(async (message) => {
+ console.log(`[${new Date().toISOString()}] Message from ${bareJid(message.from)}: ${message.body.slice(0, 50)}...`);
+
+ try {
+ const agent = getOrCreateAgent(message.from);
+ const response = await agent.processMessage(message.body);
+
+ await xmpp.sendMessage(message.from, response);
+ console.log(`[${new Date().toISOString()}] Response sent (${response.length} chars)`);
+ } catch (error) {
+ console.error("Error processing message:", error);
+ await xmpp.sendMessage(
+ message.from,
+ `Error processing your message: ${error instanceof Error ? error.message : 'Unknown error'}`
+ );
+ }
+ });
+
+ // Graceful shutdown
+ const shutdown = async (signal: string) => {
+ console.log(`\nReceived ${signal}, shutting down...`);
+ await xmpp.stop();
+ process.exit(0);
+ };
+
+ process.on("SIGINT", () => shutdown("SIGINT"));
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
+
+ // Start XMPP client
+ console.log("\nConnecting to XMPP server...");
+ console.log(`Bot JID: ${config.jid}`);
+ console.log(`Owner JID: ${config.ownerJid}`);
+ console.log("\nWaiting for messages...\n");
+
+ await xmpp.start();
+}
+
+main().catch((error) => {
+ console.error("Fatal error:", error);
+ process.exit(1);
+});
package.json
@@ -8,6 +8,7 @@
"build": "tsc",
"dev": "tsc --watch",
"start": "node dist/main.js",
+ "start:pi": "node dist/pi/main-test.js",
"test": "vitest run",
"test:watch": "vitest",
"test:ui": "vitest --ui"
test-pi-bot.sh
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+# Test script for Pi-based Daneel bot
+#
+# This script runs the new Pi-based implementation
+
+set -euo pipefail
+
+# Check if we're in the right directory
+if [ ! -f "package.json" ] || ! grep -q "daneel" package.json; then
+ echo "Error: Must run from daneel project directory"
+ exit 1
+fi
+
+# Check if built
+if [ ! -d "dist/pi" ]; then
+ echo "Building project..."
+ npm run build
+fi
+
+# Required environment variables
+: "${DANEEL_XMPP_JID:=researchbot@xmpp.sbr.pm}"
+: "${DANEEL_OWNER_JID:=vincent@xmpp.sbr.pm}"
+
+# Check for required password
+if [ -z "${DANEEL_XMPP_PASSWORD:-}" ]; then
+ echo "ERROR: DANEEL_XMPP_PASSWORD is not set"
+ echo ""
+ echo "To get the password from aomi:"
+ echo " ssh aomi.home 'sudo cat /run/agenix/xmpp-research-bot-password'"
+ echo ""
+ echo "Then set it:"
+ echo " export DANEEL_XMPP_PASSWORD='<password>'"
+ exit 1
+fi
+
+# Check for API key
+if [ -z "${GOOGLE_API_KEY:-}" ] && [ -z "${GEMINI_API_KEY:-}" ]; then
+ echo "ERROR: No Google API key found"
+ echo ""
+ echo "Set either:"
+ echo " export GOOGLE_API_KEY='...'"
+ echo " export GEMINI_API_KEY='...'"
+ exit 1
+fi
+
+# Use GEMINI_API_KEY if GOOGLE_API_KEY not set
+: "${GOOGLE_API_KEY:=${GEMINI_API_KEY:-}}"
+
+# Optional settings
+: "${DANEEL_DATA_DIR:=./data}"
+: "${DANEEL_INBOX_PATH:=~/desktop/org/inbox.org}"
+: "${DANEEL_DEBUG:=true}"
+
+# Create data directory
+mkdir -p "$DANEEL_DATA_DIR"
+
+echo "=== Daneel Pi Test Configuration ==="
+echo "XMPP JID: $DANEEL_XMPP_JID"
+echo "Owner JID: $DANEEL_OWNER_JID"
+echo "Data Dir: $DANEEL_DATA_DIR"
+echo "Inbox Path: $DANEEL_INBOX_PATH"
+echo "Debug: $DANEEL_DEBUG"
+echo ""
+echo "API Keys:"
+echo " Google/Gemini: $([ -n "$GOOGLE_API_KEY" ] && echo "✓" || echo "✗")"
+echo ""
+echo "Starting Daneel (Pi Edition)..."
+echo "==================================="
+echo ""
+
+# Export environment
+export DANEEL_XMPP_JID
+export DANEEL_XMPP_PASSWORD
+export DANEEL_OWNER_JID
+export DANEEL_DATA_DIR
+export DANEEL_INBOX_PATH
+export DANEEL_DEBUG
+export GOOGLE_API_KEY
+
+# Run the Pi-based bot
+exec npm run start:pi
TESTING-PI.md
@@ -0,0 +1,228 @@
+# Testing Daneel (Pi Edition)
+
+This guide shows how to test the new Pi-based Daneel implementation.
+
+## Current Status
+
+**Implemented:**
+- ✅ Pi agent wrapper (Phase 3)
+- ✅ Status tool (Phase 4, partial)
+- ✅ Model prefix switching (opus:, g:, etc.)
+- ✅ Slash commands (/ping, /help, /clear, /models, /stats)
+- ✅ XMPP connectivity (using old XmppClient)
+
+**Not Yet Implemented:**
+- ⏭️ Tools integration with agent (status tool exists but not wired to agent yet)
+- ⏭️ Org-mode tool
+- ⏭️ Research tool
+- ⏭️ Web search tool
+- ⏭️ Session persistence
+
+## Prerequisites
+
+1. **XMPP password** from aomi:
+ ```bash
+ ssh aomi.home 'sudo cat /run/agenix/xmpp-research-bot-password'
+ ```
+
+2. **Google API key** (already in environment):
+ ```bash
+ echo $GEMINI_API_KEY # Should show your key
+ ```
+
+## Quick Start
+
+```bash
+# 1. Set the XMPP password
+export DANEEL_XMPP_PASSWORD='<paste-password-from-aomi>'
+
+# 2. Run the test script
+./test-pi-bot.sh
+```
+
+You should see:
+```
+Daneel - XMPP Research Bot (Pi Edition)
+=========================================
+
+Using default model: Google Gemini 2.0 Flash
+Connecting to XMPP server...
+Bot JID: researchbot@xmpp.sbr.pm
+Owner JID: vincent@xmpp.sbr.pm
+
+Waiting for messages...
+```
+
+## Testing from XMPP Client
+
+Open your XMPP client (connected as `vincent@xmpp.sbr.pm`) and message `researchbot@xmpp.sbr.pm`:
+
+### Basic Commands
+
+```
+/ping
+→ pong!
+
+/help
+→ Shows available commands and model prefixes
+
+/models
+→ Lists all available models
+
+/stats
+→ Shows session statistics
+```
+
+### Conversation
+
+```
+Hello!
+→ Gemini responds
+
+What's 2+2?
+→ Gemini answers
+
+/clear
+→ Conversation cleared
+```
+
+### Model Switching
+
+```
+g: Hello from Gemini
+→ Uses Gemini 2.0 Flash (explicit)
+
+opus: Explain quantum computing
+→ Switches to Claude Opus 4 (if ANTHROPIC_API_KEY set)
+
+sonnet: Write a haiku
+→ Switches to Claude Sonnet 4
+
+Regular message
+→ Uses last selected model
+```
+
+### Status Tool (Not Yet Integrated)
+
+The status tool exists and is tested, but it's not yet wired into the agent. After Phase 4 is complete, you'll be able to:
+
+```
+Show me system status
+→ Agent will use status tool and return uptime/memory/load
+```
+
+## What Works vs What Doesn't
+
+### ✅ Working
+
+- XMPP connection and messaging
+- Model selection (via config, not API key detection yet)
+- Model prefix parsing and switching
+- Slash commands
+- Conversation context maintenance
+- Per-JID session isolation
+
+### ⏳ Partially Working
+
+- Status tool (implemented but not integrated with agent)
+
+### ❌ Not Working Yet
+
+- Automatic tool calling (agent has empty tools array)
+- Org-mode saving
+- Research queries
+- Web search
+- Session persistence to disk
+
+## Troubleshooting
+
+### "DANEEL_XMPP_PASSWORD is not set"
+
+Get it from aomi:
+```bash
+ssh aomi.home 'sudo cat /run/agenix/xmpp-research-bot-password'
+export DANEEL_XMPP_PASSWORD='...'
+```
+
+### "No Google API key found"
+
+Check environment:
+```bash
+echo $GEMINI_API_KEY
+# or
+export GOOGLE_API_KEY='...'
+```
+
+### Connection timeout
+
+Make sure XMPP server is running:
+```bash
+ping xmpp.sbr.pm
+# Should be on aion
+```
+
+### Model switching doesn't work
+
+Currently need API keys for each provider:
+- `ANTHROPIC_API_KEY` for Claude models
+- `GOOGLE_API_KEY` or `GEMINI_API_KEY` for Gemini
+- `OPENAI_API_KEY` for GPT models
+
+Without the API key, switching to that provider will fail.
+
+## Comparing Old vs New Implementation
+
+### Old (Custom)
+```bash
+./test-run.sh
+# Uses custom LLM providers
+# 8 providers
+# Custom session management
+```
+
+### New (Pi-based)
+```bash
+./test-pi-bot.sh
+# Uses Pi libraries
+# 20+ providers available
+# Pi's Agent and session management
+```
+
+Both should behave similarly for basic conversation, but the Pi version has more providers available.
+
+## Next Steps
+
+After Phase 4 is complete:
+1. Tools will be integrated with agent
+2. Can test tool calling
+3. Can test org-mode saving
+4. Can test research queries
+
+## Manual Testing Checklist
+
+- [ ] Bot connects to XMPP
+- [ ] `/ping` responds with "pong!"
+- [ ] `/help` shows commands
+- [ ] Basic conversation works
+- [ ] `g: message` uses Gemini
+- [ ] `/clear` clears conversation
+- [ ] `/stats` shows message counts
+- [ ] `/models` lists available models
+- [ ] Bot responds only to owner JID
+- [ ] Per-JID sessions are isolated
+
+## Development Workflow
+
+```bash
+# Watch mode (auto-rebuild on file changes)
+npm run dev
+
+# In another terminal, run the bot
+./test-pi-bot.sh
+
+# Run tests
+npm test
+
+# Run specific test file
+npx vitest src/pi/agent-wrapper.test.ts
+```