nonoka-cli 0.2.5__tar.gz → 0.2.10__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 (161) hide show
  1. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/.gitignore +9 -1
  2. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/PKG-INFO +290 -66
  3. nonoka_cli-0.2.10/README.md +754 -0
  4. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/pyproject.toml +13 -2
  5. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/__init__.py +1 -1
  6. nonoka_cli-0.2.10/src/nonoka_cli/benchmark/__init__.py +1 -0
  7. nonoka_cli-0.2.10/src/nonoka_cli/benchmark/harbor.py +458 -0
  8. nonoka_cli-0.2.10/src/nonoka_cli/benchmark/swe_bench.py +353 -0
  9. nonoka_cli-0.2.10/src/nonoka_cli/benchmark/swe_environment.py +119 -0
  10. nonoka_cli-0.2.10/src/nonoka_cli/benchmark/swe_runner.py +176 -0
  11. nonoka_cli-0.2.10/src/nonoka_cli/benchmark/watchdog.py +163 -0
  12. nonoka_cli-0.2.10/src/nonoka_cli/bridge/__init__.py +39 -0
  13. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/bridge/events.py +57 -5
  14. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/bridge/handler.py +179 -15
  15. nonoka_cli-0.2.10/src/nonoka_cli/bridge/nonoka_tools.py +306 -0
  16. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/bridge/protocol.py +74 -2
  17. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/bridge/server.py +51 -5
  18. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/cli.py +15 -1
  19. nonoka_cli-0.2.10/src/nonoka_cli/commands/benchmark_cmd.py +853 -0
  20. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/commands/config_cmd.py +7 -5
  21. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/commands/doctor_cmd.py +136 -1
  22. nonoka_cli-0.2.10/src/nonoka_cli/commands/eval_cmd.py +55 -0
  23. nonoka_cli-0.2.10/src/nonoka_cli/commands/logs_cmd.py +61 -0
  24. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/commands/opencode_cmd.py +46 -27
  25. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/commands/plugin_cmd.py +54 -4
  26. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/commands/run_cmd.py +23 -0
  27. nonoka_cli-0.2.10/src/nonoka_cli/commands/sessions_cmd.py +58 -0
  28. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/config/loader.py +12 -9
  29. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/config/models.py +57 -9
  30. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/agent_factory.py +361 -94
  31. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/context.py +1 -0
  32. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/context_trimmer.py +5 -1
  33. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/namespaces.py +1 -0
  34. nonoka_cli-0.2.10/src/nonoka_cli/core/operational_signals.py +353 -0
  35. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/orchestrator.py +201 -92
  36. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/plugin_manifest.py +85 -20
  37. nonoka_cli-0.2.10/src/nonoka_cli/core/project_agents.py +502 -0
  38. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/prompt_builder.py +84 -44
  39. nonoka_cli-0.2.10/src/nonoka_cli/core/run_evidence.py +105 -0
  40. nonoka_cli-0.2.10/src/nonoka_cli/core/scorecard.py +142 -0
  41. nonoka_cli-0.2.10/src/nonoka_cli/core/semantic_cache.py +107 -0
  42. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/tool_output_policy.py +28 -0
  43. nonoka_cli-0.2.10/src/nonoka_cli/safety/__init__.py +6 -0
  44. nonoka_cli-0.2.10/src/nonoka_cli/safety/preflight.py +62 -0
  45. nonoka_cli-0.2.10/src/nonoka_cli/safety/sandbox.py +96 -0
  46. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/tools/builtins/agent_tools.py +3 -3
  47. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/tools/builtins/file_tools.py +88 -5
  48. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/utils/logging.py +13 -7
  49. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/utils/trace_logger.py +4 -0
  50. nonoka_cli-0.2.10/tests/fixtures/bridge_external_capabilities.json +30 -0
  51. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/integration/test_server_external_capabilities.py +2 -1
  52. nonoka_cli-0.2.10/tests/integration/test_watchdog_process_group.py +34 -0
  53. nonoka_cli-0.2.10/tests/unit/benchmark/test_harbor.py +311 -0
  54. nonoka_cli-0.2.10/tests/unit/benchmark/test_swe_environment.py +66 -0
  55. nonoka_cli-0.2.10/tests/unit/benchmark/test_watchdog.py +147 -0
  56. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/bridge/test_events.py +63 -0
  57. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/bridge/test_handler.py +241 -14
  58. nonoka_cli-0.2.10/tests/unit/bridge/test_nonoka_tools.py +111 -0
  59. nonoka_cli-0.2.10/tests/unit/bridge/test_package.py +10 -0
  60. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/bridge/test_protocol.py +71 -0
  61. nonoka_cli-0.2.10/tests/unit/bridge/test_server.py +129 -0
  62. nonoka_cli-0.2.10/tests/unit/commands/test_benchmark_cmd.py +240 -0
  63. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/commands/test_config_cmd.py +1 -1
  64. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/commands/test_doctor_cmd.py +41 -4
  65. nonoka_cli-0.2.10/tests/unit/commands/test_eval_cmd.py +43 -0
  66. nonoka_cli-0.2.10/tests/unit/commands/test_logs_cmd.py +47 -0
  67. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/commands/test_opencode_cmd.py +42 -20
  68. nonoka_cli-0.2.10/tests/unit/commands/test_plugin_cmd.py +56 -0
  69. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/commands/test_run_cmd.py +9 -0
  70. nonoka_cli-0.2.10/tests/unit/commands/test_swe_bench_cmd.py +173 -0
  71. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/config/test_models.py +0 -27
  72. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_agent_factory.py +202 -44
  73. nonoka_cli-0.2.10/tests/unit/core/test_operational_signals.py +111 -0
  74. nonoka_cli-0.2.10/tests/unit/core/test_orchestrator.py +47 -0
  75. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_plugin_manifest.py +61 -0
  76. nonoka_cli-0.2.10/tests/unit/core/test_project_agents.py +232 -0
  77. nonoka_cli-0.2.10/tests/unit/core/test_prompt_builder.py +15 -0
  78. nonoka_cli-0.2.10/tests/unit/core/test_safety_policy.py +17 -0
  79. nonoka_cli-0.2.10/tests/unit/core/test_scorecard.py +66 -0
  80. nonoka_cli-0.2.10/tests/unit/core/test_semantic_cache.py +93 -0
  81. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_tool_output_policy.py +40 -0
  82. nonoka_cli-0.2.10/tests/unit/safety/test_preflight.py +14 -0
  83. nonoka_cli-0.2.10/tests/unit/tools/test_file_tools.py +60 -0
  84. nonoka_cli-0.2.10/tests/unit/utils/test_logging.py +23 -0
  85. nonoka_cli-0.2.5/.agents/skills/nonoka-tui-testing/SKILL.md +0 -413
  86. nonoka_cli-0.2.5/.agents/skills/nonoka-tui-testing/references/checklist.md +0 -48
  87. nonoka_cli-0.2.5/.agents/skills/nonoka-tui-testing/scripts/analyze-timeline.py +0 -100
  88. nonoka_cli-0.2.5/.agents/skills/nonoka-tui-testing/scripts/capture-screenshots.py +0 -191
  89. nonoka_cli-0.2.5/.agents/skills/nonoka-tui-testing/scripts/setup-sandbox.sh +0 -237
  90. nonoka_cli-0.2.5/.agents/skills/tui-testing/SKILL.md +0 -60
  91. nonoka_cli-0.2.5/.agents/skills/tui-testing/scripts/opencode_tui.py +0 -288
  92. nonoka_cli-0.2.5/.nonoka/plugin.json.example +0 -37
  93. nonoka_cli-0.2.5/.nonoka/repo_map.jsonl +0 -85
  94. nonoka_cli-0.2.5/README.md +0 -530
  95. nonoka_cli-0.2.5/TODO.md +0 -43
  96. nonoka_cli-0.2.5/docs/external-mcp-skill-design.md +0 -542
  97. nonoka_cli-0.2.5/docs/nonoka-cli-complex-task-evaluation.md +0 -254
  98. nonoka_cli-0.2.5/docs/nonoka-cli-refactor-design.md +0 -735
  99. nonoka_cli-0.2.5/docs/subagent-refactor-design.md +0 -162
  100. nonoka_cli-0.2.5/docs/subagent-refactor-plan.md +0 -134
  101. nonoka_cli-0.2.5/install.sh +0 -373
  102. nonoka_cli-0.2.5/nonoka.yaml +0 -15
  103. nonoka_cli-0.2.5/nonoka.yaml.example +0 -50
  104. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/.gitignore +0 -34
  105. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/LICENSE +0 -21
  106. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/README.md +0 -89
  107. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/bun.lock +0 -43
  108. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/package.json +0 -53
  109. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/src/index.ts +0 -116
  110. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/src/nonoka-language-model.ts +0 -654
  111. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/src/protocol.ts +0 -174
  112. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/src/stream.ts +0 -275
  113. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/tests/language-model.test.ts +0 -251
  114. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/tests/protocol.test.ts +0 -113
  115. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/tests/stream.test.ts +0 -85
  116. nonoka_cli-0.2.5/packages/nonoka-opencode-provider/tsconfig.json +0 -24
  117. nonoka_cli-0.2.5/scripts/quick-install.sh +0 -23
  118. nonoka_cli-0.2.5/src/nonoka_cli/bridge/__init__.py +0 -19
  119. nonoka_cli-0.2.5/src/nonoka_cli/core/planning_service.py +0 -192
  120. nonoka_cli-0.2.5/src/nonoka_cli/core/review_service.py +0 -293
  121. nonoka_cli-0.2.5/src/nonoka_cli/core/subagent_service.py +0 -184
  122. nonoka_cli-0.2.5/tests/unit/core/test_orchestrator.py +0 -205
  123. nonoka_cli-0.2.5/tests/unit/core/test_planning_service.py +0 -174
  124. nonoka_cli-0.2.5/tests/unit/core/test_review_service.py +0 -251
  125. nonoka_cli-0.2.5/uv.lock +0 -3533
  126. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/LICENSE +0 -0
  127. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/NOTICE +0 -0
  128. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/__main__.py +0 -0
  129. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/commands/__init__.py +0 -0
  130. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/config/__init__.py +0 -0
  131. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/config/manager.py +0 -0
  132. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/__init__.py +0 -0
  133. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/git_service.py +0 -0
  134. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/mcp_service.py +0 -0
  135. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/plugin_manifest_converter.py +0 -0
  136. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/repo_map_service.py +0 -0
  137. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/runner_service.py +0 -0
  138. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/session_service.py +0 -0
  139. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/task_state.py +0 -0
  140. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/core/tool_service.py +0 -0
  141. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/mcp/__init__.py +0 -0
  142. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/mcp/manager.py +0 -0
  143. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/mcp/models.py +0 -0
  144. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/sessions/__init__.py +0 -0
  145. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/sessions/manager.py +0 -0
  146. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/sessions/models.py +0 -0
  147. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/skills/__init__.py +0 -0
  148. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/tools/__init__.py +0 -0
  149. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/tools/builtins/__init__.py +0 -0
  150. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/tools/loader.py +0 -0
  151. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/utils/__init__.py +0 -0
  152. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/src/nonoka_cli/utils/errors.py +0 -0
  153. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/conftest.py +0 -0
  154. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/config/test_loader.py +0 -0
  155. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_context_trimmer.py +0 -0
  156. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_git_service.py +0 -0
  157. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_plugin_manifest_converter.py +0 -0
  158. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_repo_map_service.py +0 -0
  159. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/core/test_task_state.py +0 -0
  160. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/sessions/test_manager.py +0 -0
  161. {nonoka_cli-0.2.5 → nonoka_cli-0.2.10}/tests/unit/utils/test_trace_logger.py +0 -0
