1# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2#
3# SPDX-License-Identifier: Unlicense
4
5# OpenCode agent definition for synu
6# Provides model configuration for routing through Synthetic API
7# OpenCode only accepts model via -m flag, not environment variables
8
9# Fallback default (used when no cache entry exists)
10typeset -g _SYNU_OPENCODE_FALLBACK_MODEL="hf:zai-org/GLM-4.6"
11
12_synu_opencode_default() {
13 local cached
14 cached=$(_synu_cache_get opencode model)
15 if [[ $? -eq 0 ]]; then
16 echo "${cached}"
17 else
18 echo "${_SYNU_OPENCODE_FALLBACK_MODEL}"
19 fi
20}
21
22_synu_agent_opencode_flags() {
23 echo "m/model="
24}
25
26_synu_agent_opencode_configure() {
27 local -A opts
28
29 # Parse flags passed from main synu
30 while [[ $# -gt 0 ]]; do
31 case "$1" in
32 --model=*) opts[model]="${1#*=}" ;;
33 esac
34 shift
35 done
36
37 # Start with default (from cache or fallback)
38 typeset -g _SYNU_OPENCODE_SELECTED_MODEL=$(_synu_opencode_default)
39
40 # Apply override if provided
41 [[ -n "${opts[model]}" ]] && typeset -g _SYNU_OPENCODE_SELECTED_MODEL="${opts[model]}"
42 return 0
43}
44
45_synu_agent_opencode_args() {
46 # Return -m flag with selected model, prefixed with synthetic/ for provider routing
47 echo -m
48 echo "synthetic/${_SYNU_OPENCODE_SELECTED_MODEL}"
49}
50
51_synu_agent_opencode_interactive() {
52 # Check for gum
53 if ! (( $+commands[gum] )); then
54 print -u2 "Error: gum is required for interactive mode. Install: https://github.com/charmbracelet/gum"
55 return 1
56 fi
57
58 # Fetch available models
59 local models_json
60 models_json=$(gum spin --spinner dot --title "Fetching models..." -- \
61 curl -s -H "Authorization: Bearer ${SYNTHETIC_API_KEY}" \
62 "https://api.synthetic.new/openai/v1/models")
63 [[ $? -ne 0 ]] && return 1
64
65 local -a model_names
66 model_names=("${(@f)$(echo "${models_json}" | jq -r '.data[].name')}")
67 [[ $? -ne 0 ]] && return 1
68
69 # Get current model for display
70 local current_id=$(_synu_opencode_default)
71 local current_name=$(echo "${models_json}" | \
72 jq -r --arg id "${current_id}" '.data[] | select(.id == $id) | .name // "unknown"')
73
74 # Select model
75 local model_name
76 model_name=$(printf "%s\n" "${model_names[@]}" | \
77 gum filter --limit 1 --header "Select model for OpenCode (current: ${current_name})" \
78 --placeholder "Filter models...")
79 [[ $? -ne 0 ]] && return 1
80
81 local model_id
82 model_id=$(echo "${models_json}" | \
83 jq -r --arg name "${model_name}" '.data[] | select(.name == $name) | .id')
84
85 if [[ -z "${model_id}" ]]; then
86 print -u2 "Error: Could not find model ID"
87 return 1
88 fi
89
90 # Build flags
91 local flags="--model=${model_id}"
92
93 # Offer to save as default
94 if gum confirm "Save as default for 'opencode'?"; then
95 _synu_cache_set opencode model "${model_id}"
96 fi
97
98 # Output flags for caller to use
99 printf '%s\n' "${flags}"
100}