DeepSeek Harness Remote
DeepSeek Harness Remote 可将手机或另一台电脑与你运行 DeepSeek Harness 的电脑安全连接,随时随地继续你的工作,方便随时查看进度并继续工作。
Translation pending
A personal AI agent that hunts opportunities that fit you, checks every fact against its source and drafts the application for you to approve.
ProductivityTypeScript · JavaScriptGitHub @PinnacleCryptNGOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Personal AI agent that hunts, verifies and scores grants, bounties & hackathons, then drafts applications. NVIDIA Nemotron on Nebius Token Factory + Tavily.
Taken from the repository README
Loading the full README.
Read the full README ↗A personal AI agent that hunts grants, bounties, hackathons and creator contests for you, verifies the terms, scores the fit, and drafts your application.
Built for the Nebius x NVIDIA Global AI Hackathon — Personal AI track.
| Opportunity page | Profile | Today's top five | Mobile |
|---|---|---|---|
unknown. Deadlines are stored in UTC and shown in your timezone. Nemotron then scores fit 0-100 with plus/minus reasons and flags risks: country not eligible, paid in the sponsor's own token, entry fees, unclear terms, deadline passed. Listing pages are not scored themselves (their links are followed instead), and closed opportunities are dropped./ explains the agent; the app lives at /dashboard: opportunities sorted by score or deadline, live countdowns, status (new / saved / applied / rejected), and a detail view with the verified terms, evidence quotes and sources.All LLM calls go through src/lib/llm.ts, an OpenAI SDK client pointed at Nebius Token Factory (https://api.tokenfactory.nebius.com/v1/, key in NEBIUS_API_KEY). There are no other LLM providers in the code.
| Step | Model (Nebius Token Factory) | Code |
|---|---|---|
| Plan profile-specific search queries | Nemotron Nano (nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B) | src/lib/hunt.ts |
| Extract reward, deadline, eligibility, payout from each page (JSON, with evidence quotes) | Nemotron Nano | src/lib/extract.ts |
| Score fit 0-100 with reasons and risks, using profile + memory | Nemotron Super (nvidia/nemotron-3-super-120b-a12b) | src/lib/score.ts |
| Daily digest | Nemotron Super | src/lib/digest.ts |
| Deep fit analysis (reasoning on) | Nemotron Ultra (nvidia/Nemotron-3-Ultra-550b-a55b) | src/lib/draft.ts |
| Drafts (application, build plan, first draft, video script, X thread, …) | Nemotron Ultra | src/lib/draft.ts |
On first use the server reads Token Factory's GET /v1/models and picks, per tier, the newest Nemotron it serves (Nemotron 3 first, then the Llama-Nemotron / Nano v2 releases); see MODEL_CANDIDATES in src/lib/llm.ts. /api/status shows the models in use. Override with NEMOTRON_NANO_MODEL, NEMOTRON_SUPER_MODEL and NEMOTRON_ULTRA_MODEL. For older Nemotron releases reasoning is toggled with the system-prompt switch (detailed thinking on/off, or /think / /no_think), and <think> blocks are always stripped before parsing.
Tavily (src/lib/tavily.ts, key in TAVILY_API_KEY):
@tavily/core SDK (src/lib/tavily.ts).search() with search_depth: "advanced", include_raw_content: "markdown", time_range: "month" and per-source include_domains (e.g. superteam.fun, devpost.com, gitcoin.co, x.com). The raw page markdown is what Nemotron reads, so one call both finds and fetches the page.extract() for results whose raw content is missing or too short, and to read the individual opportunities linked from listing pages (basic depth, about 1 credit per 5 pages).crawl() of ecosystem grant hubs (see below).src/lib/extract.ts asks Nemotron for { value, evidence } per field, with "unknown" when the page doesn't say. The server then normalises the page and the quote and drops any value whose evidence isn't found on the page. Deadlines without a stated timezone are flagged as such. Rule-based risks (sponsor token, entry fee, unclear terms, closed, excluded country) are computed from the verified fields in src/lib/score.ts, so the model can add risks but can't remove them.
agent_steps (operation, model, tokens, time, success) by src/lib/trace.ts. Each opportunity page shows the calls made for it.src/lib/schemas.ts) as response_format: json_schema. If Token Factory or the model rejects it, chatJson falls back to JSON mode, then to plain text, and remembers which models don't support it.POST /api/hunt creates a hunts row and runs the hunt after responding; the dashboard polls GET /api/hunt?id= for live stage and counts. The daily cron starts a separate /api/cron/hunt call per user, each with its own time limit, and retries once.src/lib/budget.ts): every Tavily response is requested with include_usage, and the credits it cost go into a daily ledger in Postgres. A hunt only starts if the month's allowance still has room: an even daily share of TAVILY_MONTHLY_BUDGET (default 900) plus TAVILY_DAILY_BURST (default 120), never more than the account's own remaining credits from Tavily's /usage endpoint minus TAVILY_ACCOUNT_RESERVE (default 40). Identical searches are reused for 12 hours and grant-hub crawls for 7 days, at no cost. Domain-filtered listing searches use basic depth (1 credit) and open-web searches use advanced (2). A fresh hunt costs about 13-15 credits; the daily job sends the digest every day but only hunts every CRON_HUNT_EVERY_DAYS (default 3), for up to CRON_MAX_USERS (default 10). /api/status shows the month's spend.src/lib/ratelimit.ts). Defaults: 4 hunts/hour per visitor, 8 per IP, 40/day site-wide; 20 AI requests/hour per visitor, 40 per IP, 1000/day. Override with HUNT_LIMIT_PER_USER_HOUR, HUNT_LIMIT_PER_IP_HOUR, HUNT_LIMIT_PER_DAY, LLM_LIMIT_PER_USER_HOUR, LLM_LIMIT_PER_IP_HOUR, LLM_LIMIT_PER_DAY.src/lib/memory.ts embeds it and the user's past saved, applied and rejected opportunities through Token Factory's embeddings API (an NVIDIA embedding model if listed, else Qwen3-Embedding / BGE; override with NEBIUS_EMBED_MODEL). The three closest past decisions, with their similarity and rejection notes, go into the Nemotron prompt, so "less like that one" works by meaning rather than exact title. Embeddings are cached on the opportunity; if the call fails, scoring uses the title lists.src/lib/recheck.ts re-reads up to 5 saved opportunities (each at most once a day) with Tavily Extract and the same Nemotron extraction and evidence check, then updates the deadline and closed status. The detail page shows what changed ("Re-checked: deadline now Nov 8").tavilyCrawl, with instructions to keep pages about a single program or funding round), alongside the searches.The app works without an account: a visitor is remembered by an httpOnly cookie. Two optional extras switch on when their env vars are set:
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET; OAuth callback <APP_URL>/api/auth/github/callback). /login or the header's Sign in runs a standard OAuth flow with a state cookie and only reads the public name and avatar. A first sign-in turns the current visitor into the account, so their profile and history carry over; signing in on another browser loads the same account (src/lib/auth.ts).TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_USERNAME). Connect Telegram on the profile opens the bot with a one-time code (valid 15 minutes). After the daily hunt the cron job sends the top five there once a day, and the digest page has a Send to Telegram button. The bot answers /digest and /stop. The webhook checks Telegram's secret-token header; run TELEGRAM_BOT_TOKEN=… APP_URL=… node scripts/telegram-webhook.mjs once to register it (src/lib/telegram.ts).eval/pages/ holds 20 real pages saved from Tavily (Superteam Earn, Devpost, Gitcoin, ecosystem grant and creator contest pages), and eval/labels.json has hand labels for what each page actually states: whether it is a single opportunity, the reward, the deadline and whether it is closed. npm run eval runs the real extraction step over all 20 and reports accuracy per field, how many values are backed by a quote found on the page, and how many fields were left unknown. Results are written to eval/results.json.
NEBIUS_API_KEY=... npm run eval
Results with nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B on Token Factory (strict JSON-schema output, thinking off), from eval/results.json:
| Check | Result |
|---|---|
| Pages extracted without error | 20/20 |
| Single opportunity vs. index/roundup page | 19/20 (95%) |
| Reward matches the label | 8/8 |
| Open/closed matches the label | 4/4 |
| Deadline matches the label | 2/2 |
| Values backed by a quote found on the page | 101/114 (89%) |
Fields left unknown | 46 |
The 13 values whose quote was not found on the page are reset to unknown by the verification step, so they never reach the dashboard. The one miss on single opportunity is an index page that was treated as one opportunity. The labelled set is small (20 pages, only some fields labelled per page), so treat these as a sanity check rather than a benchmark.
Nemotron 3 models reason before answering by default, and that reasoning counts against max_tokens. Fast calls (extraction, scoring, planning) send chat_template_kwargs: {"enable_thinking": false}; without it, long pages ran out of tokens mid-JSON and the eval extracted 0/20.
Requires Node 20+.
git clone https://github.com/PinnacleCryptNG/grant-hunter.git
cd grant-hunter
npm install
cp .env.example .env.local # add NEBIUS_API_KEY and TAVILY_API_KEY
npm run dev # http://localhost:3000
Without DATABASE_URL, data is kept in an embedded Postgres (PGlite) under ./.data. Open the app, fill in your profile under Profile, then press Hunt now.
Each browser gets its own anonymous user (cookie) with an empty profile. Hunting unlocks once the profile has at least one skill.
npm test # vitest: evidence check, unknown fields, risk rules, score caps, hunt URL filters, digest ranking, rate limits, structured output
npx tsc --noEmit && npm run lint
To run the whole pipeline offline (no Token Factory credits), scripts/mock-token-factory.mjs is a test-only stand-in for the chat completions endpoint. It also returns a made-up payout quote on some pages, so you can watch the evidence check turn it into unknown:
npm run mock:llm & # http://localhost:4010/v1/
NEBIUS_API_KEY=mock NEBIUS_BASE_URL=http://localhost:4010/v1/ npm run dev
The deployed app always uses Nebius Token Factory. GitHub Actions (.github/workflows/ci.yml) runs type checks, lint, tests and a production build on every push and pull request.
DATABASE_URL. Tables are created automatically on first request.NEBIUS_API_KEY, TAVILY_API_KEY, CRON_SECRET (any random string).vercel.json schedules GET /api/cron daily at 06:00 UTC: for each user active in the last 7 days with daily hunting on and a filled-in profile (up to CRON_MAX_USERS, default 10), it starts a separate run that re-checks saved opportunities and sends the digest, and hunts again if the last hunt is at least CRON_HUNT_EVERY_DAYS old and Tavily credits allow.| Route | Purpose |
|---|---|
GET/PUT /api/profile | Read / save the profile |
POST /api/hunt | Start a hunt in the background (Tavily → Nemotron extract → verify → score); returns huntId |
GET /api/hunt[?id=] | Hunt status and live progress |
GET /api/opportunities | Scored opportunities for the current user |
GET/PATCH /api/opportunities/:id | Detail, drafts and agent trace / set status and feedback note |
POST /api/opportunities/:id/rescore | Rescore with the latest profile and memory |
POST /api/opportunities/:id/analyze | Deep fit analysis (Nemotron Ultra) |
POST/PATCH /api/opportunities/:id/draft | Generate a draft (Nemotron Ultra) / edit or approve it |
GET /api/digest[?regenerate=1] | Today's top 5 |
GET /api/cron | Daily schedule: starts one hunt per user (needs CRON_SECRET) |
POST /api/cron/hunt | One user's scheduled hunt + digest (needs CRON_SECRET) |
GET /api/status | Which keys, models and database are configured |
MIT, see LICENSE.