@@ -61,4 +61,12 @@ verdaccio-storage/
61
61
 
62
62
  # Private planning documents
63
63
  DESIGN.md
64
- REFACTOR.md
64
+ REFACTOR.md
65
+ /SWE_BENCH_FOLLOW_UP.md
66
+ /TODO.md
67
+ /nonoka.yaml
68
+
69
+ # Runtime nonoka project artifacts
70
+ .nonoka/repo_map.jsonl
71
+ .nonoka/tasks/
72
+ .nonoka/eval/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nonoka-cli
3
- Version: 0.2.5
3
+ Version: 0.2.10
4
4
  Summary: OpenCode backend for the Nonoka Agent framework
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Requires-Python: >=3.10
17
- Requires-Dist: nonoka>=1.3.4
17
+ Requires-Dist: nonoka>=1.3.7
18
18
  Requires-Dist: pydantic>=2.0
19
19
  Requires-Dist: python-dotenv>=1.0
20
20
  Requires-Dist: pyyaml>=6.0
@@ -29,6 +29,8 @@ Description-Content-Type: text/markdown
29
29
 
30
30
  # nonoka-cli
31
31
 
32
+ English | [简体中文](README.zh-CN.md)
33
+
32
34
  OpenCode backend for the [Nonoka](https://pypi.org/project/nonoka/) Agent framework.
33
35
 
34
36
  `nonoka-cli` runs as a stdio NDJSON bridge server (`nonoka-cli --server`) that
@@ -99,7 +101,7 @@ For scripted setups, use the non-interactive mode (you'll still need to set the
99
101
  API key via `.env` or `export`):
100
102
 
101
103
  ```bash
102
- nonoka-cli config init --yes --model deepseek-chat
104
+ nonoka-cli config init --yes --model deepseek/deepseek-v4-pro
103
105
  ```
104
106
 
105
107
  2. Generate an OpenCode config in the current project or globally:
@@ -130,10 +132,11 @@ Example output:
130
132
 
131
133
  ```
132
134
  nonoka-cli doctor
133
- ✓ nonoka-cli 0.2.5
135
+ ✓ nonoka-cli 0.2.10
134
136
  ✓ Python 3.11
135
137
  ✓ opencode 1.18.2
136
- ✓ provider nonoka-opencode-provider@0.2.12
138
+ ✓ provider nonoka-opencode-provider@0.2.16
139
+ ✓ nonoka framework 1.3.7
137
140
  ✓ config ~/.config/nonoka/config.yaml
138
141
  ✓ API key DEEPSEEK_API_KEY set
139
142
  ✓ OpenCode provider config in /home/user/.config/opencode/opencode.json
@@ -146,12 +149,196 @@ key with a real (small) call, use:
146
149
  nonoka-cli doctor --check-llm
147
150
  ```
148
151
 
152
+ Verify the Docker-backed command sandbox separately:
153
+
154
+ ```bash
155
+ nonoka-cli doctor --check-sandbox
156
+ ```
157
+
158
+ ## Execution Observability
159
+
160
+ Every local runner session writes credential-redacted structured events to
161
+ `~/.local/share/nonoka/events.db`. Events include LLM prompts/responses,
162
+ tool I/O, errors, and LiteLLM token/cost usage. Inspect them without opening
163
+ the database directly:
164
+
165
+ ```bash
166
+ nonoka-cli sessions list
167
+ nonoka-cli sessions show <session-id>
168
+ nonoka-cli logs --session-id <session-id>
169
+ nonoka-cli logs --json
170
+ ```
171
+
172
+ The framework exposes a provider-neutral `TelemetryExporter` protocol and
173
+ `ObservabilityPipeline`; downstream applications can add Langfuse, OTLP, or
174
+ other exporters without coupling `Runner` to a vendor SDK. Export failures are
175
+ best-effort and never interrupt an agent run.
176
+
177
+ ## Service Deployment
178
+
179
+ `nonoka-agent` includes an authenticated FastAPI application with `/run`,
180
+ `/chat`, `/tasks`, `/health`, and `/metrics`. Set a bearer token before
181
+ starting it:
182
+
183
+ ```bash
184
+ export NONOKA_API_TOKEN="replace-with-a-long-random-token"
185
+ uv run uvicorn nonoka.server.app:create_app --factory --host 0.0.0.0 --port 8000
186
+ ```
187
+
188
+ For a containerized deployment, copy `.env.example` to `.env`, set
189
+ `NONOKA_API_TOKEN`, then run `docker compose up --build`. Compose defaults to
190
+ PostgreSQL for persisted events; local development stays on SQLite. The service
191
+ is non-root, read-only, drops Linux capabilities, and does not mount the host
192
+ Docker socket.
193
+
194
+ ## Agent evaluation
195
+
196
+ `nonoka-cli eval` is a thin frontend for the framework-owned benchmark engine. Its
197
+ scored built-ins are the open HumanEval and MBPP datasets. The bundled
198
+ `tool_use` suite is deliberately labelled as deterministic smoke/regression
199
+ coverage; it is not presented as a substitute for an open benchmark. Results
200
+ are stored under `.nonoka/eval/` in the current project and can be compared
201
+ locally:
202
+
203
+ ```bash
204
+ nonoka-cli eval list
205
+ nonoka-cli eval run --dataset humaneval --model deepseek/deepseek-v4-pro --limit 20
206
+ nonoka-cli eval run --dataset mbpp --model deepseek/deepseek-v4-pro --limit 20
207
+ nonoka-cli eval leaderboard
208
+ ```
209
+
210
+ Each built-in run records a normal Nonoka agent and a same-model direct
211
+ baseline, including pass@1, turns, tool calls, token usage, wall time, and the
212
+ agent lift. Live model calls are opt-in and are never part of the default test
213
+ suite.
214
+
215
+ For a release comparison, create a manifest before incurring any model cost.
216
+ It pins the model policy and includes HumanEval, MBPP sanitized, EvalPlus,
217
+ τ³ retail/airline, and Terminal-Bench. EvalPlus runs in a separate environment
218
+ because it owns the official strengthened verifier:
219
+
220
+ ```bash
221
+ nonoka-cli eval matrix plan --model deepseek/deepseek-v4-pro --output .nonoka/eval/release-matrix.json
222
+ export NONOKA_EVALPLUS_PYTHON=/path/to/evalplus-python
223
+ nonoka-cli eval matrix run --manifest .nonoka/eval/release-matrix.json --include evalplus-humaneval
224
+ ```
225
+
226
+ For complex agent tasks, the framework delegates to official harnesses instead
227
+ of reimplementing their verifiers. τ³-bench (the `tau2-bench` package) provides
228
+ multi-turn customer-service tasks with policies, simulated users, environment
229
+ tools, and action-level reward; it runs from an isolated Python 3.12
230
+ environment because of its dependency pins:
231
+
232
+ ```bash
233
+ export NONOKA_TAU2_PYTHON=/path/to/tau2-python
234
+ nonoka-cli eval external run --benchmark tau2-bench --model deepseek/deepseek-v4-pro --domain retail --limit 10
235
+ ```
236
+
237
+ For framework-only terminal-agent tasks, Terminal-Bench 2 delegates Docker
238
+ lifecycle and verification to Harbor. The OpenCode bridge has its own
239
+ reproducible benchmark command, so a framework score is never presented as a
240
+ CLI bridge score. Install Harbor plus the local framework/CLI checkouts in an
241
+ isolated environment, then verify prerequisites before starting a live run:
242
+
243
+ ```bash
244
+ uv venv .venv-bench --python 3.13
245
+ uv pip install --python .venv-bench/bin/python -e ../nonoka-agent -e . harbor
246
+ export NONOKA_HARBOR_BIN="$PWD/.venv-bench/bin/harbor"
247
+ nonoka-cli doctor --check-benchmarks
248
+ nonoka-cli benchmark smoke --model deepseek/deepseek-v4-pro
249
+ nonoka-cli benchmark terminal-bench --model deepseek/deepseek-v4-pro
250
+ ```
251
+
252
+ The Terminal-Bench command builds fresh local wheels, stages the built OpenCode
253
+ provider plus its dependencies, and copies verified host OpenCode and Python
254
+ 3.13 runtime artifacts into every Harbor task container. The runtime is also
255
+ registered in uv's conventional managed-Python directory, so both the non-root
256
+ agent and official verifier scripts can reuse it without downloading another
257
+ interpreter. This ensures the
258
+ official verifier observes OpenCode using the current nonoka bridge against the task
259
+ filesystem—not a host-side shell. To verify provisioning before spending model
260
+ tokens, run one pinned task first:
261
+
262
+ ```bash
263
+ nonoka-cli benchmark terminal-bench --task regex-log --install-only
264
+ ```
265
+
266
+ The adapter also exposes the staged `uv` as `/root/.local/bin/uv` and `uvx`.
267
+ Verifier scripts that replace that binary still discover the registered Python
268
+ runtime. This does not preinstall task-specific test packages, data, or solution
269
+ artifacts.
270
+
271
+ Live benchmark runs do not impose cumulative model-turn, tool-call, or
272
+ per-model-call limits by default. The one-hour process watchdog only protects
273
+ against a lost or permanently stuck agent process. Use `--max-turns`,
274
+ `--tool-budget`, or `--timeout` when a deliberately bounded profile is needed.
275
+
276
+ Harbor receives the model credential through its `${DEEPSEEK_API_KEY}`
277
+ environment template. The value is never placed in the benchmark manifest or
278
+ artifact directory.
279
+
280
+ Each bridge run writes a credential-redacted manifest, OpenCode JSON events,
281
+ provider/bridge traces, and a reference to the official Harbor job directory
282
+ under `.nonoka/eval/opencode/`. Docker access is required.
283
+
284
+ SWE-bench Lite uses the official verifier and keeps its bridge artifacts
285
+ separate from Terminal-Bench. It requires the official `swebench` package,
286
+ Docker, at least 120 GiB free disk, and 16 GiB RAM for a full Lite run. A
287
+ single explicit instance may be generated and verified on a constrained host:
288
+
289
+ ```bash
290
+ nonoka-cli benchmark swe-bench --instance-id django__django-10914 \
291
+ --model deepseek/deepseek-v4-flash \
292
+ --swebench-python /path/to/swebench-venv/bin/python \
293
+ --max-workers 1 \
294
+ --artifact-dir .nonoka/eval/swe-flash-django-10914
295
+ ```
296
+
297
+ To verify a previously generated prediction without another model call, pass
298
+ its official `predictions.jsonl` instead:
299
+
300
+ ```bash
301
+ nonoka-cli benchmark swe-bench --instance-id <instance-id> \
302
+ --predictions /path/to/predictions.jsonl \
303
+ --artifact-dir .nonoka/eval/swe-lite-<instance-id>
304
+ ```
305
+
306
+ The command writes a verifier command, stdout/stderr, `diagnosis.json`, and a
307
+ human-readable diagnosis. It classifies infrastructure, bridge/provider,
308
+ agent-loop, and verifier failures separately; use the same instance for an
309
+ explicit Aider or native OpenCode comparison after a healthy bridge run fails.
310
+
311
+ ### Verified benchmark and regression results
312
+
313
+ The current verification-contract and bounded multi-agent implementation has passed the following checks against the local sibling `nonoka-agent` checkout:
314
+
315
+ - `543` deterministic nonoka-agent tests passed (`45` opt-in live tests were deselected).
316
+ - `280` nonoka-cli unit, integration, and bridge tests passed.
317
+ - `62` OpenCode provider tests passed, followed by a successful TypeScript build.
318
+ - A clean OpenCode TUI multi-agent run used `agent__spawn` for both planning and review, recovered two intentionally partial file observations with bounded follow-up reads, completed a real workspace change, and passed all `16` focused acceptance tests. Its final response turn exposed no tools and made no host tool calls.
319
+ - Official SWE-bench Lite verification for eight distinct instances: `astropy__astropy-12907`, `django__django-10914`, `django__django-10924`, `django__django-11001`, `django__django-11099`, `pytest-dev__pytest-11143`, `pallets__flask-4045`, and `sympy__sympy-11400`.
320
+
321
+ The pinned `swe-flash-selected10-v1` regression sample resolved 6 of 10 instances with `deepseek/deepseek-v4-flash`. Subsequent `deepseek/deepseek-v4-pro` runs independently resolved several Django and cross-project instances and, after the verification-contract remediation, resolved the previously failing `pallets__flask-4045` and `sympy__sympy-11400` instances. All reported results come from the official SWE-bench verifier rather than model-authored assertions. They are targeted engineering samples, not a claim of a full SWE-bench Lite score.
322
+
323
+ Reference end-to-end validation with `deepseek/deepseek-v4-pro` against the
324
+ pinned Terminal-Bench 2 revision (`69671fba`) has earned official Harbor reward
325
+ `1` on three distinct tasks: `sanitize-git-repo`, `configure-git-webserver`, and
326
+ `break-filter-js-from-html`. The latest bridge-hardening rerun of
327
+ `break-filter-js-from-html` completed without an exception in 10m21s. These are
328
+ single-trial engineering checks, not a statistically representative leaderboard
329
+ score.
330
+
331
+ `benchmark smoke` pins OpenCode to the checkout's built provider with a local
332
+ `file:` dependency and temporarily writes an isolated `opencode.json` in the
333
+ benchmark workspace. Use a clean `--cwd` (or pass `--provider-source`) so it
334
+ never overrides an existing project OpenCode configuration.
335
+
149
336
  ## Configuration
150
337
 
151
338
  ### `nonoka-cli config init`
152
339
 
153
340
  Interactive wizard that writes `~/.config/nonoka/config.yaml`. It asks for a
154
- model identifier (e.g. `deepseek-chat`, `openai/gpt-4o`, `ollama/llama3.3`), a
341
+ model identifier (e.g. `deepseek/deepseek-v4-pro`, `openai/gpt-4o`, `ollama/llama3.3`), a
155
342
  masked API key, and whether to save it to `~/.config/nonoka/.env` (recommended),
156
343
  directly in `config.yaml`, or skip saving. It also asks for a system prompt and
157
344
  whether to auto-approve all tool calls.
@@ -176,6 +363,46 @@ nonoka-cli config set hitl.dangerous_tools '["write_file", "execute_command"]'
176
363
 
177
364
  Print the resolved configuration and its file path.
178
365
 
366
+ ### Cost controls and response cache
367
+
368
+ The runner keeps a local SQLite exact-response cache by default. It only stores
369
+ complete responses without tool calls, and its key includes the model, complete
370
+ message history, tool schema, generation settings, and workspace namespace.
371
+
372
+ Semantic reuse is opt-in because it has a stricter correctness contract. It
373
+ uses an OpenAI-compatible embedding endpoint only for deterministic, tool-free,
374
+ single-turn requests in a Git worktree. The cache scope is recomputed before
375
+ each completion from `HEAD`, tracked/untracked changes, the repo-map index,
376
+ system prompt, and workspace path. A write made earlier in the same OpenCode
377
+ session therefore invalidates semantic candidates immediately. Non-Git
378
+ workspaces, tool calls, and multi-turn conversations fall back to the model.
379
+
380
+ ```yaml
381
+ cache:
382
+ enabled: true
383
+ path: ~/.cache/nonoka/llm-cache.sqlite3
384
+ ttl_seconds: 604800
385
+ semantic_enabled: true
386
+ embedding_model: qwen3.7-text-embedding
387
+ embedding_api_base: https://your-endpoint/compatible-mode/v1
388
+ embedding_api_key_env: DASHSCOPE_API_KEY
389
+ embedding_dimensions: 1024
390
+ semantic_threshold: 0.92
391
+
392
+ budget:
393
+ max_total_tokens: 120000
394
+ max_cost_usd: 5.0
395
+ fail_on_unknown_cost: true
396
+ ```
397
+
398
+ Keep the embedding credential in the named environment variable or
399
+ `~/.config/nonoka/.env`, never in `config.yaml`. A semantic hit is recorded as
400
+ saved usage rather than actual spend; the event store exposes cache source and
401
+ similarity score without storing raw cache queries. `max_total_tokens` and
402
+ `max_cost_usd` are hard limits persisted with the task session; when price data
403
+ is unavailable, `fail_on_unknown_cost: true` terminates the task rather than
404
+ silently exceeding the cost budget.
405
+
179
406
  ### `nonoka-cli opencode init`
180
407
 
181
408
  Generate or merge an `opencode.json` in the current directory and create
@@ -207,7 +434,7 @@ A typical generated `opencode.json` looks like:
207
434
  "configPath": "~/.config/nonoka/config.yaml"
208
435
  },
