opencode.zsh

  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}