agent-chief 0.3.1__py3-none-any.whl

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.
Files changed (83) hide show
  1. agent_chief-0.3.1.dist-info/METADATA +324 -0
  2. agent_chief-0.3.1.dist-info/RECORD +83 -0
  3. agent_chief-0.3.1.dist-info/WHEEL +4 -0
  4. agent_chief-0.3.1.dist-info/entry_points.txt +2 -0
  5. agent_chief-0.3.1.dist-info/licenses/LICENSE +21 -0
  6. cli/__init__.py +0 -0
  7. cli/connect.py +142 -0
  8. cli/init.py +201 -0
  9. cli/main.py +435 -0
  10. cli/runtime.py +262 -0
  11. context/__init__.py +0 -0
  12. context/infer.py +110 -0
  13. context/providers/__init__.py +0 -0
  14. context/providers/calendar.py +101 -0
  15. context/providers/clock.py +28 -0
  16. core/__init__.py +0 -0
  17. core/brain.py +403 -0
  18. core/config.py +36 -0
  19. core/digest.py +107 -0
  20. core/embedding.py +77 -0
  21. core/learner.py +246 -0
  22. core/policy.py +109 -0
  23. core/schema.py +96 -0
  24. core/scorer.py +256 -0
  25. core/state.py +292 -0
  26. delivery/__init__.py +0 -0
  27. delivery/base.py +69 -0
  28. delivery/desktop.py +31 -0
  29. delivery/telegram.py +90 -0
  30. delivery/terminal.py +17 -0
  31. demo/__init__.py +0 -0
  32. demo/day_of_engineer.json +642 -0
  33. demo/runner.py +255 -0
  34. dispatch/__init__.py +0 -0
  35. dispatch/acceptance.py +88 -0
  36. dispatch/executor.py +133 -0
  37. eval/__init__.py +6 -0
  38. eval/generate_golden.py +269 -0
  39. eval/golden.jsonl +201 -0
  40. eval/learning.py +185 -0
  41. eval/reports/.gitkeep +0 -0
  42. eval/reports/learning.md +34 -0
  43. eval/runner.py +222 -0
  44. ingest/__init__.py +0 -0
  45. ingest/connectors/__init__.py +38 -0
  46. ingest/connectors/composio.py +106 -0
  47. ingest/http.py +219 -0
  48. ingest/mcp_server.py +65 -0
  49. ingest/normalize.py +55 -0
  50. ingest/sources/__init__.py +0 -0
  51. ingest/sources/base.py +51 -0
  52. ingest/sources/github.py +43 -0
  53. ingest/sources/rss.py +52 -0
  54. judge/__init__.py +0 -0
  55. judge/anthropic.py +35 -0
  56. judge/base.py +150 -0
  57. judge/deepseek.py +8 -0
  58. judge/factory.py +50 -0
  59. judge/fixtures.py +26 -0
  60. judge/ollama.py +27 -0
  61. judge/openai.py +31 -0
  62. judge/pricing.py +53 -0
  63. judge/prompts.py +97 -0
  64. judge/templates/v1/context.j2 +3 -0
  65. judge/templates/v1/distill.j2 +4 -0
  66. judge/templates/v1/retry.j2 +1 -0
  67. judge/templates/v1/system.j2 +12 -0
  68. judge/templates/v1/topic_infer.j2 +2 -0
  69. judge/templates/v1/user.j2 +2 -0
  70. judge/templates/v1/verify.j2 +4 -0
  71. memory/__init__.py +0 -0
  72. memory/associate.py +33 -0
  73. memory/store.py +62 -0
  74. policy/POLICY.template.md +9 -0
  75. policy/USER.template.md +3 -0
  76. policy/__init__.py +0 -0
  77. skills/__init__.py +0 -0
  78. skills/claude-code/SKILL.md +56 -0
  79. skills/openclaw/SKILL.md +56 -0
  80. skills/openclaw/__init__.py +0 -0
  81. skills/openclaw/hook.py +74 -0
  82. ui/__init__.py +6 -0
  83. ui/console.html +191 -0