209
436
  "models": {
210
- "default": { "name": "Nonoka deepseek-chat" }
437
+ "default": { "name": "Nonoka deepseek-v4-pro" }
211
438
  }
212
439
  }
213
440
  },
@@ -292,7 +519,7 @@ nonoka-cli can merge MCP tools and lazy-loaded skills alongside OpenCode's
292
519
  native tools. Configure them in `~/.config/nonoka/config.yaml`:
293
520
 
294
521
  ```yaml
295
- model: deepseek-chat
522
+ model: deepseek/deepseek-v4-pro
296
523
 
297
524
  mcp_servers:
298
525
  filesystem:
@@ -305,13 +532,12 @@ skills:
305
532
  - nextjs-best-practices
306
533
  ```
307
534
 
535
+ Store each skill at `.agents/skills/<name>/SKILL.md` in the project or at `~/.agents/skills/<name>/SKILL.md` for user-wide use. Project definitions take precedence. Legacy flat `skills/<name>.md` files are still recognized.
536
+
308
537
  - **MCP tools** are executed locally by nonoka-cli and are exposed with a
309
538
  `mcp__<server>__<tool>` namespace prefix so they do not collide with OpenCode
310
539
  native tools.
311
- - **Skills** use nonoka-agent's lazy `SkillRegistry`. Only names and
312
- descriptions are injected into the system prompt; full guidance is loaded
313
- on-demand via the `load_skill` tool. Skill tools are prefixed with
314
- `skill__<skill>__<tool>` in external-tools mode.
540
+ - **Skills** use nonoka-agent's lazy `SkillRegistry`. Discovery reads names and descriptions without importing skill tools; enabled skill tools are resolved when the runtime catalog is built, while full guidance, its root directory, and bundled resource paths are loaded on-demand via `load_skill` and protected from normal context compaction. Skill tools are prefixed with `skill__<skill>__<tool>` in external-tools mode.
315
541
 
