loki-mode 6.76.1 → 6.77.0
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/run.sh +6 -6
- package/dashboard/__init__.py +1 -1
- package/dashboard/static/index.html +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/providers/aider.sh +14 -1
- package/providers/claude.sh +16 -2
- package/providers/cline.sh +14 -1
- package/providers/model_catalog.json +82 -0
- package/providers/models.sh +79 -0
- package/references/multi-provider.md +4 -4
- package/skills/production.md +2 -2
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Multi-agent autonomous startup system. Triggers on "Loki Mode". Takes PRD to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v6.
|
|
6
|
+
# Loki Mode v6.77.0
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -272,4 +272,4 @@ The following features are documented in skill modules but not yet fully automat
|
|
|
272
272
|
| Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
|
|
273
273
|
| Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
|
|
274
274
|
|
|
275
|
-
**v6.
|
|
275
|
+
**v6.77.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
6.
|
|
1
|
+
6.77.0
|
package/autonomy/run.sh
CHANGED
|
@@ -1453,7 +1453,7 @@ get_provider_tier_param() {
|
|
|
1453
1453
|
echo "${CLINE_DEFAULT_MODEL:-${LOKI_CLINE_MODEL:-default}}"
|
|
1454
1454
|
;;
|
|
1455
1455
|
aider)
|
|
1456
|
-
echo "${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-
|
|
1456
|
+
echo "${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-opus-4-7}}"
|
|
1457
1457
|
;;
|
|
1458
1458
|
*)
|
|
1459
1459
|
echo "development"
|
|
@@ -3143,7 +3143,7 @@ invoke_cline_capture() {
|
|
|
3143
3143
|
invoke_aider() {
|
|
3144
3144
|
local prompt="$1"
|
|
3145
3145
|
shift
|
|
3146
|
-
local model="${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-
|
|
3146
|
+
local model="${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-opus-4-7}}"
|
|
3147
3147
|
local extra_flags="${LOKI_AIDER_FLAGS:-}"
|
|
3148
3148
|
# shellcheck disable=SC2086
|
|
3149
3149
|
# < /dev/null prevents aider from blocking on stdin in non-interactive mode
|
|
@@ -3156,7 +3156,7 @@ invoke_aider() {
|
|
|
3156
3156
|
invoke_aider_capture() {
|
|
3157
3157
|
local prompt="$1"
|
|
3158
3158
|
shift
|
|
3159
|
-
local model="${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-
|
|
3159
|
+
local model="${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-opus-4-7}}"
|
|
3160
3160
|
local extra_flags="${LOKI_AIDER_FLAGS:-}"
|
|
3161
3161
|
# shellcheck disable=SC2086
|
|
3162
3162
|
aider --message "$prompt" --yes-always --no-auto-commits \
|
|
@@ -3749,7 +3749,7 @@ track_iteration_complete() {
|
|
|
3749
3749
|
elif [ "${PROVIDER_NAME:-claude}" = "cline" ]; then
|
|
3750
3750
|
model_tier="${CLINE_DEFAULT_MODEL:-${LOKI_CLINE_MODEL:-sonnet}}"
|
|
3751
3751
|
elif [ "${PROVIDER_NAME:-claude}" = "aider" ]; then
|
|
3752
|
-
model_tier="${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-
|
|
3752
|
+
model_tier="${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-opus-4-7}}"
|
|
3753
3753
|
fi
|
|
3754
3754
|
local phase="${LAST_KNOWN_PHASE:-}"
|
|
3755
3755
|
[ -z "$phase" ] && phase=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('currentPhase', 'unknown'))" 2>/dev/null || echo "unknown")
|
|
@@ -9991,8 +9991,8 @@ if __name__ == "__main__":
|
|
|
9991
9991
|
;;
|
|
9992
9992
|
aider)
|
|
9993
9993
|
# Aider: Tier 3 - degraded mode, 18+ providers
|
|
9994
|
-
echo "[loki] Aider model: ${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-
|
|
9995
|
-
echo "[loki] Aider model: ${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-
|
|
9994
|
+
echo "[loki] Aider model: ${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-opus-4-7}}, tier: $tier_param" >> "$log_file"
|
|
9995
|
+
echo "[loki] Aider model: ${AIDER_DEFAULT_MODEL:-${LOKI_AIDER_MODEL:-claude-opus-4-7}}, tier: $tier_param" >> "$agent_log"
|
|
9996
9996
|
{ invoke_aider "$prompt" 2>&1 | tee -a "$log_file" "$agent_log" "$iter_output"; \
|
|
9997
9997
|
} && exit_code=0 || exit_code=$?
|
|
9998
9998
|
;;
|
package/dashboard/__init__.py
CHANGED
|
@@ -11085,7 +11085,7 @@ var LokiDashboard=(()=>{var kt=Object.defineProperty;var Yt=Object.getOwnPropert
|
|
|
11085
11085
|
${s}
|
|
11086
11086
|
</div>
|
|
11087
11087
|
</div>
|
|
11088
|
-
`,this._bindEvents(),!this._paused){let r=t.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ht);var $e={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},gemini:{initial:"G",color:"#2F71E3",bgColor:"rgba(47, 113, 227, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},Vt={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},ut=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/providers/health");this._providers=t.providers||[]}catch{this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-
|
|
11088
|
+
`,this._bindEvents(),!this._paused){let r=t.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ht);var $e={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},gemini:{initial:"G",color:"#2F71E3",bgColor:"rgba(47, 113, 227, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},Vt={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},ut=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/providers/health");this._providers=t.providers||[]}catch{this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"gemini",status:"healthy",latency_ms:320,tokens_used:78600,model:"gemini-3-pro",api_version:"v1beta",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(t){return t==null?"--":t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatLatency(t){return t==null?"--":t<1e3?t+"ms":(t/1e3).toFixed(1)+"s"}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleExpand(t){this._expandedProvider=this._expandedProvider===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(e=>{e.addEventListener("click",()=>{this._toggleExpand(e.dataset.provider)})})}_getStyles(){return`
|
|
11089
11089
|
:host {
|
|
11090
11090
|
display: block;
|
|
11091
11091
|
}
|
package/docs/INSTALLATION.md
CHANGED
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
package/providers/aider.sh
CHANGED
|
@@ -50,7 +50,20 @@ PROVIDER_MAX_PARALLEL=1
|
|
|
50
50
|
# Aider supports 18+ providers; model configured via LOKI_AIDER_MODEL env var
|
|
51
51
|
# or provider-specific env vars (OPENAI_API_KEY, OPENAI_API_BASE, etc.)
|
|
52
52
|
# NOTE: Aider uses litellm for model routing, so full model strings are needed (not CLI aliases)
|
|
53
|
-
|
|
53
|
+
# Aider default model -- reads from providers/model_catalog.json via models.sh when
|
|
54
|
+
# available so new model releases only require updating that single catalog file.
|
|
55
|
+
_aider_default_from_catalog() {
|
|
56
|
+
local script_dir
|
|
57
|
+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
58
|
+
if [ -f "${script_dir}/models.sh" ]; then
|
|
59
|
+
# shellcheck source=./models.sh
|
|
60
|
+
source "${script_dir}/models.sh"
|
|
61
|
+
loki_latest_model aider development 2>/dev/null || echo "claude-opus-4-7"
|
|
62
|
+
else
|
|
63
|
+
echo "claude-opus-4-7"
|
|
64
|
+
fi
|
|
65
|
+
}
|
|
66
|
+
AIDER_DEFAULT_MODEL="${LOKI_AIDER_MODEL:-${LOKI_MODEL_DEVELOPMENT:-$(_aider_default_from_catalog)}}"
|
|
54
67
|
PROVIDER_MODEL_PLANNING="$AIDER_DEFAULT_MODEL"
|
|
55
68
|
PROVIDER_MODEL_DEVELOPMENT="$AIDER_DEFAULT_MODEL"
|
|
56
69
|
PROVIDER_MODEL_FAST="$AIDER_DEFAULT_MODEL"
|
package/providers/claude.sh
CHANGED
|
@@ -45,7 +45,13 @@ PROVIDER_MAX_PARALLEL=10
|
|
|
45
45
|
|
|
46
46
|
# Model Configuration (Abstract Tiers)
|
|
47
47
|
# Default: Haiku disabled for quality. Use --allow-haiku or LOKI_ALLOW_HAIKU=true to enable.
|
|
48
|
-
# Claude Code CLI resolves aliases (opus/sonnet/haiku) to latest
|
|
48
|
+
# The Claude Code CLI resolves aliases (opus/sonnet/haiku) to the latest available
|
|
49
|
+
# model at invocation time, so we pass aliases rather than dated IDs. The canonical
|
|
50
|
+
# mapping lives in providers/model_catalog.json (single source of truth):
|
|
51
|
+
# opus -> latest Opus (e.g. claude-opus-4-7 -- 1M context, adaptive thinking)
|
|
52
|
+
# sonnet -> latest Sonnet (e.g. claude-sonnet-4-6)
|
|
53
|
+
# haiku -> latest Haiku (e.g. claude-haiku-4-5)
|
|
54
|
+
# Override per tier with LOKI_CLAUDE_MODEL_PLANNING, _DEVELOPMENT, _FAST.
|
|
49
55
|
CLAUDE_DEFAULT_PLANNING="opus"
|
|
50
56
|
CLAUDE_DEFAULT_DEVELOPMENT="opus" # Opus for dev (was sonnet)
|
|
51
57
|
CLAUDE_DEFAULT_FAST="sonnet"
|
|
@@ -69,10 +75,18 @@ else
|
|
|
69
75
|
fi
|
|
70
76
|
|
|
71
77
|
# Context and Limits
|
|
72
|
-
|
|
78
|
+
# Opus 4.7 ships with 1M context at standard pricing (no long-context premium).
|
|
79
|
+
# RARV-C uses this headroom for deeper memory retrieval and longer task budgets.
|
|
80
|
+
PROVIDER_CONTEXT_WINDOW=1000000
|
|
73
81
|
PROVIDER_MAX_OUTPUT_TOKENS=128000
|
|
74
82
|
PROVIDER_RATE_LIMIT_RPM=50
|
|
75
83
|
|
|
84
|
+
# Effort / thinking defaults for Opus 4.7 (used when Loki invokes the API
|
|
85
|
+
# directly; the interactive CLI manages this automatically).
|
|
86
|
+
PROVIDER_DEFAULT_EFFORT="${LOKI_CLAUDE_EFFORT:-xhigh}" # xhigh recommended for coding
|
|
87
|
+
PROVIDER_DEFAULT_THINKING="${LOKI_CLAUDE_THINKING:-adaptive}"
|
|
88
|
+
PROVIDER_DEFAULT_TASK_BUDGET_TOKENS="${LOKI_CLAUDE_TASK_BUDGET:-0}" # 0 = unset (open-ended)
|
|
89
|
+
|
|
76
90
|
# Cost (USD per 1K tokens, approximate)
|
|
77
91
|
PROVIDER_COST_INPUT_PLANNING=0.015
|
|
78
92
|
PROVIDER_COST_OUTPUT_PLANNING=0.075
|
package/providers/cline.sh
CHANGED
|
@@ -51,7 +51,20 @@ PROVIDER_MAX_PARALLEL=1
|
|
|
51
51
|
# Cline supports 12+ providers; model configured via LOKI_CLINE_MODEL env var
|
|
52
52
|
# or `cline auth` one-time setup. Defaults are placeholders.
|
|
53
53
|
# NOTE: Cline uses its own model routing, so full model strings are needed (not CLI aliases)
|
|
54
|
-
|
|
54
|
+
# Cline default model -- reads from providers/model_catalog.json via models.sh when
|
|
55
|
+
# available so new model releases only require updating that single catalog file.
|
|
56
|
+
_cline_default_from_catalog() {
|
|
57
|
+
local script_dir
|
|
58
|
+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
59
|
+
if [ -f "${script_dir}/models.sh" ]; then
|
|
60
|
+
# shellcheck source=./models.sh
|
|
61
|
+
source "${script_dir}/models.sh"
|
|
62
|
+
loki_latest_model cline development 2>/dev/null || echo "claude-opus-4-7"
|
|
63
|
+
else
|
|
64
|
+
echo "claude-opus-4-7"
|
|
65
|
+
fi
|
|
66
|
+
}
|
|
67
|
+
CLINE_DEFAULT_MODEL="${LOKI_CLINE_MODEL:-${LOKI_MODEL_DEVELOPMENT:-$(_cline_default_from_catalog)}}"
|
|
55
68
|
PROVIDER_MODEL_PLANNING="$CLINE_DEFAULT_MODEL"
|
|
56
69
|
PROVIDER_MODEL_DEVELOPMENT="$CLINE_DEFAULT_MODEL"
|
|
57
70
|
PROVIDER_MODEL_FAST="$CLINE_DEFAULT_MODEL"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Canonical model catalog. Update this single file when a provider ships a new model. Providers/web-app/docs read from here.",
|
|
3
|
+
"schema_version": 1,
|
|
4
|
+
"updated": "2026-04-18",
|
|
5
|
+
"providers": {
|
|
6
|
+
"claude": {
|
|
7
|
+
"latest_planning": "claude-opus-4-7",
|
|
8
|
+
"latest_development": "claude-opus-4-7",
|
|
9
|
+
"latest_fast": "claude-sonnet-4-6",
|
|
10
|
+
"cli_aliases": {
|
|
11
|
+
"opus": "claude-opus-4-7",
|
|
12
|
+
"sonnet": "claude-sonnet-4-6",
|
|
13
|
+
"haiku": "claude-haiku-4-5"
|
|
14
|
+
},
|
|
15
|
+
"models": [
|
|
16
|
+
{
|
|
17
|
+
"id": "claude-opus-4-7",
|
|
18
|
+
"alias": "opus",
|
|
19
|
+
"tier": "planning",
|
|
20
|
+
"context_window": 1000000,
|
|
21
|
+
"max_output": 128000,
|
|
22
|
+
"notes": "Adaptive thinking, xhigh effort for agentic coding"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "claude-sonnet-4-6",
|
|
26
|
+
"alias": "sonnet",
|
|
27
|
+
"tier": "development",
|
|
28
|
+
"context_window": 1000000,
|
|
29
|
+
"max_output": 64000
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "claude-haiku-4-5",
|
|
33
|
+
"alias": "haiku",
|
|
34
|
+
"tier": "fast",
|
|
35
|
+
"context_window": 200000,
|
|
36
|
+
"max_output": 64000
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"codex": {
|
|
41
|
+
"latest_planning": "gpt-5.3-codex",
|
|
42
|
+
"latest_development": "gpt-5.3-codex",
|
|
43
|
+
"latest_fast": "gpt-5.3-codex",
|
|
44
|
+
"models": [
|
|
45
|
+
{ "id": "gpt-5.3-codex", "tier": "planning" },
|
|
46
|
+
{ "id": "o3", "tier": "planning" },
|
|
47
|
+
{ "id": "o4-mini", "tier": "fast" }
|
|
48
|
+
],
|
|
49
|
+
"notes": "Codex uses a single model with effort level (xhigh/high/low) for tier differentiation"
|
|
50
|
+
},
|
|
51
|
+
"gemini": {
|
|
52
|
+
"latest_planning": "gemini-3-pro-preview",
|
|
53
|
+
"latest_development": "gemini-3-pro-preview",
|
|
54
|
+
"latest_fast": "gemini-3-flash-preview",
|
|
55
|
+
"models": [
|
|
56
|
+
{ "id": "gemini-3-pro-preview", "tier": "planning", "context_window": 1000000 },
|
|
57
|
+
{ "id": "gemini-3-flash-preview", "tier": "fast", "context_window": 1000000 }
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"cline": {
|
|
61
|
+
"latest_planning": "claude-opus-4-7",
|
|
62
|
+
"latest_development": "claude-opus-4-7",
|
|
63
|
+
"latest_fast": "claude-sonnet-4-6",
|
|
64
|
+
"models": [
|
|
65
|
+
{ "id": "claude-opus-4-7", "tier": "planning" },
|
|
66
|
+
{ "id": "claude-sonnet-4-6", "tier": "development" },
|
|
67
|
+
{ "id": "gpt-4.1", "tier": "development" }
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"aider": {
|
|
71
|
+
"latest_planning": "claude-opus-4-7",
|
|
72
|
+
"latest_development": "claude-opus-4-7",
|
|
73
|
+
"latest_fast": "claude-sonnet-4-6",
|
|
74
|
+
"models": [
|
|
75
|
+
{ "id": "claude-opus-4-7", "tier": "planning" },
|
|
76
|
+
{ "id": "claude-sonnet-4-6", "tier": "development" },
|
|
77
|
+
{ "id": "gpt-4.1", "tier": "development" },
|
|
78
|
+
{ "id": "ollama_chat/deepseek-coder", "tier": "fast" }
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Dynamic model-catalog loader for Loki Mode providers.
|
|
3
|
+
#
|
|
4
|
+
# Instead of hardcoding dated model IDs (e.g. claude-sonnet-4-5-20250929)
|
|
5
|
+
# throughout the codebase, every provider and caller reads from the single
|
|
6
|
+
# source of truth at providers/model_catalog.json. When a new model ships,
|
|
7
|
+
# update that one JSON file and every provider picks it up.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# source providers/models.sh
|
|
11
|
+
# model=$(loki_latest_model claude planning) # -> claude-opus-4-7
|
|
12
|
+
# model=$(loki_latest_model gemini fast) # -> gemini-3-flash-preview
|
|
13
|
+
#
|
|
14
|
+
# Env override order: LOKI_<PROVIDER>_MODEL_<TIER> > LOKI_<PROVIDER>_MODEL > catalog latest.
|
|
15
|
+
|
|
16
|
+
# Resolve catalog path relative to this script, regardless of CWD.
|
|
17
|
+
_LOKI_MODELS_SH_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
18
|
+
LOKI_MODEL_CATALOG="${LOKI_MODEL_CATALOG:-$_LOKI_MODELS_SH_DIR/model_catalog.json}"
|
|
19
|
+
|
|
20
|
+
# Return the "latest_<tier>" id for a provider from the catalog.
|
|
21
|
+
# Args: $1 provider (claude|codex|gemini|cline|aider)
|
|
22
|
+
# $2 tier (planning|development|fast)
|
|
23
|
+
loki_latest_model() {
|
|
24
|
+
local provider="${1:-claude}"
|
|
25
|
+
local tier="${2:-planning}"
|
|
26
|
+
local tier_upper
|
|
27
|
+
tier_upper=$(printf '%s' "$tier" | tr '[:lower:]' '[:upper:]')
|
|
28
|
+
local provider_upper
|
|
29
|
+
provider_upper=$(printf '%s' "$provider" | tr '[:lower:]' '[:upper:]')
|
|
30
|
+
|
|
31
|
+
# Env override chain
|
|
32
|
+
local override="LOKI_${provider_upper}_MODEL_${tier_upper}"
|
|
33
|
+
if [ -n "${!override:-}" ]; then
|
|
34
|
+
printf '%s' "${!override}"
|
|
35
|
+
return 0
|
|
36
|
+
fi
|
|
37
|
+
local generic_override="LOKI_${provider_upper}_MODEL"
|
|
38
|
+
if [ -n "${!generic_override:-}" ]; then
|
|
39
|
+
printf '%s' "${!generic_override}"
|
|
40
|
+
return 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if [ ! -f "$LOKI_MODEL_CATALOG" ]; then
|
|
44
|
+
return 1
|
|
45
|
+
fi
|
|
46
|
+
# Require python3 (all Loki runtimes ship with it).
|
|
47
|
+
python3 - "$LOKI_MODEL_CATALOG" "$provider" "$tier" <<'PY'
|
|
48
|
+
import json, sys
|
|
49
|
+
catalog_path, provider, tier = sys.argv[1], sys.argv[2], sys.argv[3]
|
|
50
|
+
with open(catalog_path) as fh:
|
|
51
|
+
data = json.load(fh)
|
|
52
|
+
p = data.get("providers", {}).get(provider)
|
|
53
|
+
if not p:
|
|
54
|
+
sys.exit(1)
|
|
55
|
+
model = p.get(f"latest_{tier}")
|
|
56
|
+
if not model:
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
print(model)
|
|
59
|
+
PY
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Print full catalog for a provider as lines: <id>\t<tier>\t<alias?>
|
|
63
|
+
# Useful for `loki provider models <name>` output.
|
|
64
|
+
loki_list_models() {
|
|
65
|
+
local provider="${1:-claude}"
|
|
66
|
+
if [ ! -f "$LOKI_MODEL_CATALOG" ]; then
|
|
67
|
+
return 1
|
|
68
|
+
fi
|
|
69
|
+
python3 - "$LOKI_MODEL_CATALOG" "$provider" <<'PY'
|
|
70
|
+
import json, sys
|
|
71
|
+
catalog_path, provider = sys.argv[1], sys.argv[2]
|
|
72
|
+
with open(catalog_path) as fh:
|
|
73
|
+
data = json.load(fh)
|
|
74
|
+
p = data.get("providers", {}).get(provider, {})
|
|
75
|
+
for m in p.get("models", []):
|
|
76
|
+
alias = m.get("alias", "")
|
|
77
|
+
print(f"{m.get('id','')}\t{m.get('tier','')}\t{alias}")
|
|
78
|
+
PY
|
|
79
|
+
}
|
|
@@ -57,15 +57,15 @@ PROVIDER_MAX_PARALLEL=10 # Maximum concurrent agents
|
|
|
57
57
|
|
|
58
58
|
#### Model Configuration
|
|
59
59
|
```bash
|
|
60
|
-
PROVIDER_MODEL_PLANNING="claude-opus-4-
|
|
61
|
-
PROVIDER_MODEL_DEVELOPMENT="claude-sonnet-4-
|
|
60
|
+
PROVIDER_MODEL_PLANNING="claude-opus-4-7"
|
|
61
|
+
PROVIDER_MODEL_DEVELOPMENT="claude-sonnet-4-6"
|
|
62
62
|
PROVIDER_MODEL_FAST="claude-haiku-4-5-20251001"
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
#### Rate Limiting
|
|
66
66
|
```bash
|
|
67
|
-
PROVIDER_RATE_LIMIT_RPM=50
|
|
68
|
-
PROVIDER_CONTEXT_WINDOW=
|
|
67
|
+
PROVIDER_RATE_LIMIT_RPM=50 # Requests per minute
|
|
68
|
+
PROVIDER_CONTEXT_WINDOW=1000000 # Max context tokens (Opus 4.7: 1M at standard pricing)
|
|
69
69
|
PROVIDER_MAX_OUTPUT_TOKENS=128000
|
|
70
70
|
```
|
|
71
71
|
|
package/skills/production.md
CHANGED
|
@@ -226,7 +226,7 @@ def batch_code_review(files: list[str]) -> str:
|
|
|
226
226
|
Request(
|
|
227
227
|
custom_id=f"review-{i}-{file.replace('/', '-')}",
|
|
228
228
|
params=MessageCreateParamsNonStreaming(
|
|
229
|
-
model="claude-sonnet-4-
|
|
229
|
+
model="claude-sonnet-4-6",
|
|
230
230
|
max_tokens=2048,
|
|
231
231
|
messages=[{
|
|
232
232
|
"role": "user",
|
|
@@ -275,7 +275,7 @@ requests = [
|
|
|
275
275
|
Request(
|
|
276
276
|
custom_id=f"review-{file}",
|
|
277
277
|
params=MessageCreateParamsNonStreaming(
|
|
278
|
-
model="claude-sonnet-4-
|
|
278
|
+
model="claude-sonnet-4-6",
|
|
279
279
|
max_tokens=2048,
|
|
280
280
|
system=SHARED_SYSTEM, # Identical across all requests
|
|
281
281
|
messages=[{"role": "user", "content": f"Review: {code}"}]
|