-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
57 lines (47 loc) · 2.7 KB
/
Copy pathMakefile
File metadata and controls
57 lines (47 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# make run PROMPT="..." [MODEL=] [REASONING=] [ARGS=]
# make run PROMPT=@prompt.txt the prompt is read from that file
# make run < request.json no PROMPT: a whole request off stdin
# make serve [ADDR=] the built-in table over HTTP
# make serve-dev [ADDR=] the same, rebuilt and restarted on a change
# Keys come from .env.local. ARGS goes straight to dragoman (--stream, --raw,
# --no-execute, -v ...). JQ=. prints the whole response.
MODEL ?= gemini-3.6-flash
BACKEND ?= $(strip $(shell case '$(MODEL)' in \
(gemini-*) echo gemini ;; (claude-*) echo anthropic ;; \
(deepseek-*) echo deepseek ;; (gpt-*|o[0-9]*) echo openai ;; \
(*/*) echo openrouter ;; esac))
JQ ?= {status, model, text: ([.output[] | select(.type=="message") | .content[].text] | join("")), calls: [.output[] | select(.type=="function_call") | {name, arguments: (.arguments | fromjson)}], usage}
ADDR ?= 127.0.0.1:8080
BIN := bin/dragoman
# The service table is embedded, so a table edit is a source change like any
# other and has to rebuild the binary.
SOURCES := $(shell find cmd internal \( -name '*.go' -o -name '*.yaml' \) 2>/dev/null)
export PROMPT MODEL REASONING
.PHONY: run serve serve-dev
$(BIN): $(SOURCES)
@go build -o $(BIN) ./cmd/dragoman
# No PROMPT means the request itself is on stdin. Otherwise jq builds the body,
# so quoting in PROMPT cannot break it.
run: $(BIN)
@set -a; [ -f ./.env.local ] && . ./.env.local; set +a; \
{ case "$$PROMPT" in "") exec cat ;; @*) PROMPT=$$(cat "$${PROMPT#@}") ;; esac; \
jq -n --arg prompt "$$PROMPT" --arg reasoning "$$REASONING" \
'{input: [{type:"message", role:"user", content:[{type:"input_text", text:$$prompt}]}]} \
+ (if $$reasoning == "" then {} else {reasoning:{effort:$$reasoning}} end)'; } \
| $(BIN) --backend $(BACKEND) --model "$$MODEL" --timing $(ARGS) \
| jq '$(JQ)'
# No --config: the embedded table is the whole of what this serves. A service
# whose key is missing from .env.local still starts and fails when it is called.
SERVE = set -a; [ -f ./.env.local ] && . ./.env.local; set +a; \
exec $(BIN) serve --addr $(ADDR) $(ARGS)
serve: $(BIN)
@$(SERVE)
# serve-dev is serve rebuilt and restarted on every source change. The .yaml is
# there because the service table is embedded: editing it is editing the binary.
# watchexec runs the build itself rather than calling back into make, so that a
# restart is the server dying and nothing else reporting on it.
serve-dev:
@command -v watchexec >/dev/null || { \
echo "serve-dev needs watchexec: brew install watchexec" >&2; exit 1; }
@exec watchexec --restart --exts go,yaml --watch cmd --watch internal \
-- 'go build -o $(BIN) ./cmd/dragoman && { $(SERVE); }'