Project Info
Inspiration
We all have busy lives juggling work, school, and everything in between, and none of us actually enjoy the part of selling online where you fight off scammers, dodge lowball offers, and answer the same "is this still available?" message ten times a day. Reselling something should be easy, but the marketplace grind makes people leave money on the table or just never list their stuff at all. So we decided to take the fighting off your hands. trAIde does the haggling, the pricing, and the busywork for you, so you get the value of your items without the headache of the negotiation.
What it does
trAIde is an AI agent that buys and sells on online marketplaces automatically, starting with eBay. You text it a picture of your item, a quick product description, and answer a couple of questions about your price range and how fast you want it gone. From there it takes over: it researches what comparable items are actually selling for, sets a smart price point, writes and publishes the listing, and then negotiates with buyers on your behalf, accepting fair offers and pushing back on lowballers. The entire experience happens over text, so there is no app to download and no dashboard you are forced to babysit. You just send a photo and let the agent close the deal.
How we built it
We built trAIde as a texting-native autonomous reselling agent, wiring together four services around a Claude reasoning core. The front door is Poke: a user just texts a photo and a casual note like "sell this, want it gone fast," and our Python backend, a stateless MCP server that Poke connects to, picks it up and replies back through a Poke webhook, so the whole experience lives in chat. Behind that, we used Orkes (Conductor-style orchestration, run via the AgentSpan runtime) to model the agent's work as durable, multi-step tool workflows covering identify, research, price, draft, publish, and negotiate, so each stage is tracked and resumable rather than one fragile script. The hands-on work happens in Browserbase, a real cloud browser that the agent drives with Stagehand to scrape eBay comparables, fill out the listing wizard, and message buyers, with each run exposed as a live, embeddable session. Everything is persisted in Redis as the single source of truth, with RedisVL powering vector search over comparable listings and Redis Agent Memory holding durable seller preferences. Finally, we built a standalone dashboard that reads Redis and Browserbase directly (read-only) to visualize the agent live without touching that backend.
Challenges we ran into
Getting Browserbase to reliably find and click the correct buttons on eBay's constantly shifting UI was harder than expected, since the listing flow does not always render the same way twice. We worked through it by debugging interactively with Claude Code until we landed on a reliable approach. Our second big hurdle was getting Poke to communicate with the rest of the agent, because the MCP server kept failing to connect. The root cause was a complicated monorepo with a lot of moving ports, so we unified everything behind a single start file that manages all of the ports for us, which made the connection stable. Finally, bypassing captchas and logging into online marketplaces was a real blocker, and we got past it by consulting a Browserbase representative for guidance on the right way to handle authenticated sessions.
Accomplishments we're proud of
We are proud that we used multiple sponsor technologies in a way that genuinely fit the product, rather than bolting on features just to check a box. Every integration, from Poke to Orkes to Browserbase to Redis, earns its place in the workflow. We are also happy with how clean the user interface and the text-based input system turned out, making a fairly complex agent feel simple to use. Most of all, we are proud that we can take an item from a single text message all the way to a real, live eBay listing, which is the core promise of the whole project working end to end.
What we learned
This project pushed us to pick up a lot of new tools quickly. We learned how to work with Claude Code as a development partner, how to orchestrate multi-step agent workflows with Orkes, how to use Redis (along with RedisVL and Agent Memory) as both a state store and a search layer, how to drive real browsers at scale with Browserbase, and how to build a texting-native interface on top of Poke. On top of the infrastructure, we also sharpened our UI design skills to turn all of that backend complexity into something clean and approachable.
What's next
for trAIde: Sell Anything, Anywhere Because we built on Browserbase instead of relying on a single eBay integration, there is huge room to scale: the same agent that drives a real browser can be pointed at almost any marketplace. Next up is expanding beyond eBay to platforms like Facebook Marketplace and Depop, so users can list once and reach buyers everywhere. We also want to round out the experience by adding buying on top of selling, letting the agent hunt for deals and negotiate purchases for you the same way it already handles sales.
Berkeley AI Hackathon '26 Project by Rishabh Roy, Arjun Jadhav, and Advaith Appajodu
https://devpost.com/software/traid-h6db5a
Traide — Text-to-Sell Resale Agent
Text a photo + a casual instruction ("Sell this keyboard, has a scratch, want it gone quickly") to your Poke assistant. trAId identifies the item, researches eBay with a real logged-in browser, texts you the comparable listings it found (title + price), prices it, drafts a listing, asks you to approve over text, publishes to eBay, then autonomously negotiates with buyers — only interrupting you when a sale closes or a listing goes stale. It can also buy: give it an item and a price cap and it hunts, haggles, and closes under budget.
Built for CalHacks AI Hackathon 2026 (24h). See PRD-trAId.md
for the full spec and docs/demo_runbook.md for the demo.
How the sponsors map in
| Sponsor | Role |
|---|---|
| Poke | The entire UI. Our /mcp server exposes start_sale, approve_sale, … ; we push proactive texts via a Poke webhook trigger (the /inbound/api-message endpoint 200s but silently drops messages). No app, no dashboard. |
| AgentSpan | Durable workflow runtime + the visual dashboard at localhost:6767. Survives restarts; real pause/resume at the approval step. Also our only LLM path — Agent(model="anthropic/claude-…"). |
| Browserbase + Stagehand | One persistent browser context (logged into eBay once in the console) drives research, publish, and offer threads with natural-language act/extract. |
| Redis | RedisVL hybrid comparable search + semantic cache, Redis Agent Memory for seller prefs, plain keys for state + the duplicate-publish lock. |
One reasoning provider
Every Claude call — product ID, pricing bullets, copy, revision parsing,
negotiation decisions — goes through AgentSpan's native model layer
(app/agents/llm.py). Nothing in this repo imports the anthropic SDK directly.
Stagehand uses its own internal LLM to drive the browser; that's the automation
engine's requirement, separate from our reasoning layer.
Architecture
Poke ──(MCP /mcp)──▶ FastAPI ──▶ AgentSpan sale workflow (durable, resumable)
▲ identify→memory→eBay research→report comps→price→copy
└──(Poke webhook: proactive)─── →propose→⏸approve→eBay publish→verify→notify
│
┌──────────────────────┼───────────────────────────┐
▼ ▼ ▼
AgentSpan(Claude) Browserbase/Stagehand Redis
(1 persistent context) (RedisVL + Agent Memory
+ state keys + lock)
Post-publish: a sell-side negotiation monitor + a buy-side purchase flow hang off
the same Redis state, the shared Browserbase context, and the Poke path.
Layout
app/
main.py FastAPI: mounts MCP at /mcp, runs the negotiation monitor
mcp_server.py Poke-facing MCP tools
poke_client.py outbound proactive Poke messages
config.py models.py settings + Pydantic contracts
agents/ llm.py (AgentSpan Claude chokepoint), identify, pricing, copywriter,
revision_parser, negotiator (hard floor/cap guardrails in code)
browser/ session (one shared context), research(+ebay_research),
publish(+ebay_publish), threads(+ebay_offers)
memory/ comparables_index (RedisVL), seller_memory (Agent Memory)
state/ redis_state (keys + publish lock), negotiation_state (policy+scheduler)
workflow/ sale, management, negotiation, purchase
scripts/ seed_seller_memory
docs/ demo_runbook.md
Run it
uv venv && source .venv/bin/activate
uv pip install -r requirements.txt
cp .env.example .env # fill in keys
# In the Browserbase console: create a Context, open it, log into eBay by hand
# once, then paste its id into BROWSERBASE_CONTEXT_ID in .env. (No login code —
# the session cookies persist in that one context across every run.)
# prerequisites: Redis Stack, Redis Agent Memory Server, AgentSpan local server
python -m scripts.seed_seller_memory # seed demo seller prefs
uvicorn app.main:app --port 8000
npx poke@latest tunnel http://localhost:8000/mcp -n "trAId"
Build-time VERIFY notes
Grounded against live docs on 2026-06-20; pin exact signatures on Day 1:
- AgentSpan:
Agent/AgentRuntime/AgentHandlekwargs, multimodal vision message shape inagents/llm.py,runtime.start/handle.approvereturn types. - MCP SDK:
FastMCP.streamable_http_app()mount path +session_manager.run(). - RedisVL:
SearchIndex,VectorQuery,SemanticCacheimport paths. - Redis Agent Memory client:
search_long_term_memory/create_long_term_memorysignatures (wrapped defensively inmemory/seller_memory.py). - Stagehand Python:
StagehandConfigfields +page.act/extractschema arg. Each is isolated behind a thin adapter so a signature fix touches one file.
Analysis
View
Metric
- 14
- 4
- 1
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- ExpressIn code
- FastAPIIn code
- HTMLIn code
- PythonIn code
- ReactIn code
- RedisIn code
- TypeScriptIn code
- JavaScriptClaimed
- Tailwind CSSClaimed
7 of 9 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeConfig · Commits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
293 KB
Source files
63
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
rishabhroyy/traide
83 files · 412 KB · @ 383ff26
Structure
Interface
40 files · 48%Screens, components and styles rendered to the user.
+2 moreAPI & routing
8 files · 10%Request entry points: routes, handlers and controllers.
Application logic
8 files · 10%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python54%
- Markdown27%
- TypeScript11%
- Shell3%
- HTML3%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
pyproject.toml
pypi · 14- agent-memory-client
- agentspan
- browserbase
- fastapi
- fastmcp
- httpx
- mcp
- pydantic
- python-dotenv
- redis
- redis-agent-memory
- redisvl
- stagehand
- uvicorn[standard]
requirements.txt
pypi · 14- agent-memory-client
- agentspan
- browserbase
- fastapi
- fastmcp
- httpx
- mcp
- playwright
- pydantic
- python-dotenv
- redis
- redisvl
- stagehand
- uvicorn[standard]
dashboard/web/package.json
npm · 7- react
- react-dom
- +5 more
dashboard/server/package.json
npm · 3- dotenv
- express
- redis
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
Feature verification
14-day stale-listing escalation with price-cut approvalVerified
only interrupting you when a sale closes or a listing goes stale
Claimed on readmehigh confidenceapp/state/negotiation_state.py:101— schedule_stale_check/stale_due implement the 14-day threshold schedulerapp/workflow/negotiation_workflow.py:119— check_stale_listings escalates and apply_price_cut resumes after approve_price_cut
Automatic pricingVerified
sets a smart price point
Claimed on Devposthigh confidenceapp/agents/pricing.py:1— price_item computes recommended price from comps, prefs and productapp/workflow/sale_workflow.py:172— _do_price calls price_item and stores a PricingResult
Autonomous buyer negotiation with hard floor guardrailsVerified
negotiates with buyers on your behalf, accepting fair offers and pushing back on lowballers
Claimed on Devposthigh confidenceapp/agents/negotiator.py:32— decide_sell_offer gets Claude's proposed move then enforce_sell_floor clamps it in codeapp/workflow/negotiation_workflow.py:51— process_listing polls buyer offers and acts with zero per-offer approval
Browserbase live, embeddable session per runVerified
each run exposed as a live, embeddable session
Claimed on Devposthigh confidenceapp/browser/session.py:236— get_live_view_url fetches Browserbase's debuggerFullscreenUrl for a sessionapp/workflow/sale_workflow.py:278— live_view_url is sent to the user via Poke when human takeover is needed
Buy-side purchase flow with hard price capVerified
It can also buy: give it an item and a price cap and it hunts, haggles, and closes under budget.
Claimed on readmehigh confidenceapp/workflow/purchase_workflow.py:43— start_purchase/_drive/_negotiate_one implement search + laddering negotiation capped by enforce_buy_capapp/mcp_server.py:211— start_purchase_search MCP tool exposes buy-side to Poke
Duplicate-publish lock in RedisVerified
plain keys for state + the duplicate-publish lock
Claimed on readmehigh confidenceapp/state/redis_state.py:120— acquire_publish_lock/release_publish_lock implement the dedup lock used in sale_workflow._do_publishapp/workflow/sale_workflow.py:248— _do_publish checks rs.acquire_publish_lock before publishing, dedup path noted
eBay comparable research with a real browserVerified
it researches what comparable items are actually selling for
Claimed on Devposthigh confidenceapp/workflow/sale_workflow.py:112— _do_research calls research_ebay and reports comp count/price range back to the userapp/browser/session.py:148— stagehand_session drives a real Browserbase context via Stagehand for the research step
Listing copy generation and eBay publishVerified
writes and publishes the listing
Claimed on Devposthigh confidenceapp/agents/copywriter.py:1— generate_ebay_copy produces listing copyapp/browser/ebay_publish.py:9— publish_ebay drives the eBay sell wizard via Stagehand's browser agent
One persistent, pre-authenticated Browserbase context (no in-app login)Verified
In the Browserbase console: create a Context, open it, log into eBay by hand once, then paste its id into BROWSERBASE_CONTEXT_ID in .env. (No login code, the session cookies persist in that one context across every run.)
Claimed on readmehigh confidenceapp/browser/session.py:1— stagehand_session defaults to settings.BROWSERBASE_CONTEXT_ID and reuses it with persist: true; no login flow exists in this module
Poke as the front-door UI (MCP server + webhook)Verified
The front door is Poke: a user just texts a photo... our Python backend, a stateless MCP server that Poke connects to, picks it up and replies back through a Poke webhook
Claimed on Devposthigh confidenceapp/mcp_server.py:47— FastMCP('trAId') stateless MCP server with tools Poke callsapp/poke_client.py:39— Poke webhook trigger used for proactive outbound messages, with documented reasoning about why /inbound/api-message doesn't work
Redis Agent Memory for durable seller preferencesVerified
Redis Agent Memory holding durable seller preferences
Claimed on Devposthigh confidenceapp/memory/seller_memory.py:111— load_seller_memory searches long-term memory via redis_agent_memory / agent_memory_client and derives SellerPrefs
Redis as single source of truth for stateVerified
Everything is persisted in Redis as the single source of truth
Claimed on Devposthigh confidenceapp/state/redis_state.py:120— acquire_publish_lock/release_publish_lock and generic get/put/merge helpers back item, listing, and research state in Redisapp/state/negotiation_state.py:17— Negotiation policy, offer threads and stale-check schedule all keyed in Redis
RedisVL hybrid vector search over comparable listingsVerified
RedisVL powering vector search over comparable listings
Claimed on Devposthigh confidenceapp/memory/comparables_index.py:101— hybrid_search uses RedisVL VectorQuery + Tag filter with a HFTextVectorizer embedding, over an index built with SearchIndex.from_dict
Single reasoning provider: all Claude calls via AgentSpan, no direct Anthropic SDK usageVerified
Every Claude call... goes through AgentSpan's native model layer (app/agents/llm.py). Nothing in this repo imports the anthropic SDK directly.
Claimed on readmehigh confidenceapp/agents/llm.py:22— run_text/run_structured build an agentspan Agent and run it through AgentRuntime; module docstring states this is the only Claude call site
Standalone read-only dashboard visualizing Redis + BrowserbaseVerified
we built a standalone dashboard that reads Redis and Browserbase directly (read-only) to visualize the agent live without touching that backend
Claimed on Devposthigh confidencedashboard/server/redisSource.mjs:1— server-side source module reading Redis for the dashboarddashboard/server/browserbaseSource.mjs:1— server-side source module reading Browserbase for the dashboarddashboard/web/src/App.tsx:1— React/TypeScript frontend consuming that dashboard server
Text-a-photo intake via Poke MCP (start_sale)Verified
You text it a picture of your item, a quick product description, and answer a couple of questions about your price range and how fast you want it gone.
Claimed on Devposthigh confidenceapp/mcp_server.py:100— start_sale MCP tool accepts description, image_urls, goals and kicks off the sale workflowapp/images.py:1— Poke's short-lived signed image URLs are downloaded to local disk immediately
Texting-native experience, no app/dashboard required for the sellerVerified
The entire experience happens over text, so there is no app to download and no dashboard you are forced to babysit.
Claimed on Devposthigh confidenceapp/poke_client.py:80— notify() relays proactive updates into the user's Poke text thread; all interaction is via MCP tools + Poke
Multi-tenant, per-texter keying via X-Poke-User-IdCode-supported
Multi-tenant: Poke sends X-Poke-User-Id on every request. Each texter is their own seller.
Claimed on readmemedium confidenceapp/mcp_server.py:67— _user_id() resolves the X-Poke-User-Id header and auto-registers the texter, keying subsequent state by that idapp/poke_client.py:18— poke_client.py explicitly notes outbound notify() is NOT truly multi-tenant: the webhook is bound to a single Poke account regardless of X-Poke-User-Id, so full multi-tenant routing is only partial
Orkes/AgentSpan durable multi-step orchestrationCode-supported
we used Orkes (Conductor-style orchestration, run via the AgentSpan runtime) to model the agent's work as durable, multi-step tool workflows covering identify, research, price, draft, publish, and negotiate, so each stage is tracked and resumable
Claimed on Devpostmedium confidenceapp/workflow/runtime.py:14— runtime() builds an AgentRuntime and handle_for() rebuilds a durable AgentHandle from a stored execution id, implying durable/resumable designapp/workflow/sale_workflow.py:1— Module docstring explicitly says this is an 'Explicit Python sale workflow, no LLM orchestration for the deterministic path' with stage tracking via rs.mark_item_stage, not an AgentSpan graph -- so the actual sell pipeline is a plain Python function chain with Redis-tracked stages rather than an AgentSpan-orchestrated durable graph. No direct import of Orkes/Conductor was found; AgentSpan is only used for the LLM calls (app/agents/llm.py) and stray runtime plumbing.
Verification/OTP handoff during publishCode-supported
getting past captchas and logging into online marketplaces was a real blocker... consulting a Browserbase representative for guidance
Claimed on Devpostmedium confidenceapp/mcp_server.py:187— submit_verification_code tool stores an OTP code in Redis for the browser flow to pick up, supporting the captcha/login friction narrative, though no direct captcha-solving code was inspected
Expansion to Facebook Marketplace, Depop and other marketplacesClaimed only
Next up is expanding beyond eBay to platforms like Facebook Marketplace and Depop, so users can list once and reach buyers everywhere.
Claimed on Devposthigh confidence
An AI agent derived these features from the project’s Devpost page and readme, then searched the code for each one. Verified features are backed by cited code; claimed-only features had no supporting code, which is not by itself proof a feature is missing.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.