uv-agent 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. uv_agent-0.1.0/.code-search/.gitignore +1 -0
  2. uv_agent-0.1.0/.code-search/files/00/00ed7e387c98d7ef.bin +0 -0
  3. uv_agent-0.1.0/.code-search/files/06/06fdade8cb2a357b.bin +0 -0
  4. uv_agent-0.1.0/.code-search/files/0b/0bb19dfda21091e2.bin +0 -0
  5. uv_agent-0.1.0/.code-search/files/12/12f45ee2ed61ca20.bin +0 -0
  6. uv_agent-0.1.0/.code-search/files/17/173f249032d9d838.bin +0 -0
  7. uv_agent-0.1.0/.code-search/files/19/19d73df15641d86c.bin +0 -0
  8. uv_agent-0.1.0/.code-search/files/20/20ba2e72a6b60622.bin +0 -0
  9. uv_agent-0.1.0/.code-search/files/22/2239b4875fe0fdf8.bin +0 -0
  10. uv_agent-0.1.0/.code-search/files/25/25559c07d119d065.bin +0 -0
  11. uv_agent-0.1.0/.code-search/files/27/2715db6ea5b2fdbd.bin +0 -0
  12. uv_agent-0.1.0/.code-search/files/2f/2ff0b007896e1441.bin +0 -0
  13. uv_agent-0.1.0/.code-search/files/30/30f4a2b346000ac2.bin +0 -0
  14. uv_agent-0.1.0/.code-search/files/35/358b77ce3308283d.bin +0 -0
  15. uv_agent-0.1.0/.code-search/files/39/39372ac99dd5247d.bin +0 -0
  16. uv_agent-0.1.0/.code-search/files/40/40705a33d911a690.bin +0 -0
  17. uv_agent-0.1.0/.code-search/files/49/4904f4b8897fe18b.bin +0 -0
  18. uv_agent-0.1.0/.code-search/files/49/49c9f8733f6113af.bin +0 -0
  19. uv_agent-0.1.0/.code-search/files/50/50a5e3c34c19cd22.bin +0 -0
  20. uv_agent-0.1.0/.code-search/files/65/6522ac861947ee16.bin +0 -0
  21. uv_agent-0.1.0/.code-search/files/6a/6ab0eb854e105f7f.bin +0 -0
  22. uv_agent-0.1.0/.code-search/files/6a/6ade00a40c70369c.bin +0 -0
  23. uv_agent-0.1.0/.code-search/files/71/717341c48ff8721e.bin +0 -0
  24. uv_agent-0.1.0/.code-search/files/72/7279d8a152b81de9.bin +0 -0
  25. uv_agent-0.1.0/.code-search/files/79/7985c2829c3c52c2.bin +0 -0
  26. uv_agent-0.1.0/.code-search/files/83/8362287575c9dc28.bin +0 -0
  27. uv_agent-0.1.0/.code-search/files/85/859784aab205bcf1.bin +0 -0
  28. uv_agent-0.1.0/.code-search/files/8f/8f2b3f194ea29f1e.bin +0 -0
  29. uv_agent-0.1.0/.code-search/files/91/916fc738a0456fdb.bin +0 -0
  30. uv_agent-0.1.0/.code-search/files/92/9252e5ce62d73b31.bin +0 -0
  31. uv_agent-0.1.0/.code-search/files/93/93b0c37eb345f50d.bin +0 -0
  32. uv_agent-0.1.0/.code-search/files/9e/9e63f2478f3a2649.bin +0 -0
  33. uv_agent-0.1.0/.code-search/files/ad/add7322784ea1245.bin +0 -0
  34. uv_agent-0.1.0/.code-search/files/af/afbe2f722d71d50f.bin +0 -0
  35. uv_agent-0.1.0/.code-search/files/b1/b150440794b53155.bin +0 -0
  36. uv_agent-0.1.0/.code-search/files/b2/b2c178a88b7f5741.bin +0 -0
  37. uv_agent-0.1.0/.code-search/files/bf/bf739231b9cc942a.bin +0 -0
  38. uv_agent-0.1.0/.code-search/files/c6/c6cddba28a677217.bin +0 -0
  39. uv_agent-0.1.0/.code-search/files/c8/c8a22d5318eca619.bin +0 -0
  40. uv_agent-0.1.0/.code-search/files/c9/c9c216a3774c99c8.bin +0 -0
  41. uv_agent-0.1.0/.code-search/files/ca/ca17c802a9f60928.bin +0 -0
  42. uv_agent-0.1.0/.code-search/files/ce/ce0aaeb682bff844.bin +0 -0
  43. uv_agent-0.1.0/.code-search/files/d1/d148861e74b78132.bin +0 -0
  44. uv_agent-0.1.0/.code-search/files/d3/d31d0752f2c1c334.bin +0 -0
  45. uv_agent-0.1.0/.code-search/files/d6/d6f21065bd0cf072.bin +0 -0
  46. uv_agent-0.1.0/.code-search/files/d9/d92e183c90aaa441.bin +0 -0
  47. uv_agent-0.1.0/.code-search/files/d9/d98822f0fd0614c4.bin +0 -0
  48. uv_agent-0.1.0/.code-search/files/e4/e4b5abfe23d3cf49.bin +0 -0
  49. uv_agent-0.1.0/.code-search/files/e5/e5aba670998f3a73.bin +0 -0
  50. uv_agent-0.1.0/.code-search/files/e6/e6f7eb4839ad6bf3.bin +0 -0
  51. uv_agent-0.1.0/.code-search/files/eb/eb71449149c18276.bin +0 -0
  52. uv_agent-0.1.0/.code-search/files/ee/eecbfd1ba2caa4a6.bin +0 -0
  53. uv_agent-0.1.0/.code-search/files/f1/f158663f029fbbd7.bin +0 -0
  54. uv_agent-0.1.0/.code-search/files/f6/f6cb99f1ef1604ef.bin +0 -0
  55. uv_agent-0.1.0/.code-search/manifest.json +1 -0
  56. uv_agent-0.1.0/.code-search/symbols.bin +0 -0
  57. uv_agent-0.1.0/.gitignore +13 -0
  58. uv_agent-0.1.0/.python-version +1 -0
  59. uv_agent-0.1.0/AGENTS.md +57 -0
  60. uv_agent-0.1.0/PKG-INFO +206 -0
  61. uv_agent-0.1.0/README.md +195 -0
  62. uv_agent-0.1.0/docs/design.md +266 -0
  63. uv_agent-0.1.0/main.py +5 -0
  64. uv_agent-0.1.0/pyproject.toml +28 -0
  65. uv_agent-0.1.0/src/uv_agent/__init__.py +5 -0
  66. uv_agent-0.1.0/src/uv_agent/agent.py +1076 -0
  67. uv_agent-0.1.0/src/uv_agent/app_factory.py +27 -0
  68. uv_agent-0.1.0/src/uv_agent/attachments.py +132 -0
  69. uv_agent-0.1.0/src/uv_agent/cli.py +117 -0
  70. uv_agent-0.1.0/src/uv_agent/clipboard.py +40 -0
  71. uv_agent-0.1.0/src/uv_agent/config.py +399 -0
  72. uv_agent-0.1.0/src/uv_agent/context.py +52 -0
  73. uv_agent-0.1.0/src/uv_agent/environment.py +79 -0
  74. uv_agent-0.1.0/src/uv_agent/errors.py +68 -0
  75. uv_agent-0.1.0/src/uv_agent/i18n.py +315 -0
  76. uv_agent-0.1.0/src/uv_agent/ids.py +7 -0
  77. uv_agent-0.1.0/src/uv_agent/jsonl.py +33 -0
  78. uv_agent-0.1.0/src/uv_agent/mcp_config.py +69 -0
  79. uv_agent-0.1.0/src/uv_agent/model_client.py +800 -0
  80. uv_agent-0.1.0/src/uv_agent/paths.py +46 -0
  81. uv_agent-0.1.0/src/uv_agent/project_rules.py +162 -0
  82. uv_agent-0.1.0/src/uv_agent/runner/__init__.py +12 -0
  83. uv_agent-0.1.0/src/uv_agent/runner/metadata.py +219 -0
  84. uv_agent-0.1.0/src/uv_agent/runner/models.py +55 -0
  85. uv_agent-0.1.0/src/uv_agent/runner/runner.py +371 -0
  86. uv_agent-0.1.0/src/uv_agent/runner/store.py +152 -0
  87. uv_agent-0.1.0/src/uv_agent/session/__init__.py +6 -0
  88. uv_agent-0.1.0/src/uv_agent/session/models.py +25 -0
  89. uv_agent-0.1.0/src/uv_agent/session/store.py +280 -0
  90. uv_agent-0.1.0/src/uv_agent/skills.py +119 -0
  91. uv_agent-0.1.0/src/uv_agent/time.py +7 -0
  92. uv_agent-0.1.0/src/uv_agent/tui/__init__.py +5 -0
  93. uv_agent-0.1.0/src/uv_agent/tui/app.py +3075 -0
  94. uv_agent-0.1.0/src/uv_agent/tui/formatting.py +232 -0
  95. uv_agent-0.1.0/src/uv_agent_runtime/__init__.py +46 -0
  96. uv_agent-0.1.0/src/uv_agent_runtime/events.py +20 -0
  97. uv_agent-0.1.0/src/uv_agent_runtime/files.py +68 -0
  98. uv_agent-0.1.0/src/uv_agent_runtime/mcp.py +239 -0
  99. uv_agent-0.1.0/src/uv_agent_runtime/patch.py +75 -0
  100. uv_agent-0.1.0/src/uv_agent_runtime/process.py +54 -0
  101. uv_agent-0.1.0/src/uv_agent_runtime/scripts.py +93 -0
  102. uv_agent-0.1.0/src/uv_agent_runtime/subagent.py +113 -0
  103. uv_agent-0.1.0/src/uv_agent_runtime/threads.py +223 -0
  104. uv_agent-0.1.0/src/uv_agent_runtime/vision.py +18 -0
  105. uv_agent-0.1.0/tests/fixtures/mcp_echo_server.py +58 -0
  106. uv_agent-0.1.0/tests/test_agent.py +1403 -0
  107. uv_agent-0.1.0/tests/test_config.py +196 -0
  108. uv_agent-0.1.0/tests/test_mcp_config.py +32 -0
  109. uv_agent-0.1.0/tests/test_metadata.py +89 -0
  110. uv_agent-0.1.0/tests/test_model_client.py +169 -0
  111. uv_agent-0.1.0/tests/test_project_rules.py +46 -0
  112. uv_agent-0.1.0/tests/test_runner.py +159 -0
  113. uv_agent-0.1.0/tests/test_runtime.py +240 -0
  114. uv_agent-0.1.0/tests/test_session_store.py +94 -0
  115. uv_agent-0.1.0/tests/test_skills.py +57 -0
  116. uv_agent-0.1.0/tests/test_tui.py +1801 -0
  117. uv_agent-0.1.0/uv.lock +475 -0
