ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A financial literacy web app with an AI coach. It teaches personal finance in plain English, gives general investment strategy guidance, and is built so that every number it quotes comes from tested code instead of the model's own arithmetic.
Live demo: sprout-financial.vercel.app
Sprout is an educational tool, not a licensed financial advisor. Nothing it says is personal financial advice.
Home (/) and FAQ (/faq) | Signed-out visitors get an introduction: what Sprout does, who it's for, how data is handled and what an account adds, with a calculator to try. Signed-in visitors get their next lesson, plan step, chats and spending. The FAQ answers common questions from what the code actually does (and only mentions features this server has switched on); it's linked from the footer, the bottom of the home and About pages and the landing page's section on data, not the header. |
AI assistant (/assistant) | A coach that explains concepts, asks for missing context before advising, and runs calculators and data lookups mid-answer. |
Course (/learn) | "First Investments": 20 short lessons in 6 modules with quizzes, a glossary and saved progress. |
My plan (/plan) | A risk quiz, goals, savings and debts turn into a money roadmap (what to do first) and a target stock range. The assistant can read it, so it stops re-asking the basics. |
Portfolio (/portfolio) | Enter holdings, import a positions CSV or screenshots (or refresh them with live prices) for an X-ray: allocation, concentration, overlapping funds, fee drag, rebalancing with new money, "where should my next $X go", a market-drop stress test with past crashes and recoveries, and a before-you-buy checklist for hot tips. |
Dashboard (/dashboard) | Plan each month's budget from the day you're paid (50/30/20 check, dated paychecks and bills, a day-by-day balance), then import a bank CSV, or screenshots from any banking app, to see spending by category and month, recurring payments, and an AI review of the trends. |
| Calculators | Compound growth, fee drag, doubling time and a 50/30/20 budget check, used by both the pages and the assistant. |
| Accounts | Optional email or Google sign-in, with password reset by email, that syncs chats, course progress, imported finances, monthly budgets, your plan and portfolio across devices. |
components/chat.tsx
→ POST /api/chat
→ lib/chat/validate.ts reject malformed or oversized input; mask card and ID numbers
→ lib/ai/spend-server.ts stop if the monthly budget (SPENDING_LIMIT) is used up
→ lib/rate-limit/ per-visitor and site-wide request caps
→ lib/ai/agent.ts streamed reply + tool loop (up to 4 tool rounds, 10 in deep research, 8 tools a round)
↳ lib/ai/system-prompt.ts persona and guardrails
↳ lib/ai/tools.ts tools wrapping lib/finance and lib/market
← one JSON event per line, rendered as Markdown as it arrives
The model decides when a tool is needed; code does the work. The tools:
| Tools | Offered when | What they wrap |
|---|---|---|
compound_growth, fee_impact, doubling_time, budget_check | always | pure functions in lib/finance/ |
get_stock_quote, get_company_profile, search_companies | a market data key is set | Financial Modeling Prep |
check_before_buying, market_drop_history | always | lib/portfolio/ (the before-you-buy checklist, past S&P 500 drops and recoveries) |
get_my_plan, analyze_my_portfolio, plan_next_dollars | the user shares their plan or holdings | lib/plan/, lib/portfolio/ |
get_finance_summary, get_spending_trends, find_transactions | the user shares imported transactions | lib/finance/transactions.ts |
search_past_chats, read_past_chat | the browser sends saved chats | lib/chat/history.ts |
create_chart, create_table | always | validators in lib/ai/graphs/ and lib/ai/artifacts.ts; rendered as interactive charts and sortable, downloadable tables |
web_search, plus web_fetch in deep-research mode | web search is switched on | run by Anthropic, with cited sources listed under the reply |
Charts and tables travel inside the reply as validated JSON blocks, so they save and reload with the chat, and the eval suite checks that a chart's points come from a tool's output. Web search has a fixed allowance per answer (3 searches, or 10 plus page reads in deep-research mode), and if the API turns search down the assistant answers that question without it instead of failing. Search queries are kept to the general question, never the user's own figures. The app's own tools have allowances too: at most 8 calls run at once and 10 market data lookups per answer, which also count against the same market data limit as the Portfolio page, so one request can't use up the data plan for everyone.
The chat shows what is sent with each question (past chats, your plan, your transactions) right in the message box, names the site behind any link to another site, and tells screen readers the finished answer once instead of every streamed word. Card, account and Social Security numbers typed into a question are masked (••••1234) before it's shown, saved, synced or sent, with a short note saying so, including numbers pasted with no-break spaces or typed in fullwidth digits, and in the titles of chats saved before masking existed. If a reply drops, Try again asks the same question again; while an answer streams, scrolling up stops the view from following until you jump back to the latest.
claude-haiku-5-5, the fastest and cheapest current Claude model, because it's a free public demo where most answers are a calculator call plus a plain-English explanation. ANTHROPIC_MODEL switches to a larger model, and npm run eval compares them on the same questions.lib/ai/spend.ts, tested) and added to a running total for the month, kept in whole micro-dollars so thousands of tiny additions don't drift. Once the total reaches SPENDING_LIMIT, the AI endpoints pause until the next month. Answers that are stopped or cut off partway are counted too, from what the stream reported before it ended, so pressing Stop (or a script dropping the connection) can't get answers for free.lib/ai/system-prompt.ts is the single source for behavior: strategy over stock picks, no market timing, no promised returns, context before advice, and what to do about scams and financial distress.npm run eval asks the real agent a fixed set of 55 questions through the same code path as the chat route, then scores each answer two ways:
claude-sonnet-5-5 by default, a different model from the assistant, so it isn't grading its own style.A case passes only when all of its checks do. The cases are grouped by what they protect:
| Area | Cases | Examples |
|---|---|---|
| Accuracy | 16 | Projections state the calculator's exact result; a chart is plotted from the calculator's output, not invented points; a market data outage produces "unavailable", not a made-up price; limits that change yearly aren't quoted from memory. |
| Safety | 13 | No stock or coin picks, even under pressure; no market timing or promised returns; no encouragement of margin for beginners; won't move money or repeat an account number, and answers a question whose card number the site masked instead of warning about it. |
| Protection | 14 | Flags a Telegram "double your money" scam and links the scams lesson; pauses investing talk for someone who can't pay rent; ignores instructions injected through a message, an imported file, a saved chat and a role-play; keeps the user's figures out of web searches and out of links; runs only its allowance when asked for 30 lookups at once. |
| Coaching | 12 | Puts 24% credit card debt ahead of investing; asks for country and emergency fund before advising, and doesn't ask twice; gives allocations as ranges with trade-offs. |
Latest results (October 27, 2026, the assistant on claude-haiku-5-5 and graded by claude-sonnet-5-5, one run of the 54 cases the suite had then): 50 of 54 cases passed (93%). By area: accuracy 15 of 16, safety 12 of 12, protection 13 of 14, coaching 10 of 12. Every tool-selection check (25 of 25) and every groundedness check (13 of 13) passed. The full report, with each failed reply, is evals/results/latest.md.
Market data is replaced with a fixture during evals, and web search is off apart from one case that checks what the agent searches for, so runs are repeatable and almost nothing but the model is billed. Evals also ignore any MONGODB_URI in .env, so they never connect to the app's database or add to its monthly spending total. Each full run writes a report to evals/results/latest.md with pass rates by area and the full reply for every failure; a run limited with --filter writes evals/results/partial.md instead.
Model answers vary between runs, so npm run eval -- --runs 3 gives a truer picture than a single pass. To compare models, set ANTHROPIC_MODEL for each run and keep EVAL_GRADER_MODEL the same.
Screenshot import has its own eval, npm run eval:screenshots: 24 drawn screens, from a plain bank app, a card statement, a brokerage table and a 401(k) app (plus a recipe and an injected instruction) to the harder kinds people really capture: dark mode, Debits/Credits columns, day-first dates, euros, long scrolling captures, rows cut off at the edges, a notification banner, a dense desktop statement, a travel card in two currencies, cost basis columns, fund names without tickers and a stocks-and-crypto app. Three more were held out from the holdings wording: a trading app whose colored boxes show each position's equity, part of a long positions list under its account total, and a 4K desktop capture wider than Claude reads. Each is scored row by row against an answer key with exact checks, and errors are counted by type. The first two changes below took Haiku from 57 to 66 of 66 reads and from 755 to all 1,125 rows exact (screenshots-compare-final-haiku.md; the starting points are screenshots-bench-haiku.md and screenshots-bench-sonnet.md). The held-out equity screen then failed 3 of 3 (screenshots-followup-haiku.md), and the third change fixed it: all 75 reads of the 25 cases are now exact (screenshots-compare-followup-haiku-wording.md).
When the rows of a holdings screenshot don't add up to the total the screen shows, the review says so above the table and asks the person to check the values (or to expect it, if the screenshot shows only part of the account). That check is code, so it costs nothing, and it never changes a value or blocks saving. It replaced a second read with Sonnet that never fired in the final runs.
Haiku at effort low stays the default: before these changes Sonnet passed only 3 more reads at 18 times the cost. npm run eval:screenshots:compare -- followup-haiku-wording <name> compares a change against the current results.
Next.js 16 (App Router) and React 19 · TypeScript in strict mode · Tailwind CSS 4 with shadcn/ui components · Recharts · Anthropic TypeScript SDK (Claude Haiku 5.5 by default) · MongoDB · Auth.js · Node's built-in test runner · GitHub Actions
Needs Node 22.18 or newer.
npm install
cp -n .env.example .env # -n keeps an existing .env; then add your Anthropic API key
npm run dev # http://localhost:3000
Only CLAUDE_API_KEY is required. .env.example lists the optional settings: the models (including the one that reads screenshots), the monthly spending limit, market data, MongoDB for accounts, Google sign-in and rate limits. Without MongoDB the app runs browser-only and hides login.
npm test # unit tests: finance math, parsers, validators, rate limits, eval scoring
npx tsc --noEmit # type check
npm run lint
npm run build
npm run eval # the eval suite above (calls the API)
GitHub Actions runs lint, the type check, the unit tests and a production build on every push to main, on every pull request and once a week, so a new advisory against a dependency shows up even when nothing changes (.github/workflows/ci.yml). The job's token is read-only and the actions are pinned to exact commits. The eval suite isn't part of CI, because it calls the paid API.
The app deploys to Vercel as a standard Next.js project.
CLAUDE_API_KEY under Environment Variables, plus any optional settings from .env.example. For accounts, set MONGODB_URI and AUTH_SECRET, and make sure the database accepts connections from Vercel.https://<your-domain>/api/auth/callback/google as an authorized redirect URI, and set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in Vercel.SITE_URL to the address people use (your custom domain, for example https://sprout.example). Canonical links, the sitemap, share cards and emailed links use it. Without it, production uses Vercel's production domain.vercel.app address, choose the "HTML tag" method and put the token in GOOGLE_SITE_VERIFICATION. Then submit https://<your-domain>/sitemap.xml. Preview deployments are never indexed: their robots.txt disallows everything and their pages carry noindex.SPENDING_LIMIT to a monthly budget in dollars, and set a monthly spend limit on the API key in the Claude Console too. The app's limit is an estimate that's updated after each call finishes, so the Console limit is the hard ceiling.The AI endpoints, logging in and signing up are rate-limited in production: 12 questions per 10 minutes and 60 per day for each visitor, 400 AI calls per day across everyone (RATE_LIMIT_DAILY_TOTAL), 10 login attempts per 15 minutes and 5 sign-ups per hour for each visitor. Visitors are told apart by IP address (IPv6 by its /64 network, so one customer can't dodge the limits by switching addresses), and the counters store only a keyed hash of it, never the address. With MongoDB configured the counters and the monthly spending total are shared by all server instances; without it each instance counts on its own, so treat the Console spend limit as the real ceiling.
Web search is billed per search on top of tokens ($10 per 1,000 searches, which the spending limit counts); set WEB_SEARCH=off to switch it and deep research off. Each assistant request writes one log line with its tools, token counts, estimated cost and timings (never the conversation), which shows up in Vercel's function logs.
/api/auth/callback/credentials endpoint, not just the login form.DATA_ENCRYPTION_KEY), every code works once, and if the secret can't be checked, password login is refused rather than let through. At most 5 codes per 15 minutes and 20 a day can be tried with an account's password, and the same while logged in (to turn it off, make new recovery codes or delete the account); wrong codes are logged and the owner is emailed when either limit is reached. Turning it on asks for the current password, or for a Google-only account a fresh Google login, and with it on, deleting the account needs a code. A Google-only account can log in with Google again instead of giving a code to turn it off or delete the account, so its owner is never locked out.app/ pages and API routes
components/ UI: chat, course, dashboard, calculators
lib/ai/ agent loop, system prompt, tools, skills (charts, tables, web search), spending limit
lib/finance/ pure finance math and CSV parsing
lib/learn/ course content and glossary
lib/auth/, lib/db/, lib/sync/ accounts and sync
lib/rate-limit/ request limits
lib/seo/ page titles and descriptions, structured data, robots.txt and sitemap
evals/ eval cases, checks, grader and runner
AGENTS.md has the full conventions for working in this codebase.
proxy.ts, rules in lib/security-headers.ts): only scripts Next.js rendered for that request or files from this site can run, and the browser can't load from or send data to other sites. That's why every page renders on each request instead of being built ahead of time. The policy covers every page response, including not-found pages at made-up addresses, so no link can start a visit under a weaker policy; API routes, the build's own files and the favicon get a stricter, script-free policy instead.