agent-chief 0.3.1__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.
Files changed (168) hide show
  1. agent_chief-0.3.1/.github/ISSUE_TEMPLATE/bug_report.yml +33 -0
  2. agent_chief-0.3.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. agent_chief-0.3.1/.github/ISSUE_TEMPLATE/feature_request.yml +23 -0
  4. agent_chief-0.3.1/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  5. agent_chief-0.3.1/.github/workflows/ci.yml +16 -0
  6. agent_chief-0.3.1/.github/workflows/publish.yml +39 -0
  7. agent_chief-0.3.1/.github/workflows/release.yml +44 -0
  8. agent_chief-0.3.1/.github/workflows/sync-release-notes.yml +48 -0
  9. agent_chief-0.3.1/.gitignore +8 -0
  10. agent_chief-0.3.1/.python-version +1 -0
  11. agent_chief-0.3.1/BLOCKERS.md +40 -0
  12. agent_chief-0.3.1/CHANGELOG.md +120 -0
  13. agent_chief-0.3.1/CLAUDE.md +71 -0
  14. agent_chief-0.3.1/CODE_OF_CONDUCT.md +39 -0
  15. agent_chief-0.3.1/CONTRIBUTING.md +67 -0
  16. agent_chief-0.3.1/LICENSE +21 -0
  17. agent_chief-0.3.1/Makefile +29 -0
  18. agent_chief-0.3.1/PKG-INFO +324 -0
  19. agent_chief-0.3.1/PROGRESS.md +86 -0
  20. agent_chief-0.3.1/README.md +287 -0
  21. agent_chief-0.3.1/README.zh-CN.md +185 -0
  22. agent_chief-0.3.1/ROADMAP.md +8 -0
  23. agent_chief-0.3.1/SECURITY.md +30 -0
  24. agent_chief-0.3.1/SPEC.md +583 -0
  25. agent_chief-0.3.1/cli/__init__.py +0 -0
  26. agent_chief-0.3.1/cli/connect.py +142 -0
  27. agent_chief-0.3.1/cli/init.py +201 -0
  28. agent_chief-0.3.1/cli/main.py +435 -0
  29. agent_chief-0.3.1/cli/runtime.py +262 -0
  30. agent_chief-0.3.1/context/__init__.py +0 -0
  31. agent_chief-0.3.1/context/infer.py +110 -0
  32. agent_chief-0.3.1/context/providers/__init__.py +0 -0
  33. agent_chief-0.3.1/context/providers/calendar.py +101 -0
  34. agent_chief-0.3.1/context/providers/clock.py +28 -0
  35. agent_chief-0.3.1/core/__init__.py +0 -0
  36. agent_chief-0.3.1/core/brain.py +403 -0
  37. agent_chief-0.3.1/core/config.py +36 -0
  38. agent_chief-0.3.1/core/digest.py +107 -0
  39. agent_chief-0.3.1/core/embedding.py +77 -0
  40. agent_chief-0.3.1/core/learner.py +246 -0
  41. agent_chief-0.3.1/core/policy.py +109 -0
  42. agent_chief-0.3.1/core/schema.py +96 -0
  43. agent_chief-0.3.1/core/scorer.py +256 -0
  44. agent_chief-0.3.1/core/state.py +292 -0
  45. agent_chief-0.3.1/delivery/__init__.py +0 -0
  46. agent_chief-0.3.1/delivery/base.py +69 -0
  47. agent_chief-0.3.1/delivery/desktop.py +31 -0
  48. agent_chief-0.3.1/delivery/telegram.py +90 -0
  49. agent_chief-0.3.1/delivery/terminal.py +17 -0
  50. agent_chief-0.3.1/demo/__init__.py +0 -0
  51. agent_chief-0.3.1/demo/day_of_engineer.json +642 -0
  52. agent_chief-0.3.1/demo/runner.py +255 -0
  53. agent_chief-0.3.1/dispatch/__init__.py +0 -0
  54. agent_chief-0.3.1/dispatch/acceptance.py +88 -0
  55. agent_chief-0.3.1/dispatch/executor.py +133 -0
  56. agent_chief-0.3.1/docs/PUBLISHING.md +66 -0
  57. agent_chief-0.3.1/docs/architecture.md +100 -0
  58. agent_chief-0.3.1/docs/assets/demo.gif +0 -0
  59. agent_chief-0.3.1/docs/assets/logo.svg +25 -0
  60. agent_chief-0.3.1/docs/blog/heartbeat-agents-are-training-you-to-ignore-them.md +170 -0
  61. agent_chief-0.3.1/docs/decisions.md +87 -0
  62. agent_chief-0.3.1/docs/launch/awesome-list-submissions.md +36 -0
  63. agent_chief-0.3.1/docs/launch/launch-plan.md +66 -0
  64. agent_chief-0.3.1/docs/openclaw-manual-test.md +38 -0
  65. agent_chief-0.3.1/docs/protocol.md +133 -0
  66. agent_chief-0.3.1/docs/release-checklist.md +38 -0
  67. agent_chief-0.3.1/docs/skill-manual-tests.md +42 -0
  68. agent_chief-0.3.1/eval/__init__.py +6 -0
  69. agent_chief-0.3.1/eval/generate_golden.py +269 -0
  70. agent_chief-0.3.1/eval/golden.jsonl +201 -0
  71. agent_chief-0.3.1/eval/learning.py +185 -0
  72. agent_chief-0.3.1/eval/reports/.gitkeep +0 -0
  73. agent_chief-0.3.1/eval/reports/learning.md +34 -0
  74. agent_chief-0.3.1/eval/runner.py +222 -0
  75. agent_chief-0.3.1/examples/README.md +16 -0
  76. agent_chief-0.3.1/examples/config.example.toml +40 -0
  77. agent_chief-0.3.1/examples/heartbeat_agent.py +33 -0
  78. agent_chief-0.3.1/examples/integrations/README.md +37 -0
  79. agent_chief-0.3.1/examples/integrations/stock_analysis_bot.py +33 -0
  80. agent_chief-0.3.1/examples/integrations/stock_feed.json +29 -0
  81. agent_chief-0.3.1/examples/integrations/webhook_template.py +65 -0
  82. agent_chief-0.3.1/examples/mcp_config.json +9 -0
  83. agent_chief-0.3.1/examples/python_client.py +47 -0
  84. agent_chief-0.3.1/examples/send-event.sh +20 -0
  85. agent_chief-0.3.1/ingest/__init__.py +0 -0
  86. agent_chief-0.3.1/ingest/connectors/__init__.py +38 -0
  87. agent_chief-0.3.1/ingest/connectors/composio.py +106 -0
  88. agent_chief-0.3.1/ingest/http.py +219 -0
  89. agent_chief-0.3.1/ingest/mcp_server.py +65 -0
  90. agent_chief-0.3.1/ingest/normalize.py +55 -0
  91. agent_chief-0.3.1/ingest/sources/__init__.py +0 -0
  92. agent_chief-0.3.1/ingest/sources/base.py +51 -0
  93. agent_chief-0.3.1/ingest/sources/github.py +43 -0
  94. agent_chief-0.3.1/ingest/sources/rss.py +52 -0
  95. agent_chief-0.3.1/judge/__init__.py +0 -0
  96. agent_chief-0.3.1/judge/anthropic.py +35 -0
  97. agent_chief-0.3.1/judge/base.py +150 -0
  98. agent_chief-0.3.1/judge/deepseek.py +8 -0
  99. agent_chief-0.3.1/judge/factory.py +50 -0
  100. agent_chief-0.3.1/judge/fixtures.py +26 -0
  101. agent_chief-0.3.1/judge/ollama.py +27 -0
  102. agent_chief-0.3.1/judge/openai.py +31 -0
  103. agent_chief-0.3.1/judge/pricing.py +53 -0
  104. agent_chief-0.3.1/judge/prompts.py +97 -0
  105. agent_chief-0.3.1/judge/templates/v1/context.j2 +3 -0
  106. agent_chief-0.3.1/judge/templates/v1/distill.j2 +4 -0
  107. agent_chief-0.3.1/judge/templates/v1/retry.j2 +1 -0
  108. agent_chief-0.3.1/judge/templates/v1/system.j2 +12 -0
  109. agent_chief-0.3.1/judge/templates/v1/topic_infer.j2 +2 -0
  110. agent_chief-0.3.1/judge/templates/v1/user.j2 +2 -0
  111. agent_chief-0.3.1/judge/templates/v1/verify.j2 +4 -0
  112. agent_chief-0.3.1/memory/__init__.py +0 -0
  113. agent_chief-0.3.1/memory/associate.py +33 -0
  114. agent_chief-0.3.1/memory/store.py +62 -0
  115. agent_chief-0.3.1/policy/POLICY.template.md +9 -0
  116. agent_chief-0.3.1/policy/USER.template.md +3 -0
  117. agent_chief-0.3.1/policy/__init__.py +0 -0
  118. agent_chief-0.3.1/pyproject.toml +88 -0
  119. agent_chief-0.3.1/scripts/demo-gif.sh +19 -0
  120. agent_chief-0.3.1/scripts/readme_metrics.py +93 -0
  121. agent_chief-0.3.1/scripts/showcase.sh +43 -0
  122. agent_chief-0.3.1/skills/__init__.py +0 -0
  123. agent_chief-0.3.1/skills/claude-code/SKILL.md +56 -0
  124. agent_chief-0.3.1/skills/openclaw/SKILL.md +56 -0
  125. agent_chief-0.3.1/skills/openclaw/__init__.py +0 -0
  126. agent_chief-0.3.1/skills/openclaw/hook.py +74 -0
  127. agent_chief-0.3.1/tests/__init__.py +0 -0
  128. agent_chief-0.3.1/tests/golden/digest.txt +9 -0
  129. agent_chief-0.3.1/tests/helpers.py +45 -0
  130. agent_chief-0.3.1/tests/test_acceptance.py +119 -0
  131. agent_chief-0.3.1/tests/test_brain_wiring.py +76 -0
  132. agent_chief-0.3.1/tests/test_chaos.py +175 -0
  133. agent_chief-0.3.1/tests/test_cli.py +32 -0
  134. agent_chief-0.3.1/tests/test_connect_cli.py +104 -0
  135. agent_chief-0.3.1/tests/test_connectors.py +148 -0
  136. agent_chief-0.3.1/tests/test_console.py +147 -0
  137. agent_chief-0.3.1/tests/test_delivery.py +98 -0
  138. agent_chief-0.3.1/tests/test_demo.py +50 -0
  139. agent_chief-0.3.1/tests/test_demo_routing.py +29 -0
  140. agent_chief-0.3.1/tests/test_digest.py +135 -0
  141. agent_chief-0.3.1/tests/test_dispatch.py +150 -0
  142. agent_chief-0.3.1/tests/test_docs.py +35 -0
  143. agent_chief-0.3.1/tests/test_eval.py +132 -0
  144. agent_chief-0.3.1/tests/test_ingest.py +155 -0
  145. agent_chief-0.3.1/tests/test_integrations.py +44 -0
  146. agent_chief-0.3.1/tests/test_judge_backends.py +198 -0
  147. agent_chief-0.3.1/tests/test_learner.py +176 -0
  148. agent_chief-0.3.1/tests/test_learning.py +137 -0
  149. agent_chief-0.3.1/tests/test_memory.py +79 -0
  150. agent_chief-0.3.1/tests/test_natural_feedback.py +132 -0
  151. agent_chief-0.3.1/tests/test_openclaw.py +66 -0
  152. agent_chief-0.3.1/tests/test_plan_attached.py +83 -0
  153. agent_chief-0.3.1/tests/test_prompts.py +125 -0
  154. agent_chief-0.3.1/tests/test_readme_metrics.py +48 -0
  155. agent_chief-0.3.1/tests/test_routing.py +191 -0
  156. agent_chief-0.3.1/tests/test_scene.py +141 -0
  157. agent_chief-0.3.1/tests/test_shadow.py +97 -0
  158. agent_chief-0.3.1/tests/test_skills_packaging.py +104 -0
  159. agent_chief-0.3.1/tests/test_sources.py +133 -0
  160. agent_chief-0.3.1/tests/test_stage1.py +155 -0
  161. agent_chief-0.3.1/tests/test_stage2.py +106 -0
  162. agent_chief-0.3.1/tests/test_state.py +120 -0
  163. agent_chief-0.3.1/tests/test_telegram.py +98 -0
  164. agent_chief-0.3.1/tests/test_trace.py +156 -0
  165. agent_chief-0.3.1/tests/test_wizard.py +81 -0
  166. agent_chief-0.3.1/ui/__init__.py +6 -0
  167. agent_chief-0.3.1/ui/console.html +191 -0
  168. agent_chief-0.3.1/uv.lock +2333 -0
