turnloop 0.1.10__tar.gz → 0.1.12__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.
- {turnloop-0.1.10 → turnloop-0.1.12}/PKG-INFO +12 -6
- {turnloop-0.1.10 → turnloop-0.1.12}/README.md +1244 -1238
- {turnloop-0.1.10 → turnloop-0.1.12}/pyproject.toml +1 -1
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_config.py +42 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_providers.py +169 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_skills_install.py +208 -0
- turnloop-0.1.12/tests/test_subagent_extras.py +186 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_system_prompt_layout.py +9 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/__init__.py +1 -1
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/agent/factory.py +172 -175
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/agent/loop.py +14 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/agent/system_prompt.py +2 -1
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/cli.py +17 -6
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/config.py +17 -2
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/diagnostics.py +5 -3
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/base.py +53 -3
- turnloop-0.1.12/turnloop/providers/registry.py +111 -0
- turnloop-0.1.10/turnloop/providers/registry.py +0 -75
- {turnloop-0.1.10 → turnloop-0.1.12}/.gitignore +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/conftest.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/fixtures/anthropic_tool_call.sse +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/fixtures/github_chrome.html +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/fixtures/github_page.html +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/fixtures/glm_tool_call.sse +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/fixtures/mcp_echo_server.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_bash.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_compaction.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_config_screen.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_configio.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_experiments.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_hooks_mcp_commands.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_loop.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_permissions.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_tools_files.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_tui.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_webfetch.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/tests/test_websearch.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/__main__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/agent/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/agent/headless.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/agent/subagent.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/commands/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/commands/dispatch.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/commands/loader.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/configio.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/context/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/context/budget.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/context/compaction.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/context/memory.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/core/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/core/events.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/core/ids.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/core/messages.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/core/tokens.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/errors.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/bakeoff.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/ceiling-check.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/context-glm.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/context.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/glm-selfhosted.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/groq-free.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/hard-calibration.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/hard-glm.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/loop.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/nvidia-smoke.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/reliability.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/rewrite-calibration.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/configs/smoke.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/graders.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/report.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/runner.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/default.yaml +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_1.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_2.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_3.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_4.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_5.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_6.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_7.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/bulky/module_8.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/circular_import/models.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/circular_import/services.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/circular_import/test_cancel.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/cli_flag/app.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/cross_file_contract/decode.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/cross_file_contract/encode.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/cross_file_contract/test_roundtrip.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/cross_file_contract/test_wire_format.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/empty/.keep +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/failing_test/calc.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/failing_test/test_calc.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/generate_bulky.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/grep_edit/ingest.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/grep_edit/load.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/grep_edit/transform.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/misleading_traceback/checkout.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/misleading_traceback/invoice.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/misleading_traceback/pricing.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/misleading_traceback/test_checkout.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/misleading_traceback/test_invoice.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/needle/inventory.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/needle/pricing.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/needle/shipping.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/regression_trap/test_validators.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/regression_trap/validators.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/rename/billing.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/rename/report.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/rename/test_billing.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/spec/parser.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/spec/test_parser.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/subtle_spec_edge/leaderboard.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/subtle_spec_edge/test_leaderboard.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/experiments/suite/fixtures/util/util.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/hooks/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/hooks/runner.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/mcp/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/mcp/adapter.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/mcp/client.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/permissions/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/permissions/engine.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/permissions/rules.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/anthropic.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/gemini.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/mock.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/openai_compat.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/pricing.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/providers/sse.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/sessions/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/sessions/models.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/sessions/store.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/skills_install.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/ask.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/base.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/bash.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/builtin.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/edit.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/glob.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/grep.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/read.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/runner.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/shell.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/skill.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/task.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/textio.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/todo.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/webfetch.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/websearch.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tools/write.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/app.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/app.tcss +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/bridge.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/config_screen.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/mcp_screen.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/session_screen.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/widgets/__init__.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/widgets/permission.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/widgets/status.py +0 -0
- {turnloop-0.1.10 → turnloop-0.1.12}/turnloop/tui/widgets/transcript.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: turnloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: A local-first agentic coding harness: streaming tool loop, permission gating, context compaction, subagents, and any LLM provider.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Pranesh-2005/turnloop
|
|
6
6
|
Author: Pranesh
|
|
@@ -49,7 +49,7 @@ tl experiment run smoke # a measurement run, offline and free
|
|
|
49
49
|
|
|
50
50
|
Four runtime dependencies: `textual`, `pydantic`, `httpx`, `pyyaml`. No vendor
|
|
51
51
|
SDKs, no agent framework — the loop is the point, so the loop is written here.
|
|
52
|
-
~21,
|
|
52
|
+
~21,900 lines of Python, 383 tests, no network in the default test run.
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -117,7 +117,7 @@ point.
|
|
|
117
117
|
Verify:
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
tl --version # turnloop 0.1.
|
|
120
|
+
tl --version # turnloop 0.1.12
|
|
121
121
|
tl doctor # every provider, key presence, shell, context budget
|
|
122
122
|
```
|
|
123
123
|
|
|
@@ -439,6 +439,12 @@ All nine ship preconfigured. `doctor` shows which have keys present.
|
|
|
439
439
|
| `blaxel` | openai_compat | `gpt-4o-mini` | `BL_API_KEY` | sandbox; ignores the model field |
|
|
440
440
|
| `ollama` | openai_compat | `qwen2.5-coder:14b` | none | local |
|
|
441
441
|
|
|
442
|
+
**Multiple keys per provider.** Free-tier accounts run out fast, so any `*_API_KEY`
|
|
443
|
+
also accepts numbered siblings: `GROQ_API_KEY`, `GROQ_API_KEY_1`, `GROQ_API_KEY_2`, ...
|
|
444
|
+
up to `_20`. On a 429, 401, or 403, turnloop rotates to the next configured key and
|
|
445
|
+
retries the same turn instead of failing it — each key is tried at most once per turn.
|
|
446
|
+
`doctor` reports the count, e.g. `GROQ_API_KEY set (3 keys)`, never the values.
|
|
447
|
+
|
|
442
448
|
Three provider facts that are configuration rather than capability, each learned from
|
|
443
449
|
a live failure:
|
|
444
450
|
|
|
@@ -1023,7 +1029,7 @@ one-line edit in a CRLF checkout does not produce a whole-file diff.
|
|
|
1023
1029
|
## Testing
|
|
1024
1030
|
|
|
1025
1031
|
```bash
|
|
1026
|
-
pytest #
|
|
1032
|
+
pytest # 383 tests, no network
|
|
1027
1033
|
ruff check turnloop
|
|
1028
1034
|
mypy turnloop
|
|
1029
1035
|
```
|
|
@@ -1032,12 +1038,12 @@ mypy turnloop
|
|
|
1032
1038
|
|---|---|---|
|
|
1033
1039
|
| `test_permissions.py` | 50 | rule grammar, compound-command splitting, mode enforcement |
|
|
1034
1040
|
| `test_experiments.py` | 36 | runner, graders, report, suite invariants, config resolution |
|
|
1035
|
-
| `test_providers.py` |
|
|
1041
|
+
| `test_providers.py` | 44 | adapters vs recorded `.sse`, image blocks, thought signatures, multi-key rotation on 429/401 |
|
|
1036
1042
|
| `test_tools_files.py` | 28 | Read/Write/Edit/Glob/Grep, encodings, newlines, image detection |
|
|
1037
1043
|
| `test_hooks_mcp_commands.py` | 28 | lifecycle hooks, MCP client, slash commands |
|
|
1038
1044
|
| `test_tui.py` | 25 | Textual snapshots, `/config` and `/mcp add` driven through a real app |
|
|
1039
1045
|
| `test_config.py` | 23 | layering, env overrides, presets, narrow-console guard |
|
|
1040
|
-
| `test_skills_install.py` |
|
|
1046
|
+
| `test_skills_install.py` | 43 | frontmatter validation, GitHub resolution, agent-mirror tiebreak, concurrent fetch ordering, console caps, non-TTY refusal on an open stdin pipe, drive-root refusal |
|
|
1041
1047
|
| `test_loop.py` | 23 | streaming, truncation, iteration cap |
|
|
1042
1048
|
| `test_compaction.py` | 16 | three tiers, tool_use/tool_result invariant |
|
|
1043
1049
|
| `test_configio.py` | 15 | minimal-diff writes, atomic save, secret-bearing MCP targets, the settings deny rules |
|