{"slug": "routing-opencode-tasks-with-jev", "title": "Routing OpenCode Tasks with Jev", "summary": "A developer built a model router for OpenCode that uses the TypeSafe AI Jev model via OpenRouter to classify coding tasks by coordination, uncertainty, and consequences, then routes each request to either a powerful or weaker model based on a computed complexity score. The classifier, tested on roughly one hundred requests, selects the powerful model when complexity meets a threshold that tightens as potential consequences grow.", "body_md": "After the release of the TypeSafe AI Jev model and its availability in OpenRouter, I decided to immediately test its capabilities and rewrite my minimalist model router in OpenCode. To do this, I wrote a tool for OpenCode that sends requests to Jev through the OpenRouter API.\n\nThe main idea is to build the solution based on three criteria.\n\nAfter testing the classifier on about a hundred different requests, I settled on the following instructions:\n\nCoordination\n\n\"Does successful implementation require reasoning about interactions or coordinated behavior across multiple parts of the system, rather than merely making localized changes in more than one file or module?\"\n\nUncertainty\n\n\"Does successful implementation require open-ended investigation to discover an unknown root cause, bottleneck, design, or implementation strategy, rather than following a bounded diagnostic procedure with clear tools and success criteria?\"\n\nConsequences\n\n\"Would an incorrect implementation have significant consequences, such as broad regressions, compatibility breakage, security issues, or data loss?\"\n\nThese have currently shown the greatest effectiveness.\n\nNext, I calculate complexity as the maximum of two criteria: coordination and uncertainty.\n\nAnd a threshold value that depends on the consequences. The more serious the consequences, the lower the threshold value and the higher the probability that a powerful model will be used to solve the task.\n\nIf complexity is greater than or equal to the threshold value, the powerful model is selected; otherwise, the weaker one is selected.\n\nWhile developing this tool, I used ideas from several sources. I will quote them below:\n\n\"Rather than ask a model to solve the entire problem in one shot, we ask independent narrow questions and defer to code where possible. [...] The results are then used programmatically to produce the output actions.\"\n\n\"The most reliable real-world workflows tend to have many independent, decomposed questions, with fine-grained behavior that's dependent on probabilities instead of discrete decisions.\"\n\n\"Jev outputs all probabilities in parallel instead of autoregressively generating by token.\"\n\n\"The end result is discrete branching, but how we get to a final answer involves a lot of domain-specific engineering that needs to be done highly consistently.\"\n\n[https://typesafe.ai/blog/introducing-system-one-models-and-jev](https://typesafe.ai/blog/introducing-system-one-models-and-jev)\n\n\"Each prompt was evaluated [...] and returned a structured JSON object containing scores for seven criteria [...] These scores constituted a computable prompt-level vector used by the routing rule. [...] consists of calculating the total weighted score of each decision alternative and then selecting the alternative with the highest final value.\"\n\n[https://www.mdpi.com/2078-2489/17/6/539](https://www.mdpi.com/2078-2489/17/6/539)\n\nThe complete source code of the tool:\n\n``` js\n// .config/opencode/tools/jev_route.ts\n\nimport { tool } from \"@opencode-ai/plugin\";\n\nconst apiKey = process.env.OPENROUTER_API_KEY;\n\nif (!apiKey) {\n  console.error(\n    \"Missing OPENROUTER_API_KEY environment variable. Please set it to your OpenRouter API key.\",\n  );\n  process.exit(1);\n}\n\nconst lite = `\nChoose lite when the plan can be implemented reliably with localized changes\nand does not require cross-cutting reasoning.\n\nTypical lite work:\n- small fixes or straightforward feature changes\n- changes confined to one area of the codebase\n- following existing patterns\n- mechanical edits, tests, lint/type fixes, config tweaks\n- investigation or commands with a clear procedure\n`;\n\nconst build = `\nChoose build only when successful implementation requires substantial\ncross-cutting reasoning, design judgment, or carries significant regression risk.\n\nChoose build when the plan involves one or more of:\n- coordinated changes across multiple components or services\n- architecture or system design decisions\n- non-trivial debugging where the root cause is unknown\n- substantial refactoring with behavioral consequences\n- public APIs or compatibility guarantees\n- database schema changes or migrations\n- concurrency, distributed systems, or complex async behavior\n- authentication, authorization, or security-sensitive logic\n- significant performance or resource-management work\n- dependency or infrastructure changes with broad impact\n`;\n\nexport default tool({\n  description:\n    \"Classifies an approved implementation plan and returns either lite or build.\",\n  args: {\n    plan: tool.schema\n      .string()\n      .describe(\"The complete approved implementation plan\"),\n  },\n  async execute({ plan }) {\n    const response = await fetch(\"https://openrouter.ai/api/alpha/decisions\", {\n      method: \"POST\",\n      headers: {\n        Authorization: `Bearer ${apiKey}`,\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({\n        model: \"~typesafe/jev-latest\",\n        state: `\nApproved implementation plan:\n${plan}\n\nIf uncertain, choose build.\n        `,\n        questions: {\n          coordination: {\n            type: \"noul\",\n            instructions:\n              // \"Does successful implementation require coordinating behavior or changes across multiple parts of the system?\",\n              \"Does successful implementation require reasoning about interactions or coordinated behavior across multiple parts of the system, rather than merely making localized changes in more than one file or module?\",\n          },\n\n          uncertainty: {\n            type: \"noul\",\n            instructions:\n              // \"Does successful implementation require resolving substantial uncertainty, such as an unknown root cause, unclear design choice, or missing implementation strategy?\",\n              // \"Does successful implementation require first discovering the root cause, bottleneck, correct design, or implementation strategy because it is not already known from the plan?\",\n              \"Does successful implementation require open-ended investigation to discover an unknown root cause, bottleneck, design, or implementation strategy, rather than following a bounded diagnostic procedure with clear tools and success criteria?\",\n          },\n\n          consequence: {\n            type: \"noul\",\n            instructions:\n              \"Would an incorrect implementation have significant consequences, such as broad regressions, compatibility breakage, security issues, or data loss?\",\n          },\n        },\n      }),\n    });\n\n    const { answers } = await response.json();\n\n    const complexity = Math.max(\n      answers.coordination.noul,\n      answers.uncertainty.noul,\n    );\n\n    const threshold = answers.consequence.noul >= 0.7 ? 0.4 : 0.65;\n\n    return complexity >= threshold ? \"build\" : \"lite\";\n  },\n});\n```\n\nThe orchestration agent is forbidden from taking any actions other than calling one tool and delegating the task. Route agent configuration:\n\n```\n---\ndescription: Routes tasks to the appropriate implementation agent\nmode: primary\nmodel: openai/gpt-5.6-luna\npermissions:\n  - action: \"*\"\n    resource: \"*\"\n    effect: deny\n\n  - action: subagent\n    resource: Build\n    effect: allow\n\n  - action: subagent\n    resource: Lite\n    effect: allow\n\n  - action: jev_route\n    resource: \"*\"\n    effect: allow\n---\n\nYou are a task orchestrator.\n\nPlanning is complete. Treat the latest plan as approved.\n\n1. Call `jev_route` with the latest approved plan.\n2. It returns `lite` or `build`.\n3. Delegate the implementation to that subagent.\n4. Do not override the routing decision.\n5. Do not implement the task yourself.\n6. After completion, verify the result and respond concisely.\n```\n\nThis is much faster and cheaper than using \"thinking\" models. It is too early to draw final conclusions, but the initial results look promising. I will observe how it goes.", "url": "https://wpnews.pro/news/routing-opencode-tasks-with-jev", "canonical_source": "https://dev.to/lbobylev/routing-opencode-tasks-with-jev-2c4n", "published_at": "2026-09-18 18:50:05+00:00", "updated_at": "2026-09-18 18:52:51.279106+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents", "large-language-models"], "entities": ["OpenCode", "Jev", "TypeSafe AI", "OpenRouter"], "alternates": {"html": "https://wpnews.pro/news/routing-opencode-tasks-with-jev", "markdown": "https://wpnews.pro/news/routing-opencode-tasks-with-jev.md", "text": "https://wpnews.pro/news/routing-opencode-tasks-with-jev.txt", "jsonld": "https://wpnews.pro/news/routing-opencode-tasks-with-jev.jsonld"}}