316
542
  Both MCP tools and skill tools remain available in standalone mode without any
317
543
  prefixing.
@@ -330,10 +556,7 @@ tools:
330
556
  When loaded, use the say_hello tool to greet the user by name.
331
557
  ```
332
558
 
333
- `greet_tool:say_hello` is resolved by Python's normal import machinery, so the
334
- module must be importable from the project working directory (or from a directory
335
- on `PYTHONPATH`). Place the tool module next to your skill file or add the skill
336
- source directory to `PYTHONPATH` if you use a nested layout.
559
+ `greet_tool:say_hello` is resolved by Python's normal import machinery, so the module must be importable from the project working directory (or from a directory on `PYTHONPATH`). For a tool file bundled with the skill, use a path relative to `SKILL.md`, for example `file: scripts/greet_tool.py:say_hello`.
337
560
 
338
561
  ### Avoiding OpenCode's native `skill` tool
339
562
 
@@ -376,55 +599,58 @@ query the index on demand.
376
599
 
377
600
  ## Sub-agent workflow
378
601
 
379
- `nonoka-cli` can optionally expose two sub-agent tools that the main agent can
380
- call for complex tasks:
381
-
382
- - `plan_task` — delegates planning to a dedicated **planner** agent and returns a
383
- numbered, file-level execution plan.
384
- - `review_changes` — delegates final review to a dedicated **reviewer** agent and
385
- returns a structured review with issues, suggestions, and an approval flag.
386
-
387
- Both are disabled by default. Enable them by setting their model in `nonoka.yaml`:
388
-
389
- ```yaml
390
- model: deepseek-chat
391
- max_turns: 20
602
+ Projects may declare bounded advisory roles in `.nonoka/plugin.json`. Each valid role becomes a local tool named `agent__<role>`; the main Agent decides whether to delegate to it.
392
603
 
