waku-agent 0.1.0__tar.gz
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.
- waku_agent-0.1.0/.env.example +192 -0
- waku_agent-0.1.0/.gitignore +31 -0
- waku_agent-0.1.0/CLAUDE.md +68 -0
- waku_agent-0.1.0/CODE_OF_CONDUCT.md +44 -0
- waku_agent-0.1.0/CONTRIBUTING.md +113 -0
- waku_agent-0.1.0/LICENSE +21 -0
- waku_agent-0.1.0/Makefile +56 -0
- waku_agent-0.1.0/PKG-INFO +576 -0
- waku_agent-0.1.0/README.md +516 -0
- waku_agent-0.1.0/SECURITY.md +43 -0
- waku_agent-0.1.0/evals/__init__.py +0 -0
- waku_agent-0.1.0/evals/coding.jsonl +2 -0
- waku_agent-0.1.0/evals/conftest.py +6 -0
- waku_agent-0.1.0/evals/dataset.jsonl +11 -0
- waku_agent-0.1.0/evals/deterministic/test_all_history.py +63 -0
- waku_agent-0.1.0/evals/deterministic/test_apple_calendar.py +44 -0
- waku_agent-0.1.0/evals/deterministic/test_apple_tools.py +129 -0
- waku_agent-0.1.0/evals/deterministic/test_browser_agent.py +71 -0
- waku_agent-0.1.0/evals/deterministic/test_cli_memory.py +52 -0
- waku_agent-0.1.0/evals/deterministic/test_coding_eval.py +95 -0
- waku_agent-0.1.0/evals/deterministic/test_compare_history.py +74 -0
- waku_agent-0.1.0/evals/deterministic/test_consolidation.py +237 -0
- waku_agent-0.1.0/evals/deterministic/test_dashboard_routes.py +107 -0
- waku_agent-0.1.0/evals/deterministic/test_delegate.py +214 -0
- waku_agent-0.1.0/evals/deterministic/test_discord_access.py +126 -0
- waku_agent-0.1.0/evals/deterministic/test_episodic_store_switch.py +299 -0
- waku_agent-0.1.0/evals/deterministic/test_experimental_toggle.py +73 -0
- waku_agent-0.1.0/evals/deterministic/test_gcal_oauth.py +207 -0
- waku_agent-0.1.0/evals/deterministic/test_google_calendar.py +211 -0
- waku_agent-0.1.0/evals/deterministic/test_history_window.py +48 -0
- waku_agent-0.1.0/evals/deterministic/test_judge.py +68 -0
- waku_agent-0.1.0/evals/deterministic/test_models.py +118 -0
- waku_agent-0.1.0/evals/deterministic/test_notion_episodes.py +194 -0
- waku_agent-0.1.0/evals/deterministic/test_packaging.py +124 -0
- waku_agent-0.1.0/evals/deterministic/test_pinned_models.py +185 -0
- waku_agent-0.1.0/evals/deterministic/test_providers.py +179 -0
- waku_agent-0.1.0/evals/deterministic/test_retrieval_gate.py +163 -0
- waku_agent-0.1.0/evals/deterministic/test_runtime_data_is_ignored.py +96 -0
- waku_agent-0.1.0/evals/deterministic/test_scoring.py +54 -0
- waku_agent-0.1.0/evals/deterministic/test_session_resume.py +65 -0
- waku_agent-0.1.0/evals/deterministic/test_session_rotation.py +89 -0
- waku_agent-0.1.0/evals/deterministic/test_shootout.py +66 -0
- waku_agent-0.1.0/evals/deterministic/test_show_trace.py +86 -0
- waku_agent-0.1.0/evals/deterministic/test_skill_encoding.py +99 -0
- waku_agent-0.1.0/evals/deterministic/test_speakable.py +26 -0
- waku_agent-0.1.0/evals/deterministic/test_static_assets.py +70 -0
- waku_agent-0.1.0/evals/deterministic/test_tool_trigger.py +127 -0
- waku_agent-0.1.0/evals/deterministic/test_trace_encoding.py +112 -0
- waku_agent-0.1.0/evals/deterministic/test_turn_meta.py +55 -0
- waku_agent-0.1.0/evals/deterministic/test_wake_word.py +39 -0
- waku_agent-0.1.0/evals/deterministic/test_working_memory.py +43 -0
- waku_agent-0.1.0/evals/deterministic/test_workspace.py +66 -0
- waku_agent-0.1.0/evals/helpers.py +87 -0
- waku_agent-0.1.0/evals/judge/anthropic_judge.py +47 -0
- waku_agent-0.1.0/evals/judge/test_response_quality.py +84 -0
- waku_agent-0.1.0/pyproject.toml +158 -0
- waku_agent-0.1.0/scripts/demo_seed.py +123 -0
- waku_agent-0.1.0/scripts/shootout.py +206 -0
- waku_agent-0.1.0/scripts/validate_skills.py +51 -0
- waku_agent-0.1.0/skills/TEMPLATE.md +23 -0
- waku_agent-0.1.0/skills/community/README.md +10 -0
- waku_agent-0.1.0/skills/community/meeting-prep/SKILL.md +39 -0
- waku_agent-0.1.0/skills/schedule-meeting/SKILL.md +25 -0
- waku_agent-0.1.0/skills/weekly-brief/SKILL.md +26 -0
- waku_agent-0.1.0/sql/init_supabase.sql +232 -0
- waku_agent-0.1.0/waku/__init__.py +10 -0
- waku_agent-0.1.0/waku/__main__.py +58 -0
- waku_agent-0.1.0/waku/app.py +103 -0
- waku_agent-0.1.0/waku/config.py +105 -0
- waku_agent-0.1.0/waku/db.py +107 -0
- waku_agent-0.1.0/waku/gateway/__init__.py +0 -0
- waku_agent-0.1.0/waku/gateway/cli.py +88 -0
- waku_agent-0.1.0/waku/gateway/discord.py +231 -0
- waku_agent-0.1.0/waku/gateway/telegram.py +148 -0
- waku_agent-0.1.0/waku/gateway/voice.py +360 -0
- waku_agent-0.1.0/waku/gateway/whatsapp.py +322 -0
- waku_agent-0.1.0/waku/loop/__init__.py +0 -0
- waku_agent-0.1.0/waku/loop/agent.py +114 -0
- waku_agent-0.1.0/waku/loop/models.py +326 -0
- waku_agent-0.1.0/waku/memory/__init__.py +186 -0
- waku_agent-0.1.0/waku/memory/consolidation.py +75 -0
- waku_agent-0.1.0/waku/memory/episodic/__init__.py +0 -0
- waku_agent-0.1.0/waku/memory/episodic/notion_store.py +164 -0
- waku_agent-0.1.0/waku/memory/episodic/store.py +57 -0
- waku_agent-0.1.0/waku/memory/procedural/__init__.py +0 -0
- waku_agent-0.1.0/waku/memory/procedural/installer.py +54 -0
- waku_agent-0.1.0/waku/memory/procedural/loader.py +91 -0
- waku_agent-0.1.0/waku/memory/retrieval_gate.py +55 -0
- waku_agent-0.1.0/waku/memory/semantic/__init__.py +0 -0
- waku_agent-0.1.0/waku/memory/semantic/store.py +78 -0
- waku_agent-0.1.0/waku/memory/semantic/supabase_store.py +58 -0
- waku_agent-0.1.0/waku/ops/README.md +66 -0
- waku_agent-0.1.0/waku/ops/__init__.py +0 -0
- waku_agent-0.1.0/waku/ops/arena.py +245 -0
- waku_agent-0.1.0/waku/ops/brief.py +35 -0
- waku_agent-0.1.0/waku/ops/browser_agent.py +162 -0
- waku_agent-0.1.0/waku/ops/catalog.py +211 -0
- waku_agent-0.1.0/waku/ops/coding_eval.py +183 -0
- waku_agent-0.1.0/waku/ops/compare_history.py +140 -0
- waku_agent-0.1.0/waku/ops/dashboard.py +901 -0
- waku_agent-0.1.0/waku/ops/judge.py +101 -0
- waku_agent-0.1.0/waku/ops/pricing.py +180 -0
- waku_agent-0.1.0/waku/ops/release_gate.py +92 -0
- waku_agent-0.1.0/waku/ops/scoring.py +59 -0
- waku_agent-0.1.0/waku/ops/settings_api.py +177 -0
- waku_agent-0.1.0/waku/ops/show_trace.py +177 -0
- waku_agent-0.1.0/waku/ops/static/README.md +62 -0
- waku_agent-0.1.0/waku/ops/static/index.html +60 -0
- waku_agent-0.1.0/waku/ops/static/js/compare.js +558 -0
- waku_agent-0.1.0/waku/ops/static/js/diagram.js +149 -0
- waku_agent-0.1.0/waku/ops/static/js/dock.js +146 -0
- waku_agent-0.1.0/waku/ops/static/js/main.js +182 -0
- waku_agent-0.1.0/waku/ops/static/js/memory.js +37 -0
- waku_agent-0.1.0/waku/ops/static/js/models.js +235 -0
- waku_agent-0.1.0/waku/ops/static/js/render.js +189 -0
- waku_agent-0.1.0/waku/ops/static/js/util.js +91 -0
- waku_agent-0.1.0/waku/ops/static/js/views.js +489 -0
- waku_agent-0.1.0/waku/ops/static/style.css +400 -0
- waku_agent-0.1.0/waku/ops/tracing.py +167 -0
- waku_agent-0.1.0/waku/ops/whiteboard/__init__.py +0 -0
- waku_agent-0.1.0/waku/ops/whiteboard/assets/github.png +0 -0
- waku_agent-0.1.0/waku/ops/whiteboard/assets/x.jpg +0 -0
- waku_agent-0.1.0/waku/ops/whiteboard/assets/youtube.png +0 -0
- waku_agent-0.1.0/waku/ops/whiteboard/build_k3_tutorial.py +178 -0
- waku_agent-0.1.0/waku/ops/whiteboard/build_pi_system.py +140 -0
- waku_agent-0.1.0/waku/ops/whiteboard/build_pi_vs_claude.py +105 -0
- waku_agent-0.1.0/waku/ops/whiteboard/style.py +379 -0
- waku_agent-0.1.0/waku/runtime/__init__.py +0 -0
- waku_agent-0.1.0/waku/runtime/session.py +127 -0
- waku_agent-0.1.0/waku/tools/__init__.py +77 -0
- waku_agent-0.1.0/waku/tools/apple.py +224 -0
- waku_agent-0.1.0/waku/tools/calendar.py +431 -0
- waku_agent-0.1.0/waku/tools/experimental.py +331 -0
- waku_agent-0.1.0/waku/tools/google_calendar.py +182 -0
- waku_agent-0.1.0/waku/tools/mcp_client.py +100 -0
- waku_agent-0.1.0/waku/tools/memory_admin.py +144 -0
- waku_agent-0.1.0/waku/tools/messages.py +39 -0
- waku_agent-0.1.0/waku/tools/notes.py +40 -0
- waku_agent-0.1.0/waku/tools/registry.py +58 -0
- waku_agent-0.1.0/waku/tools/search.py +99 -0
- waku_agent-0.1.0/waku/tools/workspace.py +120 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# ── Provider ────────────────────────────────────────────────────────────────
|
|
2
|
+
# Pick ONE provider and paste its key below. That's the whole setup.
|
|
3
|
+
# anthropic (default) · openai · gemini · deepseek · minimax · kimi · glm · openrouter · opencode_zen · opencode_go
|
|
4
|
+
# No paid key? openrouter's default models are $0 ":free" ids (rate-limited).
|
|
5
|
+
WAKU_PROVIDER=anthropic
|
|
6
|
+
|
|
7
|
+
# Keys — only the one for your chosen provider is needed.
|
|
8
|
+
# (Keep comments on their own line: python-dotenv reads inline text as the value.)
|
|
9
|
+
# anthropic → https://console.anthropic.com
|
|
10
|
+
ANTHROPIC_API_KEY=
|
|
11
|
+
# openai → https://platform.openai.com
|
|
12
|
+
OPENAI_API_KEY=
|
|
13
|
+
# gemini → https://aistudio.google.com
|
|
14
|
+
GEMINI_API_KEY=
|
|
15
|
+
# deepseek → https://platform.deepseek.com
|
|
16
|
+
DEEPSEEK_API_KEY=
|
|
17
|
+
# minimaxi → https://platform.minimaxi.com
|
|
18
|
+
MINIMAX_API_KEY=
|
|
19
|
+
# kimi → https://platform.moonshot.ai
|
|
20
|
+
MOONSHOT_API_KEY=
|
|
21
|
+
# glm → https://z.ai
|
|
22
|
+
ZHIPU_API_KEY=
|
|
23
|
+
# openrouter (one key, hundreds of hosted models) → https://openrouter.ai/keys
|
|
24
|
+
OPENROUTER_API_KEY=
|
|
25
|
+
# xai / grok → https://console.x.ai
|
|
26
|
+
XAI_API_KEY=
|
|
27
|
+
# opencode zen → https://opencode.ai/zen/v1
|
|
28
|
+
OPENCODE_ZEN_API_KEY=
|
|
29
|
+
# opencode go → https://opencode.ai/zen/go/v1
|
|
30
|
+
OPENCODE_GO_API_KEY=
|
|
31
|
+
|
|
32
|
+
# ── Models (optional) ───────────────────────────────────────────────────────
|
|
33
|
+
# Each provider has sensible defaults (see waku/loop/models.py PROVIDERS):
|
|
34
|
+
# anthropic: claude-sonnet-5 + claude-haiku-4-5 (gate/summarizer)
|
|
35
|
+
# openai: gpt-5.6 + gpt-5.6-luna
|
|
36
|
+
# gemini: gemini-3.5-flash + gemini-3.1-flash-lite
|
|
37
|
+
# deepseek: deepseek-v4-pro + deepseek-v4-pro
|
|
38
|
+
# minimax: MiniMax-M3 + MiniMax-M2
|
|
39
|
+
# kimi: kimi-k3 + kimi-k2.6 (gate/summarizer)
|
|
40
|
+
# (K3-only key? set WAKU_SMALL_MODEL=kimi-k3 too)
|
|
41
|
+
# glm: glm-5.2 + glm-5-turbo
|
|
42
|
+
# openrouter: nemotron-3-super:free + gemma-4-26b:free (both $0,
|
|
43
|
+
# rate-limited; Settings lists the live catalog, free first)
|
|
44
|
+
# openrouter's whole point is picking a different model, so WAKU_MODEL takes
|
|
45
|
+
# any "<vendor>/<model>" slug from https://openrouter.ai/models — e.g.
|
|
46
|
+
# WAKU_MODEL=meta-llama/llama-3.1-70b-instruct
|
|
47
|
+
# Override here if you want something else — they're just strings:
|
|
48
|
+
# WAKU_MODEL=
|
|
49
|
+
# WAKU_SMALL_MODEL=
|
|
50
|
+
# Advanced: point at any compatible endpoint / bring your own key var:
|
|
51
|
+
# WAKU_BASE_URL=
|
|
52
|
+
# WAKU_API_KEY=
|
|
53
|
+
|
|
54
|
+
# ── Waku home (optional) ──────────────────────────────────────────────────
|
|
55
|
+
# Where memory (state.db), calendar.ics, outbox/ and traces/ live.
|
|
56
|
+
# WAKU_HOME=.waku
|
|
57
|
+
|
|
58
|
+
# ── Loop guardrails (optional) ──────────────────────────────────────────────
|
|
59
|
+
# WAKU_MAX_ITERATIONS=10
|
|
60
|
+
# WAKU_MAX_TOKENS=2048
|
|
61
|
+
# Working memory window: how many recent turns enter the prompt (default 12).
|
|
62
|
+
# Older turns stay in state.db + consolidation; the retrieval gate brings them
|
|
63
|
+
# back when relevant. Caps context/cost/latency on long (esp. Telegram) threads.
|
|
64
|
+
# WAKU_HISTORY_TURNS=12
|
|
65
|
+
|
|
66
|
+
# ── Memory tuning (optional) ────────────────────────────────────────────────
|
|
67
|
+
# Consolidate chats into durable facts only after N new exchanges.
|
|
68
|
+
# WAKU_CONSOLIDATE_EVERY=6
|
|
69
|
+
# WAKU_RETRIEVAL_TOP_K=4
|
|
70
|
+
|
|
71
|
+
# ── Tracing (optional): pip install -e '.[tracing]' ────────────────────────
|
|
72
|
+
# JSONL traces are ALWAYS written to $WAKU_HOME/traces/. To also see them in
|
|
73
|
+
# a dashboard: run `make trace` (Phoenix on localhost:6006) and uncomment:
|
|
74
|
+
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
|
|
75
|
+
# (Langfuse cloud speaks OTel too — use their endpoint + auth headers instead.)
|
|
76
|
+
|
|
77
|
+
# ── Apple ecosystem (optional, macOS) ───────────────────────────────────────
|
|
78
|
+
# Sync created events into Calendar.app (a dedicated "Waku" calendar):
|
|
79
|
+
# WAKU_APPLE_CALENDAR=1
|
|
80
|
+
# Give the agent read/write tools for Calendar, Mail, Reminders, Notes — so it
|
|
81
|
+
# can brief you on your real week ("brief me"). First use triggers the macOS
|
|
82
|
+
# Automation permission prompts for each app.
|
|
83
|
+
# WAKU_APPLE_TOOLS=1
|
|
84
|
+
# Limit calendar reads to named calendars (faster; comma-separated):
|
|
85
|
+
# WAKU_APPLE_CALENDARS=Work,Home
|
|
86
|
+
|
|
87
|
+
# ── Google Calendar writes (optional): pip install -e '.[gcal]' ────────────
|
|
88
|
+
# SQLite + calendar.ics remain the source of truth. This only mirrors events
|
|
89
|
+
# created by create_event; list_events stays local and requests use sendUpdates=none.
|
|
90
|
+
# Authenticate first with Application Default Credentials, then enable:
|
|
91
|
+
# WAKU_GOOGLE_CALENDAR=1
|
|
92
|
+
# WAKU_GOOGLE_CALENDAR_ID=primary
|
|
93
|
+
|
|
94
|
+
# ── Open files in your editor (optional) ────────────────────────────────────
|
|
95
|
+
# Dashboard "reveal" links open files in this editor when it's on PATH
|
|
96
|
+
# (falls back to cursor, then code, then Finder):
|
|
97
|
+
# WAKU_EDITOR=cursor
|
|
98
|
+
|
|
99
|
+
# ── Experimental tools (optional) ───────────────────────────────────────────
|
|
100
|
+
# delegate_task (LIVE): hand coding jobs to pi, the open-source coding agent —
|
|
101
|
+
# npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
102
|
+
# The terminal/browser/cron skeletons still just report "coming soon".
|
|
103
|
+
# WAKU_EXPERIMENTAL=1
|
|
104
|
+
# Max seconds pi may spend on one delegated task (default 300):
|
|
105
|
+
# WAKU_DELEGATE_TIMEOUT=300
|
|
106
|
+
|
|
107
|
+
# ── Web search (optional) ───────────────────────────────────────────────────
|
|
108
|
+
# The search_web tool works keyless via DuckDuckGo, but that endpoint often
|
|
109
|
+
# blocks automated requests. For reliable search (e.g. the "find the World Cup
|
|
110
|
+
# games left and add them to my calendar" loop demo), set a free Tavily key:
|
|
111
|
+
# sign up at https://tavily.com → copy the key here.
|
|
112
|
+
# TAVILY_API_KEY=
|
|
113
|
+
|
|
114
|
+
# ── MCP servers (optional): pip install -e '.[mcp]' ─────────────────────────
|
|
115
|
+
# Connect Model Context Protocol servers by creating .waku/mcp.json:
|
|
116
|
+
# {"servers": [{"name": "fs", "command": "npx",
|
|
117
|
+
# "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]}]}
|
|
118
|
+
# Their tools register as <server>_<tool> and appear to the agent automatically.
|
|
119
|
+
|
|
120
|
+
# ── Voice gateway (optional): pip install -e '.[voice]' ────────────────────
|
|
121
|
+
# Unset = push-to-talk (Enter, speak, Enter). Set a wake word — ANY phrase —
|
|
122
|
+
# and `make voice` becomes always-listening:
|
|
123
|
+
# WAKU_WAKE_WORD=waku waku
|
|
124
|
+
# What it says when it wakes:
|
|
125
|
+
# WAKU_WAKE_ACK=Yes?
|
|
126
|
+
# Stay in the conversation after answering (Siri-style) for N seconds before
|
|
127
|
+
# needing "waku waku" again:
|
|
128
|
+
# WAKU_FOLLOWUP_SECONDS=8
|
|
129
|
+
# STT model (tiny/base/small — bigger = more accurate, slower):
|
|
130
|
+
# WAKU_WHISPER_MODEL=base
|
|
131
|
+
# TTS engine: 'say' (macOS built-in, default) or 'kokoro' (neural British
|
|
132
|
+
# butler — first: pip install kokoro soundfile):
|
|
133
|
+
# WAKU_TTS=say
|
|
134
|
+
# WAKU_VOICE=Daniel
|
|
135
|
+
# (for kokoro use voices like bm_george / bm_fable)
|
|
136
|
+
# Mic sensitivity: lower if it never hears you, higher if it wakes on noise:
|
|
137
|
+
# WAKU_MIC_THRESHOLD=0.005
|
|
138
|
+
|
|
139
|
+
# ── Reliability (optional) ──────────────────────────────────────────────────
|
|
140
|
+
# Max seconds any single LLM call may take before erroring instead of hanging:
|
|
141
|
+
# WAKU_LLM_TIMEOUT=120
|
|
142
|
+
|
|
143
|
+
# ── Telegram gateway (optional): pip install -e '.[telegram]' ──────────────
|
|
144
|
+
# Create a bot: message @BotFather → /newbot. Find your numeric user id via
|
|
145
|
+
# @userinfobot to lock the bot to yourself.
|
|
146
|
+
# TELEGRAM_BOT_TOKEN=
|
|
147
|
+
# TELEGRAM_ALLOWED_USER=
|
|
148
|
+
|
|
149
|
+
# ── Discord gateway (optional): pip install -e '.[discord]' ────────────────
|
|
150
|
+
# Create a bot in the Discord Developer Portal and enable Message Content Intent.
|
|
151
|
+
#
|
|
152
|
+
# READ THIS: the bot answers out of YOUR memory, with YOUR tools, on YOUR key.
|
|
153
|
+
# Default posture is deny — DMs only, and NO server channel is answered until
|
|
154
|
+
# you name it below. Every message it answers is a billed agent turn, and its
|
|
155
|
+
# chat log feeds consolidation, so a stranger's message can become a permanent
|
|
156
|
+
# fact in your memory. Open it up one line at a time.
|
|
157
|
+
# DISCORD_BOT_TOKEN=
|
|
158
|
+
# DISCORD_ALLOWED_USER= # comma-separated ids. Empty = anyone may DM it.
|
|
159
|
+
# DISCORD_ALLOWED_CHANNEL= # comma-separated channel ids. Empty = no channel.
|
|
160
|
+
# DISCORD_REQUIRE_MENTION=1 # in a channel, only reply when @-mentioned
|
|
161
|
+
# DISCORD_MAX_TURNS_PER_HOUR=30 # hard spend ceiling across all users
|
|
162
|
+
# DISCORD_HOME=.waku-discord # a SEPARATE memory — use this for any shared server
|
|
163
|
+
# ── WhatsApp gateway (optional): pip install -e '.[whatsapp]' ──────────────
|
|
164
|
+
# Meta Cloud API access token (temporary: 24h, permanent via System User).
|
|
165
|
+
# See waku/gateway/whatsapp.py docstring for full setup guide.
|
|
166
|
+
# WHATSAPP_TOKEN=
|
|
167
|
+
# Phone Number ID from WhatsApp > Getting Started in your Meta app dashboard.
|
|
168
|
+
# WHATSAPP_PHONE_NUMBER_ID=
|
|
169
|
+
# App Secret from your app's Settings → Basic → App Secret.
|
|
170
|
+
# Required: Meta signs every webhook with this; without it, anyone who finds
|
|
171
|
+
# your URL can forge payloads and drive the agent.
|
|
172
|
+
# WHATSAPP_APP_SECRET=
|
|
173
|
+
# Any random string — you'll enter it in Meta's webhook config page.
|
|
174
|
+
# WHATSAPP_VERIFY_TOKEN=
|
|
175
|
+
# Optional: lock the gateway to one phone number (without '+' prefix).
|
|
176
|
+
# WHATSAPP_ALLOWED_PHONE=
|
|
177
|
+
|
|
178
|
+
# ── Supabase vector memory (optional): pip install -e '.[supabase]' ────────
|
|
179
|
+
# The launch-rag upgrade path: run sql/init_supabase.sql on a fresh project.
|
|
180
|
+
# Embeddings use OPENAI_API_KEY above (text-embedding-3-small).
|
|
181
|
+
# WAKU_SEMANTIC_STORE=supabase
|
|
182
|
+
# SUPABASE_URL=
|
|
183
|
+
# SUPABASE_SERVICE_KEY=
|
|
184
|
+
|
|
185
|
+
# ── Notion episodic memory (optional): pip install -e '.[notion]' ───────────
|
|
186
|
+
# Store episodes (dated memory summaries) in a Notion database instead of the
|
|
187
|
+
# local state.db. Create an integration at https://www.notion.so/my-integrations,
|
|
188
|
+
# share a database with it (properties: Name = title, Summary = rich text), then
|
|
189
|
+
# paste its copied Notion link below (a raw database ID also works):
|
|
190
|
+
# WAKU_EPISODIC_STORE=notion
|
|
191
|
+
# NOTION_TOKEN=ntn_...
|
|
192
|
+
# NOTION_EPISODES_DATABASE_ID=https://app.notion.com/p/...
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.venv/
|
|
4
|
+
.env
|
|
5
|
+
state.db
|
|
6
|
+
traces/
|
|
7
|
+
*.ics
|
|
8
|
+
.DS_Store
|
|
9
|
+
dist/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.waku/
|
|
13
|
+
.waku.bak-*/
|
|
14
|
+
.waku.prerename-bak/
|
|
15
|
+
# Any ALTERNATE agent home, not just the default one. DISCORD_HOME gives the
|
|
16
|
+
# bot its own memory (see waku/gateway/discord.py); WAKU_HOME can point anywhere.
|
|
17
|
+
# Without this glob only `.waku/` was covered, so a second home's SOUL.md,
|
|
18
|
+
# usage.jsonl and outbox/ were tracked — the exact files you least want pushed.
|
|
19
|
+
.waku-*/
|
|
20
|
+
.env.prerename-bak
|
|
21
|
+
|
|
22
|
+
# Delegated coding deliverables (dated run folders + auto-run logs)
|
|
23
|
+
waku_workspace/
|
|
24
|
+
|
|
25
|
+
# Google OAuth: the client file you download from Cloud Console, and any token
|
|
26
|
+
# it produces. Nothing here should ever be committed — belt and braces, because
|
|
27
|
+
# the docs used to tell people to drop credentials.json in the repo root.
|
|
28
|
+
credentials.json
|
|
29
|
+
client_secret*.json
|
|
30
|
+
*token*.json
|
|
31
|
+
.gcp/
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# waku-agent — working conventions
|
|
2
|
+
|
|
3
|
+
**Waku** — a local-first personal assistant demonstrating the four pillars behind every
|
|
4
|
+
serious agent: Harness, Loop, Memory, and Eval/LLM-Ops. It began as a teaching repo you
|
|
5
|
+
could read in an afternoon, and it's now growing toward a full open-source assistant (the
|
|
6
|
+
next Hermes / OpenClaw). The bar for every change: **clear, honest code a newcomer can
|
|
7
|
+
follow** — each pillar legible on its own. The project will get bigger; it must never get
|
|
8
|
+
muddier. New scope is welcome when it stays self-contained, tested, and readable; complexity
|
|
9
|
+
for its own sake is not.
|
|
10
|
+
|
|
11
|
+
## Architecture map (file ↔ diagram box)
|
|
12
|
+
|
|
13
|
+
- `waku/gateway/` — cli, voice (wake word), telegram. Gateways only move text.
|
|
14
|
+
- `waku/runtime/session.py` — working memory assembly (SOUL.md + memory + history)
|
|
15
|
+
- `waku/loop/agent.py` — THE loop; `loop/models.py` — pluggable providers, 2 wire formats
|
|
16
|
+
- `waku/tools/` — create_event / save_note / send_message (flagship task only)
|
|
17
|
+
- `waku/memory/` — semantic (FTS5) / episodic / procedural (SKILL.md) +
|
|
18
|
+
`retrieval_gate.py` (hero 1) + `consolidation.py` (every N exchanges)
|
|
19
|
+
- `waku/ops/` — tracing (JSONL + OTel), dashboard (localhost:7777), release_gate,
|
|
20
|
+
`compare_history.py` (the Compare arena's own JSONL scoreboard — never state.db)
|
|
21
|
+
- `evals/deterministic/` (0/1, pytest) vs `evals/judge/` (DeepEval, scored) — never mix
|
|
22
|
+
- Runtime state lives in `.waku/` (state.db, calendar.ics, outbox/, traces/) — gitignored
|
|
23
|
+
|
|
24
|
+
## Rules
|
|
25
|
+
|
|
26
|
+
- **Be concise.** Sean wants short replies: lead with the answer, cut preamble and
|
|
27
|
+
recap. A few lines beats a wall of text. Expand only when he asks for detail.
|
|
28
|
+
- **Never wipe runtime data without asking first, every time.** `scripts/demo_seed.py`
|
|
29
|
+
and anything else that clears `.waku` (memory, calendar, chat log, traces, or the
|
|
30
|
+
`usage.jsonl` spend ledger) must be proposed and explicitly approved by the user
|
|
31
|
+
*immediately before each run*. Permission never carries over from a previous run.
|
|
32
|
+
The script backs up first, but restoring is a hassle — ask, wait for a clear yes,
|
|
33
|
+
then run. It refuses to do anything without the `--yes` flag for this reason.
|
|
34
|
+
- **Version control — commit AND ship every milestone, same turn.** The moment a change
|
|
35
|
+
works (tests pass / verified live), commit it with a detailed message (subject = what,
|
|
36
|
+
body = WHY + what it survived) and get it onto GitHub before moving on. Never end a
|
|
37
|
+
turn or session with working changes left uncommitted — the repo must always be traceable
|
|
38
|
+
from GitHub, and uncommitted work has been lost to branch switches before. Use the `/ship`
|
|
39
|
+
skill. If several milestones land in one session, commit each as its own logical commit.
|
|
40
|
+
- **`main` is protected — `git push origin main` is REJECTED, for everyone.** Since
|
|
41
|
+
2026-07-26 a commit only lands once `skills-and-evals` is green, and `enforce_admins`
|
|
42
|
+
is on, so the rule binds Sean and Claude identically. Ship via
|
|
43
|
+
`git checkout -b <topic>` → `gh pr create --fill` → `gh pr checks --watch` (~30s) →
|
|
44
|
+
`gh pr merge --squash --delete-branch`. `GH006: Protected branch update failed` is the
|
|
45
|
+
guard working; never route around it. Merging a COMMUNITY PR still needs Sean's
|
|
46
|
+
explicit per-PR yes (see `.claude/skills/review-pr/SKILL.md`).
|
|
47
|
+
- **Gate before push**: `make gate` (deterministic must pass; judge runs with a key).
|
|
48
|
+
When a live bug is found, fix it AND add a regression case to `evals/deterministic/`.
|
|
49
|
+
- **No emojis** in any UI surface (dashboard, CLI output, README prose).
|
|
50
|
+
- **No new dependencies without discussion** — the core is stdlib + anthropic/openai.
|
|
51
|
+
Optional features go behind extras (`[voice]`, `[telegram]`, ...).
|
|
52
|
+
- **Footprint ladder — where new capability goes.** Every registered tool ships in
|
|
53
|
+
every prompt, so the core stays narrow and capability lives at the edges. In order:
|
|
54
|
+
extend existing code → a skill (`SKILL.md`, no Python) → a CLI + README →
|
|
55
|
+
a tool behind an extra → a gateway (one file, text in/out only) →
|
|
56
|
+
**a new core tool, last resort**. Full version, with the "declined even when
|
|
57
|
+
well-built" list, in `CONTRIBUTING.md`.
|
|
58
|
+
- **Scope**: scheduling is the flagship teaching task, but the project is growing toward a
|
|
59
|
+
full assistant. New capabilities (providers, tools, gateways, integrations) are welcome
|
|
60
|
+
when they're self-contained, tested, and keep the core legible. Reject only complexity
|
|
61
|
+
that muddies how the system works or bloats the default path — prefer opt-in extras.
|
|
62
|
+
- Providers are framed neutrally in docs (Anthropic, OpenAI, Gemini, DeepSeek, Kimi, GLM,
|
|
63
|
+
OpenRouter) — no ranking, no "open-source vs closed" framing.
|
|
64
|
+
|
|
65
|
+
## Commands
|
|
66
|
+
|
|
67
|
+
`make run` · `make voice` · `make dashboard` (7777) · `make trace` (6006) ·
|
|
68
|
+
`make eval` · `make gate` · `make lint` · tests live under `evals/`, not `tests/`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## The short version
|
|
4
|
+
|
|
5
|
+
Be decent. Assume the other person is trying to help. Critique code, not people.
|
|
6
|
+
|
|
7
|
+
waku is a teaching repo — a lot of the people opening their first-ever pull
|
|
8
|
+
request will do it here. That's the point, and it sets the bar for how we
|
|
9
|
+
answer them.
|
|
10
|
+
|
|
11
|
+
## What that means in practice
|
|
12
|
+
|
|
13
|
+
- **Explain the why.** "This won't work" is useless; "this crashes because the
|
|
14
|
+
SQLite connection is bound to the thread that opened it" teaches something.
|
|
15
|
+
- **A rejected PR is not a rejected person.** If we decline a change, we say
|
|
16
|
+
what would have made it land — and forking is always fair game, that's what
|
|
17
|
+
MIT is for.
|
|
18
|
+
- **No harassment, personal attacks, or demeaning comments** about anyone's
|
|
19
|
+
experience level, background, identity, or English. Plenty of contributors
|
|
20
|
+
here aren't writing in their first language.
|
|
21
|
+
- **Don't derail.** Issues are for the work; the [Discord](https://discord.gg/7Ntxzm3eJ)
|
|
22
|
+
is for everything else.
|
|
23
|
+
- **Credit people.** If someone's idea shaped a change, say so in the PR.
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
This applies in issues, pull requests, reviews, commit messages, the Discord,
|
|
28
|
+
and anywhere someone is representing the project.
|
|
29
|
+
|
|
30
|
+
## Enforcement
|
|
31
|
+
|
|
32
|
+
Report anything that crosses the line by private message to
|
|
33
|
+
[@ShenSeanChen](https://github.com/ShenSeanChen), or the email on his GitHub
|
|
34
|
+
profile. Reports stay private.
|
|
35
|
+
|
|
36
|
+
Responses are proportionate: usually a quiet word, sometimes an edited or
|
|
37
|
+
removed comment, and — for repeated or serious behavior — a block from the
|
|
38
|
+
repo. The maintainer's call is final, and he'll explain it.
|
|
39
|
+
|
|
40
|
+
## A note on tone
|
|
41
|
+
|
|
42
|
+
Direct, evidence-first review is welcome and encouraged; that's what makes the
|
|
43
|
+
code good. There's a difference between "this has a race condition, here's the
|
|
44
|
+
trace" and being unkind about it. Stay on the first side of that line.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Contributing to Waku
|
|
2
|
+
|
|
3
|
+
Waku started as a teaching repo you could read in an afternoon, and it's growing toward a
|
|
4
|
+
full local-first assistant — the next Hermes / OpenClaw, with 1/100th the code. Contributions
|
|
5
|
+
are genuinely welcome. The project will get bigger; the one thing it must never do is get
|
|
6
|
+
*muddier*.
|
|
7
|
+
|
|
8
|
+
**The bar for every PR:** clear, self-contained, and tested. A newcomer should be able to open
|
|
9
|
+
the file you touched and follow what it does. New capability is great — complexity that hides
|
|
10
|
+
how the system works is what we push back on.
|
|
11
|
+
|
|
12
|
+
## The easiest contribution: a skill (no Python needed)
|
|
13
|
+
|
|
14
|
+
1. Copy [`skills/TEMPLATE.md`](skills/TEMPLATE.md) to `skills/community/<your-skill>/SKILL.md`
|
|
15
|
+
2. Fill in `name` + `description` (the Agent Skills frontmatter) and the body
|
|
16
|
+
3. Test locally: `python scripts/validate_skills.py`, then chat — your skill loads when it matches
|
|
17
|
+
4. Open a PR. CI runs the same validator.
|
|
18
|
+
|
|
19
|
+
Anyone can then try your skill instantly:
|
|
20
|
+
`waku skill install <link to your SKILL.md>`
|
|
21
|
+
|
|
22
|
+
## Code contributions
|
|
23
|
+
|
|
24
|
+
Good places to add real value:
|
|
25
|
+
|
|
26
|
+
- **Providers** (`waku/loop/models.py`): most models expose an OpenAI- or Anthropic-compatible
|
|
27
|
+
endpoint, so a new provider is usually one `PROVIDERS` row — no new wire code. Add a pricing
|
|
28
|
+
row in the dashboard and a case to `evals/deterministic/test_providers.py`.
|
|
29
|
+
- **Gateways** (`waku/gateway/`): receive/send for a new channel (WhatsApp, Discord, Slack,
|
|
30
|
+
email). Keep it to one file; the CLI gateway is the reference.
|
|
31
|
+
- **Memory stores** (`waku/memory/semantic/`): match the `add`/`search` interface of
|
|
32
|
+
`SqliteFactStore`. The Supabase adapter is the reference.
|
|
33
|
+
- **Tools** (`waku/tools/`): a new capability the agent can call. Follow `calendar.py` and the
|
|
34
|
+
`new-tool` skill — schema, safe execution, honest output, and a deterministic eval.
|
|
35
|
+
|
|
36
|
+
Two rules that keep contributions safe to merge:
|
|
37
|
+
|
|
38
|
+
- **Test what you add.** Every behavior change gets a deterministic eval in
|
|
39
|
+
`evals/deterministic/` (0/1, no network). If you found a bug, add the case that catches it.
|
|
40
|
+
- **Heavy or optional deps go behind an extra** (`[voice]`, `[telegram]`, `[voice-neural]`, …),
|
|
41
|
+
never in the default install. No new core dependency without discussion.
|
|
42
|
+
|
|
43
|
+
Run the gate before pushing: `make gate` (deterministic must pass; judge evals run if you have
|
|
44
|
+
a key). `make lint` too. CI runs the gate on every PR — it must be green to merge.
|
|
45
|
+
|
|
46
|
+
## Where does my change go? — the footprint ladder
|
|
47
|
+
|
|
48
|
+
The core is a narrow waist; capability belongs at the edges. Every tool waku
|
|
49
|
+
registers is sent to the model on **every single call**, so the bar for adding
|
|
50
|
+
one is deliberately high. Start at the top of this ladder and only move down
|
|
51
|
+
when the rung above genuinely can't do it:
|
|
52
|
+
|
|
53
|
+
1. **Extend something that already exists.** A new provider is usually one
|
|
54
|
+
`PROVIDERS` row. A new memory backend matches an existing interface.
|
|
55
|
+
2. **A skill** — `skills/community/<name>/SKILL.md`. Markdown, no Python, no new
|
|
56
|
+
context cost until the model actually needs it. This is the easiest and most
|
|
57
|
+
underrated contribution; see above.
|
|
58
|
+
3. **A CLI + a README.** waku can already run any program on your machine. A
|
|
59
|
+
command-line tool with docs beside it costs nothing until it's used.
|
|
60
|
+
4. **A tool behind an extra** — `waku/tools/`, heavy deps gated by
|
|
61
|
+
`[voice]`/`[notion]`/`[gcal]`-style extras, off by default.
|
|
62
|
+
5. **A gateway** — `waku/gateway/`, one file. Gateways only move text: in via
|
|
63
|
+
`waku.respond()`, out again. No memory, no tools, no loop logic.
|
|
64
|
+
6. **A new core tool — last resort.** It has to earn its place in every prompt.
|
|
65
|
+
|
|
66
|
+
If you're unsure which rung you're on, open an issue and ask before writing
|
|
67
|
+
code. That conversation is cheaper than a rejected PR.
|
|
68
|
+
|
|
69
|
+
## Scope — what we'll say no to, kindly
|
|
70
|
+
|
|
71
|
+
We welcome growth; we decline **complexity that muddies the core**: frameworks that hide the
|
|
72
|
+
loop, changes that bloat the default path for everyone, or features that can't be read and
|
|
73
|
+
tested on their own. When we say no, we'll explain why — and forking is always fair game
|
|
74
|
+
(that's what MIT is for).
|
|
75
|
+
|
|
76
|
+
Concretely, these get declined **even when the code is good**:
|
|
77
|
+
|
|
78
|
+
- **Speculative infrastructure** — an abstraction with no second caller yet. Add
|
|
79
|
+
the second use case first; the right shape is obvious then and guessed now.
|
|
80
|
+
- **A new core dependency.** The default install is stdlib plus the two API
|
|
81
|
+
clients. Heavy or optional things go behind an extra.
|
|
82
|
+
- **Anything that costs every user context** for a feature some users want —
|
|
83
|
+
that's what the ladder above is for.
|
|
84
|
+
- **A behavior change with no deterministic eval.** If it can break, pin it.
|
|
85
|
+
- **Hidden network calls, reading `.env` or secrets, or running code at install
|
|
86
|
+
time.** waku runs on people's own machines with their own keys.
|
|
87
|
+
- **A "fix" that removes the thing it secures** — e.g. sandboxing a tool by
|
|
88
|
+
making it not work.
|
|
89
|
+
|
|
90
|
+
None of this is about the quality of your code. It's about what everyone who
|
|
91
|
+
installs waku has to carry.
|
|
92
|
+
|
|
93
|
+
## What you can expect from us
|
|
94
|
+
|
|
95
|
+
- **A first response within 48 hours** — even if it's "this needs a proper look,
|
|
96
|
+
give me a few days." Silence is the one thing we try never to do.
|
|
97
|
+
- **Comment on an issue before you start and it gets assigned to you**, so two
|
|
98
|
+
people never build the same thing. (This has already gone wrong once, and it
|
|
99
|
+
cost someone a weekend.)
|
|
100
|
+
- **CI runs on your PR** — if it's your first contribution, GitHub needs a
|
|
101
|
+
maintainer to approve the run. If it seems stuck, say so on the PR; that
|
|
102
|
+
delay is ours, not yours.
|
|
103
|
+
|
|
104
|
+
## A note on safety
|
|
105
|
+
|
|
106
|
+
Because Waku runs on people's own machines with their own keys, PRs must never add hidden
|
|
107
|
+
network calls, read or transmit secrets/`.env`, or run code at install time. Keep it local,
|
|
108
|
+
keep it legible.
|
|
109
|
+
|
|
110
|
+
## Community
|
|
111
|
+
|
|
112
|
+
Questions, show-and-tell, pair-debugging: [Discord](https://discord.gg/7Ntxzm3eJ). By
|
|
113
|
+
contributing you agree your work is licensed under the repo's MIT license.
|
waku_agent-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sean Chen (ShenSeanChen)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# waku-agent — one command per pillar.
|
|
2
|
+
#
|
|
3
|
+
# Make is not a framework — it's a 45-year-old command shortcut tool that
|
|
4
|
+
# ships with every Mac/Linux. Each target below is just the shell command
|
|
5
|
+
# you'd otherwise type. `make run` = "run the python below", nothing more.
|
|
6
|
+
#
|
|
7
|
+
# PY picks the project venv automatically so you never need to remember
|
|
8
|
+
# `source .venv/bin/activate` — both work, this is just fewer steps.
|
|
9
|
+
PY := $(shell [ -x .venv/bin/python ] && echo .venv/bin/python || echo python)
|
|
10
|
+
|
|
11
|
+
.PHONY: run voice telegram discord brief dashboard trace eval eval-judge gate lint
|
|
12
|
+
.PHONY: run voice telegram whatsapp brief dashboard trace eval eval-judge gate lint
|
|
13
|
+
|
|
14
|
+
run: ## chat with Waku in the terminal
|
|
15
|
+
$(PY) -m waku
|
|
16
|
+
|
|
17
|
+
voice: ## talk to it — push-to-talk, or always-on with WAKU_WAKE_WORD
|
|
18
|
+
$(PY) -m waku voice
|
|
19
|
+
|
|
20
|
+
telegram: ## phone → laptop (needs TELEGRAM_BOT_TOKEN in .env)
|
|
21
|
+
$(PY) -m waku telegram
|
|
22
|
+
|
|
23
|
+
discord: ## Discord → laptop (needs DISCORD_BOT_TOKEN in .env)
|
|
24
|
+
$(PY) -m waku discord
|
|
25
|
+
whatsapp: ## WhatsApp → laptop (needs WHATSAPP_TOKEN in .env, public URL)
|
|
26
|
+
$(PY) -m waku whatsapp
|
|
27
|
+
|
|
28
|
+
brief: ## morning briefing from calendar + mail + memory
|
|
29
|
+
$(PY) -m waku brief
|
|
30
|
+
|
|
31
|
+
# The server holds dashboard.py in memory: static JS/CSS reload on refresh, but
|
|
32
|
+
# Python routes do NOT. After pulling a change that touches dashboard.py (or any
|
|
33
|
+
# imported module), stop this and re-run it, or the UI shows stale backend data.
|
|
34
|
+
dashboard: ## everything on one page — http://localhost:7777 (restart after a backend pull)
|
|
35
|
+
$(PY) -m waku.ops.dashboard
|
|
36
|
+
|
|
37
|
+
trace: ## deep trace waterfalls (Phoenix) at http://localhost:6006
|
|
38
|
+
$(PY) -m phoenix.server.main serve
|
|
39
|
+
|
|
40
|
+
eval: ## deterministic evals (0/1, no judge involved)
|
|
41
|
+
$(PY) -m pytest -q evals/deterministic
|
|
42
|
+
|
|
43
|
+
eval-judge: ## LLM-as-judge evals (scored %, needs an API key)
|
|
44
|
+
$(PY) -m pytest -q evals/judge
|
|
45
|
+
|
|
46
|
+
gate: ## the release gate: deterministic must pass, judge must clear threshold
|
|
47
|
+
$(PY) -m waku.ops.release_gate
|
|
48
|
+
|
|
49
|
+
shootout: ## same tasks, different brains: make shootout RUNS="kimi:kimi-k3 anthropic:claude-opus-4-8"
|
|
50
|
+
$(PY) scripts/shootout.py $(RUNS)
|
|
51
|
+
|
|
52
|
+
shootout-coding: ## coding round via pi, scored by tests: make shootout-coding RUNS="kimi:kimi-k3 anthropic:claude-opus-4-8"
|
|
53
|
+
$(PY) scripts/shootout.py $(RUNS) --coding
|
|
54
|
+
|
|
55
|
+
lint:
|
|
56
|
+
$(PY) -m ruff check waku evals scripts
|