@@ -0,0 +1,33 @@
1
+ name: 🐛 Bug report
2
+ description: Something behaves wrong
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: what
7
+ attributes:
8
+ label: What happened?
9
+ description: What did you do, what did you expect, what happened instead?
10
+ placeholder: |
11
+ 1. Sent an event with `curl -X POST ...`
12
+ 2. Expected route "digest", got "interrupt" at 2 AM
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: decision
17
+ attributes:
18
+ label: The Decision (if routing-related)
19
+ description: Paste the Decision JSON (route, score, components, reason) — `chief status` or the webhook response.
20
+ render: json
21
+ - type: input
22
+ id: version
23
+ attributes:
24
+ label: Version
25
+ placeholder: "agent-chief 0.1.0 · Python 3.12 · Ubuntu 24.04"
26
+ validations:
27
+ required: true
28
+ - type: textarea
29
+ id: logs
30
+ attributes:
31
+ label: Relevant log output
32
+ description: "`~/.chief/audit.log` lines or console output. Redact tokens."
33
+ render: shell
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: 💬 Question / discussion
4
+ url: https://github.com/SmileLikeYe/agent-chief/discussions
5
+ about: Not sure it's a bug? Ask here first — unpolished questions welcome.
@@ -0,0 +1,23 @@
1
+ name: 💡 Feature request
2
+ description: An idea that would make Chief better
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: The problem
9
+ description: What attention-management pain does this solve? Start from the pain, not the solution.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: solution
14
+ attributes:
15
+ label: Proposed solution
16
+ description: How you imagine it working. Sketches and half-ideas welcome.
17
+ - type: checkboxes
18
+ id: scope
19
+ attributes:
20
+ label: Scope check
21
+ options:
22
+ - label: I checked ROADMAP.md — this isn't something v1 deliberately excludes (web UI, cloud sync, Slack/Discord delivery, …)
23
+ required: true
@@ -0,0 +1,11 @@
1
+ ## What & why
2
+
3
+ <!-- One or two sentences: what changes, and why it's worth changing. -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] `make lint test` is green (218+ tests, fully offline)
8
+ - [ ] Behavior changes come with a test that pins them
9
+ - [ ] If a demo event legitimately re-routes: fixture table updated deliberately, reason stated below
10
+ - [ ] Nothing from `SPEC.md §13` (no arbitrary shell, no web UI, no cloud/telemetry, …)
11
+ - [ ] Spec ambiguity resolved? → one-line ADR added to `docs/decisions.md`
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: astral-sh/setup-uv@v5
12
+ with:
13
+ python-version: "3.12"
14
+ - run: uv sync --dev
15
+ - run: uv run ruff check .
16
+ - run: uv run pytest
@@ -0,0 +1,39 @@
1
+ name: Publish to PyPI
2
+ # Trusted Publishing (OIDC) — no API token stored in the repo. One-time setup:
3
+ # PyPI → project → Publishing → add a GitHub publisher:
4
+ # owner=SmileLikeYe, repo=agent-chief, workflow=publish.yml, environment=pypi
5
+ # Then: publishing happens automatically when a v* tag's GitHub Release is
6
+ # published, or manually via the Actions tab (workflow_dispatch).
7
+ on:
8
+ release:
9
+ types: [published]
10
+ workflow_dispatch:
11
+ inputs:
12
+ repository:
13
+ description: "testpypi or pypi"
14
+ default: "pypi"
15
+ permissions:
16
+ contents: read
17
+ id-token: write # required for Trusted Publishing
18
+ jobs:
19
+ publish:
20
+ runs-on: ubuntu-latest
21
+ environment: pypi
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: astral-sh/setup-uv@v5
25
+ with:
26
+ python-version: "3.12"
27
+ - run: uv sync --dev
28
+ - run: uv run ruff check .
29
+ - run: uv run pytest
30
+ - run: uv build
31
+ # sanity: the exact wheel must run the demo before it reaches an index
32
+ - run: uvx --from dist/*.whl chief demo --fast
33
+ - name: Publish
34
+ run: |
35
+ if [ "${{ github.event.inputs.repository }}" = "testpypi" ]; then
36
+ uv publish --publish-url https://test.pypi.org/legacy/
37
+ else
38
+ uv publish
39
+ fi
@@ -0,0 +1,44 @@
1
+ name: Release
2
+ on:
3
+ push:
4
+ tags: ["v*"]
5
+ permissions:
6
+ contents: write
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: astral-sh/setup-uv@v5
13
+ with:
14
+ python-version: "3.12"
15
+ - run: uv sync --dev
16
+ - run: uv run ruff check .
17
+ - run: uv run pytest
18
+ - run: uv build
19
+ # the demo must run from the exact wheel being released
20
+ - run: uvx --from dist/*.whl chief demo --fast
21
+ - name: Extract this version's CHANGELOG section
22
+ run: |
23
+ # literal match (index, not regex) so tags with metachars can't misparse
24
+ awk -v h="## [${GITHUB_REF_NAME#v}]" '
25
+ index($0, h) == 1 {hit=1; next}
26
+ hit && /^## \[/ {exit}
27
+ hit {print}' CHANGELOG.md > notes.md
28
+ [ -s notes.md ] || echo "See CHANGELOG.md for details." > notes.md
29
+ - name: Create or update the GitHub release
30
+ env:
31
+ GH_TOKEN: ${{ github.token }}
32
+ run: |
33
+ # only the changelog's newest version may take the Latest badge —
34
+ # tagging an old hotfix must not steal it
35
+ newest=$(grep -oP '^## \[\K[0-9]+\.[0-9]+\.[0-9]+(?=\])' CHANGELOG.md | head -1)
36
+ latest_flag="--latest=false"
37
+ [ "$GITHUB_REF_NAME" = "v$newest" ] && latest_flag="--latest"
38
+ if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
39
+ gh release edit "$GITHUB_REF_NAME" --notes-file notes.md "$latest_flag"
40
+ gh release upload "$GITHUB_REF_NAME" dist/* --clobber
41
+ else
42
+ gh release create "$GITHUB_REF_NAME" dist/* \
43
+ --title "$GITHUB_REF_NAME" --notes-file notes.md "$latest_flag"
44
+ fi
@@ -0,0 +1,48 @@
1
+ name: Sync release notes
2
+ # Release notes live in CHANGELOG.md; this keeps published GitHub releases in
3
+ # sync with it (and backfills a release for any tag that predates release.yml).
4
+ # Runs only when the changelog (or this file) changes.
5
+ # NOTE: the `## [x.y.z]` heading format is load-bearing — both this workflow
6
+ # and release.yml parse it.
7
+ on:
8
+ push:
9
+ branches: [main]
10
+ paths: ["CHANGELOG.md", ".github/workflows/sync-release-notes.yml"]
11
+ permissions:
12
+ contents: write
13
+ jobs:
14
+ sync:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Upsert a release per changelog version
19
+ env:
20
+ GH_TOKEN: ${{ github.token }}
21
+ run: |
22
+ # semver only, anchored to the closing bracket: "[Unreleased]" and
23
+ # malformed headings never become version tokens; no-match is a no-op
24
+ versions=$(grep -oP '^## \[\K[0-9]+\.[0-9]+\.[0-9]+(?=\])' CHANGELOG.md || true)
25
+ for version in $versions; do
26
+ tag="v$version"
27
+ # tag existence is a remote fact — never trust the local checkout
28
+ gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/$tag" >/dev/null || {
29
+ echo "no tag $tag on the remote; skipping"; continue; }
30
+ # literal match (index, not regex) so versions with metachars can't misparse
31
+ awk -v h="## [$version]" '
32
+ index($0, h) == 1 {hit=1; next}
33
+ hit && /^## \[/ {exit}
34
+ hit {print}' CHANGELOG.md > notes.md
35
+ # never blank a published release with an empty extraction
36
+ [ -s notes.md ] || { echo "empty notes for $tag; skipping"; continue; }
37
+ if gh release view "$tag" >/dev/null 2>&1; then
38
+ gh release edit "$tag" --notes-file notes.md
39
+ else
40
+ gh release create "$tag" --title "$tag" --notes-file notes.md --latest=false
41
+ fi
42
+ done
43
+ # the changelog lists newest first: its first version is Latest —
44
+ # but only if that release exists yet (changelog may land pre-tag)
45
+ latest="v$(printf '%s\n' $versions | head -1)"
46
+ if gh release view "$latest" >/dev/null 2>&1; then
47
+ gh release edit "$latest" --latest
48
+ fi
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ dist/
5
+ *.egg-info/
6
+ .pytest_cache/
7
+ .ruff_cache/
8
+ dist/
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,40 @@
1
+ # Blockers & Mocked Steps
2
+
3
+ Log of steps that needed human-only resources; implemented against mocks/fixtures per goal rule 3.
4
+
5
+ - Step 8: no live LLM API key (DeepSeek/Anthropic/OpenAI) and no local Ollama on this machine. All four adapters implemented and exercised against recorded HTTP cassettes (httpx.MockTransport); the ≥20/24 demo-agreement test uses cassettes synthesized from the demo fixture's judge blocks, so it validates the wire format + parsing + pipeline, not live model quality. To validate live: `chief init`, pick a backend, rerun tests with a key.
6
+ - Step 9: sentence-transformers/torch cannot be installed on this machine — disk has <1GB free and CPU torch alone needs ~2GB. The `embeddings` extra + SentenceTransformerEmbedder wiring is implemented and the fallback path is tested; all similarity tests run on the deterministic HashEmbedder. To validate the real model: free ~3GB, `uv sync --extra embeddings`, rerun pytest.
7
+ - Step 10: headless dev machine has no notification daemon; DesktopChannel's plyer path is unit-tested with an injected notify_fn and the real path was smoke-tested to degrade gracefully to terminal.
8
+ - Step 11: no Telegram bot token / live chat available. Channel implemented against the Bot HTTP API and integration-tested with an httpx test double (sendMessage payloads, silent flag, inline buttons, callback→feedback rows, mute→POLICY.md). To validate live: create a bot via @BotFather, set [delivery] telegram_token/chat_id, run `chief run`.
9
+ - Step 17: acceptance says "with real embeddings" — blocked by the same disk constraint as Step 9 (torch will not fit). The #5→#19 chain is verified with the deterministic HashEmbedder through MemoryStore/batch_associate; swap in the real model via config once the embeddings extra is installable.
10
+ - Step 20: fresh-machine <10min manual check — verified the local path on this machine: `uv tool install`/`uvx` → `chief init --defaults` (~5s) → `chief run` up with webhook answering in <1 min. A truly fresh machine with a live LLM key could not be exercised tonight (no spare machine/key); the wizard, config, service unit, and run wiring are all covered by tests.
11
+ - Step 22: no local OpenClaw install available. Integration is file-protocol based (tasks/ inbox, outbox/ pickup) and fully covered by tests against a faked OpenClaw home; the manual transcript in docs/openclaw-manual-test.md documents the faked run and what a live run would change.
12
+ - Step 23: "clean machine" quickstart verified on this machine via isolated uvx (1.8s to demo end, well under 60s); a literally separate machine wasn't available tonight.
13
+ - Step 24: publishing to (test) PyPI needs an account token only a human can provide. Everything short of upload is done and verified: `make release-check` runs the demo from the built wheel via isolated uvx (the exact `uvx agent-chief demo` code path), the GIF is reproducible via `make demo-gif`, and v0.1.0 is tagged. To finish: `uv publish --index testpypi` with a token, then re-verify.
14
+
15
+ ## Step 25/27 · Real-backend eval + prompt compare (v3.1)
16
+ - Status: harness complete and CI-gated with the fixtures backend and offline
17
+ doubles; the CAPABILITY agreement number and prompt-compare diffs against a
18
+ REAL backend need an LLM API key (or a local Ollama pull).
19
+ - Un-mock: `chief eval --backend deepseek` (or ollama/anthropic/openai) with
20
+ `[llm].api_key` set in ~/.chief/config.toml; for prompt changes,
21
+ `chief eval --compare v1 v2 --backend deepseek` and attach the report per
22
+ CONTRIBUTING.md.
23
+
24
+ ## Step 29 · Dual skill packaging — live-host halves (v3.1)
25
+ - Status: both SKILL.md files lint clean; `chief lite` transcripts in
26
+ docs/skill-manual-tests.md are real output. The live halves need hosts this
27
+ machine doesn't have: a local OpenClaw install (see Step 22 entry) and a
28
+ Claude Code session with the skill loaded and API credentials.
29
+ - Un-mock: copy skills/claude-code/ into a project's .claude/skills/, run a
30
+ watcher that finds something, verify the agent calls `chief lite` and obeys
31
+ the route; for OpenClaw follow docs/openclaw-manual-test.md.
32
+
33
+ ## Step 34 · Composio connector — live verification (v3.2)
34
+ - Status: adapter complete against Composio's documented v3 envelope +
35
+ svix-style HMAC signatures; verified with signed fixtures (GitHub PR,
36
+ Gmail, Slack triggers). A live round-trip needs a composio.dev account,
37
+ a webhook subscription pointed at this machine (tunnel), and its secret.
38
+ - Un-mock: `chief connect composio --secret <whsec_...>`, subscribe
39
+ triggers in the Composio dashboard to https://<tunnel>/v1/connectors/composio,
40
+ fire a test trigger, watch `chief ui` History.
@@ -0,0 +1,120 @@
1
+ # Changelog
2
+
3
+ All notable changes to Chief are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
5
+ [SemVer](https://semver.org) (0.x: minor bumps may break).
6
+
7
+ ## [0.3.1] — 2026-07-06
8
+
9
+ Security & robustness hardening of the v0.3.0 product surface (from a
10
+ dedicated multi-agent review pass).
11
+
12
+ ### Fixed
13
+ - **Console XSS → token theft** closed: event/task ids (attacker-shaped) now
14
+ ride escaped `data-*` attributes with delegated listeners, never inline
15
+ handlers.
16
+ - All API auth uses constant-time comparison (`hmac.compare_digest`); uvicorn
17
+ binds `127.0.0.1` explicitly on both servers.
18
+ - **Composio webhook**: timestamp freshness (±5 min anti-replay), 1 MiB body
19
+ cap before buffering, non-ASCII signature headers no longer 500, non-dict
20
+ trigger data wrapped instead of crashing.
21
+ - Console task-approve honors `task.executor` (was hardcoded `claude_code` — an
22
+ escalation over the query-only shell executor).
23
+ - History search runs in SQL, so matches beyond the newest rows are found.
24
+ - One `apply_feedback` path behind HTTP/MCP/Telegram/console: the natural
25
+ should/shouldn't-interrupt signals now learn identically everywhere (MCP and
26
+ Telegram previously only stored a raw row); unknown signals are rejected.
27
+ - `chief connect` backs up and refuses to rewrite configs its serializer can't
28
+ round-trip, instead of corrupting them in place.
29
+
30
+ ## [0.3.0] — 2026-07-06
31
+
32
+ The "product surface" release (SPEC v3.2, Steps 32–36): Chief for people, not
33
+ just for people who read specs.
34
+
35
+ ### Added
36
+ - **Local web console** (`chief ui`, also served by `chief run`) at
37
+ `127.0.0.1:8787/ui`: Today / History / Rules / Tasks / Sources views,
38
+ POLICY.md editing that takes effect immediately, dispatch approve/reject
39
+ (verification still enforced), and 👍/👎 on every decision. Single user,
40
+ token-gated, one static HTML file — no cloud, no build toolchain.
41
+ - **Natural feedback**: `should_interrupt` / `should_not_interrupt` as
42
+ first-class signals — stronger than every inferred signal — via the console,
43
+ `POST /v1/feedback`, the MCP `feedback` tool, and new Telegram buttons.
44
+ - **Connector framework** with **Composio** as the flagship adapter:
45
+ HMAC-verified trigger webhooks (`/v1/connectors/composio`) translate
46
+ GitHub/Gmail/Slack/500+ app events into candidate events; documented slots
47
+ for zapier/n8n and MCP-push agents.
48
+ - **One-click connect**: `chief connect composio|github|rss` edits config
49
+ surgically and prints exact next steps; `chief sources` shows status.
50
+ - SPEC §13 revised by the owner: local-only console and connector ingest are
51
+ in scope; the hosted-UI and chat-delivery bans stand.
52
+
53
+ ## [0.2.0] — 2026-07-05
54
+
55
+ The "trust & distribution" release (SPEC v3.1, Steps 25–31) plus two
56
+ multi-agent review hardening passes.
57
+
58
+ ### Added
59
+ - **Eval harness** (`chief eval`): a 200-case golden dataset with strictly
60
+ separated CAPABILITY (improvable, report the number) and REGRESSION evals
61
+ (the demo 24 — 100% forever, CI-gated); bucketed markdown reports by
62
+ route/topic/scene.
63
+ - **Decision tracing + cost accounting** (`chief trace <event_id>`): per-stage
64
+ latency, tokens in/out/cached, and USD cost on every decision, with
65
+ per-model list prices (DeepSeek cache-hit vs cache-miss modeled explicitly).
66
+ The Tact Report gained a cost dimension: % events reaching the LLM, cache
67
+ hit rate, judgment spend — all windowed to the report period.
68
+ - **Prompt governance**: all prompts are versioned Jinja2 templates
69
+ (`judge/templates/v1/`); the version is stamped into every judged decision's
70
+ audit record, and `chief eval --compare v1 v2` produces an agreement-delta +
71
+ flipped-samples diff. House rule: no prompt change merges without one.
72
+ - **Graceful degradation**: chaos-tested judge failures (malformed JSON,
73
+ timeout, backend down) fall back to rules-only conservative routing — never
74
+ interrupt while blind, never drop — marked `degraded=true`, auto-recovering,
75
+ and surfaced in `chief status`.
76
+ - **`chief lite`**: zero-daemon judgment-only mode (stages 1–3 + routing) for
77
+ one-shot callers and skills.
78
+ - **Dual skill packaging**: Claude Code skill alongside the OpenClaw skill.
79
+ - **Integration examples** (`examples/integrations/`): a stock-analysis-bot
80
+ feed and a generic webhook template, both runnable offline.
81
+ - **Quantified README**: the first screen leads with numbers regenerated from
82
+ the deterministic demo replay via `make readme-metrics`, gated by tests.
83
+ - Open-source scaffolding: LICENSE (MIT), CONTRIBUTING, CODE_OF_CONDUCT,
84
+ SECURITY, issue/PR templates, examples/, bilingual README, `chief --version`.
85
+
86
+ ### Fixed (highlights from the two review passes)
87
+ - Cost accounting: per-model pricing (default gpt-4o-mini configs were billed
88
+ at gpt-4o rates, ~17×); failed retries and mid-retry transport errors are
89
+ billed; a single `Decision.cost` source of truth.
90
+ - Robustness: `"usage": null` from OpenAI-compatible proxies no longer breaks
91
+ judgments; the Brain's outer judge timeout (150s) now fits HTTPJudge's full
92
+ retry budget; unknown `prompt_version` fails fast at startup; LLM-echoed
93
+ `usage` keys are stripped before validation.
94
+ - Reserved-namespace hardening: the degradation marker moved to a dedicated
95
+ `meta` table and externally supplied dunder topics are namespaced at ingest.
96
+ - Eval integrity: regression gates before the paid capability run; a broken
97
+ fixture fails loud while a flaky backend degrades a single case instead of
98
+ aborting a paid run; loud warning when "low agreement" is really an outage.
99
+
100
+ ## [0.1.0] — 2026-07-04
101
+
102
+ Initial release: the full SPEC v3 implementation (Steps 1–24).
103
+
104
+ - Three-stage worthiness engine (hard rules → similarity classifier → LLM
105
+ judge: ollama/deepseek/anthropic/openai, all optional) × scene engine with
106
+ per-scene interrupt thresholds.
107
+ - Five routes: interrupt / digest / dispatch / curate / drop; dispatch
108
+ verifies results before reporting ("done is a claim, not a proof") and
109
+ arrives with a plan.
110
+ - Shadow mode (trust is earned), Tact Report, EMA learner with nightly
111
+ human-readable POLICY.md distillation.
112
+ - Ingest protocol: webhook + MCP tools + GitHub/RSS pollers; delivery over
113
+ terminal/desktop/Telegram with feedback buttons.
114
+ - Fully offline deterministic demo (`uvx agent-chief demo`) with a
115
+ full-table routing regression.
116
+
117
+ [0.3.1]: https://github.com/SmileLikeYe/agent-chief/compare/v0.3.0...v0.3.1
118
+ [0.3.0]: https://github.com/SmileLikeYe/agent-chief/compare/v0.2.0...v0.3.0
119
+ [0.2.0]: https://github.com/SmileLikeYe/agent-chief/compare/v0.1.0...v0.2.0
120
+ [0.1.0]: https://github.com/SmileLikeYe/agent-chief/releases/tag/v0.1.0
@@ -0,0 +1,71 @@
1
+ # CLAUDE.md
2
+
3
+ Chief — a local-first "chief of staff" that triages everything competing for
4
+ the user's attention (agents, heartbeats, CI, RSS) into exactly one of:
5
+ interrupt / digest / dispatch / curate / drop. Spec: `SPEC.md` (§ references
6
+ throughout the code point there). Build log: `PROGRESS.md`.
7
+
8
+ ## Commands
9
+
10
+ ```bash
11
+ make test # uv run pytest (313 tests, offline, no keys needed)
12
+ make lint # uv run ruff check .
13
+ make demo # offline day-of-engineer replay (deterministic)
14
+ make readme-metrics # regenerate the quantified README first screen
15
+ make release-check # lint + test + build wheel + run demo from the wheel via uvx
16
+ uv run pytest tests/test_routing.py -k name # single test
17
+ uv run chief eval # regression (demo 24, must be 100%) + capability (golden 200)
18
+ uv run chief trace <event_id> # replay one decision chain with costs
19
+ uv run chief lite '<event json>' # zero-daemon judgment (skills use this)
20
+ uv run chief ui # local web console at 127.0.0.1:8787/ui
21
+ uv run chief connect composio --secret … # + github / rss; chief sources
22
+ uv run chief eval --learning # preference-learning reward-loop eval
23
+ ```
24
+
25
+ Everything runs through `uv`. Python 3.12. No network, no API keys, and no
26
+ real `~/.chief` are needed for the test suite — tests set `CHIEF_HOME` to a
27
+ tmpdir and use the `fixtures` judge backend.
28
+
29
+ ## Architecture (one paragraph)
30
+
31
+ `ingest/` normalizes payloads (webhook :8787, MCP tools, GitHub/RSS pollers) →
32
+ `core/brain.py::Brain.process` runs the pipeline: triage-merge → stage-1 hard
33
+ rules (`core/scorer.py::stage1`) → stage-2 similarity classifier → memory
34
+ associate → LLM judge (`judge/`, pluggable via `judge/factory.py`) →
35
+ `score_and_route` (score = Σ w_topic·component, per-scene thresholds from
36
+ `context/infer.py::SCENE_POLICY`) → persist to SQLite (`core/state.py`, all
37
+ tables use a JSON `data` blob column) → fire-and-forget actor
38
+ (`cli/runtime.py::make_actor`) delivers or dispatches. Dispatch always
39
+ "arrives with a plan": executor runs first, result is verified
40
+ (`dispatch/acceptance.py` — "done is a claim, not a proof"), then delivery.
41
+ Learning: `core/learner.py` (EMA topic weights, shadow mode, nightly
42
+ threshold tuning at 03:00 via the scheduler in `cli/runtime.py`).
43
+ v3.1 additions: `eval/` (golden 200-case dataset + agreement harness),
44
+ `Decision.trace` (per-stage latency/tokens/USD via `judge/pricing.py`),
45
+ versioned prompts (`judge/templates/<v>/*.j2`), and judge-failure degradation
46
+ (rules-only conservative routing, `degraded=true`, auto-recovery).
47
+
48
+ ## Conventions
49
+
50
+ - Tests first: each `tests/test_*.py` encodes the SPEC §9 acceptance criteria
51
+ for its step. The demo routing table is a full-table regression
52
+ (`tests/test_demo_routing.py`) — if you change routing behavior on purpose,
53
+ update the fixture table deliberately, never loosen the test.
54
+ - Ambiguity in the spec → pick the simpler option and add a one-line ADR to
55
+ `docs/decisions.md`.
56
+ - `SPEC.md §13` is a hard forbidden list: no arbitrary shell execution
57
+ (`dispatch/executor.py` shell templates are a query-only argv whitelist —
58
+ keep it that way, never `shell=True`), no mic/screen/geofencing, no web UI,
59
+ no cloud sync, no Slack/Discord/WeChat delivery.
60
+ - Embeddings default to the dependency-free `HashEmbedder`
61
+ (`core/embedding.py`); sentence-transformers is an optional extra
62
+ (`--extra embeddings`) — never make it a hard import.
63
+ - Human-only resources (LLM keys, Telegram token, PyPI creds) are mocked;
64
+ status and un-mock instructions live in `BLOCKERS.md`.
65
+ - Prompts are versioned template dirs; no prompt change without a
66
+ `chief eval --compare` diff report (CONTRIBUTING.md).
67
+ - Release flow: bump pyproject version + add a CHANGELOG.md entry + push a
68
+ `v*` tag; workflows do the rest. The `## [x.y.z]` changelog heading format
69
+ is load-bearing — release.yml and sync-release-notes.yml parse it.
70
+ - Commit style: `feat(scope): ...` / `fix:` / `docs:` / `review(phaseN): ...`;
71
+ ruff + pytest green on every commit.
@@ -0,0 +1,39 @@
1
+ # Code of Conduct
2
+
3
+ ## Our pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our standards
13
+
14
+ Examples of behavior that contributes to a positive environment:
15
+
16
+ - Demonstrating empathy and kindness toward other people
17
+ - Being respectful of differing opinions, viewpoints, and experiences
18
+ - Giving and gracefully accepting constructive feedback
19
+ - Focusing on what is best for the overall community
20
+
21
+ Examples of unacceptable behavior:
22
+
23
+ - Trolling, insulting or derogatory comments, and personal or political attacks
24
+ - Public or private harassment
25
+ - Publishing others' private information without their explicit permission
26
+ - Other conduct which could reasonably be considered inappropriate in a
27
+ professional setting
28
+
29
+ ## Enforcement
30
+
31
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
32
+ reported to the maintainers via GitHub issues or the contact listed in
33
+ [SECURITY.md](SECURITY.md). All complaints will be reviewed and investigated
34
+ promptly and fairly.
35
+
36
+ ## Attribution
37
+
38
+ This Code of Conduct is adapted from the
39
+ [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
@@ -0,0 +1,67 @@
1
+ # Contributing to Chief
2
+
3
+ Thanks for your interest! Chief is small on purpose — the whole brain fits in
4
+ your head after an afternoon of reading. This document gets you productive in
5
+ five minutes.
6
+
7
+ ## Dev setup
8
+
9
+ ```bash
10
+ git clone https://github.com/SmileLikeYe/agent-chief && cd agent-chief
11
+ uv sync --dev # Python 3.12+, https://docs.astral.sh/uv/
12
+ make test lint # 218 tests + ruff, fully offline — no keys needed
13
+ make demo # the offline day-of-engineer replay
14
+ ```
15
+
16
+ The test suite needs **no network, no API keys, and no real `~/.chief`** —
17
+ tests point `CHIEF_HOME` at a tmpdir and use the deterministic `fixtures`
18
+ judge. If your change needs a key to test, it's designed wrong; add a cassette
19
+ (see `judge/fixtures.py` and the httpx MockTransport tests).
20
+
21
+ ## The rules of the house
22
+
23
+ 1. **Tests first.** Every behavior change lands with the test that pins it.
24
+ The demo routing table (`tests/test_demo_routing.py`) is a full-table
25
+ regression — if your change legitimately re-routes a demo event, update the
26
+ fixture table deliberately and say why in the PR; never loosen the test.
27
+ 2. **`SPEC.md §13` is a hard no.** No arbitrary shell execution (the shell
28
+ executor is a query-only argv whitelist — never `shell=True`), no
29
+ mic/screen/geofencing, no web UI, no cloud sync, no telemetry.
30
+ 3. **Ambiguity → simpler option + a one-line ADR** in
31
+ [`docs/decisions.md`](docs/decisions.md).
32
+ 4. **No prompt change merges without an eval diff report.** Prompts are
33
+ versioned Jinja2 templates under `judge/templates/<version>/`. To change
34
+ one: copy the current version dir to a new version, edit there, run
35
+ `chief eval --compare <old> <new>` against a real backend, and attach the
36
+ generated `eval/reports/compare-*.md` (agreement delta + flipped samples)
37
+ to the PR.
38
+ 5. **Keep the core dependency-light.** Embeddings default to the
39
+ dependency-free `HashEmbedder`; heavyweight deps go behind optional extras.
40
+ 6. **Green on every commit**: `make lint test` must pass.
41
+
42
+ ## Commit style
43
+
44
+ ```
45
+ feat(scope): add per-topic dispatch propensity
46
+ fix: telegram poller surfaces HTTP errors
47
+ docs: clarify quiet-hours semantics
48
+ ```
49
+
50
+ ## Pull requests
51
+
52
+ - One logical change per PR; small is beautiful.
53
+ - Explain *why* in the description; the diff explains *what*.
54
+ - CI (ruff + pytest on 3.12) must be green.
55
+
56
+ ## Good first areas
57
+
58
+ - New **scene providers** (`context/providers/`) — e.g. OS focus/lock state.
59
+ - New **judge backends** (`judge/`) — subclass the HTTP judge, ~40 lines.
60
+ - New **ingest sources** (`ingest/sources/`) — subclass `Poller`, ~60 lines.
61
+ - New **delivery channels** (`delivery/`) — but check `ROADMAP.md` first;
62
+ Slack/Discord/WeChat are deliberately v2.
63
+
64
+ ## Questions
65
+
66
+ Open a [discussion or issue](https://github.com/SmileLikeYe/agent-chief/issues)
67
+ — unpolished questions welcome.
@@ -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.
@@ -0,0 +1,29 @@
1
+ .PHONY: test lint demo demo-gif showcase clean-dist build release-check readme-metrics
2
+
3
+ test:
4
+ uv run pytest
5
+
6
+ lint:
7
+ uv run ruff check .
8
+
9
+ demo:
10
+ uv run chief demo
11
+
12
+ readme-metrics:
13
+ uv run python scripts/readme_metrics.py --write
14
+
15
+ demo-gif:
16
+ bash scripts/demo-gif.sh
17
+
18
+ showcase:
19
+ bash scripts/showcase.sh
20
+
21
+ clean-dist:
22
+ rm -f dist/*
23
+
24
+ build: clean-dist
25
+ uv build
26
+
27
+ release-check: lint test build
28
+ uvx --isolated --from dist/agent_chief-*-py3-none-any.whl chief demo --fast > /dev/null
29
+ @echo "release check passed"