393
- agents:
394
- planner:
395
- model: deepseek-chat
396
- system_prompt: "You are a planning agent..."
397
- reviewer:
398
- model: deepseek-chat
399
- system_prompt: "You are a senior code reviewer..."
604
+ ```json
605
+ {
606
+ "schema_version": "1.0",
607
+ "name": "project-agents",
608
+ "agents": [
609
+ {
610
+ "name": "planner",
611
+ "description": "Produce a concise implementation plan.",
612
+ "model": "deepseek/deepseek-v4-pro",
613
+ "system_prompt": "Return a numbered plan, risks, and focused checks.",
614
+ "max_turns": 2,
615
+ "max_invocations": 1,
616
+ "allowed_tools": []
617
+ },
618
+ {
619
+ "name": "reviewer",
620
+ "description": "Review a proposed change for blocking defects.",
621
+ "model": "deepseek/deepseek-v4-pro",
622
+ "system_prompt": "Return blocking issues, missing requirements, and an approval decision.",
623
+ "output_contract": "review",
624
+ "max_turns": 3,
625
+ "max_invocations": 2,
626
+ "allowed_tools": []
627
+ }
628
+ ],
629
+ "dynamic_agent": {
630
+ "enabled": true,
631
+ "model": "deepseek/deepseek-v4-pro",
632
+ "base_system_prompt": "You are a temporary advisory sub-agent. Return concise, actionable findings to the parent.",
633
+ "max_turns": 2,
634
+ "max_invocations": 2,
635
+ "max_instruction_chars": 2000,
636
+ "max_context_chars": 16000
637
+ }
638
+ }
400
639
  ```