@@ -0,0 +1,324 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-chief
3
+ Version: 0.3.1
4
+ Summary: Chief — the chief of staff for your agents and information sources
5
+ Project-URL: Homepage, https://github.com/SmileLikeYe/agent-chief
6
+ Project-URL: Repository, https://github.com/SmileLikeYe/agent-chief
7
+ Project-URL: Issues, https://github.com/SmileLikeYe/agent-chief/issues
8
+ Project-URL: Changelog, https://github.com/SmileLikeYe/agent-chief/releases
9
+ Author: SmileLikeYe
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: agents,attention,chief-of-staff,interruption-management,llm,local-first,mcp,notifications,triage
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Communications
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: aiosqlite>=0.22.1
24
+ Requires-Dist: fastapi>=0.139.0
25
+ Requires-Dist: fastmcp>=3.4.2
26
+ Requires-Dist: httpx>=0.28.1
27
+ Requires-Dist: jinja2>=3.1
28
+ Requires-Dist: plyer>=2.1.0
29
+ Requires-Dist: pydantic>=2.7
30
+ Requires-Dist: questionary>=2.1.1
31
+ Requires-Dist: rich>=13.7
32
+ Requires-Dist: typer>=0.12
33
+ Requires-Dist: uvicorn>=0.50.0
34
+ Provides-Extra: embeddings
35
+ Requires-Dist: sentence-transformers>=3.0; extra == 'embeddings'
36
+ Description-Content-Type: text/markdown
37
+
38
+ <div align="center">
39
+
40
+ <img src="docs/assets/logo.svg" alt="Chief" width="640"/>
41
+
42
+ **Your agents don't need more power. They need a chief of staff.**
43
+
44
+ [![CI](https://github.com/SmileLikeYe/agent-chief/actions/workflows/ci.yml/badge.svg)](https://github.com/SmileLikeYe/agent-chief/actions/workflows/ci.yml)
45
+ [![Release](https://img.shields.io/github/v/release/SmileLikeYe/agent-chief?color=6366f1)](https://github.com/SmileLikeYe/agent-chief/releases)
46
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)](pyproject.toml)
47
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
48
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
49
+ [![Local First](https://img.shields.io/badge/local--first-no%20cloud%2C%20no%20telemetry-8b5cf6)](#privacy)
50
+
51
+ [Quickstart](#-60-second-quickstart) · [How it works](#-how-it-decides) ·
52
+ [Connect your agent](#-connect-your-agent-3-lines) · [Docs](docs/) ·
53
+ [简体中文](README.zh-CN.md)
54
+
55
+ </div>
56
+
57
+ ---
58
+
59
+ <!-- metrics:start -->
60
+ **24 events in → 1 interruption** (96% intercepted: 14 blocked outright, the rest batched, dispatched, or remembered)
61
+ · only **75% of events ever reach the LLM** — the noisiest 25% dies on hard rules in microseconds, for free
62
+ · stable-prefix prompts: **70% of judge input tokens cache-hit** (system + context blocks)
63
+ · projected judgment cost **$0.104 per 1,000 events** (DeepSeek list prices, cache-aware)
64
+
65
+ *(every number regenerates from the deterministic demo replay: `make readme-metrics`)*
66
+ <!-- metrics:end -->
67
+
68
+ Chief sits between you and everything that wants your attention — agents,
69
+ heartbeats, CI, RSS, watchers. Everything flows into it; it thinks for itself;
70
+ then it does exactly one of three things:
71
+
72
+ 1. 🔔 **Interrupt** you — only when worth it, at the right moment, *arriving with a plan*.
73
+ 2. 🤖 **Dispatch** work to your agents — and verify the result before reporting ("done" is a claim, not a proof).
74
+ 3. 📚 **Curate** into memory — facts and intents not worth mentioning now, waiting to be connected later.
75
+
76
+ <div align="center">
77
+
78
+ ![demo](docs/assets/demo.gif)
79
+
80
+ *A day of an engineer's life: 24 events in → 14 blocked · 6 batched · 3 handled · **interrupted exactly once**.*
81
+
82
+ </div>
83
+
84
+ ## ✨ Highlights
85
+
86
+ | | |
87
+ |---|---|
88
+ | 🧠 **Three-stage worthiness engine** | Hard rules (µs) → similarity classifier (ms) → LLM judge (only when needed). Cheap first, smart last. |
89
+ | 🎭 **Scene-aware timing** | Sleeping / deep work / meeting / commute — per-scene interrupt thresholds. The *same* event rings at your desk and waits in a digest at 2 AM. |
90
+ | 🕶️ **Shadow mode** | For its first 7 days Chief never actually interrupts — it shows you what it *would* have done, and earns the right to ring. |
91
+ | 📝 **Explainable, editable policy** | Everything it learns distills nightly into a human-readable `POLICY.md`. Your edits win, effective immediately. |
92
+ | ✅ **Verified dispatch** | Agents report "done"; Chief checks. Acceptance command or LLM second opinion — fails closed. |
93
+ | 🔌 **Protocol, not pipes** | One `POST /v1/events` (or MCP `propose`) connects anything in minutes. |
94
+ | 🔒 **Local-first** | One SQLite file + markdown under `~/.chief`. No cloud, no telemetry, no web UI. |
95
+
96
+ ## ⚡ 60-second quickstart
97
+
98
+ ```bash
99
+ uvx agent-chief demo # zero keys, zero config, fully offline
100
+ ```
101
+
102
+ You'll watch a day of an engineer's life replay: 24 events in → 14 blocked ·
103
+ 6 batched · 3 handled (all verified) · **interrupted exactly once**.
104
+
105
+ Ready for real sources?
106
+
107
+ ```bash
108
+ uvx agent-chief init # 60s wizard, every question skippable
109
+ chief run # the resident brain
110
+ ```
111
+
112
+ ## 🔕 Kill the "all clear" reports
113
+
114
+ If you run heartbeat agents, you know the ritual: *"All clear, nothing to
115
+ report."* Every few hours. Forever. Each one costs a glance, and the glances
116
+ add up until you stop reading — including the one that mattered.
117
+
118
+ Chief drops zero-information reports on the floor (regex **and** embedding
119
+ similarity against a canned empty-report set, both required — a security scan
120
+ that *mentions* "all clear" still gets through). The demo opens and closes with
121
+ this, because it's the single most requested feature among heartbeat users.
122
+
123
+ ## 🔍 Explainable judgment, every single time
124
+
125
+ No decision is a black box. Every Decision carries its **reason, five scored
126
+ components, the rules it matched, and what it cost** — and `chief trace`
127
+ replays the whole chain after the fact:
128
+
129
+ ```console
130
+ $ chief trace evt_20260706_1040_ab12
131
+ CI failed on main: test_auth_flow broken by PR #482 dev.ci · github-actions
132
+ route dispatch at stage 3 in scene deep_work (confidence 0.85)
133
+ score 0.87 urgency=0.90 relevance=0.90 actionability=0.85 novelty=0.80 confidence=0.90
134
+ ┌────────────┬───────┬──────────────────────┐
135
+ │ stage │ ms │ note │
136
+ │ stage1 │ 0.1 │ no hard rule fired │
137
+ │ associate │ 1.2 │ 0 memory hits │
138
+ │ judge │ 812.4 │ backend deepseek │
139
+ │ route │ 0.3 │ routed dispatch │
140
+ └────────────┴───────┴──────────────────────┘
141
+ tokens: 1104 in (704 cached) / 96 out · prompt v1 · cost $0.000301
142
+ ```
143
+
144
+ Prompts are versioned templates (`judge/templates/v1/`), the version is
145
+ stamped into every decision, and **no prompt change merges without an eval
146
+ diff** on the 200-case golden set (`chief eval --compare v1 v2`). If the LLM
147
+ backend dies, Chief degrades to rules-only conservative routing — never
148
+ interrupts while blind — and heals itself when the backend returns.
149
+
150
+ ## 📈 It learns your preferences — and proves it
151
+
152
+ The 👍/👎 you give ("worth my attention" / "don't bother me") is a reward
153
+ signal; the per-topic EMA weights are the policy; feedback trains them. Chief
154
+ ships an eval that measures the loop closing — a simulated user with hidden
155
+ preferences, corrected only by the ±1 signal:
156
+
157
+ ```console
158
+ $ chief eval --learning
159
+ Routing agreement: 0% → 100% (+100%) · converged in 2 rounds
160
+ r 0 | | 0%
161
+ r 1 |█████████████████ | 86%
162
+ r 2 |████████████████████| 100%
163
+ ```
164
+
165
+ No labels, no gradient, no black box (SPEC §13: explainable by construction).
166
+ It corrects the *borderline* calls — the ones that actually need judgment,
167
+ since stage-1 rules already handle the obvious. Watch the learned per-topic
168
+ lean in the console's **Learning** tab, or reproduce the curve with
169
+ `chief eval --learning`.
170
+
171
+ > 📝 The engineering story behind Chief — the funnel, per-model cost accounting,
172
+ > and the falsifiable learning loop — is written up in
173
+ > **[docs/blog](docs/blog/heartbeat-agents-are-training-you-to-ignore-them.md)**.
174
+
175
+ ## 🕶️ Shadow mode: trust is earned
176
+
177
+ For its first 7 days (or 50 graded samples), Chief **never actually interrupts
178
+ you**. Would-be interrupts land in the digest annotated
179
+ `⚡ would have: interrupted you (score 0.87, scene deep_work)` with ✓/✗ grading
180
+ buttons. You watch it think, grade its calls, and only when it graduates does it
181
+ earn the right to ring. Graduation comes with a **Tact Report** (`chief report`).
182
+
183
+ ## 🧠 How it decides
184
+
185
+ Two axes, never one: **content worthiness × scene tolerance**.
186
+
187
+ ```mermaid
188
+ flowchart LR
189
+ subgraph sources [Anything]
190
+ A1[Agents] & A2[CI / GitHub] & A3[RSS / watchers] & A4[Heartbeats]
191
+ end
192
+ sources -->|"POST /v1/events · MCP propose"| N[Normalize<br/>+ topic inference]
193
+ N --> S1{"Stage 1<br/>hard rules (µs)"}
194
+ S1 -->|survives| S2{"Stage 2<br/>similarity (ms)"}
195
+ S2 -->|unfamiliar| M[Associate<br/>memory] --> S3{"Stage 3<br/>LLM judge"}
196
+ S3 --> R["score × scene<br/>threshold"]
197
+ S2 -->|familiar| R
198
+ R --> I[🔔 interrupt]
199
+ R --> D[📰 digest]
200
+ R --> P[🤖 dispatch → verify] --> I
201
+ R --> C[📚 curate]
202
+ R --> X[🗑 drop]
203
+ SC["Scene engine<br/>clock · calendar · focus"] -.-> R
204
+ L["Learner<br/>EMA · nightly distill"] -.-> S1 & S2 & R
205
+ ```
206
+
207
+ - A three-stage worthiness engine: hard rules (µs) → similarity classifier (ms)
208
+ → LLM judge (pluggable: **Ollama local**, DeepSeek, Anthropic, OpenAI).
209
+ - A scene engine (clock, calendar, focus, lock state — pluggable providers)
210
+ with per-scene interrupt thresholds; low-confidence scenes degrade toward silence.
211
+ - Every learned preference distills nightly into a **human-readable
212
+ [`POLICY.md`](policy/POLICY.template.md)** you can read and edit; your edits
213
+ win, effective immediately.
214
+
215
+ Deep dive: **[docs/architecture.md](docs/architecture.md)**.
216
+
217
+ ## 🔌 Connect your agent (3 lines)
218
+
219
+ ```bash
220
+ curl -X POST http://localhost:8787/v1/events \
221
+ -H "Authorization: Bearer $CHIEF_TOKEN" -H "Content-Type: application/json" \
222
+ -d '{"source":"my-agent","topic":"dev.ci","summary":"CI failed on main"}'
223
+ ```
224
+
225
+ Chief answers with a Decision — route, score, and a one-line reason. MCP agents
226
+ use the `propose` tool instead, and `chief lite` gives zero-daemon judgment for
227
+ one-shot callers. Full contract: **[docs/protocol.md](docs/protocol.md)**
228
+ · runnable samples: **[examples/](examples/)**.
229
+
230
+ ## 🖥️ The console — see it think, correct it in one click
231
+
232
+ `chief ui` (or the resident `chief run`) serves a local console at
233
+ `http://127.0.0.1:8787/ui` — single user, token-gated, no cloud:
234
+
235
+ - **Today** — digest queue, interrupts, LLM share and spend at a glance
236
+ - **History** — every decision with its reason, score, cost; searchable
237
+ - **Rules** — edit `POLICY.md` in place; your edits win, live immediately
238
+ - **Tasks** — approve/reject dispatched work (verification still applies)
239
+ - **👍/👎 on every decision** — "worth my attention" / "don't bother me";
240
+ Chief's learner weighs these above every inferred signal
241
+
242
+ <!-- console screenshot: docs/assets/console.png (make console-shot) -->
243
+
244
+ ## 🔌 Out-of-the-box sources
245
+
246
+ ```bash
247
+ chief connect composio --secret whsec_… # GitHub, Gmail, Slack, 500+ apps
248
+ chief connect github # gh notifications poller
249
+ chief connect rss --url https://hnrss.org/frontpage
250
+ chief sources # see what's wired up
251
+ ```
252
+
253
+ **[Composio](https://composio.dev)** is the flagship connector: point its
254
+ trigger webhooks at `/v1/connectors/composio` (HMAC-verified) and every
255
+ connected app flows through Chief's judgment. The connector registry leaves
256
+ documented slots for zapier/n8n-style automations and MCP-push agents — one
257
+ adapter module each.
258
+
259
+ ## 🧩 Skills: make your agents good citizens
260
+
261
+ Drop-in skills teach agent hosts to route through Chief instead of pinging you:
262
+
263
+ - **[skills/claude-code/](skills/claude-code/SKILL.md)** — Claude Code agents
264
+ propose via `chief lite` (no daemon needed) and obey the route.
265
+ - **[skills/openclaw/](skills/openclaw/SKILL.md)** — OpenClaw agents propose
266
+ via MCP; interrupts ride OpenClaw's own channels back to you.
267
+
268
+ Both encode the same iron rule: *the agent MUST NOT message the user directly.*
269
+
270
+ ## 🔗 Integrations: Chief as the judgment layer
271
+
272
+ Noisy upstream bots in, one accountable judgment layer in the middle:
273
+ **[examples/integrations/](examples/integrations/)** ships a runnable
274
+ stock-analysis-bot feed (watch five "all good" reports die and three real
275
+ findings survive) and a generic webhook template any agent can copy — both
276
+ fully offline.
277
+
278
+ ## 📁 Project layout
279
+
280
+ ```
281
+ core/ brain loop, 3-stage scorer, learner, digest, SQLite state
282
+ context/ scene engine + providers (clock, calendar)
283
+ judge/ pluggable LLM judges: ollama · deepseek · anthropic · openai · fixtures
284
+ ingest/ webhook (FastAPI), MCP server, GitHub/RSS pollers, normalizer
285
+ dispatch/ executors (claude-code, whitelisted shell) + verification
286
+ delivery/ terminal · desktop · telegram (feedback buttons)
287
+ memory/ curate, associate, expire → archive
288
+ demo/ the offline day-of-engineer replay fixture + runner
289
+ skills/ OpenClaw integration (propose-and-obey)
290
+ ```
291
+
292
+ ## 🧪 Quality
293
+
294
+ 218 tests run fully offline — no keys, no network. The demo's routing table is
295
+ a full-table regression: all 24 events' routes are pinned in CI forever.
296
+
297
+ ```bash
298
+ make test lint # pytest + ruff
299
+ make demo # the offline replay
300
+ make release-check # build the wheel, run the demo from it via uvx
301
+ ```
302
+
303
+ ## 🗺 Roadmap & contributing
304
+
305
+ See [ROADMAP.md](ROADMAP.md) for what's deliberately out of v1 (web UI, cloud
306
+ sync, Slack/Discord delivery, …) and [CONTRIBUTING.md](CONTRIBUTING.md) to get
307
+ hacking — the dev loop is `uv sync --dev && make test`. Design decisions live
308
+ as one-line ADRs in [docs/decisions.md](docs/decisions.md);
309
+ [SPEC.md](SPEC.md) is the full implementation spec the project was built from,
310
+ step by step ([PROGRESS.md](PROGRESS.md)).
311
+
312
+ ## 🔒 Privacy
313
+
314
+ Local-first by construction: one SQLite file + markdown under `~/.chief`.
315
+ No cloud, no telemetry, no web UI, no arbitrary shell execution. The only
316
+ network calls are the ones you configure (your LLM backend, your Telegram bot).
317
+
318
+ ## ⭐ Star history
319
+
320
+ [![Star History Chart](https://api.star-history.com/svg?repos=SmileLikeYe/agent-chief&type=Date)](https://star-history.com/#SmileLikeYe/agent-chief&Date)
321
+
322
+ ## 📄 License
323
+
324
+ [MIT](LICENSE)
@@ -0,0 +1,83 @@
1
+ cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ cli/connect.py,sha256=hkAdy9TJWzFr53cWu8rvAnhnTxOjEP_lrZYi9sWBQBk,5278
3
+ cli/init.py,sha256=2rDr4001gY3VQfQY-XUHMFM_TWj4LobY9sbnaQsD7_U,6176
4
+ cli/main.py,sha256=pNIrhXaqRyRcS7IkzD_FSdEdg2EyJklo7wcD0uumCII,14557
5
+ cli/runtime.py,sha256=M3kcvhRb78bWyPbf1771J-1EaZCWcJ75omq_ISXxf_Q,9606
6
+ context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ context/infer.py,sha256=nN5eGffD7TVg0cfmgsR-1cMAY9BJC2YmMAIw34Ov5Fs,3915
8
+ context/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ context/providers/calendar.py,sha256=RncSzwbJjfmm1yWcnvhKQPNDmHE3gVe4l2ystISdnb4,3098
10
+ context/providers/clock.py,sha256=stB0LdmXgVGB44cVQ97Zn275bqSzGxDxZc6B0suREeQ,748
11
+ core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ core/brain.py,sha256=addobzmXF24OUxor8wtg7VPHM7v4aKh_OYTgbKq0f34,16081
13
+ core/config.py,sha256=-vw3XBJf4aK-NsF3aitTErGsbe-K3gMviCgL45HK908,740
14
+ core/digest.py,sha256=3i61wOyMoxjMngUmXe6ytXRgG3Re0v9gzA9a4T4Hr5Y,3814
15
+ core/embedding.py,sha256=D-697p2NQy4pqobKq-EZqRvtU8-3fr3nnsgD6TXIY2Y,2419
16
+ core/learner.py,sha256=rCF_fxNoLNg3mkXgpEtbQVR2Bfu7Vl9XcuIDl5WYaFE,9673
17
+ core/policy.py,sha256=4P9jC46L-sWkP2GJDB0NLTL5mSrt0KJv8RRtTHXufho,3907
18
+ core/schema.py,sha256=1nnztlsSWMUjckvtl0SaSHvl49ddy0C1mAoH7Qebfk8,2614
19
+ core/scorer.py,sha256=4e7h91SB6YXYtIK8fl_M_uE4oAOTh3Y5z6ihnEtb1CE,9080
20
+ core/state.py,sha256=O9HhLbncSN26647S9tMMmu-L1skL_cfzAOvPjZAuapk,12061
21
+ delivery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ delivery/base.py,sha256=IRgjY4c4wgGdiYysYnqHBoVCSTXG_Sj62LNg3ZdcFCE,2239
23
+ delivery/desktop.py,sha256=8dWHg4TtvAy64Zbae2-LjoOExv48i2cITUYAqVo7Cio,1004
24
+ delivery/telegram.py,sha256=-uLrHBxssXsLKdifEaxY1liEF1PKz1Z_olZ14sMSB5E,3543
25
+ delivery/terminal.py,sha256=2gdEWCvfRicr-dTCJGaMU6AJQaB64UiDuxhMCw1W_yg,552
26
+ demo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ demo/day_of_engineer.json,sha256=VA10oRVPZsjYC5ctlTXCrF72RB1lBSjp5z4HOuqWsxM,17597
28
+ demo/runner.py,sha256=ofUyjoYhfMpOluKswIvE0HyBPWwAaYaOB36XK7YtmVk,9277
29
+ dispatch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ dispatch/acceptance.py,sha256=lqNprHWMlP5_RxGVQctQYz00HvU8KuyjEKBAqoQYPrY,2945
31
+ dispatch/executor.py,sha256=0k2YhiiuJRwB-iXfLeDYXIcKC456QFvOm1rf8UL-Fw0,4655
32
+ eval/__init__.py,sha256=H7YCzkOuxGtWgN6XfSre21GOqiiAfbHcNQK_LUY5Q_c,266
33
+ eval/generate_golden.py,sha256=dZoJpDGmfg7CWqcHdJK9EdDJGfNEegx0SNieg2Dwt9g,10979
34
+ eval/golden.jsonl,sha256=wnoZj7vSmDZ96N8D3BzyG6oQJOg3oiTy-zdsciKh59E,105755
35
+ eval/learning.py,sha256=OJOHvZiuC2B5-9vURS8WSaA-J5-zxP3EjypzMP6yiS0,8074
36
+ eval/runner.py,sha256=YRaExD1u8OJ8DWo6NMhGuso7XUuiPRJFtCOptF9jaAA,7819
37
+ eval/reports/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ eval/reports/learning.md,sha256=gktqJcdcO_ex_HetQDEB3rxR1OT2Hq3m4dnkt81j3Fk,1525
39
+ ingest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ ingest/http.py,sha256=CvFunMnzfduxgKklV06DWeUkF-nsfmMKlzi1nXVJDLo,9096
41
+ ingest/mcp_server.py,sha256=umvHjyNdgJ0e5Nz2Xaai6jZD8y3KMgnvgwee2WpClzA,2537
42
+ ingest/normalize.py,sha256=HJ2LztmxOE8t5qTR_bPenShvs2FxZQsvS0KX36e_bHc,2023
43
+ ingest/connectors/__init__.py,sha256=n-BXMadM-R8Zeg_5TqwMXsMTCYdmzuJypkbJPjR6Pvo,2033
44
+ ingest/connectors/composio.py,sha256=yvM1hrOAubJYMFvFFvt4tWrPjl1bBXCskzcS18Mgduw,3884
45
+ ingest/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ ingest/sources/base.py,sha256=IOTFStzoNzJ12oEr0FMKX7zOUXh4RH-eNo4deiFNaRM,1737
47
+ ingest/sources/github.py,sha256=iFWpEHQtIf4RB7kqTBqZISHmaTb8L2qshKyemeZoy2M,1556
48
+ ingest/sources/rss.py,sha256=54a5FGBmZvY3ESFO46ZmeB16C3pgkFP9NvqN9hBg_lM,1790
49
+ judge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
+ judge/anthropic.py,sha256=dKw4jJPBGugrEQxCovr1qK5KtVW9IYn1gvA1yZzpqNE,1364
51
+ judge/base.py,sha256=w2HPBXpwf_KQGXgnwSxUWdVHlmbiR9R9aBEHqQEi_yU,5352
52
+ judge/deepseek.py,sha256=CUOvwpsndhBHTNscDu94UL0v5WhJspVcoCXlnid0lNQ,223
53
+ judge/factory.py,sha256=Py7zeRGxLblrfyH1Wj7wVl20y94Ml5OO9hwY5tonLOU,1696
54
+ judge/fixtures.py,sha256=3VmwX42vBXnsvSzTzATI-cprmw4_0hGVeNxTKpNlwes,851
55
+ judge/ollama.py,sha256=cqITQsShPKYOSXuqz4_Y67I-wNyxJuul_0U8CN13YbA,874
56
+ judge/openai.py,sha256=I6yrr_UAJ_5-N_eGgMjdmzgfaqDzzrwErSKwxy02Z6w,1250
57
+ judge/pricing.py,sha256=8h1PBMtDdHRxYqOYT0EtNT-ejBiNPF8QVG2zkik17Mk,2568
58
+ judge/prompts.py,sha256=wZr3temoIgU862DVXs4FGvCBu6LPZVu1-4PhwbhcavQ,3401
59
+ judge/templates/v1/context.j2,sha256=RzT49TXfHyL9hniMOSZuAGFOh5L1fYSqkhF3tcRaVfQ,131
60
+ judge/templates/v1/distill.j2,sha256=m6HXezlORQ8uFBZC6AOYt8JDlZQtjmqLl8Y4uOzzPG0,232
61
+ judge/templates/v1/retry.j2,sha256=YfoQjk1J0Nw_6kRrPf6dbIQAI2RuiPH-UJet0IJ2Cek,125
62
+ judge/templates/v1/system.j2,sha256=O2OQ6r8a5-LyF3SP3XG0qpZKz3iaju5F83pkzVqzZAY,777
63
+ judge/templates/v1/topic_infer.j2,sha256=NMgkT3lIyWTdvIeHqh8eWcXlhjs9BbmIGBHC9UyMCZs,164
64
+ judge/templates/v1/user.j2,sha256=LtwCQQkerPYRW3JlhJdlGZHSc-CqE33dBEDtPYLXDJo,97
65
+ judge/templates/v1/verify.j2,sha256=0SizlJItqfJ3YCyfpiAr8N-B7-qNvcCt2vqRxhVABC8,204
66
+ memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ memory/associate.py,sha256=GfRiDt0lWps88Fx5qfmeDm4hA2QqS30q2DRzQIthX_g,956
68
+ memory/store.py,sha256=9DDFUgeoRpx2bL5YpyjjlZwk4sjTqG4SQeewYVeWjVY,2185
69
+ policy/POLICY.template.md,sha256=4LfYQr5hLuArNyXnjD-j8XlUEh8mg6wtU8St-f5YHkM,130
70
+ policy/USER.template.md,sha256=BPhdZJ2STQZT-GFdxI555UqgsxrriqCgtqJ_ceXUO4E,74
71
+ policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ skills/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ skills/claude-code/SKILL.md,sha256=S691-I-FG3zovRyK8KyHcEGPeXzhhJovWpPPrTW5O5w,2296
74
+ skills/openclaw/SKILL.md,sha256=tvXm2mlXiXKFq3VIzbg89rCL0NkWElw1HvaJabhP6w4,2269
75
+ skills/openclaw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
+ skills/openclaw/hook.py,sha256=6rZW_eP6Jl6Ai61148iW8WM7k0lgyZ49XriVOFFnRiU,2449
77
+ ui/__init__.py,sha256=FOAADGRiLgpvtK8nWAA9oQNj1pqXUppDVefd_oiA9Mk,238
78
+ ui/console.html,sha256=KV7q4zihsIfYv_C3lYQiusEZ9f784iDctOfSov9Z4ck,10454
79
+ agent_chief-0.3.1.dist-info/METADATA,sha256=NdDmscurj5D25RFZsrzJ8pRicyu4aDTraMwPrwVBY00,14867
80
+ agent_chief-0.3.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
81
+ agent_chief-0.3.1.dist-info/entry_points.txt,sha256=RF6w2blJQtBS8tYrU9tn6ozRWigW8xMW6Ml4SU0Rpws,39
82
+ agent_chief-0.3.1.dist-info/licenses/LICENSE,sha256=gAWc9EgnR4F1P5UoitqjY98lQyexagPVTKo3dViksvQ,1068
83
+ agent_chief-0.3.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ chief = cli.main:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SmileLikeYe
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.
cli/__init__.py ADDED
File without changes
cli/connect.py ADDED
@@ -0,0 +1,142 @@
1
+ """SPEC v3.2 Step 35: one-click source connection.
2
+
3
+ `chief connect <source>` edits ~/.chief/config.toml surgically (everything
4
+ else preserved) and prints the exact next actions. Config writing stays
5
+ dependency-free: our schema is flat sections (plus one nested `connectors.*`
6
+ level) of strings/bools/ints/string-lists, so a tiny serializer suffices.
7
+ """
8
+
9
+ import base64
10
+ import hashlib
11
+ import hmac
12
+ import json
13
+ import tomllib
14
+
15
+ from rich.console import Console
16
+
17
+ from core.config import chief_home, config_path, load_config
18
+
19
+ console = Console(soft_wrap=True, highlight=False) # keep URLs copy-pastable
20
+
21
+
22
+ class UnsupportedConfig(Exception):
23
+ """The existing config uses TOML our tiny serializer can't round-trip."""
24
+
25
+
26
+ def _scalar(v) -> str:
27
+ if isinstance(v, bool):
28
+ return "true" if v else "false"
29
+ if isinstance(v, int | float):
30
+ return str(v)
31
+ if isinstance(v, str):
32
+ return json.dumps(v)
33
+ if isinstance(v, list) and all(isinstance(i, str | int | float | bool) for i in v):
34
+ return "[" + ", ".join(json.dumps(i) for i in v) + "]"
35
+ raise UnsupportedConfig(f"cannot serialize value {v!r}")
36
+
37
+
38
+ def _serialize(cfg: dict) -> str:
39
+ # our schema is flat sections plus one connectors.* level; anything deeper
40
+ # (or a root-level scalar, or a list of tables) we refuse rather than corrupt
41
+ lines: list[str] = []
42
+ for section, body in cfg.items():
43
+ if not isinstance(body, dict):
44
+ raise UnsupportedConfig(f"root-level key {section!r} is not a section")
45
+ scalars = {k: v for k, v in body.items() if not isinstance(v, dict)}
46
+ tables = {k: v for k, v in body.items() if isinstance(v, dict)}
47
+ if scalars or not tables:
48
+ lines.append(f"[{section}]")
49
+ lines += [f"{k} = {_scalar(v)}" for k, v in scalars.items()]
50
+ lines.append("")
51
+ for sub, subbody in tables.items():
52
+ if any(isinstance(v, dict) for v in subbody.values()):
53
+ raise UnsupportedConfig(f"[{section}.{sub}] nests too deep")
54
+ lines.append(f"[{section}.{sub}]")
55
+ lines += [f"{k} = {_scalar(v)}" for k, v in subbody.items()]
56
+ lines.append("")
57
+ return "\n".join(lines)
58
+
59
+
60
+ def _update_config(mutate) -> dict:
61
+ path = config_path()
62
+ raw = path.read_text(encoding="utf-8") if path.exists() else ""
63
+ cfg = tomllib.loads(raw) if raw else {}
64
+ mutate(cfg)
65
+ try:
66
+ rendered = _serialize(cfg)
67
+ except UnsupportedConfig as exc:
68
+ raise SystemExit(
69
+ f"chief connect can't safely rewrite {path} ({exc}).\n"
70
+ f"Edit the config by hand — add the section shown in the docs — and re-run."
71
+ ) from exc
72
+ chief_home().mkdir(parents=True, exist_ok=True)
73
+ if raw:
74
+ path.with_suffix(".toml.bak").write_text(raw, encoding="utf-8") # keep a backup
75
+ path.write_text(rendered, encoding="utf-8")
76
+ return cfg
77
+
78
+
79
+ def connect_composio(secret: str) -> None:
80
+ _update_config(
81
+ lambda cfg: cfg.setdefault("connectors", {}).setdefault("composio", {}).update(
82
+ {"webhook_secret": secret}
83
+ )
84
+ )
85
+ port = load_config().get("ingest", {}).get("webhook_port", 8787)
86
+
87
+ # prove the secret + verifier agree before the user leaves the terminal
88
+ from ingest.connectors.composio import verify_signature
89
+
90
+ body = json.dumps({"probe": True}).encode()
91
+ mac = base64.b64encode(
92
+ hmac.new(secret.encode(), b"wh_probe.0." + body, hashlib.sha256).digest()
93
+ ).decode()
94
+ assert verify_signature(secret, "wh_probe", "0", body, f"v1,{mac}")
95
+ console.print("✅ secret stored · signed sample verified locally")
96
+ console.print(
97
+ f"\nNext, in the Composio dashboard (composio.dev):\n"
98
+ f" 1. connect the apps you want (GitHub, Gmail, Slack, …)\n"
99
+ f" 2. enable their triggers\n"
100
+ f" 3. set the webhook subscription URL to\n"
101
+ f" [bold]https://<your-tunnel>/v1/connectors/composio[/bold]\n"
102
+ f" (local port {port}; use cloudflared/ngrok/tailscale funnel)\n"
103
+ f" 4. fire a test trigger and watch it in chief ui → History"
104
+ )
105
+
106
+
107
+ def connect_github() -> None:
108
+ import shutil
109
+
110
+ _update_config(lambda cfg: cfg.setdefault("ingest", {}).update({"github": True}))
111
+ if shutil.which("gh"):
112
+ console.print("✅ github notifications poller enabled (5 min via `gh api`)")
113
+ else:
114
+ console.print(
115
+ "✅ enabled — but [yellow]`gh` CLI not found[/yellow]: "
116
+ "install it and run `gh auth login` before `chief run`"
117
+ )
118
+
119
+
120
+ def connect_rss(url: str) -> None:
121
+ def mutate(cfg):
122
+ urls = cfg.setdefault("ingest", {}).setdefault("rss_urls", [])
123
+ if url not in urls:
124
+ urls.append(url)
125
+
126
+ _update_config(mutate)
127
+ console.print(f"✅ feed added — polled every 30 min: {url}")
128
+
129
+
130
+ def show_sources() -> None:
131
+ from rich.table import Table
132
+
133
+ from ingest.connectors import connector_status
134
+
135
+ table = Table(title="sources")
136
+ table.add_column("connector")
137
+ table.add_column("status")
138
+ table.add_column("")
139
+ for s in connector_status():
140
+ status = "[green]connected[/green]" if s["connected"] else "[dim]not configured[/dim]"
141
+ table.add_row(s["name"], status, s["detail"])
142
+ console.print(table)