Private
Public Access
1
0
Commit Graph

21 Commits

Author SHA1 Message Date
Catherine Renelle 2f389ab8e9 Security hardening: fix IDOR vulnerabilities, add rate limiting, SSRF protection, and encryption upgrades
- Fix ReconciliationController and BankSync LinkAccount/UpdateLinkedAccount IDOR (verify account ownership)
- Add ASP.NET Core rate limiting: strict on auth endpoints, global on all API routes
- Harden SSRF validation on Ollama URL (IPv6-mapped bypass, link-local, 0.0.0.0 blocking)
- Upgrade encryption from AES-CBC to AES-GCM with HKDF key derivation (backward-compatible decrypt)
- Add startup validation that rejects default JWT/encryption keys in Production
- Add security headers (X-Frame-Options, CSP, HSTS, Cache-Control, nosniff) to API and nginx
- Mask account numbers in API responses (show last 4 digits only)
- Add password strength validation (min 8 chars) and BCrypt work factor 12
- Hash refresh tokens (SHA-256) before database storage
- Set JWT ClockSkew to zero for immediate expiry enforcement
- Add file upload size limit (10 MB) and filename sanitization
- Cap transaction search PageSize to 200
- Fix FileWatcherService cross-user account matching in multi-user deployments
- Sanitize console.error calls to prevent token leakage in browser logs
- Parameterize raw SQL in SimpleFinConnectionMigration
- Make AuthService.GenerateAuthResponse fully async

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:53:20 -05:00
Catherine Renelle b38865050c Include memo field in AI chat transaction summaries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:24:37 -05:00
Catherine Renelle 688dd333dc Add adjustable context size, custom chatbot name, and cat icon for AI chat
Settings > AI tab now includes context size slider (2048–131072) with VRAM
estimate and a chatbot name field. ChatService reads both dynamically instead
of hardcoding num_ctx=16384 and "Purrse AI". Chat panel FAB and empty state
use mdi-cat icon to match the rest of the app.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:38:07 -05:00
Catherine Renelle 401147009a Increase Ollama context window to 16k tokens
Ollama defaults to 2048 tokens which is far too small for page context
data + 15 tool definitions + conversation history. Added num_ctx=16384
via the options field on all Ollama requests. With Qwen at ~4GB and
7GB VRAM free this fits comfortably.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 19:25:24 -05:00
Catherine Renelle f5d6e9f98e Distinguish read vs write operations in AI system prompt
The AI was claiming to update categories without actually calling the
update tool — it answered from page context as if the change was made.
Restructured the system prompt to clearly separate read-only questions
(can answer from page data) from mutations (MUST call tools). The AI
is now told to never claim a change was made without calling the
appropriate tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:53:07 -05:00
Catherine Renelle 8aeee44368 Add logging and retry-without-tools for empty AI responses
When the model returns empty content with page context present, the
15 tool definitions likely overwhelm the model's attention. Now on
empty response, the request is retried with tools stripped so the
model focuses on answering from the page data. Also added diagnostic
logging for page context receipt and empty response details.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:44:39 -05:00
Catherine Renelle 8a295c48dd Handle empty string AI responses as fallback
The null-coalescing operator only caught null, not empty/whitespace
responses. When Ollama returns empty content (common when the model
hesitates between tool calling and text), the empty string was saved
as the assistant message. Now uses IsNullOrWhiteSpace to catch both.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:26:32 -05:00
Catherine Renelle 8e342045eb Skip tool-use nudge when page context provides data
The nudge forced the AI to call a tool even when the answer was
already in the page context (e.g. Sarku transactions visible on the
Transactions page). This caused the model to pick an unrelated tool.
Now the nudge also checks for page context — if the current page has
data attached, the model is allowed to answer from it directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:23:10 -05:00
Catherine Renelle 8421d244f2 Fix AI date search matching only midnight instead of full day
When the AI searched for transactions on a specific date like
"2026-02-11", ParseDateArg produced 2026-02-11T00:00:00Z (midnight).
The query "Date <= midnight" excluded any transaction stored with a
time component later that day. Now date-only end dates are bumped to
23:59:59.999 so the full day is covered. Applied to search_transactions,
get_spending_by_category, and get_income_vs_expense tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:36:26 -05:00
Catherine Renelle dbe351ac45 Fix AI ignoring tool results and page context in follow-ups
Two issues caused the AI to lose context in multi-turn conversations:

