{"slug": "integrating-reasonix-1-x-with-deepseek-v4-acp-model-selector-integration-in", "title": "Integrating Reasonix 1.x with DeepSeek V4: ACP Model Selector Integration in Practice", "summary": "HagiCode integrated Reasonix 1.x with DeepSeek V4, revealing a semantic migration challenge where startup parameters were reduced to a single `-model` flag, with credentials and policies moved to `reasonix.toml`. The adaptation layer uses a 'field preservation, semantic migration' pattern, preserving legacy fields but ignoring them at runtime.", "body_md": "This article discusses how to switch Reasonix 1.x, a local ACP CLI provider, to DeepSeek V4 in HagiCode. The focus isn't really on \"getting it in,\" but rather on the semantic changes from Reasonix 0.x to 1.x—startup parameters were cut down to just one\n\n`-model`\n\n, credentials and policies moved to`reasonix.toml`\n\n. Let's walk through the pitfalls encountered and the verification path, bit by bit.\n\nRecently someone asked a pretty specific question: how to integrate Reasonix 1.x version to use DeepSeek V4 in HagiCode.\n\nAt first glance it looked like a configuration question, but digging into the code revealed it's actually a CLI semantic migration problem. Reasonix is a local ACP (Agent Communication Protocol) CLI within HagiCode's multi-Agent Provider system. Its position in HagiCode's three-tier architecture is clear:\n\n`ReasonixProvider`\n\n, `ReasonixOptions`\n\n, wrapping `reasonix acp`\n\nprocess startup, ACP handshake, streaming notification mapping.`ReasonixCliProvider`\n\nthin adapter, `AIProviderType.ReasonixCli = 12`\n\n, `ReasonixGrain`\n\n, Hero parameter mapping, health monitoring.The entire integration chain is already implemented in the archived proposal `openspec/changes/archive/2026-06-06-integrate-reasonix-agent-provider`\n\n. So the question isn't \"how to get Reasonix into the system\" anymore, but \"once it's in, how to switch the model to DeepSeek V4\".\n\nThe key turning point is: Reasonix 1.x and 0.x have fundamentally different ACP bootstrap semantics. This change directly determines how you configure DeepSeek V4. After all, once semantics change, even if the surface looks similar, it's a different beast entirely.\n\nI'll leave that hanging: to untangle this complexity of multiple providers and multiple models, HagiCode adopted a \"field preservation, semantic migration\" design at the Reasonix adaptation layer. I'll explain exactly why this trade-off was chosen later.\n\nThe solution shared in this article comes from our practical experience in the\n\n[HagiCode]project.HagiCode is an AI coding assistant project supporting multiple local/remote Agent Providers. Code is open sourced at\n\n[HagiCode-org/site].\n\nLook directly at `ReasonixProvider.BuildCommandArguments`\n\n:\n\n```\ninternal virtual IReadOnlyList<string> BuildCommandArguments(ReasonixOptions options)\n{\n    var arguments = new List<string> { \"acp\" };\n    // Reasonix 1.x reduced ACP bootstrap to a transport-scoped provider selector.\n    AppendOption(arguments, \"-model\", options.Model);\n    foreach (var argument in NormalizeExtraArguments(options.ExtraArguments))\n        arguments.Add(argument);\n    return arguments;\n}\n```\n\nThat comment is the key: 1.x condensed ACP bootstrap to a \"transport-scoped provider selector.\" In plain English—the only flag still meaningful at startup is `-model`\n\n.\n\nThose legacy flags from the 0.x era are explicitly filtered out:\n\n```\nprivate static readonly HashSet<string> FilteredBootstrapFlags = new(StringComparer.OrdinalIgnoreCase)\n{\n    \"-model\", \"-m\", \"--model\",\n    \"-dir\", \"--dir\",\n    \"-effort\", \"--effort\",\n    \"-budget\", \"--budget\",\n    \"-transcript\", \"--transcript\",\n    \"-mcp\", \"--mcp\",\n    \"-mcp-prefix\", \"--mcp-prefix\",\n    \"-yolo\", \"--yolo\",\n    \"--dangerously-skip-permissions\",\n    \"--no-proxy\"\n};\n```\n\nUnit tests directly prove this. Pass in a bunch of legacy flags, the command line comes out clean, no errors, just silently dropped:\n\n```\narguments.ShouldBe(\n[\n    \"acp\",\n    \"-model\", \"deepseek-v4-flash\"\n]);\n```\n\nHere's an interesting design choice. Fields like `Effort`\n\n, `BudgetUsd`\n\n, `TranscriptPath`\n\n, `EnableYolo`\n\n, `McpServerSpecs`\n\n, `McpPrefix`\n\nin `ReasonixOptions`\n\nare all preserved, but each comment honestly states \"Reasonix 1.x ACP no longer accepts ... so this value is currently ignored\".\n\nThis is a classic **field preservation, semantic migration** pattern: caller contracts aren't broken (0.x code still compiles, still passes values), but at runtime these values are silently dropped. Policy-type things (permissions, MCP plugins, proxy) are required to move to `reasonix.toml`\n\n.\n\nTo put it another way, it's like your original light switch is still on the wall, but the renovation guy changed the wiring. Now the switch is just decoration, the real lighting control moved to the smart home panel. The switch looks unchanged, pressing it doesn't error out, but the light just doesn't turn on.\n\nSo the core action for integrating DeepSeek V4 is actually just one sentence: **pass the model id through the -model selector, configure credentials/endpoint in reasonix.toml**.\n\nIn HagiCode's tests and README, the DeepSeek series uses the standard pattern through the `Model`\n\nfield:\n\n``` js\nvar reasonixOptions = new ReasonixOptions\n{\n    WorkingDirectory = \"/path/to/repo\",\n    Model = \"deepseek-flash\",\n    SessionId = \"reasonix-session-123\"\n};\n```\n\nTests repeatedly show `Model = \"deepseek-v4-flash\"`\n\n, corresponding to the generated command line `reasonix acp -model deepseek-v4-flash`\n\n. The specific model id (`deepseek-v4-flash`\n\n, `deepseek-flash`\n\n, etc.) should follow the Reasonix 1.x version you installed and the provider aliases registered in `reasonix.toml`\n\n—after all, whether an alias is real or not, Reasonix knows best.\n\nThis is the second semantic change in 1.x, easy to get confused about. In 0.x you used `--dir`\n\nto specify working directory, in 1.x it changed to using `session/new`\n\n/ `session/load`\n\nwithin the ACP protocol:\n\n``` js\nvar sessionHandle = await sessionClient.StartSessionAsync(\n    workingDirectory,\n    options.SessionId,\n    model: null,   // Model selection completely determined by startup -model\n    startupCts.Token);\n```\n\nNote that the `model`\n\nparameter in `StartSessionAsync`\n\npasses `null`\n\n—model selection is completely determined by `-model`\n\nat startup, session level no longer overrides the model. `SessionId`\n\nis still a provider-native continuity hint, used only to resume sessions.\n\nPutting the above analysis together into an executable path, let's walk through four steps.\n\nReasonix is a locally installed, `IsPubliclyInstallable: false`\n\nprovider, can't be installed via npm publicly. First put the `reasonix`\n\nexecutable in PATH. After installing, verify with HagiCode.Libs' built-in console:\n\n```\n# Run Ping scenario, execute reasonix acp handshake and report version\ndotnet run --project src/HagiCode.Libs.Reasonix.Console -- --test-provider reasonix\n```\n\nIf handshake fails, it's usually one of two cases: either PATH didn't find `reasonix`\n\n, or `reasonix.toml`\n\nisn't configured. There aren't really any other reasons.\n\n1.x no longer accepts startup flags like `--api-key`\n\n, `--base-url`\n\n. Model provider endpoint, API key, proxy policies all need to be written to `reasonix.toml`\n\n. Configuration roughly includes:\n\n`-model`\n\nselector (like `deepseek-v4-flash`\n\n)Specific field names should follow the documentation of your installed Reasonix version. HagiCode's side only cares about passing through `-model deepseek-v4-flash`\n\n, how this alias resolves to the actual model is Reasonix's business—responsibility boundaries are clearly drawn, don't cross lines.\n\nThe resolution priority in backend `ReasonixCliProvider.ResolveModel`\n\nis: request.Model takes priority, otherwise fall back to `_config.Model`\n\n:\n\n``` js\nprivate string? ResolveModel(AIRequest request)\n{\n    var model = string.IsNullOrWhiteSpace(request.Model)\n        ? _config.Model\n        : request.Model;\n    return string.IsNullOrWhiteSpace(model) ? null : model.Trim();\n}\n```\n\nSo in `appsettings`\n\nor runtime config, set the provider's Model to DeepSeek V4's alias:\n\n```\n{\n  \"AIProvider\": {\n    \"Providers\": {\n      \"ReasonixCli\": {\n        \"Type\": \"ReasonixCli\",\n        \"Model\": \"deepseek-v4-flash\",\n        \"Settings\": {}\n      }\n    }\n  }\n}\n```\n\nHere's a trap that's easy to step in: `Settings`\n\ncan only hold keys within the whitelist:\n\n```\nprivate static readonly IReadOnlyList<string> SupportedSettingKeys =\n[\n    \"effort\", \"budgetUsd\", \"transcriptPath\",\n    \"enableYolo\", \"arguments\", \"startupTimeoutMs\", \"reasoning\"\n];\n```\n\n`ValidateConfigurationOverrides`\n\nwill directly reject keys outside the whitelist. And most of these keys are ignored in 1.x (corresponding to those ignored fields in `ReasonixOptions`\n\n), so **never stuff DeepSeek credentials into Settings**, that's not where they belong, credentials go to `reasonix.toml`\n\n.\n\nAfter configuration, run the full suite with Reasonix's dedicated console, explicitly specifying the model as DeepSeek V4:\n\n```\n# Default suite: four scenarios - Ping / Simple Prompt / Complex Prompt / Session Resume\ndotnet run --project src/HagiCode.Libs.Reasonix.Console -- \\\n  --test-provider-full --model deepseek-v4-flash --repo .\n```\n\nIf all four scenarios pass green, the model selector, ACP handshake, streaming notifications, session recovery—the entire chain is connected. Green means peace of mind.\n\nIf you go through HagiCode's Hero career UI instead of directly modifying appsettings, after selecting Reasonix in `HeroCliEquipmentForm`\n\n, the form fields are:\n\n`reasonix`\n\n`deepseek-v4-flash`\n\n(key field for switching to DeepSeek V4)Actually, only the `model`\n\nfield affects DeepSeek V4 behavior, the rest are just decoration under 1.x. This is also HagiCode's \"field preservation, semantic migration\" design reflected in the UI—the form doesn't break old user habits, but the fields that actually take effect are converged.\n\n`ReasonixCliProvider`\n\nuses `ConcurrentDictionary<string, string>`\n\nto maintain session bindings, binding key is calculated from sessionId, working directory, executable path, and model:\n\n``` js\nvar bindingKey = NormalizedAcpCliAdapter.BuildBindingKey(\n    effectiveRequest.CessionId,\n    options.WorkingDirectory,\n    options.ExecutablePath,\n    options.Model);\n```\n\nThis means if you switch models mid-session in the same session, the binding key changes and it's treated as a new session. So **after integrating DeepSeek V4, keep the model alias stable throughout the session lifecycle**, otherwise resume will break. I learned this the hard way through actual testing—blood and tears lesson, still remember the taste.\n\nReasonix uses the `Provider`\n\nstrategy (not `Grain`\n\nstrategy) in `AgentCliMonitoringRegistry`\n\n, since it might not be installed:\n\n```\nnew AgentCliMonitoringDescriptor\n{\n    CliId = \"reasonix\",\n    DisplayName = \"Reasonix\",\n    ProviderType = AIProviderType.ReasonixCli,\n    Strategy = Provider, // ping-based, via PATH discovery\n    ExecutableCandidates = [\"reasonix\"]\n}\n```\n\nFrontend health checks show whether Reasonix is available. If `reasonix`\n\nisn't in PATH, the UI gracefully degrades to \"unavailable\"—this logic is built in, no need to worry about it yourself.\n\n`deepseek-v4-flash`\n\nmust be a real alias registered in `reasonix.toml`\n\n, otherwise ACP handshake passes but sending prompts still fails. Verify with console first before going to Hero, don't cut corners.`arguments`\n\nto Pass Legacy Flags`NormalizeExtraArguments`\n\nfilters out `--effort`\n\n, `--budget`\n\n, etc., passing them is futile, wasted effort.`reasonix.toml`\n\n, HagiCode's side Settings whitelist doesn't have these fields at all.`startupTimeoutMs`\n\nfrom default 15000, this field is recognized in 1.x.`resolveEconomicSystemByExecutorType`\n\nmaps Reasonix to the `'claude'`\n\nbucket, purely for display, doesn't affect billing.If you just want to confirm DeepSeek V4 works quickly without touching Hero UI:\n\n`reasonix.toml`\n\n(DeepSeek endpoint + key + alias)`ReasonixCli.Model = \"deepseek-v4-flash\"`\n\nin `appsettings`\n\n`dotnet run --project src/HagiCode.Libs.Reasonix.Console -- --test-provider-full --model deepseek-v4-flash`\n\nReturning to the original question—\"how to integrate Reasonix 1.x to use DeepSeek v4\".\n\nThe answer is actually just one sentence: **pass the model alias through the -model selector, configure credentials and policies in reasonix.toml, don't count on CLI flags**.\n\nBehind that one sentence is a pretty clean semantic convergence by Reasonix 1.x: startup parameters cut to just `-model`\n\n, working directory and session recovery moved into ACP protocol, policies all sunk into toml. HagiCode's adaptation layer didn't fight this change head-on, but chose the gentle \"field preservation, semantic migration\" route—old code still compiles, still passes values, silently ignored at runtime, converging effective switches to just `-model`\n\n.\n\nThe benefit of this trade-off is smooth migration, the cost is documentation needs to be clear—which is why this article exists. Just remember three things:\n\n`-model`\n\n`-model deepseek-v4-flash`\n\nHagiCode chose to design the Reasonix adaptation layer this way essentially because it needs to accommodate multiple providers, multiple model versions, multiple deployment forms. This complexity of multiple languages, multiple platforms is exactly why we repeatedly polish the provider adaptation strategy in HagiCode.\n\n`repos/Hagicode.Libs/src/HagiCode.Libs.Providers/Reasonix/ReasonixProvider.cs`\n\n`repos/Hagicode.Libs/src/HagiCode.Libs.Providers/Reasonix/ReasonixOptions.cs`\n\n`repos/hagicode-core/src/PCode.ClaudeHelper/AI/Providers/ReasonixCliProvider.cs`\n\n`openspec/changes/archive/2026-06-06-integrate-reasonix-agent-provider`\n\n`openspec/specs/reasonix-backend-integration/spec.md`\n\n`repos/Hagicode.Libs/tests/HagiCode.Libs.Providers.Tests/ReasonixProviderTests.cs`\n\nAround \"Integrating Reasonix 1.x with DeepSeek V4: ACP Model Selector Integration in Practice,\" a more solid approach is to first gradually get key configurations, dependency boundaries, and implementation paths working, then fill in optimization details.\n\nWhen goals, steps, and acceptance criteria are clear, this type of solution usually flows more smoothly into actual delivery.\n\nThanks for reading. If this article helped, consider liking, bookmarking, or sharing it.\n\nThis article was created with AI assistance and reviewed by the author before publication.", "url": "https://wpnews.pro/news/integrating-reasonix-1-x-with-deepseek-v4-acp-model-selector-integration-in", "canonical_source": "https://dev.to/newbe36524/integrating-reasonix-1x-with-deepseek-v4-acp-model-selector-integration-in-practice-19dp", "published_at": "2026-06-19 01:50:20+00:00", "updated_at": "2026-06-19 02:30:12.675537+00:00", "lang": "en", "topics": ["developer-tools", "large-language-models", "ai-tools"], "entities": ["Reasonix", "DeepSeek V4", "HagiCode", "HagiCode-org/site"], "alternates": {"html": "https://wpnews.pro/news/integrating-reasonix-1-x-with-deepseek-v4-acp-model-selector-integration-in", "markdown": "https://wpnews.pro/news/integrating-reasonix-1-x-with-deepseek-v4-acp-model-selector-integration-in.md", "text": "https://wpnews.pro/news/integrating-reasonix-1-x-with-deepseek-v4-acp-model-selector-integration-in.txt", "jsonld": "https://wpnews.pro/news/integrating-reasonix-1-x-with-deepseek-v4-acp-model-selector-integration-in.jsonld"}}