401
640
 
402
- `max_turns` at the top level controls the main executor agent. The
403
- `planner`/`reviewer` roles each have their own `max_turns` inside
404
- `agents.<role>`.
641
+ The tool input is `{"task": "...", "context": "..."}`. Child Agents use isolated memory, one-level delegation, bounded turns, and no tools. They cannot read or modify the workspace, so the parent must include all relevant evidence in `context`; their output is advisory and cannot replace editing or verification.
405
642
 
406
- When enabled, these tools are injected into the main agent's tool list
407
- alongside OpenCode's native tools. The main agent decides when to call them;
408
- the planner/reviewer run inside their own short-lived `nonoka` agent invocation
409
- and return their results as tool output.
643
+ When `dynamic_agent.enabled` is true, the main Agent also receives `agent__spawn`. It may choose a bounded `role`, `instructions`, `task`, and `context`, but the project policy fixes the model, base prompt, turn budget, invocation budget, and input sizes. Dynamically created children are still tool-free and cannot create further agents. The tool deliberately accepts no `model`, `tools`, permission, or budget arguments.
410
644
 
411
- `review_changes` accepts an optional `files` argument. When the main agent
412
- passes file paths, the reviewer reads those files and prepends their contents
413
- to the review context automatically:
645
+ After the configured mutation and verification evidence is satisfied, Nonoka uses a tool-free finalization turn. This prevents optional cleanup or repeated checks from consuming the remaining turn budget after a task is already done. For evidence-gated runs, `maxTurns` therefore counts work turns and the runtime reserves one additional model call solely to produce the final response.
414
646
 