@@ -0,0 +1 @@
1
+ *
@@ -0,0 +1 @@
1
+ {"files":{"src/uv_agent/tui/app.py":{"cache_key":"9e63f2478f3a2649","size":117503,"mtime_ms":1778949869118,"symbol_count":238},"src/uv_agent/tui/formatting.py":{"cache_key":"8362287575c9dc28","size":9045,"mtime_ms":1778926845642,"symbol_count":21},"src/uv_agent_runtime/files.py":{"cache_key":"ce0aaeb682bff844","size":1994,"mtime_ms":1778844906258,"symbol_count":6},"src/uv_agent_runtime/mcp.py":{"cache_key":"d6f21065bd0cf072","size":8380,"mtime_ms":1778854721771,"symbol_count":18},"src/uv_agent/agent.py":{"cache_key":"7279d8a152b81de9","size":44515,"mtime_ms":1778949815439,"symbol_count":41},"src/uv_agent/errors.py":{"cache_key":"ca17c802a9f60928","size":2287,"mtime_ms":1778857955717,"symbol_count":4},"src/uv_agent/runner/metadata.py":{"cache_key":"c6cddba28a677217","size":1889,"mtime_ms":1778834057385,"symbol_count":6},"main.py":{"cache_key":"0bb19dfda21091e2","size":70,"mtime_ms":1778833982527,"symbol_count":0},"src/uv_agent/runner/store.py":{"cache_key":"d148861e74b78132","size":6206,"mtime_ms":1778858052255,"symbol_count":11},"src/uv_agent/time.py":{"cache_key":"6ab0eb854e105f7f","size":140,"mtime_ms":1778833982529,"symbol_count":1},"src/uv_agent/project_rules.py":{"cache_key":"afbe2f722d71d50f","size":5167,"mtime_ms":1778849504735,"symbol_count":13},"tests/test_runner.py":{"cache_key":"9252e5ce62d73b31","size":5358,"mtime_ms":1778864536950,"symbol_count":7},"tests/test_config.py":{"cache_key":"39372ac99dd5247d","size":6322,"mtime_ms":1778950522169,"symbol_count":9},"tests/test_session_store.py":{"cache_key":"7985c2829c3c52c2","size":3391,"mtime_ms":1778917866600,"symbol_count":4},"src/uv_agent/jsonl.py":{"cache_key":"916fc738a0456fdb","size":899,"mtime_ms":1778833982529,"symbol_count":5},"src/uv_agent_runtime/events.py":{"cache_key":"6ade00a40c70369c","size":617,"mtime_ms":1778844923018,"symbol_count":3},"tests/fixtures/mcp_echo_server.py":{"cache_key":"6522ac861947ee16","size":1501,"mtime_ms":1778845695426,"symbol_count":2},"tests/test_tui.py":{"cache_key":"30f4a2b346000ac2","size":61520,"mtime_ms":1778950414497,"symbol_count":64},"src/uv_agent/model_client.py":{"cache_key":"173f249032d9d838","size":28274,"mtime_ms":1778858345461,"symbol_count":44},"tests/test_runtime.py":{"cache_key":"d98822f0fd0614c4","size":7457,"mtime_ms":1778899196421,"symbol_count":14},"src/uv_agent/app_factory.py":{"cache_key":"e4b5abfe23d3cf49","size":906,"mtime_ms":1778856521696,"symbol_count":1},"src/uv_agent/environment.py":{"cache_key":"eb71449149c18276","size":2671,"mtime_ms":1778857955716,"symbol_count":7},"src/uv_agent_runtime/__init__.py":{"cache_key":"20ba2e72a6b60622","size":1111,"mtime_ms":1778864387381,"symbol_count":1},"src/uv_agent/mcp_config.py":{"cache_key":"b2c178a88b7f5741","size":2296,"mtime_ms":1778845376516,"symbol_count":4},"tests/test_project_rules.py":{"cache_key":"add7322784ea1245","size":1536,"mtime_ms":1778849664712,"symbol_count":2},"src/uv_agent/ids.py":{"cache_key":"12f45ee2ed61ca20","size":131,"mtime_ms":1778833982528,"symbol_count":1},"src/uv_agent_runtime/patch.py":{"cache_key":"e6f7eb4839ad6bf3","size":2221,"mtime_ms":1778864716915,"symbol_count":5},"src/uv_agent/runner/__init__.py":{"cache_key":"e5aba670998f3a73","size":271,"mtime_ms":1778834057384,"symbol_count":1},"src/uv_agent/i18n.py":{"cache_key":"c9c216a3774c99c8","size":14040,"mtime_ms":1778949893231,"symbol_count":4},"src/uv_agent/runner/runner.py":{"cache_key":"eecbfd1ba2caa4a6","size":13733,"mtime_ms":1778914428144,"symbol_count":12},"src/uv_agent/runner/models.py":{"cache_key":"717341c48ff8721e","size":1329,"mtime_ms":1778899098182,"symbol_count":4},"src/uv_agent/cli.py":{"cache_key":"40705a33d911a690","size":4591,"mtime_ms":1778899126715,"symbol_count":2},"src/uv_agent_runtime/threads.py":{"cache_key":"f158663f029fbbd7","size":8394,"mtime_ms":1778917751092,"symbol_count":13},"src/uv_agent/session/store.py":{"cache_key":"bf739231b9cc942a","size":10919,"mtime_ms":1778917740674,"symbol_count":21},"src/uv_agent/clipboard.py":{"cache_key":"06fdade8cb2a357b","size":1284,"mtime_ms":1778909578950,"symbol_count":3},"src/uv_agent/skills.py":{"cache_key":"d92e183c90aaa441","size":4247,"mtime_ms":1778913046840,"symbol_count":5},"src/uv_agent/session/__init__.py":{"cache_key":"859784aab205bcf1","size":195,"mtime_ms":1778834216290,"symbol_count":1},"tests/test_mcp_config.py":{"cache_key":"25559c07d119d065","size":887,"mtime_ms":1778845412388,"symbol_count":1},"src/uv_agent/tui/__init__.py":{"cache_key":"f6cb99f1ef1604ef","size":90,"mtime_ms":1778834261125,"symbol_count":1},"src/uv_agent/paths.py":{"cache_key":"8f2b3f194ea29f1e","size":1495,"mtime_ms":1778867977697,"symbol_count":6},"src/uv_agent/attachments.py":{"cache_key":"4904f4b8897fe18b","size":3919,"mtime_ms":1778854575881,"symbol_count":9},"src/uv_agent/__init__.py":{"cache_key":"19d73df15641d86c","size":98,"mtime_ms":1778833982528,"symbol_count":2},"src/uv_agent_runtime/scripts.py":{"cache_key":"2715db6ea5b2fdbd","size":3378,"mtime_ms":1778858092519,"symbol_count":5},"src/uv_agent_runtime/subagent.py":{"cache_key":"c8a22d5318eca619","size":3846,"mtime_ms":1778899209139,"symbol_count":5},"src/uv_agent/context.py":{"cache_key":"49c9f8733f6113af","size":1592,"mtime_ms":1778849521392,"symbol_count":4},"src/uv_agent/config.py":{"cache_key":"00ed7e387c98d7ef","size":13987,"mtime_ms":1778950515355,"symbol_count":29},"tests/test_metadata.py":{"cache_key":"50a5e3c34c19cd22","size":1053,"mtime_ms":1778834328526,"symbol_count":3},"src/uv_agent_runtime/process.py":{"cache_key":"b150440794b53155","size":1354,"mtime_ms":1778844916303,"symbol_count":3},"src/uv_agent/session/models.py":{"cache_key":"358b77ce3308283d","size":577,"mtime_ms":1778834216290,"symbol_count":3},"src/uv_agent_runtime/vision.py":{"cache_key":"2ff0b007896e1441","size":607,"mtime_ms":1778854575881,"symbol_count":1},"tests/test_model_client.py":{"cache_key":"93b0c37eb345f50d","size":5442,"mtime_ms":1778854760658,"symbol_count":8},"tests/test_skills.py":{"cache_key":"d31d0752f2c1c334","size":1770,"mtime_ms":1778913061518,"symbol_count":3},"tests/test_agent.py":{"cache_key":"2239b4875fe0fdf8","size":51000,"mtime_ms":1778950371821,"symbol_count":30}}}
Binary file
@@ -0,0 +1,13 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # uv-agent runtime data
13
+ .uv-agent/
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,57 @@
1
+ # uv-agent Project Rules
2
+
3
+ This repository builds `uv-agent`, an experimental coding agent with a Textual TUI. The product goal is documented in `docs/design.md`; this file records the repository rules an agent should follow while editing the project.
4
+
5
+ ## Project Shape
6
+
7
+ - `src/uv_agent/`: host application, configuration, model clients, session store, Python runner, project rules, skills/MCP discovery, and TUI.
8
+ - `src/uv_agent_runtime/`: helper package injected into managed Python scripts so scripts can access file helpers, subprocess helpers, structured events, image attachment, saved script summaries, subagent launch helpers, and MCP clients.
9
+ - `tests/`: pytest coverage for runner, runtime, model clients, project rules, sessions, config, and Textual UI behavior.
10
+ - `docs/design.md`: product semantics and longer design notes. Keep it aligned when changing architecture or user-visible behavior.
11
+
12
+ ## Hard Boundaries
13
+
14
+ - The agent has exactly one external action surface: `run_python`.
15
+ - `run_python` executes Python through the managed runner. Do not add direct shell, filesystem, browser, network, or MCP model tools.
16
+ - Python scripts may call `subprocess`; that capability must stay inside the Python runner boundary.
17
+ - Managed scripts declare third-party dependencies with PEP 723 inline metadata. Do not add a separate dependency argument to the tool API.
18
+ - `uv_agent_runtime` must work as a package dependency for managed scripts; scripts must not rely on the repository checkout, current `.venv`, or implicit import paths.
19
+ - MCP and skills are progressively disclosed context. MCP calls happen through Python runtime helpers, not direct model tool calls.
20
+
21
+ ## Prompt And Context
22
+
23
+ - Keep the stable system prompt concise and structured with explicit XML-style sections and closing tags.
24
+ - Include stable host metadata and detected user language in the system prompt.
25
+ - Keep AGENTS rules, skills summaries, and MCP declarations out of the stable prompt. Append them as dynamic workspace context only when first seen, changed, removed, or after compaction.
26
+ - If dynamic context is removed, the next update must explicitly tell the agent not to rely on older appended context.
27
+ - Compression must use the latest system prompt, model config, runner config, and dynamic workspace context after a thread resumes.
28
+
29
+ ## TUI Rules
30
+
31
+ - TUI uses Textual and should remain a Codex-style single transcript with a bottom composer.
32
+ - Composer is multi-line: Enter inserts a newline; Ctrl+Enter or Ctrl+J sends.
33
+ - Typing `/` from an empty composer opens the full-screen command picker. Editing or deleting an existing slash command must not reopen it.
34
+ - Full-screen pickers must support keyboard and mouse: type to filter, arrows/PageUp/PageDown to move, Enter to select, Esc to close.
35
+ - TUI displays model reasoning, tool starts/results, compaction, image attachment, and errors as compact transcript events.
36
+ - TUI should not implement model protocol, runner execution, JSONL persistence, compression, or configuration rules directly; consume events from `AgentEngine` and formatting helpers instead.
37
+
38
+ ## Config And State
39
+
40
+ - User config lives at `~/.uv-agent/config.json`; project overrides may live in `.uv-agent/config.json`.
41
+ - Project runtime state lives under user-level `~/.uv-agent/projects/<project-id>/` by default.
42
+ - `.uv-agent/` in this repository is ignored local state. Do not commit debug screenshots, local config, scripts, runs, or thread state.
43
+ - Never commit API keys, tokens, provider secrets, or redacted copies that still reveal secret material.
44
+
45
+ ## Development
46
+
47
+ - Use `uv` for project commands, especially `uv run pytest`.
48
+ - Follow normal Python `src/` layout conventions. Keep library code importable without starting the TUI.
49
+ - Use typed dataclasses or structured dictionaries for persisted and cross-module data shapes when practical.
50
+ - Prefer focused tests with each behavior change. Update existing tests when changing prompt structure, runner semantics, context management, or TUI keyboard behavior.
51
+ - Keep comments sparse and useful. Use comments for non-obvious compatibility, caching, or protocol decisions; do not narrate ordinary control flow.
52
+
53
+ ## Verification
54
+
55
+ - Run `uv run pytest` before committing meaningful behavior changes.
56
+ - For TUI interaction changes, add or update Textual `run_test` coverage. Manual screenshots can be exported with `App.export_screenshot()` into `.uv-agent/screenshots/`.
57
+ - Before committing, check `git status --short` and ensure no secrets or ignored local artifacts are staged.
@@ -0,0 +1,206 @@
1
+ Metadata-Version: 2.4
2
+ Name: uv-agent
3
+ Version: 0.1.0
4
+ Summary: Experimental Python-runner coding agent with a Textual TUI
5
+ Requires-Python: >=3.14
6
+ Requires-Dist: httpx>=0.28.1
7
+ Requires-Dist: openai>=2.36.0
8
+ Requires-Dist: pillow>=12.0.0
9
+ Requires-Dist: textual>=6.5.0
10
+ Description-Content-Type: text/markdown
11
+
12
+ # uv-agent
13
+
14
+ Experimental coding agent with a Textual TUI. The agent has one external action surface: it submits Python scripts to a managed `uv run` runner.
15
+
16
+ ## Run
17
+
18
+ ```powershell
19
+ uv run uv-agent
20
+ ```
21
+
22
+ Run the published package without installing it first:
23
+
24
+ ```powershell
25
+ uvx uv-agent
26
+ ```
27
+
28
+ Single prompt smoke test:
29
+
30
+ ```powershell
31
+ uv run uv-agent ask "Reply with exactly: ok"
32
+ ```
33
+
34
+ Resume a thread without opening the TUI:
35
+
36
+ ```powershell
37
+ uv run uv-agent ask --thread thr_xxx "Continue from here"
38
+ ```
39
+
40
+ ## Local Config
41
+
42
+ User-level provider config lives at `~/.uv-agent/config.json` by default. A project can override it with `.uv-agent/config.json`; that project-local directory is ignored by git.
43
+
44
+ The config supports providers, models, levels, runtime options, and runner options. Secrets such as `api_key` must stay in ignored local config or environment variables.
45
+
46
+ Minimal shape:
47
+
48
+ ```json
49
+ {
50
+ "providers": {
51
+ "local": {
52
+ "base_url": "https://api.example.com",
53
+ "api_key_env": "UV_AGENT_API_KEY",
54
+ "responses": { "path": "/responses" },
55
+ "chat_completions": { "path": "/chat/completions" }
56
+ }
57
+ },
58
+ "models": {
59
+ "main": {
60
+ "provider": "local",
61
+ "model": "gpt-5.5",
62
+ "api": "responses",
63
+ "context_window_tokens": 258000
64
+ },
65
+ "chat": {
66
+ "provider": "local",
67
+ "model": "gpt-5.4-mini",
68
+ "api": "chat_completions",
69
+ "context_window_tokens": 258000
70
+ }
71
+ },
72
+ "levels": {
73
+ "medium": { "model": "main" },
74
+ "chat": { "model": "chat" }
75
+ },
76
+ "ui": {
77
+ "language": "auto"
78
+ },
79
+ "runner": {
80
+ "max_saved_scripts": 32
81
+ }
82
+ }
83
+ ```
84
+
85
+ Supported model APIs:
86
+
87
+ - `responses`
88
+ - `chat_completions`
89
+ - `anthropic_messages`
90
+
91
+ Streaming uses SSE when the provider supports it.
92
+
93
+ Compression can be tuned under `runtime.compression` with `trigger_ratio`,
94
+ `target_ratio`, and `min_tokens`. The TUI reads provider `usage` when available
95
+ and falls back to a local estimate for the context meter.
96
+
97
+ ## Runtime Scripts
98
+
99
+ Agent scripts declare dependencies with PEP 723 inline metadata. The runner records managed script artifacts, run JSONL, and thread JSONL under `~/.uv-agent/projects/<project-id>/`, injects the configured runtime dependency into inline metadata when needed, and supports rerunning saved scripts.
100
+
101
+ The PyPI package currently ships both `uv_agent` and `uv_agent_runtime`, so the
102
+ default injected runtime dependency is the installed `uv-agent` version. This
103
+ lets `uvx uv-agent` run the host app while managed scripts install the same
104
+ package and import `uv_agent_runtime`.
105
+
106
+ For local source development, override the runtime dependency in
107
+ `.uv-agent/config.json`:
108
+
109
+ ```json
110
+ {
111
+ "runner": {
112
+ "runtime_dependency": "uv-agent @ file:///C:/path/to/uv-agent"
113
+ }
114
+ }
115
+ ```
116
+
117
+ Each project keeps the 32 most recently used managed scripts by default
118
+ (`runner.max_saved_scripts`). Run logs are still kept separately. Scripts can
119
+ inspect recent saved scripts with `uv_agent_runtime.saved_scripts()`.
120
+
121
+ `uv_agent_runtime` exposes convenience helpers for text/JSON files, unified-diff patches, subprocesses, structured events, nested `uv-agent ask` calls by model level, image context, saved script summaries, compact thread digests, and MCP stdio servers declared in `.agents/mcp.json`.
122
+
123
+ Image context is added from a script with `look_at`:
124
+
125
+ ```python
126
+ from uv_agent_runtime import look_at
127
+
128
+ look_at("screenshot.png", note="inspect the failed layout")
129
+ ```
130
+
131
+ The host copies the image into the project state attachments directory and
132
+ appends it to later model input. Large image bytes are not stored directly in
133
+ thread JSONL.
134
+
135
+ Saved scripts can be rerun by passing `script_id` or `run_id` to `run_python`;
136
+ `rerun_mode="replay"` inherits a previous run's arguments when a `run_id` is
137
+ available.
138
+
139
+ Nested agents are launched from Python with level names rather than concrete
140
+ models:
141
+
142
+ ```python
143
+ from uv_agent_runtime import ask
144
+
145
+ result = ask("inspect the test failure", check=True)
146
+ print(result.text)
147
+ ```
148
+
149
+ Pass `level` only when intentionally selecting one of the level names defined in
150
+ the config; omit it to use the default level.
151
+
152
+ MCP remains a Python-triggered runtime capability, not a direct model tool:
153
+
154
+ ```python
155
+ from uv_agent_runtime import connect_named
156
+
157
+ with connect_named("filesystem") as client:
158
+ client.initialize()
159
+ print(client.list_tools())
160
+ ```
161
+
162
+ ## Workspace Rules
163
+
164
+ `AGENTS.md` context is loaded from `~/.agents/AGENTS.md` and from the current
165
+ git root down to the startup directory, including `AGENTS.*.md` variants.
166
+ Rules, discovered skills, and MCP declarations are kept out of the stable system
167
+ prompt. The engine appends a compact workspace-context update only when that
168
+ context is first seen, changed, removed, or when a thread continues after
169
+ compaction. Removal updates explicitly tell the agent not to rely on older
170
+ appended rule/capability context unless it appears again. Context update events
171
+ are stored in thread JSONL for change tracking, but they are not reconstructed as
172
+ ordinary conversation items or included in compression input.
173
+
174
+ ## TUI
175
+
176
+ The default TUI follows a Codex-style shape: a single transcript, inline Python runner events, full-screen focus panels, and a bottom composer with a bordered input box plus a compact status line.
177
+
178
+ - `Enter`: insert a newline in the composer
179
+ - `Ctrl+Enter` or `Ctrl+J`: send the composer text
180
+ - `Esc`: clear the composer or close the open panel
181
+ - `Ctrl+S` or `/status`: open detailed runtime status
182
+ - `Ctrl+O` or `/threads`: open a searchable thread picker and resume history
183
+ - `Ctrl+P`: open a full-screen command palette
184
+ - Selecting composer text copies it after a short delay and shows a notification
185
+ - `Ctrl+C`: press twice to interrupt a running turn; when idle, press twice to quit
186
+ - `/quit`: quit after a second confirmation
187
+ - `?` + `Ctrl+Enter` or `/help`: show local commands
188
+ - `/context`: show context budget and loaded workspace rules
189
+ - `/rules`: inspect loaded `AGENTS.md` files
190
+ - `/new [title]`, `/threads`, and `/clear`: light thread controls
191
+ - `/config`: edit user-facing settings (`default_level`, `language`, `auto_compress`) and show config sources / redacted merged config
192
+ - `/models`: read-only view of configured models. Add or modify models in the config file; this command never writes
193
+ - `/level [name]`: the only runtime model switch. Picks one of the levels defined in the config for this session
194
+ - `/mcp`: show MCP declarations from `.agents/mcp.json`
195
+ - `/skills` and `/skill [name]`: inspect `.agents/skills` entries
196
+ - `/runs`: show the latest Python run summary from this TUI session
197
+ - `/scripts`: show recent managed script summaries
198
+ - `/panel`: reminder that panels close with `Esc`
199
+ - Python runs appear inline with script/run ids, exit status, stdout/stderr summaries, and truncation markers
200
+ - Reasoning/tool/runtime events appear as compact timeline entries; detailed run output remains available in `/runs`.
201
+ - Typing `/` opens the full-screen command picker; `Ctrl+P` opens the same picker. Type to filter, use arrows/PageUp/PageDown to move, and Enter to select.
202
+ - Temporary panels open as full-screen overlays with search/scroll/select behavior.
203
+
204
+ For manual UI checks, Textual's `App.export_screenshot()` works in headless
205
+ tests and writes SVG snapshots. Local debug captures belong under `.uv-agent/`
206
+ so they stay out of git.
@@ -0,0 +1,195 @@
1
+ # uv-agent
2
+
3
+ Experimental coding agent with a Textual TUI. The agent has one external action surface: it submits Python scripts to a managed `uv run` runner.
4
+
5
+ ## Run
6
+
7
+ ```powershell
8
+ uv run uv-agent
9
+ ```
10
+
11
+ Run the published package without installing it first:
12
+
13
+ ```powershell
14
+ uvx uv-agent
15
+ ```
16
+
17
+ Single prompt smoke test:
18
+
19
+ ```powershell
20
+ uv run uv-agent ask "Reply with exactly: ok"
21
+ ```
22
+
23
+ Resume a thread without opening the TUI:
24
+
25
+ ```powershell
26
+ uv run uv-agent ask --thread thr_xxx "Continue from here"
27
+ ```
28
+
29
+ ## Local Config
30
+
31
+ User-level provider config lives at `~/.uv-agent/config.json` by default. A project can override it with `.uv-agent/config.json`; that project-local directory is ignored by git.
32
+
33
+ The config supports providers, models, levels, runtime options, and runner options. Secrets such as `api_key` must stay in ignored local config or environment variables.
34
+
35
+ Minimal shape:
36
+
37
+ ```json
38
+ {
39
+ "providers": {
40
+ "local": {
41
+ "base_url": "https://api.example.com",
42
+ "api_key_env": "UV_AGENT_API_KEY",
43
+ "responses": { "path": "/responses" },
44
+ "chat_completions": { "path": "/chat/completions" }
45
+ }
46
+ },
47
+ "models": {
48
+ "main": {
49
+ "provider": "local",
50
+ "model": "gpt-5.5",
51
+ "api": "responses",
52
+ "context_window_tokens": 258000
53
+ },
54
+ "chat": {
55
+ "provider": "local",
56
+ "model": "gpt-5.4-mini",
57
+ "api": "chat_completions",
58
+ "context_window_tokens": 258000
59
+ }
60
+ },
61
+ "levels": {
62
+ "medium": { "model": "main" },
63
+ "chat": { "model": "chat" }
64
+ },
65
+ "ui": {
66
+ "language": "auto"
67
+ },
68
+ "runner": {
69
+ "max_saved_scripts": 32
70
+ }
71
+ }
72
+ ```
73
+
74
+ Supported model APIs:
75
+
76
+ - `responses`
77
+ - `chat_completions`
78
+ - `anthropic_messages`
79
+
80
+ Streaming uses SSE when the provider supports it.
81
+
82
+ Compression can be tuned under `runtime.compression` with `trigger_ratio`,
83
+ `target_ratio`, and `min_tokens`. The TUI reads provider `usage` when available
84
+ and falls back to a local estimate for the context meter.
85
+
86
+ ## Runtime Scripts
87
+
88
+ Agent scripts declare dependencies with PEP 723 inline metadata. The runner records managed script artifacts, run JSONL, and thread JSONL under `~/.uv-agent/projects/<project-id>/`, injects the configured runtime dependency into inline metadata when needed, and supports rerunning saved scripts.
89
+
90
+ The PyPI package currently ships both `uv_agent` and `uv_agent_runtime`, so the
91
+ default injected runtime dependency is the installed `uv-agent` version. This
92
+ lets `uvx uv-agent` run the host app while managed scripts install the same
93
+ package and import `uv_agent_runtime`.
94
+
95
+ For local source development, override the runtime dependency in
96
+ `.uv-agent/config.json`:
97
+
98
+ ```json
99
+ {
100
+ "runner": {
101
+ "runtime_dependency": "uv-agent @ file:///C:/path/to/uv-agent"
102
+ }
103
+ }
104
+ ```
105
+
106
+ Each project keeps the 32 most recently used managed scripts by default
107
+ (`runner.max_saved_scripts`). Run logs are still kept separately. Scripts can
108
+ inspect recent saved scripts with `uv_agent_runtime.saved_scripts()`.
109
+
110
+ `uv_agent_runtime` exposes convenience helpers for text/JSON files, unified-diff patches, subprocesses, structured events, nested `uv-agent ask` calls by model level, image context, saved script summaries, compact thread digests, and MCP stdio servers declared in `.agents/mcp.json`.
111
+
112
+ Image context is added from a script with `look_at`:
113
+
114
+ ```python
115
+ from uv_agent_runtime import look_at
116
+
117
+ look_at("screenshot.png", note="inspect the failed layout")
118
+ ```
119
+
120
+ The host copies the image into the project state attachments directory and
121
+ appends it to later model input. Large image bytes are not stored directly in
122
+ thread JSONL.
123
+
124
+ Saved scripts can be rerun by passing `script_id` or `run_id` to `run_python`;
125
+ `rerun_mode="replay"` inherits a previous run's arguments when a `run_id` is
126
+ available.
127
+
128
+ Nested agents are launched from Python with level names rather than concrete
129
+ models:
130
+
131
+ ```python
132
+ from uv_agent_runtime import ask
133
+
134
+ result = ask("inspect the test failure", check=True)
135
+ print(result.text)
136
+ ```
137
+
138
+ Pass `level` only when intentionally selecting one of the level names defined in
139
+ the config; omit it to use the default level.
140
+
141
+ MCP remains a Python-triggered runtime capability, not a direct model tool:
142
+
143
+ ```python
144
+ from uv_agent_runtime import connect_named
145
+
146
+ with connect_named("filesystem") as client:
147
+ client.initialize()
148
+ print(client.list_tools())
149
+ ```
150
+
151
+ ## Workspace Rules
152
+
153
+ `AGENTS.md` context is loaded from `~/.agents/AGENTS.md` and from the current
154
+ git root down to the startup directory, including `AGENTS.*.md` variants.
155
+ Rules, discovered skills, and MCP declarations are kept out of the stable system
156
+ prompt. The engine appends a compact workspace-context update only when that
157
+ context is first seen, changed, removed, or when a thread continues after
158
+ compaction. Removal updates explicitly tell the agent not to rely on older
159
+ appended rule/capability context unless it appears again. Context update events
160
+ are stored in thread JSONL for change tracking, but they are not reconstructed as
161
+ ordinary conversation items or included in compression input.
162
+
163
+ ## TUI
164
+
165
+ The default TUI follows a Codex-style shape: a single transcript, inline Python runner events, full-screen focus panels, and a bottom composer with a bordered input box plus a compact status line.
166
+
167
+ - `Enter`: insert a newline in the composer
168
+ - `Ctrl+Enter` or `Ctrl+J`: send the composer text
169
+ - `Esc`: clear the composer or close the open panel
170
+ - `Ctrl+S` or `/status`: open detailed runtime status
171
+ - `Ctrl+O` or `/threads`: open a searchable thread picker and resume history
172
+ - `Ctrl+P`: open a full-screen command palette
173
+ - Selecting composer text copies it after a short delay and shows a notification
174
+ - `Ctrl+C`: press twice to interrupt a running turn; when idle, press twice to quit
175
+ - `/quit`: quit after a second confirmation
176
+ - `?` + `Ctrl+Enter` or `/help`: show local commands
177
+ - `/context`: show context budget and loaded workspace rules
178
+ - `/rules`: inspect loaded `AGENTS.md` files
179
+ - `/new [title]`, `/threads`, and `/clear`: light thread controls
180
+ - `/config`: edit user-facing settings (`default_level`, `language`, `auto_compress`) and show config sources / redacted merged config
181
+ - `/models`: read-only view of configured models. Add or modify models in the config file; this command never writes
182
+ - `/level [name]`: the only runtime model switch. Picks one of the levels defined in the config for this session
183
+ - `/mcp`: show MCP declarations from `.agents/mcp.json`
184
+ - `/skills` and `/skill [name]`: inspect `.agents/skills` entries
185
+ - `/runs`: show the latest Python run summary from this TUI session
186
+ - `/scripts`: show recent managed script summaries
187
+ - `/panel`: reminder that panels close with `Esc`
188
+ - Python runs appear inline with script/run ids, exit status, stdout/stderr summaries, and truncation markers
189
+ - Reasoning/tool/runtime events appear as compact timeline entries; detailed run output remains available in `/runs`.
190
+ - Typing `/` opens the full-screen command picker; `Ctrl+P` opens the same picker. Type to filter, use arrows/PageUp/PageDown to move, and Enter to select.
191
+ - Temporary panels open as full-screen overlays with search/scroll/select behavior.
192
+
193
+ For manual UI checks, Textual's `App.export_screenshot()` works in headless
194
+ tests and writes SVG snapshots. Local debug captures belong under `.uv-agent/`
195
+ so they stay out of git.