1# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2#
3# SPDX-License-Identifier: Unlicense
4
5function synu --description "Universal agent wrapper with Synthetic API quota tracking"
6 # If no arguments, just print the quota
7 if test (count $argv) -lt 1
8 set -l quota (_synu_get_quota)
9 if test $status -ne 0
10 echo "Error: Could not fetch quota" >&2
11 return 1
12 end
13 set -l requests (echo "$quota" | cut -d' ' -f1)
14 set -l limit (echo "$quota" | cut -d' ' -f2)
15 set -l remaining (math "$limit - $requests")
16 set -l percent_used (math -s0 "$requests * 100 / $limit")
17 printf "Usage: "
18 if test $percent_used -lt 33
19 set_color -b green black
20 else if test $percent_used -lt 67
21 set_color -b yellow black
22 else
23 set_color -b red black
24 end
25 printf " %s%% " $percent_used
26 set_color normal
27 printf " (%s/%s remaining)\n" $remaining $limit
28 return 0
29 end
30
31 # Check for interactive mode: synu i <agent> [args...]
32 if test "$argv[1]" = "i"
33 if test (count $argv) -lt 2
34 echo "Error: Interactive mode requires an agent name" >&2
35 echo "Usage: synu i <agent> [args...]" >&2
36 return 1
37 end
38
39 set -l agent $argv[2]
40 set -l agent_args $argv[3..-1]
41
42 # Source agent definition if it exists
43 set -l agent_file (status dirname)/_synu_agents/$agent.fish
44 if test -f "$agent_file"
45 source $agent_file
46 end
47
48 # Check for interactive function
49 if not functions -q _synu_agent_{$agent}_interactive
50 echo "Error: Agent '$agent' does not support interactive mode" >&2
51 return 1
52 end
53
54 # Get flags from interactive selection
55 set -l interactive_flags (_synu_agent_{$agent}_interactive)
56 set -l interactive_status $status
57 if test $interactive_status -ne 0
58 return $interactive_status
59 end
60
61 # Recursively call synu with selected flags
62 synu $agent $interactive_flags $agent_args
63 return $status
64 end
65
66 # Extract agent name (first argument) and remaining args
67 set -l agent $argv[1]
68 set -l agent_args $argv[2..-1]
69
70 # Source agent definition if it exists
71 set -l agent_file (status dirname)/_synu_agents/$agent.fish
72 if test -f "$agent_file"
73 source $agent_file
74 end
75
76 # Check if agent has a configuration function
77 if functions -q _synu_agent_{$agent}_configure
78 # Get flag specification
79 set -l flag_spec (_synu_agent_{$agent}_flags)
80
81 # Parse flags using agent's spec, ignoring unknown flags for passthrough
82 # We need to capture which flags were set to pass to configure
83 set -l parsed_args
84 if test -n "$flag_spec"
85 # Parse with --ignore-unknown so agent-native flags pass through
86 # @fish-lsp-disable-next-line 4004
87 argparse --ignore-unknown $flag_spec -- $agent_args
88 or return 1
89
90 # argv now contains non-flag args after argparse
91 set agent_args $argv
92
93 # Rebuild the flag arguments to pass to configure
94 # Check each possible flag and add if set
95 for flag in L/large l/light o/opus s/sonnet H/haiku a/agent m/model
96 set -l long_flag (string split '/' $flag)[2]
97 set -l var_name _flag_$long_flag
98 if set -q $var_name
99 set parsed_args $parsed_args --$long_flag=$$var_name
100 end
101 end
102 end
103
104 # Configure the agent environment
105 _synu_agent_{$agent}_configure $parsed_args
106 or return 1
107 end
108
109 # Check if agent provides extra CLI arguments (for agents that don't use env vars)
110 set -l extra_args
111 if functions -q _synu_agent_{$agent}_args
112 set extra_args (_synu_agent_{$agent}_args)
113 end
114
115 # Fetch quota before agent execution
116 set -l quota_before (_synu_get_quota)
117 if test $status -ne 0
118 # If quota fetch fails, still execute the agent but warn
119 echo "Warning: Could not fetch quota before execution" >&2
120 # Set default values if quota fetch fails
121 set -l quota_before "0 0"
122 end
123
124 # Parse pre-execution quota values
125 set -l requests_before (echo "$quota_before" | cut -d' ' -f1)
126 set -l limit (echo "$quota_before" | cut -d' ' -f2)
127
128 # Execute the agent with all arguments passed through unchanged
129 # Use 'command' to bypass function recursion and call the actual binary
130 # extra_args contains agent-specific CLI flags (e.g., -m for opencode)
131 command $agent $extra_args $agent_args
132 set -l exit_status $status
133
134 # Clean up environment variables set by agent
135 if functions -q _synu_agent_{$agent}_env_vars
136 for var in (_synu_agent_{$agent}_env_vars)
137 set -e $var
138 end
139 end
140
141 # Fetch quota after agent execution
142 set -l quota_after (_synu_get_quota)
143 if test $status -ne 0
144 # If quota fetch fails, still exit but warn
145 echo "Warning: Could not fetch quota after execution" >&2
146 return $exit_status
147 end
148
149 # Parse post-execution quota values
150 set -l requests_after (echo "$quota_after" | cut -d' ' -f1)
151 # Note: limit is the same before and after, using pre-execution value
152
153 # Calculate session usage: final_requests - initial_requests
154 set -l session_usage (math "$requests_after - $requests_before")
155
156 # Calculate remaining quota: limit - requests_after
157 set -l remaining (math "$limit - $requests_after")
158
159 # Calculate percentage used: (requests_after * 100) / limit
160 set -l percent_used (math -s0 "$requests_after * 100 / $limit")
161
162 # Display session usage and remaining quota with color
163 # Force a newline first for proper separation from agent output
164 printf "\n"
165 printf "Session: %s requests\n" $session_usage
166 printf "Overall: "
167
168 # Determine color based on usage percentage
169 # Green: <33%, Yellow: 33-66%, Red: >66%
170 if test $percent_used -lt 33
171 set_color -b green black
172 else if test $percent_used -lt 67
173 set_color -b yellow black
174 else
175 set_color -b red black
176 end
177 printf " %s%% " $percent_used
178 set_color normal
179 printf " (%s/%s remaining)\n" $remaining $limit
180
181 return $exit_status
182end