415
- ```yaml
416
- # In the conversation the model can call:
417
- # review_changes({
418
- # "task": "Review the changes against the goal: add logging",
419
- # "context": "<diff or summary>",
420
- # "files": ["src/main.py", "src/utils.py"]
421
- # })
647
+ Validate the effective role configuration with:
648
+
649
+ ```bash
650
+ nonoka-cli plugin validate --manifest .nonoka/plugin.json
422
651
  ```
423
652
 
424
- > **Note:** `plan_task` and `review_changes` used to live in `nonoka-agent`. They
425
- > have been moved to `nonoka-cli` so that sub-agent configuration (model, system
426
- > prompt, max turns) is controlled by the CLI config and can use different
427
- > models from the main agent.
653
+ Set `NONOKA_DISABLE_PROJECT_AGENTS=1` to disable both static project roles and dynamic spawning. Benchmark profiles set this automatically so existing single-Agent scores remain comparable.
428
654
 
429
655
  ## Plugin manifest
430
656
 
@@ -432,13 +658,12 @@ Projects can declare their own Nonoka plugins via `.nonoka/plugin.json`:
432
658
 
433
659
  ```json
434
660
  {
661
+ "schema_version": "1.0",
435
662
  "name": "my-plugin",
436
- "skills": ["code-review"],
437
- "agents": {
438
- "planner": { "system_prompt": "..." }
439
- },
440
- "mcpServers": {},
441
- "allowedTools": ["read", "edit", "bash"]
663
+ "skills": [{"name": "code-review"}],
664
+ "agents": [],
665
+ "mcp_servers": {},
666
+ "allowed_tools": ["read", "edit", "bash"]
442
667
  }
