diff --git a/functions/_synu_agents/opencode.fish b/functions/_synu_agents/opencode.fish new file mode 100644 index 0000000000000000000000000000000000000000..7eed3d89d2705f2fb391899fa9661d748b588dd7 --- /dev/null +++ b/functions/_synu_agents/opencode.fish @@ -0,0 +1,88 @@ +# SPDX-FileCopyrightText: Amolith +# +# SPDX-License-Identifier: Unlicense + +# OpenCode agent definition for synu +# Provides model configuration for routing through Synthetic API +# OpenCode only accepts model via -m flag, not environment variables + +# Source cache functions +source (status dirname)/../_synu_cache.fish + +# Fallback default (used when no cache entry exists) +set -g _synu_opencode_fallback_model "hf:MiniMaxAI/MiniMax-M2" + +function _synu_opencode_default --description "Get default model" + set -l cached (_synu_cache_get opencode model) + if test $status -eq 0 + echo $cached + else + echo $_synu_opencode_fallback_model + end +end + +function _synu_agent_opencode_flags --description "Return argparse-compatible flag specification" + echo "m/model=" +end + +function _synu_agent_opencode_configure --description "Configure OpenCode model selection" + # Parse flags passed from main synu + argparse 'm/model=' -- $argv + or return 1 + + # Start with default (from cache or fallback) + set -g _synu_opencode_selected_model (_synu_opencode_default) + + # Apply override if provided + if set -q _flag_model + set -g _synu_opencode_selected_model $_flag_model + end +end + +function _synu_agent_opencode_args --description "Return CLI arguments to pass to opencode" + # Return -m flag with selected model + echo -m + echo $_synu_opencode_selected_model +end + +function _synu_agent_opencode_interactive --description "Interactive model selection using gum" + # Check for gum + if not command -q gum + echo "Error: gum is required for interactive mode. Install: https://github.com/charmbracelet/gum" >&2 + return 1 + end + + # Fetch available models + set -l models_json (gum spin --spinner dot --title "Fetching models..." -- \ + curl -s -H "Authorization: Bearer $SYNTHETIC_API_KEY" \ + "https://api.synthetic.new/openai/v1/models") + or return 1 + + set -l model_names (echo $models_json | jq -r '.data[].name') + or return 1 + + # Select model + set -l model_name (printf "%s\n" $model_names | \ + gum filter --limit 1 --header "Select model for OpenCode" \ + --placeholder "Filter models...") + or return 1 + + set -l model_id (echo $models_json | \ + jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id') + + if test -z "$model_id" + echo "Error: Could not find model ID" >&2 + return 1 + end + + # Build flags + set -l flags --model=$model_id + + # Offer to save as default + if gum confirm "Save as default for 'opencode'?" + _synu_cache_set opencode model $model_id + end + + # Output flags for caller to use + echo $flags +end diff --git a/functions/synu.fish b/functions/synu.fish index 4432d8acc1c512bfc62309209aa47023a2b138ce..dd54c7b1aa0ab28cbbe2351e8a1a79edb79eec57 100644 --- a/functions/synu.fish +++ b/functions/synu.fish @@ -83,6 +83,7 @@ function synu --description "Universal agent wrapper with Synthetic API quota tr set -l parsed_args if test -n "$flag_spec" # Parse with --ignore-unknown so agent-native flags pass through + # @fish-lsp-disable-next-line 4004 argparse --ignore-unknown $flag_spec -- $agent_args or return 1 @@ -91,8 +92,7 @@ function synu --description "Universal agent wrapper with Synthetic API quota tr # Rebuild the flag arguments to pass to configure # Check each possible flag and add if set - for flag in L/large l/light o/opus s/sonnet H/haiku a/agent - set -l short_flag (string split '/' $flag)[1] + for flag in L/large l/light o/opus s/sonnet H/haiku a/agent m/model set -l long_flag (string split '/' $flag)[2] set -l var_name _flag_$long_flag if set -q $var_name @@ -106,6 +106,12 @@ function synu --description "Universal agent wrapper with Synthetic API quota tr or return 1 end + # Check if agent provides extra CLI arguments (for agents that don't use env vars) + set -l extra_args + if functions -q _synu_agent_{$agent}_args + set extra_args (_synu_agent_{$agent}_args) + end + # Fetch quota before agent execution set -l quota_before (_synu_get_quota) if test $status -ne 0 @@ -121,7 +127,8 @@ function synu --description "Universal agent wrapper with Synthetic API quota tr # Execute the agent with all arguments passed through unchanged # Use 'command' to bypass function recursion and call the actual binary - command $agent $agent_args + # extra_args contains agent-specific CLI flags (e.g., -m for opencode) + command $agent $extra_args $agent_args set -l exit_status $status # Fetch quota after agent execution