@zachjxyz/moxie 0.3.4 → 0.3.7
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/bin/moxie +1 -1
- package/lib/agents.sh +3 -1
- package/lib/gateway-agent.mjs +2 -1
- package/lib/gateway-cost.mjs +22 -6
- package/lib/phases.sh +4 -1
- package/lib/tokens.sh +4 -27
- package/package.json +1 -1
package/bin/moxie
CHANGED
package/lib/agents.sh
CHANGED
|
@@ -271,9 +271,10 @@ dispatch_agent() {
|
|
|
271
271
|
|
|
272
272
|
# Gateway agent: dispatch via Node.js script
|
|
273
273
|
if _is_gateway_agent "$agent"; then
|
|
274
|
-
local model endpoint api_key
|
|
274
|
+
local model endpoint api_key run_id
|
|
275
275
|
model=$(_agent_model "$agent")
|
|
276
276
|
endpoint=$(toml_get "$MOXIE_CONFIG" "gateway.endpoint" "https://ai-gateway.vercel.sh")
|
|
277
|
+
run_id=$(toml_get "$MOXIE_CONFIG" "gateway.run_id" "")
|
|
277
278
|
api_key=$(gateway_get_key "vercel-ai-gateway") || {
|
|
278
279
|
echo "ERROR: Gateway API key not found. Run 'moxie init' to configure." >&2
|
|
279
280
|
return 1
|
|
@@ -285,6 +286,7 @@ dispatch_agent() {
|
|
|
285
286
|
GATEWAY_MODEL="$model" \
|
|
286
287
|
GATEWAY_PHASE="$phase" \
|
|
287
288
|
GATEWAY_AGENT="$agent" \
|
|
289
|
+
GATEWAY_RUN_ID="$run_id" \
|
|
288
290
|
timeout "$timeout_secs" \
|
|
289
291
|
node "$MOXIE_ROOT/lib/gateway-agent.mjs" "$(cat "$prompt_file")" || {
|
|
290
292
|
local rc=$?
|
package/lib/gateway-agent.mjs
CHANGED
|
@@ -18,6 +18,7 @@ const MAX_TURNS = parseInt(process.env.GATEWAY_MAX_TURNS || '50', 10);
|
|
|
18
18
|
const IDLE_TIMEOUT_MS = parseInt(process.env.GATEWAY_IDLE_TIMEOUT || '120000', 10);
|
|
19
19
|
const PHASE = process.env.GATEWAY_PHASE || 'unknown';
|
|
20
20
|
const AGENT_NAME = process.env.GATEWAY_AGENT || 'unknown';
|
|
21
|
+
const RUN_ID = process.env.GATEWAY_RUN_ID || '';
|
|
21
22
|
const CWD = process.cwd();
|
|
22
23
|
|
|
23
24
|
if (!API_KEY) { process.stderr.write('ERROR: GATEWAY_API_KEY not set\n'); process.exit(1); }
|
|
@@ -310,7 +311,7 @@ function chatCompletion(messages) {
|
|
|
310
311
|
stream_options: { include_usage: true },
|
|
311
312
|
providerOptions: {
|
|
312
313
|
gateway: {
|
|
313
|
-
tags: [`project:moxie`, `phase:${PHASE}`, `agent:${AGENT_NAME}`],
|
|
314
|
+
tags: [`project:moxie`, `phase:${PHASE}`, `agent:${AGENT_NAME}`, ...(RUN_ID ? [`run:${RUN_ID}`] : [])],
|
|
314
315
|
user: 'moxie',
|
|
315
316
|
},
|
|
316
317
|
},
|
package/lib/gateway-cost.mjs
CHANGED
|
@@ -7,18 +7,34 @@ import https from 'https';
|
|
|
7
7
|
import http from 'http';
|
|
8
8
|
|
|
9
9
|
const API_KEY = process.env.GATEWAY_API_KEY;
|
|
10
|
+
const RUN_ID = process.env.GATEWAY_RUN_ID || '';
|
|
10
11
|
const endpoint = process.argv[2] || 'https://ai-gateway.vercel.sh';
|
|
11
|
-
const startDate = process.argv[3];
|
|
12
|
-
const endDate = process.argv[4];
|
|
12
|
+
const startDate = process.argv[3] || '';
|
|
13
|
+
const endDate = process.argv[4] || '';
|
|
13
14
|
|
|
14
15
|
if (!API_KEY) { process.stderr.write('ERROR: GATEWAY_API_KEY not set\n'); process.exit(1); }
|
|
15
|
-
if (!startDate || !endDate) { process.stderr.write('ERROR: start_date and end_date required\n'); process.exit(1); }
|
|
16
16
|
|
|
17
17
|
const url = new URL(`${endpoint}/v1/report`);
|
|
18
|
-
url.searchParams.set('start_date', startDate);
|
|
19
|
-
url.searchParams.set('end_date', endDate);
|
|
20
18
|
url.searchParams.set('group_by', 'tag');
|
|
21
|
-
|
|
19
|
+
|
|
20
|
+
if (RUN_ID) {
|
|
21
|
+
// Filter by run ID — captures the full session regardless of dates
|
|
22
|
+
url.searchParams.set('tags', `run:${RUN_ID}`);
|
|
23
|
+
// Still need dates — use a wide window
|
|
24
|
+
const now = new Date();
|
|
25
|
+
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
26
|
+
const tomorrow = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
|
27
|
+
url.searchParams.set('start_date', thirtyDaysAgo.toISOString().slice(0, 10));
|
|
28
|
+
url.searchParams.set('end_date', tomorrow.toISOString().slice(0, 10));
|
|
29
|
+
} else if (startDate && endDate) {
|
|
30
|
+
// Fallback: filter by date range + project tag
|
|
31
|
+
url.searchParams.set('start_date', startDate);
|
|
32
|
+
url.searchParams.set('end_date', endDate);
|
|
33
|
+
url.searchParams.set('tags', 'project:moxie');
|
|
34
|
+
} else {
|
|
35
|
+
process.stderr.write('ERROR: Either GATEWAY_RUN_ID or start_date/end_date required\n');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
22
38
|
|
|
23
39
|
const isHttps = url.protocol === 'https:';
|
|
24
40
|
const mod = isHttps ? https : http;
|
package/lib/phases.sh
CHANGED
|
@@ -425,9 +425,12 @@ HEADER
|
|
|
425
425
|
|
|
426
426
|
# Gateway section (if any gateway models selected)
|
|
427
427
|
if [ ${#SELECTED_GATEWAY_INDICES[@]} -gt 0 ]; then
|
|
428
|
-
|
|
428
|
+
local run_id
|
|
429
|
+
run_id="run-$(date +%Y%m%d-%H%M%S)-$$"
|
|
430
|
+
cat >> "$config_file" <<GATEWAY
|
|
429
431
|
[gateway]
|
|
430
432
|
endpoint = "https://ai-gateway.vercel.sh"
|
|
433
|
+
run_id = "$run_id"
|
|
431
434
|
|
|
432
435
|
GATEWAY
|
|
433
436
|
fi
|
package/lib/tokens.sh
CHANGED
|
@@ -200,36 +200,13 @@ _show_gateway_cost() {
|
|
|
200
200
|
local api_key
|
|
201
201
|
api_key=$(gateway_get_key "vercel-ai-gateway" 2>/dev/null) || return
|
|
202
202
|
|
|
203
|
-
#
|
|
204
|
-
local
|
|
205
|
-
|
|
206
|
-
import csv, glob, datetime
|
|
207
|
-
earliest = None
|
|
208
|
-
for f in glob.glob('$MOXIE_DIR/phases/*/token-usage.csv'):
|
|
209
|
-
with open(f) as fh:
|
|
210
|
-
for row in csv.DictReader(fh):
|
|
211
|
-
ts = row.get('timestamp', '')
|
|
212
|
-
if len(ts) >= 13:
|
|
213
|
-
try:
|
|
214
|
-
dt = datetime.datetime.strptime(ts[:13], '%m%d%y-%H%M%S')
|
|
215
|
-
if earliest is None or dt < earliest:
|
|
216
|
-
earliest = dt
|
|
217
|
-
except ValueError:
|
|
218
|
-
pass
|
|
219
|
-
if earliest:
|
|
220
|
-
print(earliest.strftime('%Y-%m-%d'))
|
|
221
|
-
else:
|
|
222
|
-
print(datetime.date.today().strftime('%Y-%m-%d'))
|
|
223
|
-
" 2>/dev/null)
|
|
224
|
-
|
|
225
|
-
local end_date
|
|
226
|
-
end_date=$(date +"%Y-%m-%d")
|
|
227
|
-
|
|
228
|
-
[ -z "$start_date" ] && return
|
|
203
|
+
# Get run_id for filtering (if available, use it; otherwise fall back to dates)
|
|
204
|
+
local run_id
|
|
205
|
+
run_id=$(toml_get "$MOXIE_CONFIG" "gateway.run_id" "")
|
|
229
206
|
|
|
230
207
|
# Call the reporting API
|
|
231
208
|
local cost_json
|
|
232
|
-
cost_json=$(GATEWAY_API_KEY="$api_key" node "$MOXIE_ROOT/lib/gateway-cost.mjs" "$gw_endpoint"
|
|
209
|
+
cost_json=$(GATEWAY_API_KEY="$api_key" GATEWAY_RUN_ID="$run_id" node "$MOXIE_ROOT/lib/gateway-cost.mjs" "$gw_endpoint" 2>/dev/null) || {
|
|
233
210
|
echo ""
|
|
234
211
|
echo "Gateway cost:"
|
|
235
212
|
echo " (unavailable — check your API key or AI Gateway dashboard)"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zachjxyz/moxie",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Run multiple AI coding agents through spec-driven phases with quorum convergence. Supports CLI agents (Claude, Codex, Qwen, Aider, Goose, Amp, Cline, Roo) and Vercel AI Gateway models.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"moxie": "bin/moxie"
|