job-forge 2.13.0 → 2.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/main.mdc +4 -1
- package/.opencode/agents/general-free.md +4 -3
- package/.opencode/agents/general-paid.md +2 -1
- package/.opencode/agents/glm-minimal.md +4 -3
- package/.opencode/opencode-model-fallback.json +9 -3
- package/AGENTS.md +4 -1
- package/CLAUDE.md +4 -1
- package/bin/create-job-forge.mjs +12 -4
- package/docs/MODEL-ROUTING.md +17 -9
- package/iso/agents/general-free.md +6 -2
- package/iso/agents/general-paid.md +5 -1
- package/iso/agents/glm-minimal.md +6 -2
- package/iso/config.json +25 -5
- package/iso/instructions.md +4 -1
- package/models.yaml +2 -12
- package/opencode.json +10 -7
- package/package.json +2 -2
package/.cursor/rules/main.mdc
CHANGED
|
@@ -41,6 +41,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
41
41
|
- [D3] Upgrade `apply` routing to `@general-paid` when offer score ≥ 4.0/5, when user flags "top-tier / dream job / high-stakes", or when late-stage pipeline (post-screens).
|
|
42
42
|
why: form-fill flows are 6+ steps; free-tier sometimes aborts mid-flow on large Greenhouse/Workday schemas; paid tier has more headroom
|
|
43
43
|
|
|
44
|
+
- [D3f] **Provider-failure downgrade on `apply` (all harnesses; OpenCode + OpenRouter especially):** If you dispatched `@general-paid` per [D3] and that subagent fails or exhausts retries with provider-side errors — copy mentioning Venice / Diem / Chutes, "insufficient" USD/credits/funds/balance, HTTP 402/429, overload / temporarily unavailable — re-dispatch the **same apply URL** once on `@general-free` before marking FAILED. Do not abandon the role solely because the upgraded tier hit a pool-specific limit.
|
|
45
|
+
why: `@general-paid` on OpenCode still uses free OpenRouter model ids; Venice-style balance errors are a backend-route issue, not proof that procedural `@general-free` cannot complete the same Greenhouse-style flow after [D5]/[H2] gates pass
|
|
46
|
+
|
|
44
47
|
- [D4] Auto-submit for offers scoring 3.0+/5 without pausing for confirmation between steps — scan → evaluate → apply is one continuous pipeline. Mark SKIP for <3.0 and move on.
|
|
45
48
|
why: JobForge is designed for end-to-end automation; pausing between steps defeats the purpose and the 3.0 gate already enforces quality
|
|
46
49
|
|
|
@@ -57,7 +60,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
57
60
|
3. Apply [D1]: batch/Geometra work → delegate; single/read-only/dev → inline.
|
|
58
61
|
4. Before any `task` batch using Geometra, run cleanup [H3].
|
|
59
62
|
5. Before `apply`, run duplicate check [H2] and location filter [D5].
|
|
60
|
-
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers.
|
|
63
|
+
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers; if that apply dispatch hits provider errors, downgrade once per [D3f].
|
|
61
64
|
7. Cap parallelism at 2 per round [H1].
|
|
62
65
|
8. One in-flight dispatch per company [H5].
|
|
63
66
|
9. Orchestrator does not fill forms in multi-job mode [H4].
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Procedural worker on free-tier model. Use for form filling via Geometra, tracker updates, TSV merges, scan dedup, OTP retrieval, and other mechanical/scripted tasks where quality-sensitive text generation is NOT required.
|
|
3
3
|
mode: subagent
|
|
4
|
-
model: openrouter/
|
|
4
|
+
model: openrouter/z-ai/glm-4.5-air:free
|
|
5
5
|
tools:
|
|
6
6
|
geometra_connect: true
|
|
7
7
|
geometra_page_model: true
|
|
@@ -17,9 +17,10 @@ tools:
|
|
|
17
17
|
temperature: 0.1
|
|
18
18
|
reasoningEffort: minimal
|
|
19
19
|
fallback_models:
|
|
20
|
-
- openrouter/
|
|
21
|
-
- openrouter/google/gemma-4-26b-a4b-it:free
|
|
20
|
+
- openrouter/minimax/minimax-m2.5:free
|
|
22
21
|
- openrouter/openai/gpt-oss-20b:free
|
|
22
|
+
- openrouter/nvidia/nemotron-3-nano-30b-a3b:free
|
|
23
|
+
- openrouter/qwen/qwen3-coder:free
|
|
23
24
|
---
|
|
24
25
|
|
|
25
26
|
You are the @general-free subagent. You run on a free-tier model, which means the orchestrator has delegated this task to you **specifically because the work is procedural**: deterministic steps, scripted outputs, no nuanced writing required.
|
|
@@ -8,9 +8,10 @@ tools:
|
|
|
8
8
|
temperature: 0.3
|
|
9
9
|
reasoningEffort: medium
|
|
10
10
|
fallback_models:
|
|
11
|
-
- openrouter/
|
|
11
|
+
- openrouter/nvidia/nemotron-3-super-120b-a12b:free
|
|
12
12
|
- openrouter/openai/gpt-oss-120b:free
|
|
13
13
|
- openrouter/z-ai/glm-4.5-air:free
|
|
14
|
+
- openrouter/qwen/qwen3-coder:free
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
You are the @general-paid subagent. The orchestrator delegated this task to you because it requires quality writing or judgment — the kind of work `@general-free` isn't well-suited for.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Narrow-scope extractor on free-tier model. Use for single-purpose tasks where the orchestrator passes the exact input and expects a small, structured output — e.g., "extract these 8 fields from this JD text" or "parse this form schema into a label→type map". NOT for multi-step workflows.
|
|
3
3
|
mode: subagent
|
|
4
|
-
model: openrouter/
|
|
4
|
+
model: openrouter/openai/gpt-oss-20b:free
|
|
5
5
|
tools:
|
|
6
6
|
geometra_*: false
|
|
7
7
|
gmail_*: false
|
|
@@ -14,9 +14,10 @@ tools:
|
|
|
14
14
|
temperature: 0
|
|
15
15
|
reasoningEffort: none
|
|
16
16
|
fallback_models:
|
|
17
|
-
- openrouter/
|
|
18
|
-
- openrouter/
|
|
17
|
+
- openrouter/google/gemma-4-26b-a4b-it:free
|
|
18
|
+
- openrouter/nvidia/nemotron-nano-9b-v2:free
|
|
19
19
|
- openrouter/google/gemma-4-31b-it:free
|
|
20
|
+
- openrouter/z-ai/glm-4.5-air:free
|
|
20
21
|
---
|
|
21
22
|
|
|
22
23
|
You are the @glm-minimal subagent. You handle narrow, one-shot extractions where the orchestrator has pre-digested the context and just needs you to do a specific transform.
|
|
@@ -3,9 +3,15 @@
|
|
|
3
3
|
"timeout_seconds": 30,
|
|
4
4
|
"notify_on_fallback": true,
|
|
5
5
|
"fallback_models": [
|
|
6
|
-
"openrouter/qwen/qwen3-next-80b-a3b-instruct:free",
|
|
7
6
|
"openrouter/openai/gpt-oss-120b:free",
|
|
8
|
-
"openrouter/
|
|
9
|
-
"openrouter/
|
|
7
|
+
"openrouter/z-ai/glm-4.5-air:free",
|
|
8
|
+
"openrouter/nvidia/nemotron-3-super-120b-a12b:free",
|
|
9
|
+
"openrouter/qwen/qwen3-next-80b-a3b-instruct:free"
|
|
10
|
+
],
|
|
11
|
+
"retryable_error_patterns": [
|
|
12
|
+
"(?i)\\bvenice\\b.*(?:insufficient|balance|credits?|diem|usd)",
|
|
13
|
+
"(?i)insufficient\\s+(?:usd|diem|credits?|funds?|balance)",
|
|
14
|
+
"(?i)credit.*balance.*too.*low",
|
|
15
|
+
"(?i)(?:temporarily\\s+)?unavailable|overloaded|try\\s+again"
|
|
10
16
|
]
|
|
11
17
|
}
|
package/AGENTS.md
CHANGED
|
@@ -36,6 +36,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
36
36
|
- [D3] Upgrade `apply` routing to `@general-paid` when offer score ≥ 4.0/5, when user flags "top-tier / dream job / high-stakes", or when late-stage pipeline (post-screens).
|
|
37
37
|
why: form-fill flows are 6+ steps; free-tier sometimes aborts mid-flow on large Greenhouse/Workday schemas; paid tier has more headroom
|
|
38
38
|
|
|
39
|
+
- [D3f] **Provider-failure downgrade on `apply` (all harnesses; OpenCode + OpenRouter especially):** If you dispatched `@general-paid` per [D3] and that subagent fails or exhausts retries with provider-side errors — copy mentioning Venice / Diem / Chutes, "insufficient" USD/credits/funds/balance, HTTP 402/429, overload / temporarily unavailable — re-dispatch the **same apply URL** once on `@general-free` before marking FAILED. Do not abandon the role solely because the upgraded tier hit a pool-specific limit.
|
|
40
|
+
why: `@general-paid` on OpenCode still uses free OpenRouter model ids; Venice-style balance errors are a backend-route issue, not proof that procedural `@general-free` cannot complete the same Greenhouse-style flow after [D5]/[H2] gates pass
|
|
41
|
+
|
|
39
42
|
- [D4] Auto-submit for offers scoring 3.0+/5 without pausing for confirmation between steps — scan → evaluate → apply is one continuous pipeline. Mark SKIP for <3.0 and move on.
|
|
40
43
|
why: JobForge is designed for end-to-end automation; pausing between steps defeats the purpose and the 3.0 gate already enforces quality
|
|
41
44
|
|
|
@@ -52,7 +55,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
52
55
|
3. Apply [D1]: batch/Geometra work → delegate; single/read-only/dev → inline.
|
|
53
56
|
4. Before any `task` batch using Geometra, run cleanup [H3].
|
|
54
57
|
5. Before `apply`, run duplicate check [H2] and location filter [D5].
|
|
55
|
-
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers.
|
|
58
|
+
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers; if that apply dispatch hits provider errors, downgrade once per [D3f].
|
|
56
59
|
7. Cap parallelism at 2 per round [H1].
|
|
57
60
|
8. One in-flight dispatch per company [H5].
|
|
58
61
|
9. Orchestrator does not fill forms in multi-job mode [H4].
|
package/CLAUDE.md
CHANGED
|
@@ -36,6 +36,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
36
36
|
- [D3] Upgrade `apply` routing to `@general-paid` when offer score ≥ 4.0/5, when user flags "top-tier / dream job / high-stakes", or when late-stage pipeline (post-screens).
|
|
37
37
|
why: form-fill flows are 6+ steps; free-tier sometimes aborts mid-flow on large Greenhouse/Workday schemas; paid tier has more headroom
|
|
38
38
|
|
|
39
|
+
- [D3f] **Provider-failure downgrade on `apply` (all harnesses; OpenCode + OpenRouter especially):** If you dispatched `@general-paid` per [D3] and that subagent fails or exhausts retries with provider-side errors — copy mentioning Venice / Diem / Chutes, "insufficient" USD/credits/funds/balance, HTTP 402/429, overload / temporarily unavailable — re-dispatch the **same apply URL** once on `@general-free` before marking FAILED. Do not abandon the role solely because the upgraded tier hit a pool-specific limit.
|
|
40
|
+
why: `@general-paid` on OpenCode still uses free OpenRouter model ids; Venice-style balance errors are a backend-route issue, not proof that procedural `@general-free` cannot complete the same Greenhouse-style flow after [D5]/[H2] gates pass
|
|
41
|
+
|
|
39
42
|
- [D4] Auto-submit for offers scoring 3.0+/5 without pausing for confirmation between steps — scan → evaluate → apply is one continuous pipeline. Mark SKIP for <3.0 and move on.
|
|
40
43
|
why: JobForge is designed for end-to-end automation; pausing between steps defeats the purpose and the 3.0 gate already enforces quality
|
|
41
44
|
|
|
@@ -52,7 +55,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
52
55
|
3. Apply [D1]: batch/Geometra work → delegate; single/read-only/dev → inline.
|
|
53
56
|
4. Before any `task` batch using Geometra, run cleanup [H3].
|
|
54
57
|
5. Before `apply`, run duplicate check [H2] and location filter [D5].
|
|
55
|
-
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers.
|
|
58
|
+
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers; if that apply dispatch hits provider errors, downgrade once per [D3f].
|
|
56
59
|
7. Cap parallelism at 2 per round [H1].
|
|
57
60
|
8. One in-flight dispatch per company [H5].
|
|
58
61
|
9. Orchestrator does not fill forms in multi-job mode [H4].
|
package/bin/create-job-forge.mjs
CHANGED
|
@@ -177,17 +177,25 @@ const opencodeCfg = {
|
|
|
177
177
|
},
|
|
178
178
|
// Register the exact OpenRouter free models the harness uses so they're
|
|
179
179
|
// selectable even if they are not in OpenCode's built-in preloaded set.
|
|
180
|
+
// This list is a superset: role primaries, per-agent fallback chains,
|
|
181
|
+
// and the orchestrator fallback chain.
|
|
180
182
|
provider: {
|
|
181
183
|
openrouter: {
|
|
182
184
|
models: {
|
|
185
|
+
// Orchestrator + agentic coding (role default)
|
|
183
186
|
'qwen/qwen3-coder:free': {},
|
|
187
|
+
// Role primaries
|
|
188
|
+
'z-ai/glm-4.5-air:free': {}, // fast
|
|
189
|
+
'qwen/qwen3-next-80b-a3b-instruct:free': {}, // quality
|
|
190
|
+
'openai/gpt-oss-20b:free': {}, // minimal
|
|
191
|
+
// Common fallbacks
|
|
192
|
+
'openai/gpt-oss-120b:free': {},
|
|
184
193
|
'minimax/minimax-m2.5:free': {},
|
|
185
|
-
'
|
|
194
|
+
'nvidia/nemotron-3-super-120b-a12b:free': {},
|
|
195
|
+
'nvidia/nemotron-3-nano-30b-a3b:free': {},
|
|
196
|
+
'nvidia/nemotron-nano-9b-v2:free': {},
|
|
186
197
|
'google/gemma-4-26b-a4b-it:free': {},
|
|
187
198
|
'google/gemma-4-31b-it:free': {},
|
|
188
|
-
'openai/gpt-oss-120b:free': {},
|
|
189
|
-
'openai/gpt-oss-20b:free': {},
|
|
190
|
-
'z-ai/glm-4.5-air:free': {},
|
|
191
199
|
},
|
|
192
200
|
},
|
|
193
201
|
},
|
package/docs/MODEL-ROUTING.md
CHANGED
|
@@ -18,9 +18,9 @@ Defined in `.opencode/agents/*.md` (shipped in the harness, symlinked into consu
|
|
|
18
18
|
|
|
19
19
|
| Agent | Model | Reasoning | Use for |
|
|
20
20
|
|-------|-------|-----------|---------|
|
|
21
|
-
| `@general-free` | `openrouter/
|
|
21
|
+
| `@general-free` | `openrouter/z-ai/glm-4.5-air:free` | `minimal` | Geometra form fills, tracker TSV merges, scan dedup, OTP retrieval via Gmail, scripted pipeline steps |
|
|
22
22
|
| `@general-paid` | `openrouter/qwen/qwen3-next-80b-a3b-instruct:free` | `medium` | Offer evaluation narratives (Blocks A-F), cover letters, "Why X?" answers, STAR+R interview stories, LinkedIn outreach prose |
|
|
23
|
-
| `@glm-minimal` | `openrouter/
|
|
23
|
+
| `@glm-minimal` | `openrouter/openai/gpt-oss-20b:free` | `none` | Narrow one-shot transforms: "extract these 8 fields from this JD text → JSON", "classify this archetype" |
|
|
24
24
|
|
|
25
25
|
The full task-to-agent mapping lives in [AGENTS.md → Subagent Routing](../AGENTS.md#subagent-routing--which-agent-for-which-task). The orchestrator (your primary session) is expected to delegate before taking any multi-step action — see the **Pre-flight delegation** rule in AGENTS.md.
|
|
26
26
|
|
|
@@ -139,15 +139,17 @@ Default chains ship upstream in each agent's YAML frontmatter (`node_modules/job
|
|
|
139
139
|
|
|
140
140
|
| Agent | Primary | Fallback chain (in order) |
|
|
141
141
|
|-------|---------|---------------------------|
|
|
142
|
-
| `@general-free` | `openrouter/minimax/minimax-m2.5:free`
|
|
143
|
-
| `@general-paid` | `openrouter/qwen/qwen3-next-80b-a3b-instruct:free` | `openrouter/
|
|
144
|
-
| `@glm-minimal` | `openrouter/google/gemma-4-26b-a4b-it:free`
|
|
142
|
+
| `@general-free` | `openrouter/z-ai/glm-4.5-air:free` | `openrouter/minimax/minimax-m2.5:free` → `openrouter/openai/gpt-oss-20b:free` → `openrouter/nvidia/nemotron-3-nano-30b-a3b:free` → `openrouter/qwen/qwen3-coder:free` |
|
|
143
|
+
| `@general-paid` | `openrouter/qwen/qwen3-next-80b-a3b-instruct:free` | `openrouter/nvidia/nemotron-3-super-120b-a12b:free` → `openrouter/openai/gpt-oss-120b:free` → `openrouter/z-ai/glm-4.5-air:free` → `openrouter/qwen/qwen3-coder:free` |
|
|
144
|
+
| `@glm-minimal` | `openrouter/openai/gpt-oss-20b:free` | `openrouter/google/gemma-4-26b-a4b-it:free` → `openrouter/nvidia/nemotron-nano-9b-v2:free` → `openrouter/google/gemma-4-31b-it:free` → `openrouter/z-ai/glm-4.5-air:free` |
|
|
145
145
|
|
|
146
146
|
These chains are deliberately free-only so the default OpenCode path never needs to pay. **Note:** OpenCode model IDs must use the provider prefix it expects (`openrouter/...`, `opencode/...`, etc.). The raw OpenRouter model slug by itself is not enough.
|
|
147
147
|
|
|
148
|
-
Consumers **do not need to configure anything** to get these defaults: the subagent chains arrive via the symlinked agent MD files, and the harness
|
|
148
|
+
Consumers **do not need to configure anything** to get these defaults: the subagent chains arrive via the symlinked agent MD files, and the harness ships `.opencode/opencode-model-fallback.json` for the main orchestrator / any agent without its own list. That JSON is **generated by `@razroo/iso-harness`** from the top-level `opencodeModelFallback` object in the harness's `iso/config.json` (same `iso build` pass as `opencode.json`), so it stays in sync with published releases — not a hand-edited file in git. `@razroo/opencode-model-fallback` (≥0.3.1) reads per-agent chains from the frontmatter-derived `fallback_models` field and falls through to the global file when no per-agent list exists. The consumer's `opencode.json` only needs `"plugin": ["@razroo/opencode-model-fallback"]` — which the scaffolder sets automatically.
|
|
149
149
|
|
|
150
|
-
**When fallback fires:** the plugin pattern-matches rate-limit / 5xx / quota / "overloaded" /
|
|
150
|
+
**When fallback fires:** the plugin pattern-matches rate-limit / 5xx / quota / "overloaded" / insufficient-balance style errors (including Venice / Diem copy — see `retryable_error_patterns` in the harness source). Failed models enter a cooldown before they're retried. Every rotation logs to `~/.config/opencode/opencode-model-fallback.log` with the trigger error, original model, and target model — grep for `"Auto-retrying with fallback model"` to confirm it fired.
|
|
151
|
+
|
|
152
|
+
**Orchestrator policy (all harnesses):** if an upgraded `@general-paid` apply still fails after model fallback, follow **[D3f]** in the shared instructions (`AGENTS.md` / `CLAUDE.md` / Cursor rules / Codex `AGENTS.md`) — re-dispatch the same URL once on `@general-free` before marking FAILED.
|
|
151
153
|
|
|
152
154
|
### Overriding an upstream chain
|
|
153
155
|
|
|
@@ -165,17 +167,23 @@ Add an `agent.<name>.fallback_models` block to your project's `opencode.json`. T
|
|
|
165
167
|
|
|
166
168
|
### Global fallback chain (agents without their own)
|
|
167
169
|
|
|
168
|
-
|
|
170
|
+
Source of truth: **`iso/config.json` → `opencodeModelFallback`** (iso-harness writes `.opencode/opencode-model-fallback.json` on `npm run build:config` / `prepack`). Applies to the orchestrator and any agent whose `fallback_models` is empty. Example shape:
|
|
169
171
|
|
|
170
172
|
```json
|
|
171
173
|
{
|
|
172
174
|
"cooldown_seconds": 60,
|
|
173
175
|
"timeout_seconds": 30,
|
|
174
176
|
"notify_on_fallback": true,
|
|
175
|
-
"fallback_models": [
|
|
177
|
+
"fallback_models": [
|
|
178
|
+
"openrouter/openai/gpt-oss-120b:free",
|
|
179
|
+
"openrouter/z-ai/glm-4.5-air:free"
|
|
180
|
+
],
|
|
181
|
+
"retryable_error_patterns": ["(?i)venice.*insufficient"]
|
|
176
182
|
}
|
|
177
183
|
```
|
|
178
184
|
|
|
185
|
+
`retryable_error_patterns` extends the plugin's built-in matchers — use it for provider-specific strings (Venice Diem balance, etc.) that do not match the stock regexes.
|
|
186
|
+
|
|
179
187
|
### Disabling fallback
|
|
180
188
|
|
|
181
189
|
Remove `"@razroo/opencode-model-fallback"` from `opencode.json:plugin` — agents keep their `model:` primary and errors propagate normally.
|
|
@@ -10,10 +10,14 @@ targets:
|
|
|
10
10
|
mode: subagent
|
|
11
11
|
temperature: 0.1
|
|
12
12
|
reasoningEffort: minimal
|
|
13
|
+
# Primary (z-ai/glm-4.5-air:free) resolves from openrouter-free preset.
|
|
14
|
+
# Fallback chain is ordered by decreasing likelihood of rate-limits,
|
|
15
|
+
# staying within free models that can tool-call Geometra + Gmail MCPs.
|
|
13
16
|
fallback_models:
|
|
14
|
-
- openrouter/
|
|
15
|
-
- openrouter/google/gemma-4-26b-a4b-it:free
|
|
17
|
+
- openrouter/minimax/minimax-m2.5:free
|
|
16
18
|
- openrouter/openai/gpt-oss-20b:free
|
|
19
|
+
- openrouter/nvidia/nemotron-3-nano-30b-a3b:free
|
|
20
|
+
- openrouter/qwen/qwen3-coder:free
|
|
17
21
|
tools:
|
|
18
22
|
geometra_connect: true
|
|
19
23
|
geometra_page_model: true
|
|
@@ -11,10 +11,14 @@ targets:
|
|
|
11
11
|
mode: subagent
|
|
12
12
|
temperature: 0.3
|
|
13
13
|
reasoningEffort: medium
|
|
14
|
+
# Primary (qwen/qwen3-next-80b-a3b-instruct:free) resolves from the
|
|
15
|
+
# openrouter-free preset. Fallback chain prioritizes models with
|
|
16
|
+
# strong long-form writing judgment over raw size.
|
|
14
17
|
fallback_models:
|
|
15
|
-
- openrouter/
|
|
18
|
+
- openrouter/nvidia/nemotron-3-super-120b-a12b:free
|
|
16
19
|
- openrouter/openai/gpt-oss-120b:free
|
|
17
20
|
- openrouter/z-ai/glm-4.5-air:free
|
|
21
|
+
- openrouter/qwen/qwen3-coder:free
|
|
18
22
|
tools:
|
|
19
23
|
geometra_*: false
|
|
20
24
|
gmail_*: false
|
|
@@ -10,10 +10,14 @@ targets:
|
|
|
10
10
|
mode: subagent
|
|
11
11
|
temperature: 0
|
|
12
12
|
reasoningEffort: none
|
|
13
|
+
# Primary (openai/gpt-oss-20b:free) resolves from openrouter-free
|
|
14
|
+
# preset. Fallback chain sticks to small dense models with reliable
|
|
15
|
+
# structured-output behavior — no creative generation upstream.
|
|
13
16
|
fallback_models:
|
|
14
|
-
- openrouter/
|
|
15
|
-
- openrouter/
|
|
17
|
+
- openrouter/google/gemma-4-26b-a4b-it:free
|
|
18
|
+
- openrouter/nvidia/nemotron-nano-9b-v2:free
|
|
16
19
|
- openrouter/google/gemma-4-31b-it:free
|
|
20
|
+
- openrouter/z-ai/glm-4.5-air:free
|
|
17
21
|
tools:
|
|
18
22
|
geometra_*: false
|
|
19
23
|
gmail_*: false
|
package/iso/config.json
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
{
|
|
2
|
+
"opencodeModelFallback": {
|
|
3
|
+
"cooldown_seconds": 60,
|
|
4
|
+
"timeout_seconds": 30,
|
|
5
|
+
"notify_on_fallback": true,
|
|
6
|
+
"fallback_models": [
|
|
7
|
+
"openrouter/openai/gpt-oss-120b:free",
|
|
8
|
+
"openrouter/z-ai/glm-4.5-air:free",
|
|
9
|
+
"openrouter/nvidia/nemotron-3-super-120b-a12b:free",
|
|
10
|
+
"openrouter/qwen/qwen3-next-80b-a3b-instruct:free"
|
|
11
|
+
],
|
|
12
|
+
"retryable_error_patterns": [
|
|
13
|
+
"(?i)\\bvenice\\b.*(?:insufficient|balance|credits?|diem|usd)",
|
|
14
|
+
"(?i)insufficient\\s+(?:usd|diem|credits?|funds?|balance)",
|
|
15
|
+
"(?i)credit.*balance.*too.*low",
|
|
16
|
+
"(?i)(?:temporarily\\s+)?unavailable|overloaded|try\\s+again"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
2
19
|
"targets": {
|
|
3
20
|
"opencode": {
|
|
4
21
|
"plugin": ["@razroo/opencode-model-fallback"],
|
|
@@ -8,13 +25,16 @@
|
|
|
8
25
|
"openrouter": {
|
|
9
26
|
"models": {
|
|
10
27
|
"qwen/qwen3-coder:free": {},
|
|
11
|
-
"
|
|
28
|
+
"z-ai/glm-4.5-air:free": {},
|
|
12
29
|
"qwen/qwen3-next-80b-a3b-instruct:free": {},
|
|
13
|
-
"google/gemma-4-26b-a4b-it:free": {},
|
|
14
|
-
"google/gemma-4-31b-it:free": {},
|
|
15
|
-
"openai/gpt-oss-120b:free": {},
|
|
16
30
|
"openai/gpt-oss-20b:free": {},
|
|
17
|
-
"
|
|
31
|
+
"openai/gpt-oss-120b:free": {},
|
|
32
|
+
"minimax/minimax-m2.5:free": {},
|
|
33
|
+
"nvidia/nemotron-3-super-120b-a12b:free": {},
|
|
34
|
+
"nvidia/nemotron-3-nano-30b-a3b:free": {},
|
|
35
|
+
"nvidia/nemotron-nano-9b-v2:free": {},
|
|
36
|
+
"google/gemma-4-26b-a4b-it:free": {},
|
|
37
|
+
"google/gemma-4-31b-it:free": {}
|
|
18
38
|
}
|
|
19
39
|
}
|
|
20
40
|
}
|
package/iso/instructions.md
CHANGED
|
@@ -36,6 +36,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
36
36
|
- [D3] Upgrade `apply` routing to `@general-paid` when offer score ≥ 4.0/5, when user flags "top-tier / dream job / high-stakes", or when late-stage pipeline (post-screens).
|
|
37
37
|
why: form-fill flows are 6+ steps; free-tier sometimes aborts mid-flow on large Greenhouse/Workday schemas; paid tier has more headroom
|
|
38
38
|
|
|
39
|
+
- [D3f] **Provider-failure downgrade on `apply` (all harnesses; OpenCode + OpenRouter especially):** If you dispatched `@general-paid` per [D3] and that subagent fails or exhausts retries with provider-side errors — copy mentioning Venice / Diem / Chutes, "insufficient" USD/credits/funds/balance, HTTP 402/429, overload / temporarily unavailable — re-dispatch the **same apply URL** once on `@general-free` before marking FAILED. Do not abandon the role solely because the upgraded tier hit a pool-specific limit.
|
|
40
|
+
why: `@general-paid` on OpenCode still uses free OpenRouter model ids; Venice-style balance errors are a backend-route issue, not proof that procedural `@general-free` cannot complete the same Greenhouse-style flow after [D5]/[H2] gates pass
|
|
41
|
+
|
|
39
42
|
- [D4] Auto-submit for offers scoring 3.0+/5 without pausing for confirmation between steps — scan → evaluate → apply is one continuous pipeline. Mark SKIP for <3.0 and move on.
|
|
40
43
|
why: JobForge is designed for end-to-end automation; pausing between steps defeats the purpose and the 3.0 gate already enforces quality
|
|
41
44
|
|
|
@@ -52,7 +55,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
52
55
|
3. Apply [D1]: batch/Geometra work → delegate; single/read-only/dev → inline.
|
|
53
56
|
4. Before any `task` batch using Geometra, run cleanup [H3].
|
|
54
57
|
5. Before `apply`, run duplicate check [H2] and location filter [D5].
|
|
55
|
-
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers.
|
|
58
|
+
6. Route by cost tier [D2]; upgrade to `@general-paid` per [D3] for high-stakes offers; if that apply dispatch hits provider errors, downgrade once per [D3f].
|
|
56
59
|
7. Cap parallelism at 2 per round [H1].
|
|
57
60
|
8. One in-flight dispatch per company [H5].
|
|
58
61
|
9. Orchestrator does not fill forms in multi-job mode [H4].
|
package/models.yaml
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
#
|
|
10
10
|
# JobForge's subagents bind to preset roles via the `role:` field in
|
|
11
11
|
# iso/agents/<slug>.md:
|
|
12
|
-
# @general-free → role: fast (Haiku / OpenRouter
|
|
12
|
+
# @general-free → role: fast (Haiku / OpenRouter GLM 4.5 Air free / gpt-5.4-mini)
|
|
13
13
|
# @general-paid → role: quality (Opus 4.7 / OpenRouter Qwen3 Next 80B free / gpt-5.4)
|
|
14
|
-
# @glm-minimal → role: minimal (Haiku / OpenRouter
|
|
14
|
+
# @glm-minimal → role: minimal (Haiku / OpenRouter GPT-OSS-20B free / gpt-5.4-nano)
|
|
15
15
|
#
|
|
16
16
|
# Override anything by adding fields here. For example, to pin Opus on
|
|
17
17
|
# Claude Code for the @general-paid (quality) role:
|
|
@@ -30,13 +30,3 @@
|
|
|
30
30
|
# model: gpt-5.4
|
|
31
31
|
|
|
32
32
|
extends: openrouter-free
|
|
33
|
-
|
|
34
|
-
# Only override the preset where we prefer a different OpenRouter pick.
|
|
35
|
-
# The preset's quality-tier OpenCode pick is openai/gpt-oss-120b:free;
|
|
36
|
-
# we prefer Qwen3 Next 80B for job-application writing quality.
|
|
37
|
-
roles:
|
|
38
|
-
quality:
|
|
39
|
-
targets:
|
|
40
|
-
opencode:
|
|
41
|
-
provider: openrouter
|
|
42
|
-
model: qwen/qwen3-next-80b-a3b-instruct:free
|
package/opencode.json
CHANGED
|
@@ -3,26 +3,29 @@
|
|
|
3
3
|
"model": "openrouter/qwen/qwen3-coder:free",
|
|
4
4
|
"agent": {
|
|
5
5
|
"fast": {
|
|
6
|
-
"model": "openrouter/
|
|
6
|
+
"model": "openrouter/z-ai/glm-4.5-air:free"
|
|
7
7
|
},
|
|
8
8
|
"quality": {
|
|
9
9
|
"model": "openrouter/qwen/qwen3-next-80b-a3b-instruct:free"
|
|
10
10
|
},
|
|
11
11
|
"minimal": {
|
|
12
|
-
"model": "openrouter/
|
|
12
|
+
"model": "openrouter/openai/gpt-oss-20b:free"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"provider": {
|
|
16
16
|
"openrouter": {
|
|
17
17
|
"models": {
|
|
18
18
|
"qwen/qwen3-coder:free": {},
|
|
19
|
-
"
|
|
19
|
+
"z-ai/glm-4.5-air:free": {},
|
|
20
20
|
"qwen/qwen3-next-80b-a3b-instruct:free": {},
|
|
21
|
-
"google/gemma-4-26b-a4b-it:free": {},
|
|
22
|
-
"google/gemma-4-31b-it:free": {},
|
|
23
|
-
"openai/gpt-oss-120b:free": {},
|
|
24
21
|
"openai/gpt-oss-20b:free": {},
|
|
25
|
-
"
|
|
22
|
+
"openai/gpt-oss-120b:free": {},
|
|
23
|
+
"minimax/minimax-m2.5:free": {},
|
|
24
|
+
"nvidia/nemotron-3-super-120b-a12b:free": {},
|
|
25
|
+
"nvidia/nemotron-3-nano-30b-a3b:free": {},
|
|
26
|
+
"nvidia/nemotron-nano-9b-v2:free": {},
|
|
27
|
+
"google/gemma-4-26b-a4b-it:free": {},
|
|
28
|
+
"google/gemma-4-31b-it:free": {}
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "job-forge",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"description": "AI-powered job search pipeline built on opencode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@razroo/iso": "^0.2.5",
|
|
91
|
-
"@razroo/iso-harness": "^0.6.
|
|
91
|
+
"@razroo/iso-harness": "^0.6.1",
|
|
92
92
|
"@razroo/iso-route": "^0.5.0",
|
|
93
93
|
"@razroo/iso-trace": "^0.1.0",
|
|
94
94
|
"@razroo/opencode-model-fallback": "^0.3.1"
|