quenda 0.1.7__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 (119) hide show
  1. quenda-0.1.7/.gitignore +50 -0
  2. quenda-0.1.7/PKG-INFO +312 -0
  3. quenda-0.1.7/README.md +268 -0
  4. quenda-0.1.7/pyproject.toml +100 -0
  5. quenda-0.1.7/src/quenda/__init__.py +31 -0
  6. quenda-0.1.7/src/quenda/_version.py +3 -0
  7. quenda-0.1.7/src/quenda/cli.py +753 -0
  8. quenda-0.1.7/src/quenda/host/__init__.py +201 -0
  9. quenda-0.1.7/src/quenda/host/commands.py +1933 -0
  10. quenda-0.1.7/src/quenda/host/compression_policy.py +117 -0
  11. quenda-0.1.7/src/quenda/host/context.py +209 -0
  12. quenda-0.1.7/src/quenda/host/identity.py +163 -0
  13. quenda-0.1.7/src/quenda/host/instructions.py +433 -0
  14. quenda-0.1.7/src/quenda/host/interactions.py +376 -0
  15. quenda-0.1.7/src/quenda/host/loader.py +829 -0
  16. quenda-0.1.7/src/quenda/host/permission.py +221 -0
  17. quenda-0.1.7/src/quenda/host/phases.py +102 -0
  18. quenda-0.1.7/src/quenda/host/registry.py +176 -0
  19. quenda-0.1.7/src/quenda/host/repl.py +453 -0
  20. quenda-0.1.7/src/quenda/host/runner.py +747 -0
  21. quenda-0.1.7/src/quenda/host/skill/__init__.py +88 -0
  22. quenda-0.1.7/src/quenda/host/skill/activation.py +180 -0
  23. quenda-0.1.7/src/quenda/host/skill/discovery.py +257 -0
  24. quenda-0.1.7/src/quenda/host/skill/models.py +101 -0
  25. quenda-0.1.7/src/quenda/host/skill/package.py +138 -0
  26. quenda-0.1.7/src/quenda/host/skill/resources.py +238 -0
  27. quenda-0.1.7/src/quenda/host/skill/routing.py +125 -0
  28. quenda-0.1.7/src/quenda/host/storage.py +580 -0
  29. quenda-0.1.7/src/quenda/host/workspace.py +380 -0
  30. quenda-0.1.7/src/quenda/interface/__init__.py +134 -0
  31. quenda-0.1.7/src/quenda/interface/activity.py +380 -0
  32. quenda-0.1.7/src/quenda/interface/console.py +295 -0
  33. quenda-0.1.7/src/quenda/interface/events.py +647 -0
  34. quenda-0.1.7/src/quenda/interface/interaction.py +72 -0
  35. quenda-0.1.7/src/quenda/interface/markdown.py +275 -0
  36. quenda-0.1.7/src/quenda/interface/repl.py +259 -0
  37. quenda-0.1.7/src/quenda/interface/selector.py +259 -0
  38. quenda-0.1.7/src/quenda/interface/status.py +347 -0
  39. quenda-0.1.7/src/quenda/interface/theme.py +205 -0
  40. quenda-0.1.7/src/quenda/interface/welcome.py +123 -0
  41. quenda-0.1.7/src/quenda/kernel/__init__.py +23 -0
  42. quenda-0.1.7/src/quenda/kernel/loop.py +332 -0
  43. quenda-0.1.7/src/quenda/kernel/model.py +46 -0
  44. quenda-0.1.7/src/quenda/kernel/tool.py +97 -0
  45. quenda-0.1.7/src/quenda/kernel/types.py +99 -0
  46. quenda-0.1.7/src/quenda/providers/__init__.py +205 -0
  47. quenda-0.1.7/src/quenda/providers/api/__init__.py +22 -0
  48. quenda-0.1.7/src/quenda/providers/api/anthropic_messages.py +355 -0
  49. quenda-0.1.7/src/quenda/providers/api/base.py +94 -0
  50. quenda-0.1.7/src/quenda/providers/api/converters.py +118 -0
  51. quenda-0.1.7/src/quenda/providers/api/openai_completions.py +292 -0
  52. quenda-0.1.7/src/quenda/providers/api/registry.py +78 -0
  53. quenda-0.1.7/src/quenda/providers/auth.py +74 -0
  54. quenda-0.1.7/src/quenda/providers/builtins/__init__.py +65 -0
  55. quenda-0.1.7/src/quenda/providers/builtins/agnes.py +28 -0
  56. quenda-0.1.7/src/quenda/providers/builtins/anthropic.py +136 -0
  57. quenda-0.1.7/src/quenda/providers/builtins/cerebras.py +29 -0
  58. quenda-0.1.7/src/quenda/providers/builtins/cohere.py +119 -0
  59. quenda-0.1.7/src/quenda/providers/builtins/dashscope.py +213 -0
  60. quenda-0.1.7/src/quenda/providers/builtins/deepseek.py +81 -0
  61. quenda-0.1.7/src/quenda/providers/builtins/fireworks.py +101 -0
  62. quenda-0.1.7/src/quenda/providers/builtins/google.py +98 -0
  63. quenda-0.1.7/src/quenda/providers/builtins/groq.py +118 -0
  64. quenda-0.1.7/src/quenda/providers/builtins/jdcloud.py +42 -0
  65. quenda-0.1.7/src/quenda/providers/builtins/minimax.py +74 -0
  66. quenda-0.1.7/src/quenda/providers/builtins/mistral.py +131 -0
  67. quenda-0.1.7/src/quenda/providers/builtins/moonshot.py +74 -0
  68. quenda-0.1.7/src/quenda/providers/builtins/nvidia.py +179 -0
  69. quenda-0.1.7/src/quenda/providers/builtins/ollama.py +152 -0
  70. quenda-0.1.7/src/quenda/providers/builtins/openai.py +193 -0
  71. quenda-0.1.7/src/quenda/providers/builtins/openrouter.py +86 -0
  72. quenda-0.1.7/src/quenda/providers/builtins/perplexity.py +55 -0
  73. quenda-0.1.7/src/quenda/providers/builtins/siliconflow.py +124 -0
  74. quenda-0.1.7/src/quenda/providers/builtins/stepfun.py +46 -0
  75. quenda-0.1.7/src/quenda/providers/builtins/tencent.py +50 -0
  76. quenda-0.1.7/src/quenda/providers/builtins/together.py +145 -0
  77. quenda-0.1.7/src/quenda/providers/builtins/volcengine.py +82 -0
  78. quenda-0.1.7/src/quenda/providers/builtins/xai.py +95 -0
  79. quenda-0.1.7/src/quenda/providers/builtins/xiaomi.py +54 -0
  80. quenda-0.1.7/src/quenda/providers/builtins/zhipu.py +138 -0
  81. quenda-0.1.7/src/quenda/providers/errors.py +127 -0
  82. quenda-0.1.7/src/quenda/providers/model.py +235 -0
  83. quenda-0.1.7/src/quenda/providers/provider.py +190 -0
  84. quenda-0.1.7/src/quenda/providers/registry.py +197 -0
  85. quenda-0.1.7/src/quenda/providers/retry.py +154 -0
  86. quenda-0.1.7/src/quenda/runtime/__init__.py +102 -0
  87. quenda-0.1.7/src/quenda/runtime/agent.py +328 -0
  88. quenda-0.1.7/src/quenda/runtime/compression.py +86 -0
  89. quenda-0.1.7/src/quenda/runtime/compressor.py +440 -0
  90. quenda-0.1.7/src/quenda/runtime/events.py +208 -0
  91. quenda-0.1.7/src/quenda/runtime/run.py +842 -0
  92. quenda-0.1.7/src/quenda/runtime/session.py +423 -0
  93. quenda-0.1.7/src/quenda/runtime/termination.py +261 -0
  94. quenda-0.1.7/src/quenda/runtime/token_estimator.py +85 -0
  95. quenda-0.1.7/src/quenda/runtime/tool_policy.py +438 -0
  96. quenda-0.1.7/src/quenda/runtime/trace.py +140 -0
  97. quenda-0.1.7/src/quenda/tools/__init__.py +139 -0
  98. quenda-0.1.7/src/quenda/tools/base.py +94 -0
  99. quenda-0.1.7/src/quenda/tools/config.py +50 -0
  100. quenda-0.1.7/src/quenda/tools/decorator.py +193 -0
  101. quenda-0.1.7/src/quenda/tools/execution/__init__.py +33 -0
  102. quenda-0.1.7/src/quenda/tools/execution/code.py +361 -0
  103. quenda-0.1.7/src/quenda/tools/execution/shell.py +226 -0
  104. quenda-0.1.7/src/quenda/tools/filesystem/__init__.py +56 -0
  105. quenda-0.1.7/src/quenda/tools/filesystem/editing.py +356 -0
  106. quenda-0.1.7/src/quenda/tools/filesystem/listing.py +175 -0
  107. quenda-0.1.7/src/quenda/tools/filesystem/reading.py +163 -0
  108. quenda-0.1.7/src/quenda/tools/filesystem/searching.py +265 -0
  109. quenda-0.1.7/src/quenda/tools/interaction.py +125 -0
  110. quenda-0.1.7/src/quenda/tools/network/__init__.py +38 -0
  111. quenda-0.1.7/src/quenda/tools/network/fetching.py +131 -0
  112. quenda-0.1.7/src/quenda/tools/network/http.py +265 -0
  113. quenda-0.1.7/src/quenda/tools/network/searching.py +119 -0
  114. quenda-0.1.7/src/quenda/tools/security/__init__.py +45 -0
  115. quenda-0.1.7/src/quenda/tools/security/patterns.py +261 -0
  116. quenda-0.1.7/src/quenda/tools/security/validation.py +190 -0
  117. quenda-0.1.7/src/quenda/tools/skill_activation.py +108 -0
  118. quenda-0.1.7/src/quenda/utils/__init__.py +21 -0
  119. quenda-0.1.7/src/quenda/utils/interrupt.py +85 -0