1. Page context was a system message buried before 20 conversation
   messages. Now it's injected directly into the user's message so
   the model sees the data right next to the question.

2. Prior tool results were replayed with role="tool", which many
   Ollama models ignore in conversation history. Now they're replayed
   as assistant messages with a [Tool Result] prefix so the model
   reliably reads them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:32:37 -05:00
Catherine Renelle 6891f2d884 Fix AI losing conversational context on terse follow-ups
The tool-use nudge fired on every first response without tools, even
when the conversation already had tool results the AI could reference.
This forced the AI to make a new (broader) tool call instead of
interpreting a short follow-up like "2026-02-11" in context of the
prior exchange. Now the nudge only fires when there are no prior tool
results in the conversation. Also added a system prompt rule telling
the AI to interpret ambiguous follow-ups in context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:26:50 -05:00
Catherine Renelle 3402a5210e Tell AI not to restate data already shown in tool result tables
Tool results are rendered as rich tables/charts in the UI, but the
system prompt was telling the AI to list transaction details and
"summarize tool results naturally", causing it to repeat the same
data in text. Updated the prompt to explain that tool results are
already visible and the AI should give a brief insight instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:15:49 -05:00
Catherine Renelle 8b6378805c Include transaction ID in category-update tool summary
The LLM summary for update_transaction_category was missing the
transaction ID, so when the user asked to undo a change the AI had
to guess which record from the page context and often picked the
wrong one. Now the summary includes the exact ID and the old category
name, giving the AI everything it needs to reverse the change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:13:19 -05:00
Catherine Renelle c2a4272585 Add floating AI chat panel with page context awareness
Replace the standalone /chat page with a bottom-right floating widget
available on every page. The panel sends page context with each message
so the AI knows what the user is viewing. On the Transactions page,
the full visible transaction list (with filters) is serialized into
the context so the AI can answer questions about on-screen entries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:51:52 -05:00
Catherine Renelle 04d21afc87 Add Ollama diagnostic logging and broaden tool-call retry
Log model name, tool count, raw response preview, and parsed
tool_call count at INFO level. Broaden the retry nudge to trigger
whenever no tools are called on the first attempt, not just when
code is detected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 20:32:48 -05:00
Catherine Renelle a7d5b880ae Strengthen system prompt and strip code blocks from AI responses
Restructure the system prompt as explicit rules to more forcefully
prevent smaller models from generating code. Add a server-side
safety net that strips fenced code blocks from assistant responses
before returning them to the user.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:13:34 -05:00
Catherine Renelle 7a44492832 Strengthen system prompt to prevent LLM from generating code
Smaller models sometimes output Python/JS code instead of invoking
tools. Add explicit instruction to never generate code and always
call the provided function tools directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:03:03 -05:00
Catherine Renelle 6552a97036 Add budget, loan, payee, and scheduled transaction tools to AI chat
Integrate 6 new tool chains into the chat service: get_budget,
get_budget_summary, get_loan_details, calculate_loan_payoff,
list_payees, and get_scheduled_transactions. Also raises the
search_transactions page_size cap from 25 to 50 and the upcoming
bills display from 5 to 10.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 08:28:31 -05:00
Catherine Renelle 26fb3dc1e1 Add category management tools to AI chat (list, create, delete)
Three new tools: list_categories shows all categories with type and
parent, create_category adds a new one with optional parent nesting,
delete_category removes non-system categories by name. Frontend renders
category tables, success alerts for creation, and warning alerts for
deletion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 23:51:18 -05:00
Catherine Renelle 713f2bfadc Fix date handling to use DateTimeKind.Utc for Npgsql
ParseDateArg now applies DateTime.SpecifyKind(Utc) since TryParse
returns Unspecified kind. Also fixed the spending report fallback
start date to use the DateTimeKind.Utc constructor overload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 23:39:56 -05:00
Catherine Renelle 846edad2a4 Add AI chat with Ollama tool calling for financial queries
Conversational AI chat that uses Ollama's native tool-calling API to query
transactions, spending reports, account balances, dashboard summaries, and
update transaction categories through natural language. Includes persistent
conversation history, a full-page chat UI with sidebar, and rich inline
rendering of tool results (tables, alerts, cards).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 23:34:16 -05:00