feat(jobs): add optional file output to job tools#519
Draft
ghul0 wants to merge 1 commit into
Draft
Conversation
Closes stickerdaniel#518. get_job_details and search_jobs gain two optional parameters: - output_mode: "display" (default, unchanged) | "file" | "both" - output_path: target path; the extension selects the format (.json dumps the full result dict, any other extension writes a readable text rendering of url/sections/job_ids). In "file" mode the tool persists the result and returns a compact confirmation (saved_path, url, job_ids, section names) instead of the full payload, so an agent can fan out over many postings without flooding the model context. "both" writes the file and still returns the full result. "display" preserves the existing behaviour exactly. The new apply_output_mode helper lives in common_utils.py and reuses the existing secure_write_text (atomic temp-file write, 0o600). Tests: unit coverage for apply_output_mode (display/file/both, json vs text rendering, missing-path error, ~ expansion) plus tool-level pass-through tests. Docs: README, docs/docker-hub.md, manifest.json.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an optional file-output mode to the two job tools so results can be written to disk instead of (or alongside) being returned to the MCP client. Implements #518.
Job results are large; fanning an agent over many postings and returning every full payload into the model context burns the window fast. With
output_mode="file"the tool persists the result and returns only a compact confirmation, so an agent can scrape many jobs without flooding context, hand the files to a downstream step (CV tailoring, scoring, human review), and keep a local record.What's in scope
get_job_detailsandsearch_jobs:output_mode: "display" | "file" | "both"— default"display", which is the existing behaviour unchanged.output_path: str | None— required when mode isfile/both. The extension drives the format:.jsondumps the full result dict; any other extension writes a readable text rendering of url/sections/job_ids.apply_output_mode(result, output_path, output_mode)incommon_utils.py, reusing the existingsecure_write_texthelper (atomic temp-file write,0o600) so file writes stay safe and consistent with the rest of the module.filemode the tool returns a compact confirmation (saved_path,url,job_ids, section names) instead of the full payload;bothwrites and still returns the full result.tests/test_common_utils.py::TestApplyOutputMode(display/file/both,.jsonvs text rendering, missing-pathValueError,~expansion) and tool-level pass-through tests intests/test_tools.py(filemode returns confirmation + writes the file; default mode still returns content).docs/docker-hub.md,manifest.json.Intentionally out of scope
apply_output_modeis generic and can wrap other tools later if there's appetite, but this PR keeps the surface small and reviewable.displaycallers see identical behaviour.Testing
uv run pytest: 551 passed locally. One pre-existing failure intest_browser_security.py::test_harden_linkedin_tree_noop_outside_linkedinreproduces onmainbefore this branch withumask=002; it's environmental and unrelated.uv run ruff check .: clean.uv run ty check: clean.manifest.jsonvalidated as JSON.Synthetic prompt
Generated with Claude Opus 4.7
Closes #518