Open Net Worth
Open Net Worth는 직접 운영하는 오픈소스 개인 AI 자산 비서로, 전체 재무를 하나의 원장에 기록하고 사용자가 제어하는 AI가 관리
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Conversational agent with real tool use over receipt data — the LLM picks the right SQL tool (list, aggregate, or detail) and answers in natural language.
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Conversational agent that answers in natural language about Peruvian receipts and invoices. Showcases real tool use: the LLM decides which SQL tool to call (list_receipts, query_aggregates, get_receipt_detail), executes it against Neon Postgres, and responds with verifiable data. Reuses the same database as Invoice Extractor — extract first, then analyze.
Author: sebpost2
Live demo · No sign-up · 27 demo receipts preloaded
list_receipts({orderBy: "total_desc"}) → grabs the first id → get_receipt_detail({id}) → writes the answer.z.enum, z.string), the AI SDK validates inputs before execution, and TypeScript infers the types on the server.streamText + useChat).<details> component showing the exact input and output JSON. Visitors see what the model queried, not just what it said.get_receipt_detail, the receipt id is shown. If it comes from a list/aggregate, the scope is shown ("Based on N receipts"). No fabricated references.react-markdown + GFM.npm run seed (Tottus, Pardos, Sodimac, Inkafarma, etc.) plus the 3 real ones from the extractor — 27 receipts total for substantial questions.evals/ lock down the agent's behavior — single-step routing (ES + EN), multi-step list → detail chains, and no-tool refusal for greetings/off-topic. Run with npm run eval. A pre-eval guard verifies the duplicated prompt copy hasn't drifted from src/lib/chat-prompts.ts.| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| Language | TypeScript |
| Styling | Tailwind CSS v4 (dark-first) |
| LLM SDK | Vercel AI SDK v6 (ai, @ai-sdk/groq, @ai-sdk/react) |
| Model | OpenAI gpt-oss-120b via Groq |
| Database | PostgreSQL (Neon, serverless) — shared with the extractor |
| ORM | Prisma 7 with @prisma/adapter-pg |
| Validation | Zod 4 |
| Markdown | react-markdown + remark-gfm |
| Rate limit | In-memory token bucket |
| LLM evals | Promptfoo (OSS) — 22 tool-selection cases under evals/ |
| Deploy | Vercel |
┌──────────┐ sendMessage ┌────────────────┐ streamText ┌──────┐
│ Client │ ─────────────> │ /api/chat │ ───────────────> │ Groq │
│ useChat │ │ (route handler)│ + tools (Zod) │ LLM │
└────┬─────┘ └────────┬───────┘ └───┬──┘
│ │ │
│ UIMessageStream │ │
│ <─────────────────────────────┤ ┌────────┐ tool call │
│ • text-delta │ │ Neon │ <────────────────┤
│ • tool-input-streaming │ │ DB │ │
│ • tool-output-available │ └────────┘ tool result ────┤
│ • text-end │ │
│ │ ... until stepCountIs(5) │
useChat({ transport: DefaultChatTransport }).streamText with the 3 tools and the Groq model.execute (Prisma query) and feeds the result back to the model.stopWhen: stepCountIs(5)) or write the final answer.| Tool | Input | Output | When the model picks it |
|---|---|---|---|
list_receipts | orderBy: "date_desc" | "date_asc" | "total_desc" | "total_asc" | Array of receipts with summary fields | "Show me my receipts", "which was the most expensive?" |
query_aggregates | metric: "total_spent" | "total_igv" | "total_subtotal" | "count" | "all" | Per-currency aggregates | "How much did I spend?", "How many receipts?", "How much VAT?" |
get_receipt_detail | id: string | Full receipt with items | "Give me the details of [id]", final step after identifying a receipt via a list |
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