loki-mode 7.39.0 → 7.39.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +27 -5
- package/autonomy/run.sh +20 -4
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +23 -2
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/providers/claude.sh +6 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 11 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v7.39.
|
|
6
|
+
# Loki Mode v7.39.1
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -398,4 +398,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
398
398
|
|
|
399
399
|
---
|
|
400
400
|
|
|
401
|
-
**v7.39.
|
|
401
|
+
**v7.39.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.39.
|
|
1
|
+
7.39.1
|
package/autonomy/loki
CHANGED
|
@@ -13433,7 +13433,12 @@ def _resolve_session_pin(alias):
|
|
|
13433
13433
|
elif _pin_tier == 'fast':
|
|
13434
13434
|
_m = _provider_model_fast()
|
|
13435
13435
|
elif _pin_tier == 'fable':
|
|
13436
|
-
|
|
13436
|
+
# fable unavailable, collapse to opus. Claude Fable 5 is not available at
|
|
13437
|
+
# the Claude API (advises use Opus 4.8); the runner dispatches opus for a
|
|
13438
|
+
# fable pin (claude.sh resolve_model_for_tier, run.sh dispatch backstop).
|
|
13439
|
+
# Quote opus pricing (\$5/\$25) so the estimator agrees with dispatch and
|
|
13440
|
+
# the dashboard (v7.39.1).
|
|
13441
|
+
_m = 'opus'
|
|
13437
13442
|
else: # development (and the '*' fallthrough)
|
|
13438
13443
|
_m = _provider_model_development()
|
|
13439
13444
|
# Apply the shared LOKI_MAX_TIER clamp with the REAL tier and resolved model
|
|
@@ -13467,6 +13472,16 @@ if _is_override:
|
|
|
13467
13472
|
else:
|
|
13468
13473
|
_dispatched_model = _resolve_session_pin(session_model_env)
|
|
13469
13474
|
|
|
13475
|
+
# fable unavailable, collapse to opus (final dispatch backstop, mirrors run.sh).
|
|
13476
|
+
# The override-path clamp (_loki_clamp_alias) leaves an uncapped fable override as
|
|
13477
|
+
# 'fable', but the runner's dispatch backstop collapses tier_param=='fable' to
|
|
13478
|
+
# opus before --model. Apply the same collapse here so the OVERRIDE route quotes
|
|
13479
|
+
# opus too, agreeing with dispatch and the dashboard. The session-pin route is
|
|
13480
|
+
# already collapsed inside _resolve_session_pin; this also covers a fable override
|
|
13481
|
+
# file (v7.39.1).
|
|
13482
|
+
if _dispatched_model == 'fable':
|
|
13483
|
+
_dispatched_model = 'opus'
|
|
13484
|
+
|
|
13470
13485
|
# Keep session_model_env (the alias) for token-volume tier mapping and provenance,
|
|
13471
13486
|
# but record when the cost ceiling actually changed the dispatched model so the
|
|
13472
13487
|
# provenance line is honest about the clamp.
|
|
@@ -13757,12 +13772,16 @@ for i in range(estimated_iterations):
|
|
|
13757
13772
|
# IS the dispatched model. In session-pinned mode (the default) the runner
|
|
13758
13773
|
# resolves the pin through provider config (_dispatched_model): a sonnet pin
|
|
13759
13774
|
# dispatches opus, so we price Opus, not the tier's static 'Sonnet' label.
|
|
13760
|
-
# The fable-architect iteration 0
|
|
13761
|
-
#
|
|
13775
|
+
# The fable-architect iteration 0 collapses to opus at dispatch (Fable 5 is
|
|
13776
|
+
# unavailable at the claude API), so it is priced as Opus, not Fable (v7.39.1).
|
|
13762
13777
|
if legacy_tier_switching:
|
|
13763
13778
|
model = info['model']
|
|
13764
13779
|
elif _fable_architect and i == 0:
|
|
13765
|
-
|
|
13780
|
+
# Architect opt-in iter-0: fable unavailable, the runner dispatches opus
|
|
13781
|
+
# for the architecture pass (LOKI_FABLE_ARCHITECT collapses to opus in
|
|
13782
|
+
# run.sh / claude.sh). Token VOLUME stays the advisor/planning tier
|
|
13783
|
+
# (50k/8k), but the priced model is Opus, not Fable (v7.39.1).
|
|
13784
|
+
model = 'Opus'
|
|
13766
13785
|
else:
|
|
13767
13786
|
model = _priced_model_for(_dispatched_model)
|
|
13768
13787
|
inp = info['input']
|
|
@@ -13969,7 +13988,10 @@ else:
|
|
|
13969
13988
|
else:
|
|
13970
13989
|
print(f' {DIM}(pinned via {_session_model_source}={session_model_env}; set LOKI_LEGACY_TIER_SWITCHING=true to rotate){NC}')
|
|
13971
13990
|
if _fable_architect:
|
|
13972
|
-
|
|
13991
|
+
# fable unavailable: the architect opt-in now runs the architecture pass
|
|
13992
|
+
# on opus (Claude Fable 5 is not available at the Claude API). Disclose
|
|
13993
|
+
# Opus so the quote matches dispatch (v7.39.1).
|
|
13994
|
+
print(f' {DIM}(+ 1 architecture iteration on Opus via LOKI_FABLE_ARCHITECT=1){NC}')
|
|
13973
13995
|
if fable_n > 0:
|
|
13974
13996
|
print(f' {YELLOW}Fable 5 is the top-tier advisory model priced at 2x Opus ({chr(36)}10/{chr(36)}50 per MTok).{NC}')
|
|
13975
13997
|
|
package/autonomy/run.sh
CHANGED
|
@@ -1822,18 +1822,23 @@ get_provider_tier_param() {
|
|
|
1822
1822
|
if [ -n "${PROVIDER_MODEL_PLANNING:-}" ]; then
|
|
1823
1823
|
echo "${PROVIDER_MODEL_PLANNING}"
|
|
1824
1824
|
elif [ "${LOKI_FABLE_ARCHITECT:-0}" = "1" ]; then
|
|
1825
|
-
|
|
1825
|
+
# fable unavailable, collapse to opus. Claude Fable 5 is
|
|
1826
|
+
# not available at the Claude API ("use Opus 4.8"); the
|
|
1827
|
+
# architect opt-in now runs opus. Matches claude.sh
|
|
1828
|
+
# resolve_model_for_tier and the estimator/dashboard.
|
|
1829
|
+
echo "opus"
|
|
1826
1830
|
else
|
|
1827
1831
|
echo "opus"
|
|
1828
1832
|
fi
|
|
1829
1833
|
;;
|
|
1830
1834
|
development) echo "${PROVIDER_MODEL_DEVELOPMENT:-opus}" ;;
|
|
1831
1835
|
fast) echo "${PROVIDER_MODEL_FAST:-sonnet}" ;;
|
|
1832
|
-
#
|
|
1836
|
+
# fable unavailable, collapse to opus. Without this arm an
|
|
1833
1837
|
# unsourced-claude.sh environment (this static fallback) would
|
|
1834
1838
|
# silently downgrade a fable-pinned tier to sonnet via the `*`
|
|
1835
|
-
# default. Matches resolve_model_for_tier's explicit fable) arm
|
|
1836
|
-
|
|
1839
|
+
# default. Matches resolve_model_for_tier's explicit fable) arm,
|
|
1840
|
+
# which now resolves to opus (Fable 5 unavailable at the API).
|
|
1841
|
+
fable) echo "opus" ;;
|
|
1837
1842
|
*) echo "sonnet" ;;
|
|
1838
1843
|
esac
|
|
1839
1844
|
;;
|
|
@@ -12781,6 +12786,17 @@ except Exception as exc:
|
|
|
12781
12786
|
log_warn "Ignoring invalid model override '$_loki_override_file' (allowed: haiku, sonnet, opus, fable); using tier $tier_param"
|
|
12782
12787
|
fi
|
|
12783
12788
|
fi
|
|
12789
|
+
# fable unavailable, collapse to opus (final dispatch backstop). Claude
|
|
12790
|
+
# Fable 5 is not available at the Claude API ("use Opus 4.8"). Any path
|
|
12791
|
+
# that left tier_param="fable" (static fallback, override file, architect
|
|
12792
|
+
# opt-in) is collapsed to opus here, after all tier_param mutations and
|
|
12793
|
+
# before the claude argv is built (--model "$tier_param"). Keeps dispatch,
|
|
12794
|
+
# the cost quote, and the dashboard effective-model in agreement. Only for
|
|
12795
|
+
# the claude provider: codex/cline/aider map tier_param to their own
|
|
12796
|
+
# effort/model strings and have no fable equivalent (v7.39.1).
|
|
12797
|
+
if [ "${PROVIDER_NAME:-claude}" = "claude" ] && [ "$tier_param" = "fable" ]; then
|
|
12798
|
+
tier_param="opus"
|
|
12799
|
+
fi
|
|
12784
12800
|
echo "=== RARV Phase: $rarv_phase, Tier: $CURRENT_TIER ($tier_param) ===" | tee -a "$log_file" "$agent_log"
|
|
12785
12801
|
log_info "RARV Phase: $rarv_phase -> Tier: $CURRENT_TIER ($tier_param)"
|
|
12786
12802
|
|
package/dashboard/__init__.py
CHANGED
package/dashboard/server.py
CHANGED
|
@@ -2406,7 +2406,12 @@ def _resolve_session_pin(alias: str) -> str:
|
|
|
2406
2406
|
elif pin_tier == "fast":
|
|
2407
2407
|
model = _provider_model_fast()
|
|
2408
2408
|
elif pin_tier == "fable":
|
|
2409
|
-
|
|
2409
|
+
# fable unavailable, collapse to opus. Claude Fable 5 is not available at
|
|
2410
|
+
# the Claude API ("use Opus 4.8"); the runner dispatches opus for a fable
|
|
2411
|
+
# pin (claude.sh resolve_model_for_tier, run.sh dispatch backstop), and
|
|
2412
|
+
# the estimator quotes opus. The dashboard effective model agrees so the
|
|
2413
|
+
# session-pin parity matrix stays green (v7.39.1).
|
|
2414
|
+
model = "opus"
|
|
2410
2415
|
else: # development (and the unknown-alias '*' fallthrough)
|
|
2411
2416
|
model = _provider_model_development()
|
|
2412
2417
|
max_tier = (os.environ.get("LOKI_MAX_TIER") or "").strip().lower()
|
|
@@ -2483,6 +2488,13 @@ async def get_session_model():
|
|
|
2483
2488
|
effective = _clamp_to_max_tier(override)
|
|
2484
2489
|
else:
|
|
2485
2490
|
effective = _resolve_session_pin(default)
|
|
2491
|
+
# fable unavailable, collapse to opus (final dispatch backstop, mirrors run.sh
|
|
2492
|
+
# and the estimator). The override-path clamp leaves an uncapped fable override
|
|
2493
|
+
# as "fable", but the runner dispatches opus for it; the session-pin route is
|
|
2494
|
+
# already collapsed inside _resolve_session_pin. Apply the same collapse here so
|
|
2495
|
+
# the reported effective model agrees with dispatch on BOTH routes (v7.39.1).
|
|
2496
|
+
if effective == "fable":
|
|
2497
|
+
effective = "opus"
|
|
2486
2498
|
return {
|
|
2487
2499
|
"override": override,
|
|
2488
2500
|
"default": default,
|
|
@@ -2533,7 +2545,16 @@ async def set_session_model(request: SessionModelRequest):
|
|
|
2533
2545
|
except OSError as exc:
|
|
2534
2546
|
raise HTTPException(status_code=500, detail=f"Could not write override: {exc}")
|
|
2535
2547
|
effective = _clamp_to_max_tier(model)
|
|
2536
|
-
|
|
2548
|
+
# `clamped` reflects ONLY the LOKI_MAX_TIER cost ceiling, computed before the
|
|
2549
|
+
# fable->opus collapse below (the collapse is model unavailability, not a cost
|
|
2550
|
+
# clamp, so it must not flip `clamped`).
|
|
2551
|
+
clamped = effective != model
|
|
2552
|
+
# fable unavailable, collapse to opus (final dispatch backstop, mirrors run.sh
|
|
2553
|
+
# and the estimator). An uncapped fable override clamps to "fable" above but the
|
|
2554
|
+
# runner dispatches opus for it, so report opus as the effective model (v7.39.1).
|
|
2555
|
+
if effective == "fable":
|
|
2556
|
+
effective = "opus"
|
|
2557
|
+
return {"model": model, "effective": effective, "clamped": clamped}
|
|
2537
2558
|
|
|
2538
2559
|
|
|
2539
2560
|
@app.get("/api/running-projects")
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v7.39.
|
|
5
|
+
**Version:** v7.39.1
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.39.
|
|
2
|
+
var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.39.1";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=QQ(ZQ(import.meta.url)),Z=d$(Q);$$=e6($Q(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var n$=L(()=>{C()});var C1={};h(C1,{runOrThrow:()=>zQ,run:()=>j,commandVersion:()=>KQ,commandExists:()=>f,ShellError:()=>a$});async function j($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[W,K,U]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:W,stderr:K,exitCode:U}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function zQ($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=XQ($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function XQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function KQ($,Q="--version"){if(!await f($))return null;let z=await j([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var a$;var d=L(()=>{a$=class a$ extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function a($){return WQ?"":$}var WQ,T,S,I,TZ,w,R,y,q;var c=L(()=>{WQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),I=a("\x1B[1;33m"),TZ=a("\x1B[0;34m"),w=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),q=a("\x1B[0m")});import{existsSync as TQ}from"fs";async function Q$(){if(B$!==void 0)return B$;let $="/opt/homebrew/bin/python3.12";if(TQ($))return B$=$,$;let Q=await f("python3.12");if(Q)return B$=Q,Q;let Z=await f("python3");return B$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B$;var W$=L(()=>{d()});var t1={};h(t1,{runStatus:()=>gQ});import{existsSync as v,readFileSync as U$,readdirSync as l1,statSync as d1}from"fs";import{resolve as D,basename as xQ}from"path";import{homedir as NQ}from"os";async function DQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${q}
|
|
3
3
|
`),process.stdout.write(`Install with:
|
|
4
4
|
`),process.stdout.write(` brew install jq (macOS)
|
|
5
5
|
`),process.stdout.write(` apt install jq (Debian/Ubuntu)
|
|
@@ -789,4 +789,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
789
789
|
`),2}default:return process.stderr.write(`Unknown command: ${Q}
|
|
790
790
|
`),process.stderr.write(o6),2}}p1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var ZZ=await QZ(Bun.argv.slice(2));process.exit(ZZ);
|
|
791
791
|
|
|
792
|
-
//# debugId=
|
|
792
|
+
//# debugId=A84007347C5EA4D964756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
3
|
"mcpName": "io.github.asklokesh/loki-mode",
|
|
4
|
-
"version": "7.39.
|
|
4
|
+
"version": "7.39.1",
|
|
5
5
|
"description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 11 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agent",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "loki-mode",
|
|
4
4
|
"displayName": "Loki Mode",
|
|
5
|
-
"version": "7.39.
|
|
5
|
+
"version": "7.39.1",
|
|
6
6
|
"description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 11 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Autonomi",
|
package/providers/claude.sh
CHANGED
|
@@ -398,7 +398,12 @@ resolve_model_for_tier() {
|
|
|
398
398
|
planning) model="$PROVIDER_MODEL_PLANNING" ;;
|
|
399
399
|
development) model="$PROVIDER_MODEL_DEVELOPMENT" ;;
|
|
400
400
|
fast) model="$PROVIDER_MODEL_FAST" ;;
|
|
401
|
-
fable
|
|
401
|
+
# fable unavailable, collapse to opus. Claude Fable 5 is not available at
|
|
402
|
+
# the Claude API ("use Opus 4.8"). The fable tier label and session-pin
|
|
403
|
+
# parsing (loki_normalize_model_alias still accepts "fable") stay; only
|
|
404
|
+
# the RESOLVED dispatch model becomes opus, matching the estimator and
|
|
405
|
+
# dashboard so the session-pin parity matrix agrees (v7.39.1).
|
|
406
|
+
fable) model="opus" ;;
|
|
402
407
|
*) model="$PROVIDER_MODEL_DEVELOPMENT" ;;
|
|
403
408
|
esac
|
|
404
409
|
|