WorkMate SG is a voice-first employment agent that turns spoken work experience into a verified profile, targeted résumé, suitable jobs, and a safely prepared application.
It is designed for frontline and low-digital-confidence workers who may be comfortable explaining what they can do, but less comfortable translating that experience into formal job titles, résumé language, and repeated application forms.
Current demo status: the FastAPI workflow is integrated and testable end to end with deterministic demo providers. The Expo app is a polished standalone Ravi prototype, but it still reads local demo data and is not connected to the backend.
- Workers can do the job but may struggle to describe their experience formally.
- Job titles, résumés, portals, and repeated forms create unnecessary barriers.
- Most AI tools stop at advice or résumé generation; WorkMate continues through application preparation and tracking.
Speak → Review profile → Choose role → Generate résumé → Find jobs → Prepare application → Review and approve → Track status
The worker remains in control throughout. Profile changes are proposed before they are applied, missing or sensitive facts stay unresolved, and application preparation stops at a human review checkpoint.
The frontend is wired to the FastAPI workflow and does not display candidate, job, résumé, or application placeholders. Set EXPO_PUBLIC_API_URL=http://127.0.0.1:8000 for web or use the laptop's LAN IP when testing on a physical phone. API requests and responses are logged in the Expo console with an [API] prefix; Uvicorn access logs show the matching server requests.
WorkMate does more than answer a prompt. It:
- Maintains persisted workflow state across the job journey.
- Summarizes progress and identifies the next action or missing information.
- Proposes profile changes without silently changing worker data.
- Waits for explicit approval before applying a proposal or completing a demo application.
- Coordinates profile, role, résumé, job-search, and application components.
- Produces ordered events, screenshots, and masked audit evidence for review.
Business state is derived deterministically from stored data rather than inferred by a language model.
| Technology | Role in WorkMate |
|---|---|
| Daytona | Optional isolated application runtime for browser setup, résumé upload, screenshots, audit artifacts, and sandbox cleanup. The runtime returns a review payload and never clicks final submit. |
| Kimi / Doubleword | The optional voice-résumé path uses Doubleword's OpenAI-compatible API with a configured model ID—which can be a Kimi model available to the account—for structured profile extraction and résumé content. Core role recommendations and profile-change proposals remain deterministic demo providers. |
| Whisper | Transcribes uploaded microphone audio for POST /api/v1/voice-resume before structured extraction begins. |
| Oxylabs | An isolated Oxylabs provider and normalization spike is implemented and tested; live job-search wiring remains in progress. |
Sponsor credentials stay server-side and are not required for the default mock-backed demo.
- Ravi speaks or types two years of warehouse experience, including scanning, packing, stock checks, and loading support.
- WorkMate creates a structured profile and asks Ravi to review it without filling unknown contact, eligibility, or salary fields.
- Ravi approves the profile; any later conversational edit appears as a separate before/after proposal.
- WorkMate recommends controlled warehouse roles, and Ravi selects Warehouse Assistant.
- The demo prepares role-specific résumé information and ranks matching warehouse jobs from seeded fixtures.
- The application runtime fills a mock portal, attaches a demo PDF, captures evidence, and stops at
waiting_for_review. - Ravi reviews the prepared fields and explicitly chooses save or
submit_demo; no external employer form is submitted.
- No silent profile changes: AI-assisted edits require before/after review and approval.
- No invented credentials, contact details, eligibility answers, salary expectations, or legal declarations.
- Unknown and sensitive fields remain visible as unresolved.
- Browser automation stops before final submission, CAPTCHA, OTP, login, or account creation.
- Important profile and application actions require explicit worker confirmation.
- Temporary Daytona environments are deleted in a
finallycleanup path, including after failures. - Audit events exclude raw personal values; browser audit output masks phone numbers and email addresses.
Expo / React Native
↓
FastAPI orchestration
├── AI providers
├── Job discovery and matching
├── Résumé generation
├── Daytona automation
└── SQLite workflow state
The backend is a modular monolith with replaceable provider and application-runtime interfaces. FastAPI owns validation and business transitions; SQLite stores sessions, profile revisions, recommendations, résumé metadata, applications, review payloads, and audit events.
- Python 3.11+
uv- Node.js 20+
pnpm
cd services/api
uv sync --extra dev
uv run uvicorn app.main:app --reload --port 8000Open http://127.0.0.1:8000/docs for the generated API reference. The default setup uses SQLite, seeded warehouse jobs, deterministic profile/role/résumé providers, and a mock application runtime.
With the API running, exercise the complete review-gated journey from the repository root:
python3 scripts/smoke_test_api.py --base-url http://127.0.0.1:8000The equivalent Bash flow is BASE_URL=http://127.0.0.1:8000 scripts/demo_flow.sh and requires curl plus jq.
cd apps/frontend
pnpm install
pnpm webUse pnpm start for Expo Go or a simulator. The current screens demonstrate voice/typed intake, profile review, job matches, application review, and tracking with local Ravi data; the microphone control is visual only and API integration is still pending.
Add OPENAI_API_KEY, DOUBLEWORD_API_KEY, and an account-valid DOUBLEWORD_MODEL to a root .env, export it into the backend process, and restart Uvicorn:
cp .env.example .env
cd services/api
set -a
source ../../.env
set +a
uv run uvicorn app.main:app --reload --port 8000Then open http://127.0.0.1:8000/demo. This temporary browser page records audio, calls Whisper and Doubleword, and produces reviewable HTML and one-page PDF résumé artifacts. The application does not load .env automatically.
Install the root dependencies and browser once:
pnpm install
pnpm exec playwright install chromium
pnpm mock-portalRestart the backend with APPLICATION_RUNTIME=node and AUTOMATION_RUNTIME=local to use the local Playwright runtime. Set AUTOMATION_RUNTIME=daytona and the Daytona values documented in .env.example to use the isolated runtime instead. Both paths stop for review.
| Area | Current state | Current boundary |
|---|---|---|
| Expo frontend | Responsive Expo Router prototype with keyboard-accessible typed fallbacks and the complete Ravi screen journey. | Uses apps/frontend/src/demo-data.ts; it does not record audio or call FastAPI yet. |
| FastAPI backend | Persisted sessions, profile revisions, workflow status, role selection, matching, applications, review payloads, events, and dashboard APIs. | Background application work is process-local rather than a durable queue. |
| Profile review | Initial approval, validated direct edits, reviewable AI-style proposals, stale-revision protection, and privacy-safe audit records. | The default extractor and natural-language change interpreter are bounded Ravi-demo mocks. |
| Voice and AI | The optional endpoint connects real Whisper transcription to a Doubleword-hosted model and validates provider JSON with retry and safe fallback. | It is separate from the persisted profile/application journey and requires sponsor credentials. |
| Résumés | The voice workflow renders real HTML and one-page PDF artifacts. | The persisted /resumes/generate path stores mock metadata only; browser automation falls back to a checked-in demo PDF. |
| Job search | Deterministic matching ranks seeded static jobs by skills, experience, location, shifts, and availability. | /jobs/search is not live; title filtering and normalized skill matching are exact rather than semantic. |
| Application automation | Mock, local Playwright, and optional Daytona preparation paths produce review data, screenshots, audit logs, and cleanup events. | Only the bundled mock portal is supported; submit_demo updates internal state and does not submit externally. |
| Oxylabs | Provider, response validation, normalization, sanitization, fixtures, probe script, and offline tests exist. | No live request was verified with sponsor credentials, and the provider is not connected to /jobs/search. |
| Document | Use it for |
|---|---|
docs/api-contract.md |
Endpoint contracts, profile review behavior, workflow stages, and application states |
docs/frontend-backend-mapping.md |
Planned screen-to-API wiring, identifier flow, failures, and accessibility requirements |
docs/oxylabs-spike.md |
Oxylabs request shape, normalization, safety, probe instructions, and integration gaps |
services/api/app/automation/README.md |
Local and Daytona runtime contracts, setup, review output, and safety guarantees |
.env.example |
Supported backend and sponsor configuration values |
api-examples/ |
Focused API requests and expected responses |
cd services/api
uv run pytest
uv run ruff format --check app tests
uv run ruff check app tests
uv run mypy appcd apps/frontend
pnpm lintRun pnpm test from the repository root for the application-automation contract tests.
No license has been selected yet.