orchid-cli 1.0.0__tar.gz → 1.0.2__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.
- orchid_cli-1.0.2/CHANGELOG.md +27 -0
- orchid_cli-1.0.2/PKG-INFO +251 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/README.md +1 -1
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/pyproject.toml +40 -1
- orchid_cli-1.0.2/tests/fixtures/__init__.py +0 -0
- orchid_cli-1.0.2/tests/fixtures/fake_tools_dates.py +39 -0
- orchid_cli-1.0.2/tests/fixtures/fake_tools_math.py +24 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/tests/test_commands_skill.py +13 -13
- orchid_cli-1.0.0/CHANGELOG.md +0 -11
- orchid_cli-1.0.0/PKG-INFO +0 -20
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/.editorconfig +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/.github/workflows/ci.yml +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/.gitignore +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/.gitlint +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/.pre-commit-config.yaml +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/AGENTS.md +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/CLAUDE.md +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/CONTRIBUTING.md +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/LICENSE +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/icon.svg +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/__init__.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/bootstrap.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/commands/__init__.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/commands/chat.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/commands/config.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/commands/index.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/commands/skill.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/orchid_cli/main.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/tests/conftest.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/tests/test_bootstrap.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/tests/test_commands_chat.py +0 -0
- {orchid_cli-1.0.0 → orchid_cli-1.0.2}/tests/test_commands_config.py +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
<!-- version list -->
|
|
4
|
+
|
|
5
|
+
## v1.0.2 (2026-04-13)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Removing external dependencies and improving error handling and final outcome for the user.
|
|
10
|
+
([`2ebc6ef`](https://github.com/gadz82/orchid-cli/commit/2ebc6efb8f96e047a3dc649710967d4aece64ab4))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## v1.0.1 (2026-04-13)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- Orchid-cli package description and readme update.
|
|
18
|
+
([`5055129`](https://github.com/gadz82/orchid-cli/commit/505512906fc9b6d88752940dd1c9b24a2eec8f0d))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## v1.0.0 (2026-04-13)
|
|
22
|
+
|
|
23
|
+
- Initial Release
|
|
24
|
+
|
|
25
|
+
## v1.0.0 (2026-04-10)
|
|
26
|
+
|
|
27
|
+
- Initial Release
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orchid-cli
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Orchid CLI — command-line interface for the Orchid agent framework
|
|
5
|
+
Project-URL: Homepage, https://github.com/gadz82/orchid
|
|
6
|
+
Project-URL: Repository, https://github.com/gadz82/orchid
|
|
7
|
+
Project-URL: Documentation, https://github.com/gadz82/orchid#readme
|
|
8
|
+
Project-URL: Issues, https://github.com/gadz82/orchid/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/gadz82/orchid/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Francesco Marchesini <gadz82@users.noreply.github.com>
|
|
11
|
+
Maintainer-email: Francesco Marchesini <gadz82@users.noreply.github.com>
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: agents,ai,cli,langgraph,llm,mcp,multi-agent,orchestration,rag
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Environment :: Console
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.11
|
|
27
|
+
Requires-Dist: httpx>=0.28.0
|
|
28
|
+
Requires-Dist: langchain-core>=0.3.0
|
|
29
|
+
Requires-Dist: orchid-ai>=1.2.0
|
|
30
|
+
Requires-Dist: pydantic-settings>=2.7.0
|
|
31
|
+
Requires-Dist: pyyaml>=6.0
|
|
32
|
+
Requires-Dist: rich>=13.0
|
|
33
|
+
Requires-Dist: typer>=0.12.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: gitlint>=0.19.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pre-commit>=4.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.9.0; extra == 'dev'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<img src="icon.svg" alt="Orchid" width="80" />
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<h1 align="center">Orchid CLI</h1>
|
|
48
|
+
|
|
49
|
+
Command-line interface for the [Orchid](https://github.com/gadz82/orchid) multi-agent AI framework.
|
|
50
|
+
|
|
51
|
+
Provides terminal access to all chat operations, configuration validation, RAG indexing, and Claude Code skill generation. Mirrors the full functionality of [orchid-api](../orchid-api) but runs locally with no server, Docker, or external database required (defaults to SQLite).
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install orchid-ai orchid-cli
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The `orchid` command is available after installation.
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Validate config:
|
|
65
|
+
orchid config validate agents.yaml
|
|
66
|
+
|
|
67
|
+
# Start an interactive chat session:
|
|
68
|
+
orchid chat interactive -c orchid.yml
|
|
69
|
+
|
|
70
|
+
# Send a single message:
|
|
71
|
+
orchid chat create -c orchid.yml -t "My Chat"
|
|
72
|
+
orchid chat send <chat_id> "Hello!" -c orchid.yml
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Commands
|
|
76
|
+
|
|
77
|
+
### Chat Management
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Create a new chat session
|
|
81
|
+
orchid chat create -c orchid.yml -t "My Chat Title"
|
|
82
|
+
|
|
83
|
+
# List all chat sessions
|
|
84
|
+
orchid chat list -c orchid.yml
|
|
85
|
+
|
|
86
|
+
# Show message history
|
|
87
|
+
orchid chat history <chat_id> -c orchid.yml
|
|
88
|
+
orchid chat history <chat_id> -c orchid.yml --limit 10
|
|
89
|
+
|
|
90
|
+
# Rename a chat
|
|
91
|
+
orchid chat rename <chat_id> "New Title" -c orchid.yml
|
|
92
|
+
|
|
93
|
+
# Share a chat (promote RAG data to user scope)
|
|
94
|
+
orchid chat share <chat_id> -c orchid.yml
|
|
95
|
+
|
|
96
|
+
# Delete a chat
|
|
97
|
+
orchid chat delete <chat_id> -c orchid.yml
|
|
98
|
+
orchid chat delete <chat_id> -c orchid.yml --force
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Chat IDs support **prefix matching** -- type the first few characters of the UUID.
|
|
102
|
+
|
|
103
|
+
### Messaging
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Send a single message and print the response
|
|
107
|
+
orchid chat send <chat_id> "What is LangGraph?" -c orchid.yml
|
|
108
|
+
|
|
109
|
+
# Override the LLM model
|
|
110
|
+
orchid chat send <chat_id> "Explain RAG" -c orchid.yml -m ollama/llama3.2
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Interactive Mode
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Start a new interactive session
|
|
117
|
+
orchid chat interactive -c orchid.yml
|
|
118
|
+
|
|
119
|
+
# Resume an existing chat
|
|
120
|
+
orchid chat interactive <chat_id> -c orchid.yml
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Slash commands available inside interactive mode:
|
|
124
|
+
|
|
125
|
+
| Command | Purpose |
|
|
126
|
+
|---------|---------|
|
|
127
|
+
| `/list` | List all chat sessions |
|
|
128
|
+
| `/switch <id>` | Switch to another chat |
|
|
129
|
+
| `/new [title]` | Create a new chat |
|
|
130
|
+
| `/history` | Show last 20 messages |
|
|
131
|
+
| `/rename <title>` | Rename current chat |
|
|
132
|
+
| `/quit` | Exit interactive mode |
|
|
133
|
+
|
|
134
|
+
### Configuration
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Validate an agents.yaml file
|
|
138
|
+
orchid config validate path/to/agents.yaml
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### RAG Indexing
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Seed the vector store with static data
|
|
145
|
+
orchid index seed -c orchid.yml
|
|
146
|
+
|
|
147
|
+
# Seed for a specific tenant
|
|
148
|
+
orchid index seed -c orchid.yml --tenant my-tenant
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Skill Generation (Claude Code)
|
|
152
|
+
|
|
153
|
+
Generate [Claude Code skills](https://docs.anthropic.com/en/docs/claude-code/skills) from your Orchid agent configuration. Each agent and orchestrator skill becomes a Claude Code skill directory with a `SKILL.md` file.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Generate skills for all agents and orchestrator skills
|
|
157
|
+
orchid skill generate path/to/agents.yaml
|
|
158
|
+
|
|
159
|
+
# Custom output directory
|
|
160
|
+
orchid skill generate path/to/agents.yaml -o .claude/skills
|
|
161
|
+
|
|
162
|
+
# Generate only specific agents/skills
|
|
163
|
+
orchid skill generate path/to/agents.yaml --include basketball,psychologist
|
|
164
|
+
|
|
165
|
+
# Overwrite existing skill directories
|
|
166
|
+
orchid skill generate path/to/agents.yaml --overwrite
|
|
167
|
+
|
|
168
|
+
# Create a zip archive for upload
|
|
169
|
+
orchid skill generate path/to/agents.yaml --zip
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**What gets converted:**
|
|
173
|
+
|
|
174
|
+
| Orchid Concept | Claude Code Skill |
|
|
175
|
+
|---|---|
|
|
176
|
+
| Agent prompt | Core SKILL.md instructions |
|
|
177
|
+
| Agent description | Skill frontmatter description |
|
|
178
|
+
| Built-in tools | Executable Python scripts in `scripts/` |
|
|
179
|
+
| Agent skills (workflows) | Step-by-step workflow instructions with script commands |
|
|
180
|
+
| Orchestrator skills | Multi-agent workflow skill |
|
|
181
|
+
| MCP servers | Noted as runtime-only (not portable) |
|
|
182
|
+
| RAG context | Noted as runtime-only (not portable) |
|
|
183
|
+
| Guardrails (global + per-agent) | Input/output rules section with actions and config |
|
|
184
|
+
|
|
185
|
+
Each agent skill includes a `scripts/` folder with standalone Python scripts that Claude Code can execute directly. Tools from the same source module are grouped into a single script file with a CLI wrapper that accepts `--arg value` arguments.
|
|
186
|
+
|
|
187
|
+
## Configuration
|
|
188
|
+
|
|
189
|
+
The `--config` (`-c`) flag points to an `orchid.yml` file:
|
|
190
|
+
|
|
191
|
+
```yaml
|
|
192
|
+
llm:
|
|
193
|
+
model: ollama/llama3.2
|
|
194
|
+
agents:
|
|
195
|
+
config_path: agents.yaml
|
|
196
|
+
rag:
|
|
197
|
+
vector_backend: null # no Qdrant needed for basic usage
|
|
198
|
+
storage:
|
|
199
|
+
class: orchid.persistence.sqlite.SQLiteChatStorage
|
|
200
|
+
dsn: ~/.orchid/chats.db
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Defaults
|
|
204
|
+
|
|
205
|
+
| Parameter | Default | Env Override |
|
|
206
|
+
|-----------|---------|-------------|
|
|
207
|
+
| LLM model | `ollama/llama3.2` | `LITELLM_MODEL` |
|
|
208
|
+
| Vector backend | `qdrant` | `VECTOR_BACKEND` |
|
|
209
|
+
| Storage class | `orchid.persistence.sqlite.SQLiteChatStorage` | `CHAT_STORAGE_CLASS` |
|
|
210
|
+
| Storage DSN | `~/.orchid/chats.db` | `CHAT_DB_DSN` |
|
|
211
|
+
|
|
212
|
+
Chat data is stored in SQLite at `~/.orchid/chats.db` by default. The directory is created automatically on first run.
|
|
213
|
+
|
|
214
|
+
## Prerequisites
|
|
215
|
+
|
|
216
|
+
- Python 3.11+
|
|
217
|
+
- Ollama running locally (for local LLM models): `ollama pull llama3.2`
|
|
218
|
+
|
|
219
|
+
## Architecture
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
orchid_cli/
|
|
223
|
+
main.py Typer entry point -- registers sub-commands
|
|
224
|
+
bootstrap.py Shared startup: load config, build graph, init storage
|
|
225
|
+
commands/
|
|
226
|
+
chat.py Full CRUD + messaging + interactive mode
|
|
227
|
+
config.py Validate agents.yaml
|
|
228
|
+
index.py Seed RAG vector store
|
|
229
|
+
skill.py Generate Claude Code skills from agents.yaml
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The CLI is a thin layer that calls `orchid` SDK functions and displays results via Rich.
|
|
233
|
+
|
|
234
|
+
## Development
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pip install -e ../orchid -e ".[dev]"
|
|
238
|
+
orchid config validate ../examples/basketball/agents.yaml
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Testing
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
pip install -e ".[dev]"
|
|
245
|
+
pytest tests/ -x
|
|
246
|
+
ruff check orchid_cli/
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT -- see [LICENSE](LICENSE).
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Orchid CLI</h1>
|
|
6
6
|
|
|
7
|
-
Command-line interface for the [Orchid](
|
|
7
|
+
Command-line interface for the [Orchid](https://github.com/gadz82/orchid) multi-agent AI framework.
|
|
8
8
|
|
|
9
9
|
Provides terminal access to all chat operations, configuration validation, RAG indexing, and Claude Code skill generation. Mirrors the full functionality of [orchid-api](../orchid-api) but runs locally with no server, Docker, or external database required (defaults to SQLite).
|
|
10
10
|
|
|
@@ -1,8 +1,40 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "orchid-cli"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.2"
|
|
4
4
|
description = "Orchid CLI — command-line interface for the Orchid agent framework"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
5
7
|
requires-python = ">=3.11"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Francesco Marchesini", email = "gadz82@users.noreply.github.com" },
|
|
10
|
+
]
|
|
11
|
+
maintainers = [
|
|
12
|
+
{ name = "Francesco Marchesini", email = "gadz82@users.noreply.github.com" },
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
24
|
+
"Environment :: Console",
|
|
25
|
+
"Typing :: Typed",
|
|
26
|
+
]
|
|
27
|
+
keywords = [
|
|
28
|
+
"ai",
|
|
29
|
+
"agents",
|
|
30
|
+
"multi-agent",
|
|
31
|
+
"cli",
|
|
32
|
+
"langgraph",
|
|
33
|
+
"rag",
|
|
34
|
+
"mcp",
|
|
35
|
+
"llm",
|
|
36
|
+
"orchestration",
|
|
37
|
+
]
|
|
6
38
|
dependencies = [
|
|
7
39
|
"orchid-ai>=1.2.0",
|
|
8
40
|
"typer>=0.12.0",
|
|
@@ -16,6 +48,13 @@ dependencies = [
|
|
|
16
48
|
[project.scripts]
|
|
17
49
|
orchid = "orchid_cli.main:app"
|
|
18
50
|
|
|
51
|
+
[project.urls]
|
|
52
|
+
Homepage = "https://github.com/gadz82/orchid"
|
|
53
|
+
Repository = "https://github.com/gadz82/orchid"
|
|
54
|
+
Documentation = "https://github.com/gadz82/orchid#readme"
|
|
55
|
+
Issues = "https://github.com/gadz82/orchid/issues"
|
|
56
|
+
Changelog = "https://github.com/gadz82/orchid/blob/main/CHANGELOG.md"
|
|
57
|
+
|
|
19
58
|
[project.optional-dependencies]
|
|
20
59
|
dev = [
|
|
21
60
|
"pytest>=8.0",
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Fake date tools for skill generation tests — no external dependencies."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def format_date(value: str, fmt: str = "%Y-%m-%d") -> str:
|
|
9
|
+
"""
|
|
10
|
+
Parse a date string and re-format it.
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
value : str
|
|
15
|
+
Input date string (e.g. ``"2025-03-15T10:30:00Z"``).
|
|
16
|
+
fmt : str
|
|
17
|
+
Output format (``strftime`` pattern). Default: ``"%Y-%m-%d"``.
|
|
18
|
+
|
|
19
|
+
Returns
|
|
20
|
+
-------
|
|
21
|
+
str
|
|
22
|
+
Formatted date string.
|
|
23
|
+
"""
|
|
24
|
+
formats_to_try = [
|
|
25
|
+
"%Y-%m-%dT%H:%M:%SZ",
|
|
26
|
+
"%Y-%m-%dT%H:%M:%S",
|
|
27
|
+
"%Y-%m-%dT%H:%M:%S%z",
|
|
28
|
+
"%Y-%m-%d %H:%M:%S",
|
|
29
|
+
"%Y-%m-%d",
|
|
30
|
+
"%d/%m/%Y",
|
|
31
|
+
"%m/%d/%Y",
|
|
32
|
+
]
|
|
33
|
+
for parse_fmt in formats_to_try:
|
|
34
|
+
try:
|
|
35
|
+
dt = datetime.strptime(value, parse_fmt)
|
|
36
|
+
return dt.strftime(fmt)
|
|
37
|
+
except ValueError:
|
|
38
|
+
continue
|
|
39
|
+
raise ValueError(f"Could not parse date '{value}' with any known format")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Fake math tools for skill generation tests — no external dependencies."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def calculate_completion_rate(enrolled: int, completed: int) -> float:
|
|
7
|
+
"""
|
|
8
|
+
Calculate course completion percentage.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
enrolled : int
|
|
13
|
+
Total number of enrolled users.
|
|
14
|
+
completed : int
|
|
15
|
+
Number of users who completed the course.
|
|
16
|
+
|
|
17
|
+
Returns
|
|
18
|
+
-------
|
|
19
|
+
float
|
|
20
|
+
Completion rate as a percentage (0.0–100.0), rounded to 1 decimal.
|
|
21
|
+
"""
|
|
22
|
+
if enrolled <= 0:
|
|
23
|
+
return 0.0
|
|
24
|
+
return round((completed / enrolled) * 100, 1)
|
|
@@ -74,7 +74,7 @@ class TestSkillGenerate:
|
|
|
74
74
|
config = _minimal_config(
|
|
75
75
|
tools={
|
|
76
76
|
"my_tool": {
|
|
77
|
-
"handler": "
|
|
77
|
+
"handler": "tests.fixtures.fake_tools_math.calculate_completion_rate",
|
|
78
78
|
"description": "Calculate completion rate",
|
|
79
79
|
},
|
|
80
80
|
},
|
|
@@ -103,7 +103,7 @@ class TestSkillGenerate:
|
|
|
103
103
|
config = _minimal_config(
|
|
104
104
|
tools={
|
|
105
105
|
"calc_rate": {
|
|
106
|
-
"handler": "
|
|
106
|
+
"handler": "tests.fixtures.fake_tools_math.calculate_completion_rate",
|
|
107
107
|
"description": "Calc rate",
|
|
108
108
|
},
|
|
109
109
|
},
|
|
@@ -113,7 +113,7 @@ class TestSkillGenerate:
|
|
|
113
113
|
out = str(tmp_path / "skills")
|
|
114
114
|
runner.invoke(app, ["skill", "generate", cfg_path, "-o", out])
|
|
115
115
|
os.unlink(cfg_path)
|
|
116
|
-
script = tmp_path / "skills" / "helper" / "scripts" / "
|
|
116
|
+
script = tmp_path / "skills" / "helper" / "scripts" / "fake_tools_math.py"
|
|
117
117
|
assert script.exists()
|
|
118
118
|
# Run the script
|
|
119
119
|
result = subprocess.run(
|
|
@@ -129,7 +129,7 @@ class TestSkillGenerate:
|
|
|
129
129
|
config = _minimal_config(
|
|
130
130
|
tools={
|
|
131
131
|
"calc_rate": {
|
|
132
|
-
"handler": "
|
|
132
|
+
"handler": "tests.fixtures.fake_tools_math.calculate_completion_rate",
|
|
133
133
|
"description": "Calc rate",
|
|
134
134
|
},
|
|
135
135
|
},
|
|
@@ -139,7 +139,7 @@ class TestSkillGenerate:
|
|
|
139
139
|
out = str(tmp_path / "skills")
|
|
140
140
|
runner.invoke(app, ["skill", "generate", cfg_path, "-o", out])
|
|
141
141
|
os.unlink(cfg_path)
|
|
142
|
-
script = tmp_path / "skills" / "helper" / "scripts" / "
|
|
142
|
+
script = tmp_path / "skills" / "helper" / "scripts" / "fake_tools_math.py"
|
|
143
143
|
result = subprocess.run(
|
|
144
144
|
[sys.executable, str(script), "--help"],
|
|
145
145
|
capture_output=True,
|
|
@@ -153,7 +153,7 @@ class TestSkillGenerate:
|
|
|
153
153
|
config = _minimal_config(
|
|
154
154
|
tools={
|
|
155
155
|
"calc_rate": {
|
|
156
|
-
"handler": "
|
|
156
|
+
"handler": "tests.fixtures.fake_tools_math.calculate_completion_rate",
|
|
157
157
|
"description": "Calc rate",
|
|
158
158
|
},
|
|
159
159
|
},
|
|
@@ -164,7 +164,7 @@ class TestSkillGenerate:
|
|
|
164
164
|
runner.invoke(app, ["skill", "generate", cfg_path, "-o", out])
|
|
165
165
|
os.unlink(cfg_path)
|
|
166
166
|
content = (tmp_path / "skills" / "helper" / "SKILL.md").read_text()
|
|
167
|
-
assert "scripts/
|
|
167
|
+
assert "scripts/fake_tools_math.py" in content
|
|
168
168
|
assert "CLAUDE_SKILL_DIR" in content
|
|
169
169
|
assert "allowed-tools" in content
|
|
170
170
|
|
|
@@ -235,7 +235,7 @@ class TestSkillGenerate:
|
|
|
235
235
|
"""Agent-level skills appear as workflows in SKILL.md."""
|
|
236
236
|
config = _minimal_config(
|
|
237
237
|
tools={
|
|
238
|
-
"step_a": {"handler": "
|
|
238
|
+
"step_a": {"handler": "tests.fixtures.fake_tools_math.calculate_completion_rate", "description": "Step A"},
|
|
239
239
|
},
|
|
240
240
|
)
|
|
241
241
|
config["agents"]["helper"]["tools"] = ["step_a"]
|
|
@@ -255,7 +255,7 @@ class TestSkillGenerate:
|
|
|
255
255
|
assert "my_workflow" in content
|
|
256
256
|
assert "A two-step workflow" in content
|
|
257
257
|
# Workflow steps should reference scripts
|
|
258
|
-
assert "scripts/
|
|
258
|
+
assert "scripts/fake_tools_math.py" in content
|
|
259
259
|
|
|
260
260
|
def test_mcp_servers_noted(self, tmp_path):
|
|
261
261
|
"""MCP servers are documented as non-portable integrations."""
|
|
@@ -279,8 +279,8 @@ class TestSkillGenerate:
|
|
|
279
279
|
"""Tools from the same module share one script file."""
|
|
280
280
|
config = _minimal_config(
|
|
281
281
|
tools={
|
|
282
|
-
"tool_a": {"handler": "
|
|
283
|
-
"tool_b": {"handler": "
|
|
282
|
+
"tool_a": {"handler": "tests.fixtures.fake_tools_math.calculate_completion_rate", "description": "A"},
|
|
283
|
+
"tool_b": {"handler": "tests.fixtures.fake_tools_dates.format_date", "description": "B"},
|
|
284
284
|
},
|
|
285
285
|
)
|
|
286
286
|
config["agents"]["helper"]["tools"] = ["tool_a", "tool_b"]
|
|
@@ -290,8 +290,8 @@ class TestSkillGenerate:
|
|
|
290
290
|
os.unlink(cfg_path)
|
|
291
291
|
scripts_dir = tmp_path / "skills" / "helper" / "scripts"
|
|
292
292
|
# Two different modules -> two script files
|
|
293
|
-
assert (scripts_dir / "
|
|
294
|
-
assert (scripts_dir / "
|
|
293
|
+
assert (scripts_dir / "fake_tools_math.py").exists()
|
|
294
|
+
assert (scripts_dir / "fake_tools_dates.py").exists()
|
|
295
295
|
|
|
296
296
|
def test_generates_zip_archive(self, tmp_path):
|
|
297
297
|
"""--zip flag creates a zip archive of all generated skills."""
|
orchid_cli-1.0.0/CHANGELOG.md
DELETED
orchid_cli-1.0.0/PKG-INFO
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: orchid-cli
|
|
3
|
-
Version: 1.0.0
|
|
4
|
-
Summary: Orchid CLI — command-line interface for the Orchid agent framework
|
|
5
|
-
License-File: LICENSE
|
|
6
|
-
Requires-Python: >=3.11
|
|
7
|
-
Requires-Dist: httpx>=0.28.0
|
|
8
|
-
Requires-Dist: langchain-core>=0.3.0
|
|
9
|
-
Requires-Dist: orchid-ai>=1.2.0
|
|
10
|
-
Requires-Dist: pydantic-settings>=2.7.0
|
|
11
|
-
Requires-Dist: pyyaml>=6.0
|
|
12
|
-
Requires-Dist: rich>=13.0
|
|
13
|
-
Requires-Dist: typer>=0.12.0
|
|
14
|
-
Provides-Extra: dev
|
|
15
|
-
Requires-Dist: gitlint>=0.19.0; extra == 'dev'
|
|
16
|
-
Requires-Dist: pre-commit>=4.0; extra == 'dev'
|
|
17
|
-
Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
|
|
18
|
-
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
|
|
19
|
-
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
20
|
-
Requires-Dist: ruff>=0.9.0; extra == 'dev'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|