443
668
  ```
444
669
 
@@ -526,7 +751,7 @@ src/nonoka_cli/
526
751
  ├── config/ # YAML config loading and Pydantic models
527
752
  ├── core/ # Orchestrator, RunnerService, SessionService, ToolService,
528
753
  │ # MCPService, AgentFactory, prompt/context/task-state/output pruning,
529
- │ # git safety net, repo map, planning, and plugin manifest
754
+ │ # git safety net, repo map, project agents, and plugin manifest
530
755
  │ # agent_factory.py # Build nonoka Agent from CLI config
531
756
  │ # prompt_builder.py # System prompt assembly for OpenCode mode
532
757
  │ # context_trimmer.py # Turn-based context window trimming
@@ -534,9 +759,8 @@ src/nonoka_cli/
534
759
  │ # tool_output_policy.py # Tool output pruning / spill policy
535
760
  │ # git_service.py # Git checkpoint / rollback helpers
536
761
  │ # repo_map_service.py # Symbol index generation and search
537
- │ # planning_service.py # Planner sub-agent (AgentTool)
538
- │ # review_service.py # Reviewer sub-agent (AgentTool)
539
762
  │ # plugin_manifest.py # .nonoka/plugin.json loader
763
+ │ # project_agents.py # Compile bounded manifest roles
540
764
  │ # plugin_manifest_converter.py # OpenCode skill/permission conversion
541
765
  ├── mcp/ # MCP server lifecycle manager (thin wrapper around nonoka-agent)
542
766
  ├── sessions/ # Session metadata persistence