feat: Add OpenCode Backend Support with Performance Instrumentation & LinkedIn Optimizations#20
feat: Add OpenCode Backend Support with Performance Instrumentation & LinkedIn Optimizations#20rothnic wants to merge 25 commits intoPickle-Pixel:mainfrom
Conversation
Add unified AgentBackend abstraction supporting both Claude Code and OpenCode: - AgentBackend abstract base class with run_job() interface - ClaudeBackend implementation for Claude Code CLI - OpenCodeBackend implementation for OpenCode CLI with MCP support - Backend detection and auto-selection logic - Backend-specific configuration in .env.example - Comprehensive tests for backend selection and output parsing - Wizard integration for backend setup and configuration - Launcher updates to use new backend abstraction This enables users to choose between Claude Code (default) and OpenCode for autonomous job application submission.
53c05f4 to
9a76346
Compare
Remove unused imports: - conftest.py: os, Path, MagicMock - test_backend_selection.py: os - test_parser_edge_cases.py: time, PropertyMock
- Revert .env.example to match origin/main - Add only OpenCode-related configuration options: - APPLY_BACKEND selection - APPLY_CLAUDE_MODEL, APPLY_OPENCODE_MODEL, APPLY_OPENCODE_AGENT - OpenCode MCP baseline requirements - Add scripts/test_opencode_apply.py for end-to-end testing - Checks prerequisites (OpenCode binary, MCP servers) - Runs applypilot apply --dry-run --url <job-url> - Provides clear output about what worked/failed
Add prerequisite checks for: - ~/.applypilot/profile.json (run applypilot init to create) - ~/.applypilot/resume.txt or resume.pdf These are required for applypilot apply to work.
Add --backend/-b option to explicitly select backend (claude or opencode).
This makes it easier to test OpenCode without relying solely on environment variables.
Changes:
- Add --backend/-b CLI option to apply command
- Display selected backend in output
- Pass backend_name to apply_main launcher function
Usage:
applypilot apply --backend opencode --url https://...
applypilot apply -b opencode --dry-run
c166b8f to
cc14e8b
Compare
SQL query 'apply_status != 'in_progress'' doesn't match NULL values. Changed to '(apply_status IS NULL OR apply_status != 'in_progress')' to properly find jobs that haven't been attempted yet.
OpenCode looks for .opencode/opencode.jsonc in the current working directory. Updated _list_mcp_servers() and run_job() to use config.APP_DIR (~/.applypilot) as the cwd so OpenCode can find the MCP server configuration.
OpenCode installs to ~/.opencode/bin/opencode by default, which may not be on PATH. Updated _find_binary to check this location if not found on PATH.
OpenCode installs to ~/.opencode/bin/opencode by default, which may not be on PATH. Updated _find_binary to check this location if not found on PATH.
…CONTENT - OpenCode expects prompt as positional argument, not via stdin - Add OPENCODE_CONFIG_CONTENT env var to disable interactive prompts - Pre-approve permissions to prevent 'question' tool from hanging - Fixes 'Session not found' and early termination issues
- Remove OPENCODE_CLIENT, OPENCODE_SERVER_PASSWORD, etc. - Ensure PATH includes ~/.opencode/bin - Set TERM for proper terminal handling - Fixes 'Session not found' error
- Add DEBUG LOGGING section to report progress at each step - Provide specific guidance for finding Apply buttons on Workday, Lever, Greenhouse - Add browser_evaluate snippet to search for apply buttons dynamically
…rolling - Add browser_evaluate step to get ALL interactive elements first - Emphasize using browser_evaluate over visual scanning - Add 'NEVER SCROLL manually' instruction - browser_snapshot is now for text content only, not element positions - Use browser_click with text references, not coordinates
- Add step-by-step upload: (1) click upload button, (2) call browser_file_upload - Emphasize that clicking FIRST is required to trigger file chooser modal - Add Workday-specific upload guidance - Include explicit JSON syntax for browser_file_upload call
- Add MCP TOOL EXAMPLES section with exact syntax - Show 2-step upload workflow: click button, then browser_file_upload - Include exact JSON syntax for paths parameter - Add examples for fill_form, click, navigate, evaluate - Fix syntax error in fill_form example
- Remove complex JavaScript examples that caused syntax errors - Replace with simple text descriptions of tool usage - Change 'NEVER SCROLL' to 'SCROLL ONLY WHEN NECESSARY' - Add form field discovery to step 2
|
Does this have failover for applying with claude when spending cap reached? Have you tested other models for applying, do they all handle this equally well? |
|
At the moment, I'm implementing this focused on extending the coding agent abstraction with a switch to use opencode rather than claude code. It doesn't yet have a fallback, but it wouldn't be too difficult to support, though would do that as a follow up. I currently have this working, but need to push some recent changes. I saw the other PR to add litellm support, so I pulled out the openai compatible api support from this PR, and am focused only on the opencode support/coding agent abstraction. Overall issues i'm seeing right now, is just that the prompt.py isn't really adequate, though at the moment I am using a very cheap model (gpt-5-mini) for testing that isn't as smart as the default one used. For example, the job I'm using for testing the application dry run wanted me to sign in with linkedin, but didn't seem to try to the option to click the continue with google button, it seemed to only want to use username and password. I signed into the browser with google so it would have easy access to social sign in, but it was explicitly told to only use username and password. I think the current challenge is we really need multiple well defined tests that test out the agent applying for positions across multiple sites that have different characteristics I do think that the current implementation of the agentic application is somewhat slow and could be significantly faster with better tooling, skills focused on particular families of sites, alternative browsers that would be less likely to have to solve captchas (camofox) or more efficient cli options (agent-browser), or code-mode, combined with config-driven custom tools. Ideally, when the agent is browsing it would more proactive information about the site and would avoid so much slow back and forth playwright tools. However, at the moment, my main focused for this PR is just adding the opencode support and any prompt optimizations to make sure it works for me and I'm pretty much there now. |
…on and LinkedIn optimizations - Add JSONL audit logging with timestamps and 30-day retention - Implement performance instrumentation to track LLM API latency - Fix pre-navigation to use Chrome CDP HTTP endpoint for persistent tabs - Fix resume upload path to copy file to worker directory - Add LinkedIn Easy Apply fast-path instructions (5-second target) - Add LinkedIn modal handling with overlay bypass for #interop-outlet - Add analyze CLI command for reviewing agent run performance - Update prompts with existence-based action workflows
feat: Add OpenCode Backend Support with Performance Instrumentation
Adds OpenCode CLI as an alternative backend to Claude Code for auto-apply orchestration.
Usage:
Claude Code remains the default. OpenCode is opt-in via
APPLY_BACKEND=opencode.What's Included
analyzecommand - Post-run performance review via CLIOpenCode Configuration Approach
Project Mode with XDG Isolation:
~/.applypilot/.opencode/opencode.jsoncapplypilot-applydefined in config~/.applypilot(isolates from global~/.config/opencode/)~/.opencode/auth.json(unaffected by redirect)Custom Agent Definition:
{ "agent": { "applypilot-apply": { "description": "Autonomous job application agent", "mode": "primary", "model": "github-copilot/gpt-5-mini", "prompt": "{file:../prompts/apply-agent.md}", "permission": { // Safety: deny file editing and bash "task": "deny", "edit": "deny", "write": "deny", "bash": "deny", // Read-only tools allowed "read": "allow", "grep": "allow", "glob": "allow", "lsp": "allow", // All Playwright browser tools enabled "playwright_browser_navigate": "allow", "playwright_browser_click": "allow", "playwright_browser_fill_form": "allow", "playwright_browser_snapshot": "allow", "playwright_browser_evaluate": "allow", "playwright_browser_file_upload": "allow", "playwright_browser_tabs": "allow", "playwright_browser_wait_for": "allow", "playwright_browser_screenshot": "allow", // All Gmail tools enabled "gmail_search_emails": "allow", "gmail_read_email": "allow", "gmail_send_email": "allow", "gmail_create_draft": "allow" } } } }Why This Approach:
Instrumentation
Captures detailed timing data:
Logs written to:
worker-{id}.events.jsonl- Structured action historyworker-{id}.perf.jsonl- Performance timing analysisObservations
From instrumented runs:
Files Changed (12 total)
Core Implementation (4 files)
src/applypilot/apply/backends.pysrc/applypilot/apply/launcher.pysrc/applypilot/apply/prompt.pysrc/applypilot/cli.pyanalyzecommandSupporting Changes (4 files)
src/applypilot/config.pysrc/applypilot/wizard/init.py.env.exampleREADME.mdTests (4 files)
tests/test_backend_selection.pytests/test_parser_edge_cases.pytests/conftest.pytests/__init__.pyFuture Optimization Opportunities
See section below for potential enhancements: custom tools, CLI optimizations, alternative browser automation (Camofox, agent-browser), MCP client direct connection, and platform-specific workflows.
Future Optimization Opportunities
This PR Is Intentionally Limited
This PR focuses solely on OpenCode integration and making it functional. The following optimizations are identified but intentionally left for future PRs to keep scope manageable:
1. Custom Tool Integration via OpenCode
OpenCode supports custom tools via MCP (Model Context Protocol). Potential optimizations:
2. CLI Tools with Stored Optimizations
Build CLI tools that leverage accumulated knowledge:
3. Alternative Browser Automation
Current: Playwright via MCP. Alternatives to explore:
4. MCP Client Direct Connection
Instead of agent-managed MCP, use programmatic MCP client:
5. Cached Analysis
6. Parallel Execution
Migration
No migration required. Existing Claude Code users unaffected.
To try OpenCode:
Checklist
analyzeCLI commandArchitecture Principle: Instrument first, optimize second. This PR establishes comprehensive instrumentation to measure before optimizing.