@@ -0,0 +1,50 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+ *~
34
+
35
+ # Testing
36
+ .pytest_cache/
37
+ .coverage
38
+ htmlcov/
39
+ .tox/
40
+
41
+ # Distribution
42
+ *.manifest
43
+ *.spec
44
+
45
+ # Logs
46
+ *.log
47
+
48
+ # OS
49
+ .DS_Store
50
+ Thumbs.db
quenda-0.1.7/PKG-INFO ADDED
@@ -0,0 +1,312 @@
1
+ Metadata-Version: 2.4
2
+ Name: quenda
3
+ Version: 0.1.7
4
+ Summary: A lightweight Agent framework with extensible model providers
5
+ Project-URL: Homepage, https://github.com/xvshiting/quenda
6
+ Project-URL: Repository, https://github.com/xvshiting/quenda
7
+ Project-URL: Documentation, https://github.com/xvshiting/quenda#readme
8
+ Project-URL: Issues, https://github.com/xvshiting/quenda/issues
9
+ Author: xvshiting
10
+ License: MIT
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Requires-Python: >=3.12
18
+ Requires-Dist: openai>=1.0.0
19
+ Requires-Dist: pyyaml>=6.0.0
20
+ Requires-Dist: typing-extensions>=4.0.0
21
+ Provides-Extra: all
22
+ Requires-Dist: anthropic>=0.25.0; extra == 'all'
23
+ Requires-Dist: httpx[socks]>=0.25.0; extra == 'all'
24
+ Requires-Dist: mypy>=1.8.0; extra == 'all'
25
+ Requires-Dist: openai>=1.0.0; extra == 'all'
26
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'all'
27
+ Requires-Dist: pytest>=8.0.0; extra == 'all'
28
+ Requires-Dist: quenda-code>=0.1.0; extra == 'all'
29
+ Requires-Dist: ruff>=0.3.0; extra == 'all'
30
+ Provides-Extra: anthropic
31
+ Requires-Dist: anthropic>=0.25.0; extra == 'anthropic'
32
+ Provides-Extra: code
33
+ Requires-Dist: quenda-code>=0.1.0; extra == 'code'
34
+ Provides-Extra: dev
35
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
36
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
37
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
38
+ Requires-Dist: ruff>=0.3.0; extra == 'dev'
39
+ Provides-Extra: network
40
+ Requires-Dist: httpx[socks]>=0.25.0; extra == 'network'
41
+ Provides-Extra: openai
42
+ Requires-Dist: openai>=1.0.0; extra == 'openai'
43
+ Description-Content-Type: text/markdown
44
+
45
+ <p align="center">
46
+ <img src="assets/branding/logo.png" alt="Quenda" width="420">
47
+ </p>
48
+
49
+ <h3 align="center">A lightweight, layered Agent framework for Python</h3>
50
+
51
+ <p align="center">
52
+ <a href="https://www.python.org/downloads/"><img alt="Python" src="https://img.shields.io/badge/python-3.12+-blue.svg"></a>
53
+ <a href="https://opensource.org/licenses/MIT"><img alt="License" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
54
+ <img alt="Status" src="https://img.shields.io/badge/status-alpha-orange.svg">
55
+ </p>
56
+
57
+ ---
58
+
59
+ ## What's New
60
+
61
+ ### 2026-06
62
+
63
+ - **Skills Framework** — Composable capability packages with instructions, resources, and tools. Discover, activate, and use skills on demand. [Learn more →](docs/skills.md)
64
+ - **Context Compression** — Automatic summarization when context grows large, with configurable policies and manual `/compress` command.
65
+ - **Interaction Requests** — LLM can ask users for choices, confirmations, and input via structured interaction protocol.
66
+ - **Agent Commands Extension** — Define custom slash commands in `extensions/commands/*.py`.
67
+ - **Custom Tool Extensions** — Agent-local tools via `extensions/tools/*.py` with `config.yaml` declaration.
68
+ - **26 Model Providers** — OpenAI, Anthropic, DeepSeek, DashScope, Moonshot, Ollama, and 20 more.
69
+
70
+ ---
71
+
72
+ ## Quenda Code
73
+
74
+ **Quenda Code** is an AI coding agent that runs in your terminal. It reads your codebase, writes code, runs commands, and helps you ship.
75
+
76
+ > 📖 **[Quenda Code Documentation →](agents/quenda-code/README.md)**
77
+
78
+ ```bash
79
+ # Install
80
+ pip install quenda quenda-code
81
+
82
+ # Start interactive session
83
+ quenda code
84
+
85
+ # One-shot task
86
+ quenda code "Add error handling to the API client"
87
+ ```
88
+
89
+ ### Features
90
+
91
+ - **Code-aware** — Reads and understands your codebase structure
92
+ - **Workspace-scoped** — All file operations stay within your project directory
93
+ - **Safe execution** — Shell commands filtered, Python code sandboxed
94
+ - **Session persistence** — Conversations saved and resumable
95
+ - **Interactive mode switching** — Switch between `code`, `architect`, and `chat` modes
96
+ - **Skills on demand** — Activate capability packages as needed
97
+
98
+ ### REPL Commands
99
+
100
+ | Command | Description |
101
+ |---------|-------------|
102
+ | `/help` | Show available commands |
103
+ | `/mode [code\|architect\|chat]` | Switch interaction mode |
104
+ | `/model <provider>/<model>` | Switch model mid-session |
105
+ | `/skill list` | List available skills |
106
+ | `/skill activate <name>` | Activate a skill |
107
+ | `/compress` | Manually compress context |
108
+ | `/status` | Show session and token info |
109
+ | `/reset` | Clear conversation history |
110
+
111
+ ### Example Session
112
+
113
+ ```
114
+ > read the main entry point and explain how it works
115
+
116
+ I'll read the main entry point...
117
+
118
+ [Reads src/quenda/cli.py]
119
+
120
+ The entry point is `cli.py:main()`. It defines two subcommands:
121
+ - `quenda run --agent <path>` — Run a custom agent from AGENT.md
122
+ - `quenda code` — Run Quenda Code Agent (built-in)
123
+
124
+ Each command supports one-shot mode (with a message) or REPL mode (without).
125
+
126
+ > add a --version flag to the CLI
127
+
128
+ I'll add a `--version` flag to the argument parser...
129
+
130
+ [Applies patch to cli.py]
131
+
132
+ Done. Added `--version` flag that prints the version and exits.
133
+
134
+ > run the tests
135
+
136
+ [Runs pytest]
137
+
138
+ All 42 tests passed.
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Quenda SDK
144
+
145
+ Build agents in Python with a minimal API:
146
+
147
+ ```python
148
+ from quenda import Agent, tool
149
+ from quenda.providers import get_provider_registry
150
+ from quenda.tools import get_core_tools
151
+ import asyncio
152
+
153
+ @tool
154
+ def calculate(expression: str) -> float:
155
+ """Safely evaluate a math expression."""
156
+ import ast
157
+ node = ast.parse(expression, mode='eval')
158
+ return eval(compile(node, '<string>', 'eval'), {"__builtins__": {}}, {})
159
+
160
+ model = get_provider_registry().get_model("deepseek", "deepseek-v4-flash")
161
+
162
+ agent = Agent(
163
+ name="assistant",
164
+ system_prompt="You are a helpful assistant.",
165
+ tools=[calculate, *get_core_tools(".")],
166
+ model=model,
167
+ )
168
+
169
+ async def main():
170
+ session = agent.open_session()
171
+ result = await session.send("What is 15% of 847?")
172
+ print(result)
173
+
174
+ asyncio.run(main())
175
+ ```
176
+
177
+ > 📖 **[SDK Tutorials](docs/tutorials/agent/01-quickstart.md)** — 8 chapters covering agents, tools, providers, sessions, and events.
178
+
179
+ ---
180
+
181
+ ## Installation
182
+
183
+ ```bash
184
+ # Quenda Code — AI coding assistant (CLI)
185
+ pip install quenda quenda-code
186
+
187
+ # Quenda SDK — Build agents in Python
188
+ pip install quenda
189
+ ```
190
+
191
+ **Requires Python 3.12+.** Zero required runtime dependencies.
192
+
193
+ ---
194
+
195
+ ## Features
196
+
197
+ - **Minimal API.** `Agent`, `Session`, `@tool`, and you're done.
198
+ - **26 model providers.** OpenAI, Anthropic, DeepSeek, DashScope, and more — one registry, one API.
199
+ - **9 core tools.** Filesystem, shell, Python sandbox, and user interaction — all workspace-scoped.
200
+ - **Skills framework.** Composable capability packages with instructions and resources.
201
+ - **Security by code.** SSRF protection, command filtering, import restrictions, workspace isolation.
202
+ - **Observable by default.** Every run emits structured events for streaming and debugging.
203
+ - **Context compression.** Automatic summarization when context grows large.
204
+
205
+ ---
206
+
207
+ ## Model Providers
208
+
209
+ Quenda ships with **26 built-in providers** covering 300+ models:
210
+
211
+ | Provider | Example Models | API Key Env |
212
+ |----------|---------------|-------------|
213
+ | `openai` | `gpt-4o`, `gpt-4-turbo` | `OPENAI_API_KEY` |
214
+ | `anthropic` | `claude-3-5-sonnet-20241022` | `ANTHROPIC_API_KEY` |
215
+ | `agnes` | `agnes-2.0-flash` | `AGNES_API_KEY` |
216
+ | `deepseek` | `deepseek-chat`, `deepseek-v4-flash` | `DEEPSEEK_API_KEY` |
217
+ | `deepseek-anthropic` | `deepseek-v4-flash` (Anthropic API) | `DEEPSEEK_API_KEY` |
218
+ | `dashscope` | `qwen-max`, `qwen-plus` | `DASHSCOPE_API_KEY` |
219
+ | `moonshot` | `moonshot-v1-8k`, `moonshot-v1-128k` | `MOONSHOT_API_KEY` |
220
+ | `openrouter` | `anthropic/claude-3.5-sonnet` | `OPENROUTER_API_KEY` |
221
+ | `ollama` | `llama3`, `mistral`, `qwen2` | local (no key) |
222
+
223
+ [Full provider list →](docs/tutorials/agent/04-providers.md)
224
+
225
+ Add a custom provider in 5 lines:
226
+
227
+ ```python
228
+ from quenda.providers import ProviderSpec, ModelSpec, get_provider_registry
229
+
230
+ registry = get_provider_registry()
231
+ registry.register(ProviderSpec(
232
+ id="my-provider",
233
+ name="My Provider",
234
+ base_url="https://api.example.com/v1",
235
+ api="openai-completions",
236
+ api_key="${MY_API_KEY}",
237
+ models=(ModelSpec(id="my-model", name="My Model", tool_calling=True),),
238
+ ))
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Built-in Tools
244
+
245
+ `get_core_tools(workspace)` returns **9 essential tools**:
246
+
247
+ | Tool | Capability |
248
+ |------|-----------|
249
+ | `list_files` | Browse directories (ls, find, tree) |
250
+ | `search_text` | Search file contents (grep, rg) |
251
+ | `read_file` | View files with line ranges |
252
+ | `write_file` | Create or overwrite files |
253
+ | `apply_patch` | Apply targeted text patches |
254
+ | `run_shell` | Execute shell commands (filtered) |
255
+ | `execute_python` | Run Python in a sandbox |
256
+ | `request_interaction` | Ask the user for input |
257
+ | `request_skill_activation` | Request skill activation |
258
+
259
+ [Full tool reference →](docs/tools.md)
260
+
261
+ ---
262
+
263
+ ## Architecture
264
+
265
+ ```
266
+ Interface → Host → Runtime → Kernel
267
+ ```
268
+
269
+ | Layer | Responsibility |
270
+ |-------|---------------|
271
+ | **Kernel** | Synchronous model-tool loop. No knowledge of agents, sessions, or users. |
272
+ | **Runtime** | Async Agent/Session/Run lifecycle. Event emission, context management. |
273
+ | **Host** | Persistence, identity, permissions, instruction composition, skills. |
274
+ | **Interface** | Event rendering, user interaction, REPL. |
275
+
276
+ Each layer depends only on the layer inside it. The Kernel is fully testable with fake models — no network required.
277
+
278
+ ---
279
+
280
+ ## Documentation
281
+
282
+ | Resource | Description |
283
+ |----------|-------------|
284
+ | **[Getting Started](docs/getting-started.md)** | Setup and your first agent |
285
+ | **[Tools Guide](docs/tools.md)** | All built-in tools with parameters |
286
+ | **[Skills Guide](docs/skills.md)** | Capability packages system |
287
+ | **[API Reference](docs/api.md)** | Complete API reference |
288
+ | **[SDK Tutorials](docs/tutorials/agent/01-quickstart.md)** | Step-by-step Python SDK guide (8 chapters) |
289
+ | **[CLI Tutorials](docs/tutorials/code/01-quickstart.md)** | Step-by-step Quenda Code guide (5 chapters) |
290
+ | **[Architecture Decisions](docs/decisions/)** | ADR records |
291
+
292
+ ---
293
+
294
+ ## Contributing
295
+
296
+ Quenda is intentionally small. Before making a change, read [`CLAUDE.md`](CLAUDE.md) and the [ADR records](docs/decisions/).
297
+
298
+ 1. Identify which architectural layer owns the change.
299
+ 2. Prefer the smallest complete change; add tests with behavior changes.
300
+ 3. Do not cross established layer boundaries.
301
+
302
+ ```bash
303
+ pip install -e ".[dev]" # editable install with dev tooling
304
+ pytest # run tests
305
+ ruff check src/quenda # lint
306
+ ```
307
+
308
+ ---
309
+
310
+ ## License
311
+
312
+ MIT
quenda-0.1.7/README.md ADDED
@@ -0,0 +1,268 @@
1
+ <p align="center">
2
+ <img src="assets/branding/logo.png" alt="Quenda" width="420">
3
+ </p>
4
+
5
+ <h3 align="center">A lightweight, layered Agent framework for Python</h3>
6
+
7
+ <p align="center">
8
+ <a href="https://www.python.org/downloads/"><img alt="Python" src="https://img.shields.io/badge/python-3.12+-blue.svg"></a>
9
+ <a href="https://opensource.org/licenses/MIT"><img alt="License" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
10
+ <img alt="Status" src="https://img.shields.io/badge/status-alpha-orange.svg">
11
+ </p>
12
+
13
+ ---
14
+
15
+ ## What's New
16
+
17
+ ### 2026-06
18
+
19
+ - **Skills Framework** — Composable capability packages with instructions, resources, and tools. Discover, activate, and use skills on demand. [Learn more →](docs/skills.md)
20
+ - **Context Compression** — Automatic summarization when context grows large, with configurable policies and manual `/compress` command.
21
+ - **Interaction Requests** — LLM can ask users for choices, confirmations, and input via structured interaction protocol.
22
+ - **Agent Commands Extension** — Define custom slash commands in `extensions/commands/*.py`.
23
+ - **Custom Tool Extensions** — Agent-local tools via `extensions/tools/*.py` with `config.yaml` declaration.
24
+ - **26 Model Providers** — OpenAI, Anthropic, DeepSeek, DashScope, Moonshot, Ollama, and 20 more.
25
+
26
+ ---
27
+
28
+ ## Quenda Code
29
+
30
+ **Quenda Code** is an AI coding agent that runs in your terminal. It reads your codebase, writes code, runs commands, and helps you ship.
31
+
32
+ > 📖 **[Quenda Code Documentation →](agents/quenda-code/README.md)**
33
+
34
+ ```bash
35
+ # Install
36
+ pip install quenda quenda-code
37
+
38
+ # Start interactive session
39
+ quenda code
40
+
41
+ # One-shot task
42
+ quenda code "Add error handling to the API client"
43
+ ```
44
+
45
+ ### Features
46
+
47
+ - **Code-aware** — Reads and understands your codebase structure
48
+ - **Workspace-scoped** — All file operations stay within your project directory
49
+ - **Safe execution** — Shell commands filtered, Python code sandboxed
50
+ - **Session persistence** — Conversations saved and resumable
51
+ - **Interactive mode switching** — Switch between `code`, `architect`, and `chat` modes
52
+ - **Skills on demand** — Activate capability packages as needed
53
+
54
+ ### REPL Commands
55
+
56
+ | Command | Description |
57
+ |---------|-------------|
58
+ | `/help` | Show available commands |
59
+ | `/mode [code\|architect\|chat]` | Switch interaction mode |
60
+ | `/model <provider>/<model>` | Switch model mid-session |
61
+ | `/skill list` | List available skills |
62
+ | `/skill activate <name>` | Activate a skill |
63
+ | `/compress` | Manually compress context |
64
+ | `/status` | Show session and token info |
65
+ | `/reset` | Clear conversation history |
66
+
67
+ ### Example Session
68
+
69
+ ```
70
+ > read the main entry point and explain how it works
71
+
72
+ I'll read the main entry point...
73
+
74
+ [Reads src/quenda/cli.py]
75
+
76
+ The entry point is `cli.py:main()`. It defines two subcommands:
77
+ - `quenda run --agent <path>` — Run a custom agent from AGENT.md
78
+ - `quenda code` — Run Quenda Code Agent (built-in)
79
+
80
+ Each command supports one-shot mode (with a message) or REPL mode (without).
81
+
82
+ > add a --version flag to the CLI
83
+
84
+ I'll add a `--version` flag to the argument parser...
85
+
86
+ [Applies patch to cli.py]
87
+
88
+ Done. Added `--version` flag that prints the version and exits.
89
+
90
+ > run the tests
91
+
92
+ [Runs pytest]
93
+
94
+ All 42 tests passed.
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Quenda SDK
100
+
101
+ Build agents in Python with a minimal API:
102
+
103
+ ```python
104
+ from quenda import Agent, tool
105
+ from quenda.providers import get_provider_registry
106
+ from quenda.tools import get_core_tools
107
+ import asyncio
108
+
109
+ @tool
110
+ def calculate(expression: str) -> float:
111
+ """Safely evaluate a math expression."""
112
+ import ast
113
+ node = ast.parse(expression, mode='eval')
114
+ return eval(compile(node, '<string>', 'eval'), {"__builtins__": {}}, {})
115
+
116
+ model = get_provider_registry().get_model("deepseek", "deepseek-v4-flash")
117
+
118
+ agent = Agent(
119
+ name="assistant",
120
+ system_prompt="You are a helpful assistant.",
121
+ tools=[calculate, *get_core_tools(".")],
122
+ model=model,
123
+ )
124
+
125
+ async def main():
126
+ session = agent.open_session()
127
+ result = await session.send("What is 15% of 847?")
128
+ print(result)
129
+
130
+ asyncio.run(main())
131
+ ```
132
+
133
+ > 📖 **[SDK Tutorials](docs/tutorials/agent/01-quickstart.md)** — 8 chapters covering agents, tools, providers, sessions, and events.
134
+
135
+ ---
136
+
137
+ ## Installation
138
+
139
+ ```bash
140
+ # Quenda Code — AI coding assistant (CLI)
141
+ pip install quenda quenda-code
142
+
143
+ # Quenda SDK — Build agents in Python
144
+ pip install quenda
145
+ ```
146
+
147
+ **Requires Python 3.12+.** Zero required runtime dependencies.
148
+
149
+ ---
150
+
151
+ ## Features
152
+
153
+ - **Minimal API.** `Agent`, `Session`, `@tool`, and you're done.
154
+ - **26 model providers.** OpenAI, Anthropic, DeepSeek, DashScope, and more — one registry, one API.
155
+ - **9 core tools.** Filesystem, shell, Python sandbox, and user interaction — all workspace-scoped.
156
+ - **Skills framework.** Composable capability packages with instructions and resources.
157
+ - **Security by code.** SSRF protection, command filtering, import restrictions, workspace isolation.
158
+ - **Observable by default.** Every run emits structured events for streaming and debugging.
159
+ - **Context compression.** Automatic summarization when context grows large.
160
+
161
+ ---
162
+
163
+ ## Model Providers
164
+
165
+ Quenda ships with **26 built-in providers** covering 300+ models:
166
+
167
+ | Provider | Example Models | API Key Env |
168
+ |----------|---------------|-------------|
169
+ | `openai` | `gpt-4o`, `gpt-4-turbo` | `OPENAI_API_KEY` |
170
+ | `anthropic` | `claude-3-5-sonnet-20241022` | `ANTHROPIC_API_KEY` |
171
+ | `agnes` | `agnes-2.0-flash` | `AGNES_API_KEY` |
172
+ | `deepseek` | `deepseek-chat`, `deepseek-v4-flash` | `DEEPSEEK_API_KEY` |
173
+ | `deepseek-anthropic` | `deepseek-v4-flash` (Anthropic API) | `DEEPSEEK_API_KEY` |
174
+ | `dashscope` | `qwen-max`, `qwen-plus` | `DASHSCOPE_API_KEY` |
175
+ | `moonshot` | `moonshot-v1-8k`, `moonshot-v1-128k` | `MOONSHOT_API_KEY` |
176
+ | `openrouter` | `anthropic/claude-3.5-sonnet` | `OPENROUTER_API_KEY` |
177
+ | `ollama` | `llama3`, `mistral`, `qwen2` | local (no key) |
178
+
179
+ [Full provider list →](docs/tutorials/agent/04-providers.md)
180
+
181
+ Add a custom provider in 5 lines:
182
+
183
+ ```python
184
+ from quenda.providers import ProviderSpec, ModelSpec, get_provider_registry
185
+
186
+ registry = get_provider_registry()
187
+ registry.register(ProviderSpec(
188
+ id="my-provider",
189
+ name="My Provider",
190
+ base_url="https://api.example.com/v1",
191
+ api="openai-completions",
192
+ api_key="${MY_API_KEY}",
193
+ models=(ModelSpec(id="my-model", name="My Model", tool_calling=True),),
194
+ ))
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Built-in Tools
200
+
201
+ `get_core_tools(workspace)` returns **9 essential tools**:
202
+
203
+ | Tool | Capability |
204
+ |------|-----------|
205
+ | `list_files` | Browse directories (ls, find, tree) |
206
+ | `search_text` | Search file contents (grep, rg) |
207
+ | `read_file` | View files with line ranges |
208
+ | `write_file` | Create or overwrite files |
209
+ | `apply_patch` | Apply targeted text patches |
210
+ | `run_shell` | Execute shell commands (filtered) |
211
+ | `execute_python` | Run Python in a sandbox |
212
+ | `request_interaction` | Ask the user for input |
213
+ | `request_skill_activation` | Request skill activation |
214
+
215
+ [Full tool reference →](docs/tools.md)
216
+
217
+ ---
218
+
219
+ ## Architecture
220
+
221
+ ```
222
+ Interface → Host → Runtime → Kernel
223
+ ```
224
+
225
+ | Layer | Responsibility |
226
+ |-------|---------------|
227
+ | **Kernel** | Synchronous model-tool loop. No knowledge of agents, sessions, or users. |
228
+ | **Runtime** | Async Agent/Session/Run lifecycle. Event emission, context management. |
229
+ | **Host** | Persistence, identity, permissions, instruction composition, skills. |
230
+ | **Interface** | Event rendering, user interaction, REPL. |
231
+
232
+ Each layer depends only on the layer inside it. The Kernel is fully testable with fake models — no network required.
233
+
234
+ ---
235
+
236
+ ## Documentation
237
+
238
+ | Resource | Description |
239
+ |----------|-------------|
240
+ | **[Getting Started](docs/getting-started.md)** | Setup and your first agent |
241
+ | **[Tools Guide](docs/tools.md)** | All built-in tools with parameters |
242
+ | **[Skills Guide](docs/skills.md)** | Capability packages system |
243
+ | **[API Reference](docs/api.md)** | Complete API reference |
244
+ | **[SDK Tutorials](docs/tutorials/agent/01-quickstart.md)** | Step-by-step Python SDK guide (8 chapters) |
245
+ | **[CLI Tutorials](docs/tutorials/code/01-quickstart.md)** | Step-by-step Quenda Code guide (5 chapters) |
246
+ | **[Architecture Decisions](docs/decisions/)** | ADR records |
247
+
248
+ ---
249
+
250
+ ## Contributing
251
+
252
+ Quenda is intentionally small. Before making a change, read [`CLAUDE.md`](CLAUDE.md) and the [ADR records](docs/decisions/).
253
+
254
+ 1. Identify which architectural layer owns the change.
255
+ 2. Prefer the smallest complete change; add tests with behavior changes.
256
+ 3. Do not cross established layer boundaries.
257
+
258
+ ```bash
259
+ pip install -e ".[dev]" # editable install with dev tooling
260
+ pytest # run tests
261
+ ruff check src/quenda # lint
262
+ ```
263
+
264
+ ---
265
+
266
+ ## License
267
+
268
+ MIT