feat(assistant): tool-calling LLM assistant replacing NLP intent parser - #337
Open
sammajayi wants to merge 3 commits into
Open
feat(assistant): tool-calling LLM assistant replacing NLP intent parser#337sammajayi wants to merge 3 commits into
sammajayi wants to merge 3 commits into
Conversation
Adds a tool-calling conversational assistant (src/agent/assistant/, src/agent/tools/) that replaces src/nlp/parser.ts as the recognition layer for open-ended requests on WhatsApp, Telegram, and a new POST /api/v1/assistant/chat endpoint, while keeping the platform's core integrity property: no money moves and no decision is attributed to the agent unless it went through the same verified, audited, idempotent paths every other feature uses. - Tool registry (src/agent/tools/): typed, Zod-schema'd wrappers over existing service-layer functions only (deposit/withdraw via executeDeposit/executeWithdraw, rebalance via executeRebalanceIfNeeded, strategy follow/unfollow, alerts, recurring deposits, and read tools for portfolio/positions/transactions/protocol rates/goals). A structural test asserts no tool imports stellar/contract or stellar/wallet directly. - Planner (src/agent/assistant/planner.ts): Anthropic tool-calling, schema-validates every proposed call before anything runs; an out-of-schema or hallucinated tool is rejected, never executed. - Confirmation gate (src/agent/assistant/confirmations.ts): every action tool is dry-run and parked, and only executes on an explicit affirmative reply to the exact confirmed proposal, with a callId-based idempotency guard against a duplicated confirmation. - Sub-account delegation: each tool declares a SubAccountPermission, enforced via a new checkSubAccountPermission() extracted from src/middleware/subAccount.ts so the assistant orchestrator can gate delegated actions outside of Express middleware. - Conversation memory (Redis-backed, TTL'd) and per-user/global token budgets, degrading to a graceful fallback reply (never a dead bot) when the model is unavailable or the budget is exhausted. - Every executed tool call writes an AgentLog row. - WhatsApp/Telegram wiring is additive and gated behind ASSISTANT_ENABLED (default off): the existing rule-based parser still handles every intent it already recognizes unconditionally; only the 'unknown' bucket is routed to the assistant. - docs/openapi.yaml documents POST /api/v1/assistant/chat. Closes Neurowealth#318
Contributor
|
Pls fix conflict |
Contributor
Author
|
@Abidoyesimze done |
The merge of main into this branch left env.ts, transaction-controller.ts, and actionTools.ts with concatenated/duplicated conflict content instead of properly resolved code: env.ts had a truncated assistant config block, transaction-controller.ts had duplicate ExecuteWithdrawParams/Result interfaces and a duplicate `transaction` declaration, and actionTools.ts needed null checks now that ExecuteDepositResult/ExecuteWithdrawResult carry a nullable transaction (PENDING_APPROVAL path from the approvals feature merged in from main). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmbhG5UojzVeXWGLta8Evn
sammajayi
force-pushed
the
feat/llm-tool-calling-assistant-318
branch
from
August 29, 2026 20:22
f0c8727 to
55fa132
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the rule-based NLP parser (
src/nlp/parser.ts) with a tool-calling LLM assistant as the recognition layer for open-ended requests, while preserving the platform's core integrity property: no money moves and no decision is attributed to the agent unless it went through the same verified, audited, idempotent paths every other feature uses. The model is a free-form planner; the codebase is the only executor.src/agent/tools/): typed, Zod-schema'd wrappers over existing service-layer functions only — read tools (portfolio_value,positions,transactions,protocol_rates,goal_status,followed_strategy) and action tools (deposit,withdraw,rebalance,create_recurring_deposit,create_alert_rule,adjust_strategy,follow_strategy,unfollow_strategy). A structural test (tests/unit/agent/tools/structural.test.ts) asserts no tool importsstellar/contractorstellar/walletdirectly, and every non-read-only tool requires confirmation.src/agent/assistant/planner.ts): Anthropic tool-calling; every proposed call is re-validated against the tool's own Zod schema before anything runs — an out-of-schema or hallucinated tool name is rejected as a grounded error, never executed.src/agent/assistant/confirmations.ts): every action tool is dry-run and parked, and only executes on an explicit affirmative reply to the exact confirmed proposal, with a callId-based idempotency guard against a duplicated confirmation. This is the load-bearing safety property and is covered by its own test suite.SubAccountPermission;checkSubAccountPermission()was extracted fromsrc/middleware/subAccount.tsso the assistant orchestrator can enforce the identical permission rule outside of Express middleware (including for dry-run previews).AgentLogrow.src/whatsapp/handler.tsandsrc/telegram/handler.tsas an additive fallback — gated behindASSISTANT_ENABLED(default off) and only reached for theunknownintent bucket, so every command the existing parser already recognizes is completely unaffected. NewPOST /api/v1/assistant/chatREST endpoint for the web app, documented indocs/openapi.yaml.executeWithdrawfromprocessOnChainTransactioninsrc/controllers/transaction-controller.ts(mirroring the existingexecuteDeposit) so the withdraw tool has a proper service-layer entry point instead of a bespoke path.Test plan
tests/unit/agent/tools/structural.test.ts— no tool imports raw stellar primitives; every tool declares a sub-account permission; every non-read-only tool requires confirmationtests/unit/agent/assistant/confirmations.test.ts— confirmation scoping, TTL expiry, ambiguous-reply handling, executed-call idempotencytests/unit/agent/assistant/planner.test.ts— schema validation, hallucinated-tool rejection, strict-schema extra-field rejectiontests/integration/agent/assistant.integration.test.ts— grounded read-tool answers, dry-run-then-confirm execution flow (through the real service path), cancellation, hallucination rejection, model-failure fallback86 suites / 1257 tests passednpm run build/npm run lintcleanCloses #318