aichat-pro-cli 2026.8.11.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.
- aichat_pro_cli-2026.8.11.0/.env.example +9 -0
- aichat_pro_cli-2026.8.11.0/CHANGELOG.md +19 -0
- aichat_pro_cli-2026.8.11.0/LICENSE +21 -0
- aichat_pro_cli-2026.8.11.0/PKG-INFO +147 -0
- aichat_pro_cli-2026.8.11.0/README.md +102 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/__init__.py +1 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/__main__.py +5 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/commands/__init__.py +1 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/commands/chat.py +312 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/commands/info.py +37 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/core/__init__.py +1 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/core/client.py +97 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/core/config.py +39 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/core/exceptions.py +37 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/core/output.py +290 -0
- aichat_pro_cli-2026.8.11.0/aichat_cli/main.py +66 -0
- aichat_pro_cli-2026.8.11.0/pyproject.toml +118 -0
- aichat_pro_cli-2026.8.11.0/tests/conftest.py +53 -0
- aichat_pro_cli-2026.8.11.0/tests/test_client.py +119 -0
- aichat_pro_cli-2026.8.11.0/tests/test_commands.py +586 -0
- aichat_pro_cli-2026.8.11.0/tests/test_config.py +48 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# AceDataCloud API Token
|
|
2
|
+
# Get yours at https://platform.acedata.cloud
|
|
3
|
+
ACEDATACLOUD_API_TOKEN=
|
|
4
|
+
|
|
5
|
+
# Optional: Custom API base URL (default: https://api.acedata.cloud)
|
|
6
|
+
# ACEDATACLOUD_API_BASE_URL=https://api.acedata.cloud
|
|
7
|
+
|
|
8
|
+
# Optional: Request timeout in seconds (default: 30)
|
|
9
|
+
# AICHAT_REQUEST_TIMEOUT=30
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2025-04-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Initial release of AiChat CLI
|
|
10
|
+
- `chat` command to send questions to large language models
|
|
11
|
+
- `models` command to list all available models
|
|
12
|
+
- `config` command to show current configuration
|
|
13
|
+
- Support for conversation continuation via `--id`
|
|
14
|
+
- Support for stateful conversations via `--stateful`
|
|
15
|
+
- Support for references/context documents via `--ref`
|
|
16
|
+
- Support for preset models via `--preset`
|
|
17
|
+
- `--json` flag for machine-readable output on all commands
|
|
18
|
+
- Rich terminal formatting for human-readable output
|
|
19
|
+
- Docker support via Dockerfile and docker-compose.yaml
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AceDataCloud
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: aichat-pro-cli
|
|
3
|
+
Version: 2026.8.11.0
|
|
4
|
+
Summary: CLI tool for AI Dialogue (aichat) via AceDataCloud API
|
|
5
|
+
Project-URL: Homepage, https://github.com/AceDataCloud/AichatCli
|
|
6
|
+
Project-URL: Repository, https://github.com/AceDataCloud/AichatCli
|
|
7
|
+
Project-URL: Issues, https://github.com/AceDataCloud/AichatCli/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/AceDataCloud/AichatCli/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: AceDataCloud <support@acedata.cloud>
|
|
10
|
+
Maintainer-email: AceDataCloud <support@acedata.cloud>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: acedata,ai,aichat,chat,cli,command-line,gpt,llm
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: click>=8.1.0
|
|
26
|
+
Requires-Dist: httpx>=0.27.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
29
|
+
Requires-Dist: rich>=13.0.0
|
|
30
|
+
Provides-Extra: all
|
|
31
|
+
Requires-Dist: aichat-pro-cli[dev,release,test]; extra == 'all'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
36
|
+
Provides-Extra: release
|
|
37
|
+
Requires-Dist: build>=1.2.0; extra == 'release'
|
|
38
|
+
Requires-Dist: twine>=6.1.0; extra == 'release'
|
|
39
|
+
Provides-Extra: test
|
|
40
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
|
|
41
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
|
|
42
|
+
Requires-Dist: pytest>=8.0.0; extra == 'test'
|
|
43
|
+
Requires-Dist: respx>=0.21.0; extra == 'test'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# AiChat CLI
|
|
47
|
+
|
|
48
|
+
A command-line tool for AI Dialogue via the [AceDataCloud](https://platform.acedata.cloud) platform.
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- **Chat with AI** — Send questions to GPT, DeepSeek, Grok, GLM, and more models
|
|
53
|
+
- **Conversation Continuation** — Resume conversations using `--id`
|
|
54
|
+
- **Stateful Sessions** — Enable multi-turn context with `--stateful`
|
|
55
|
+
- **References** — Inject context documents into prompts with `--ref`
|
|
56
|
+
- **Rich Output** — Beautiful terminal formatting with `--json` for scripting
|
|
57
|
+
- **Many Models** — GPT-5, GPT-4o, o3, o4-mini, DeepSeek, Grok, GLM, and more
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install aichat-pro-cli
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Set your API token
|
|
69
|
+
export ACEDATACLOUD_API_TOKEN=your_token_here
|
|
70
|
+
|
|
71
|
+
# Ask a question
|
|
72
|
+
aichat chat "What is the capital of France?"
|
|
73
|
+
|
|
74
|
+
# Use a specific model
|
|
75
|
+
aichat chat "Explain quantum computing" -m gpt-4o
|
|
76
|
+
|
|
77
|
+
# Continue a conversation
|
|
78
|
+
aichat chat "Tell me more" --id 64a67fff-61dc-4801-8339-2c69334c61d6
|
|
79
|
+
|
|
80
|
+
# Stateful conversation (server remembers context)
|
|
81
|
+
aichat chat "My name is Alice" --stateful
|
|
82
|
+
aichat chat "What is my name?" --id <returned-id> --stateful
|
|
83
|
+
|
|
84
|
+
# With reference documents
|
|
85
|
+
aichat chat "Summarize this" --ref "https://example.com/doc.txt"
|
|
86
|
+
|
|
87
|
+
# Get JSON output
|
|
88
|
+
aichat chat "Hello" --json | jq '.answer'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Commands
|
|
92
|
+
|
|
93
|
+
| Command | Description |
|
|
94
|
+
|---------|-------------|
|
|
95
|
+
| `chat` | Send a question to an AI model (`/aichat/conversations`) |
|
|
96
|
+
| `models` | List all available models |
|
|
97
|
+
| `config` | Show current configuration |
|
|
98
|
+
|
|
99
|
+
## Chat Options
|
|
100
|
+
|
|
101
|
+
| Option | Description |
|
|
102
|
+
|--------|-------------|
|
|
103
|
+
| `-m`, `--model` | Model to use (default: `gpt-4o`) |
|
|
104
|
+
| `--id` | Conversation ID to continue |
|
|
105
|
+
| `--preset` | Preset model name |
|
|
106
|
+
| `--stateful` | Enable stateful conversation |
|
|
107
|
+
| `--ref` | Reference URL or text (repeatable) |
|
|
108
|
+
| `--json` | Output raw JSON |
|
|
109
|
+
|
|
110
|
+
## Configuration
|
|
111
|
+
|
|
112
|
+
| Environment Variable | Description | Default |
|
|
113
|
+
|---------------------|-------------|---------|
|
|
114
|
+
| `ACEDATACLOUD_API_TOKEN` | API authentication token | (required) |
|
|
115
|
+
| `ACEDATACLOUD_API_BASE_URL` | API base URL | `https://api.acedata.cloud` |
|
|
116
|
+
| `AICHAT_REQUEST_TIMEOUT` | Request timeout in seconds | `30` |
|
|
117
|
+
|
|
118
|
+
You can also use a `.env` file or pass `--token` directly.
|
|
119
|
+
|
|
120
|
+
## Docker
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
docker compose run aichat-cli chat "Hello!"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Development
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Install with dev dependencies
|
|
130
|
+
pip install -e ".[all]"
|
|
131
|
+
|
|
132
|
+
# Run tests
|
|
133
|
+
pytest
|
|
134
|
+
|
|
135
|
+
# Run linter
|
|
136
|
+
ruff check .
|
|
137
|
+
ruff format --check .
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
143
|
+
|
|
144
|
+
## Links
|
|
145
|
+
|
|
146
|
+
- [AceDataCloud Platform](https://platform.acedata.cloud)
|
|
147
|
+
- [API Documentation](https://docs.acedata.cloud)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# AiChat CLI
|
|
2
|
+
|
|
3
|
+
A command-line tool for AI Dialogue via the [AceDataCloud](https://platform.acedata.cloud) platform.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Chat with AI** — Send questions to GPT, DeepSeek, Grok, GLM, and more models
|
|
8
|
+
- **Conversation Continuation** — Resume conversations using `--id`
|
|
9
|
+
- **Stateful Sessions** — Enable multi-turn context with `--stateful`
|
|
10
|
+
- **References** — Inject context documents into prompts with `--ref`
|
|
11
|
+
- **Rich Output** — Beautiful terminal formatting with `--json` for scripting
|
|
12
|
+
- **Many Models** — GPT-5, GPT-4o, o3, o4-mini, DeepSeek, Grok, GLM, and more
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install aichat-pro-cli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Set your API token
|
|
24
|
+
export ACEDATACLOUD_API_TOKEN=your_token_here
|
|
25
|
+
|
|
26
|
+
# Ask a question
|
|
27
|
+
aichat chat "What is the capital of France?"
|
|
28
|
+
|
|
29
|
+
# Use a specific model
|
|
30
|
+
aichat chat "Explain quantum computing" -m gpt-4o
|
|
31
|
+
|
|
32
|
+
# Continue a conversation
|
|
33
|
+
aichat chat "Tell me more" --id 64a67fff-61dc-4801-8339-2c69334c61d6
|
|
34
|
+
|
|
35
|
+
# Stateful conversation (server remembers context)
|
|
36
|
+
aichat chat "My name is Alice" --stateful
|
|
37
|
+
aichat chat "What is my name?" --id <returned-id> --stateful
|
|
38
|
+
|
|
39
|
+
# With reference documents
|
|
40
|
+
aichat chat "Summarize this" --ref "https://example.com/doc.txt"
|
|
41
|
+
|
|
42
|
+
# Get JSON output
|
|
43
|
+
aichat chat "Hello" --json | jq '.answer'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Commands
|
|
47
|
+
|
|
48
|
+
| Command | Description |
|
|
49
|
+
|---------|-------------|
|
|
50
|
+
| `chat` | Send a question to an AI model (`/aichat/conversations`) |
|
|
51
|
+
| `models` | List all available models |
|
|
52
|
+
| `config` | Show current configuration |
|
|
53
|
+
|
|
54
|
+
## Chat Options
|
|
55
|
+
|
|
56
|
+
| Option | Description |
|
|
57
|
+
|--------|-------------|
|
|
58
|
+
| `-m`, `--model` | Model to use (default: `gpt-4o`) |
|
|
59
|
+
| `--id` | Conversation ID to continue |
|
|
60
|
+
| `--preset` | Preset model name |
|
|
61
|
+
| `--stateful` | Enable stateful conversation |
|
|
62
|
+
| `--ref` | Reference URL or text (repeatable) |
|
|
63
|
+
| `--json` | Output raw JSON |
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
| Environment Variable | Description | Default |
|
|
68
|
+
|---------------------|-------------|---------|
|
|
69
|
+
| `ACEDATACLOUD_API_TOKEN` | API authentication token | (required) |
|
|
70
|
+
| `ACEDATACLOUD_API_BASE_URL` | API base URL | `https://api.acedata.cloud` |
|
|
71
|
+
| `AICHAT_REQUEST_TIMEOUT` | Request timeout in seconds | `30` |
|
|
72
|
+
|
|
73
|
+
You can also use a `.env` file or pass `--token` directly.
|
|
74
|
+
|
|
75
|
+
## Docker
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
docker compose run aichat-cli chat "Hello!"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Install with dev dependencies
|
|
85
|
+
pip install -e ".[all]"
|
|
86
|
+
|
|
87
|
+
# Run tests
|
|
88
|
+
pytest
|
|
89
|
+
|
|
90
|
+
# Run linter
|
|
91
|
+
ruff check .
|
|
92
|
+
ruff format --check .
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
98
|
+
|
|
99
|
+
## Links
|
|
100
|
+
|
|
101
|
+
- [AceDataCloud Platform](https://platform.acedata.cloud)
|
|
102
|
+
- [API Documentation](https://docs.acedata.cloud)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""AiChat CLI - AI Dialogue via AceDataCloud API."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""AiChat CLI commands package."""
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"""Chat command."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from aichat_cli.core.client import get_client
|
|
8
|
+
from aichat_cli.core.exceptions import AichatError
|
|
9
|
+
from aichat_cli.core.output import (
|
|
10
|
+
ACTIONS2,
|
|
11
|
+
DEFAULT_MODEL,
|
|
12
|
+
DEFAULT_MODEL2,
|
|
13
|
+
MODEL_GROUPS,
|
|
14
|
+
MODELS,
|
|
15
|
+
MODELS2,
|
|
16
|
+
print_answer,
|
|
17
|
+
print_error,
|
|
18
|
+
print_json,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _parse_json_option(value: str | None, param_hint: str) -> dict | list | None:
|
|
23
|
+
"""Parse a JSON string option, raising BadParameter on invalid JSON."""
|
|
24
|
+
if value is None:
|
|
25
|
+
return None
|
|
26
|
+
try:
|
|
27
|
+
return json.loads(value)
|
|
28
|
+
except json.JSONDecodeError as exc:
|
|
29
|
+
raise click.BadParameter("Must be a valid JSON string.", param_hint=param_hint) from exc
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@click.command()
|
|
33
|
+
@click.argument("question")
|
|
34
|
+
@click.option(
|
|
35
|
+
"-m",
|
|
36
|
+
"--model",
|
|
37
|
+
default=DEFAULT_MODEL,
|
|
38
|
+
type=click.Choice(MODELS, case_sensitive=True),
|
|
39
|
+
help=f"Model to use (default: {DEFAULT_MODEL}).",
|
|
40
|
+
show_default=True,
|
|
41
|
+
)
|
|
42
|
+
@click.option(
|
|
43
|
+
"--id",
|
|
44
|
+
"conversation_id",
|
|
45
|
+
default=None,
|
|
46
|
+
help="Conversation ID to continue an existing conversation.",
|
|
47
|
+
)
|
|
48
|
+
@click.option(
|
|
49
|
+
"--preset",
|
|
50
|
+
default=None,
|
|
51
|
+
help="Preset model name.",
|
|
52
|
+
)
|
|
53
|
+
@click.option(
|
|
54
|
+
"--stateful",
|
|
55
|
+
is_flag=True,
|
|
56
|
+
default=False,
|
|
57
|
+
help="Enable stateful conversation (server remembers context).",
|
|
58
|
+
)
|
|
59
|
+
@click.option(
|
|
60
|
+
"--ref",
|
|
61
|
+
"references",
|
|
62
|
+
multiple=True,
|
|
63
|
+
help="Reference URL or text to include as context (can be repeated).",
|
|
64
|
+
)
|
|
65
|
+
@click.option("--json", "output_json", is_flag=True, help="Output raw JSON.")
|
|
66
|
+
@click.pass_context
|
|
67
|
+
def chat(
|
|
68
|
+
ctx: click.Context,
|
|
69
|
+
question: str,
|
|
70
|
+
model: str,
|
|
71
|
+
conversation_id: str | None,
|
|
72
|
+
preset: str | None,
|
|
73
|
+
stateful: bool,
|
|
74
|
+
references: tuple[str, ...],
|
|
75
|
+
output_json: bool,
|
|
76
|
+
) -> None:
|
|
77
|
+
"""Send a question to an AI model and get an answer.
|
|
78
|
+
|
|
79
|
+
QUESTION is the prompt or question to send to the model.
|
|
80
|
+
|
|
81
|
+
\b
|
|
82
|
+
Examples:
|
|
83
|
+
aichat chat "What is the capital of France?"
|
|
84
|
+
aichat chat "Explain AI" -m gpt-4o
|
|
85
|
+
aichat chat "Tell me more" --id 64a67fff-61dc-4801-8339-2c69334c61d6
|
|
86
|
+
aichat chat "My name is Alice" --stateful
|
|
87
|
+
aichat chat "Summarize this" --ref "https://example.com/doc.txt"
|
|
88
|
+
"""
|
|
89
|
+
client = get_client(ctx.obj.get("token"))
|
|
90
|
+
try:
|
|
91
|
+
payload: dict[str, object] = {
|
|
92
|
+
"question": question,
|
|
93
|
+
"model": model,
|
|
94
|
+
"id": conversation_id,
|
|
95
|
+
"preset": preset,
|
|
96
|
+
"stateful": stateful if stateful else None,
|
|
97
|
+
"references": list(references) if references else None,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
result = client.converse(**payload) # type: ignore[arg-type]
|
|
101
|
+
if output_json:
|
|
102
|
+
print_json(result)
|
|
103
|
+
else:
|
|
104
|
+
print_answer(result)
|
|
105
|
+
except AichatError as e:
|
|
106
|
+
print_error(e.message)
|
|
107
|
+
raise SystemExit(1) from e
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@click.command(name="chat2")
|
|
111
|
+
@click.argument("question", required=False, default=None)
|
|
112
|
+
@click.option(
|
|
113
|
+
"-m",
|
|
114
|
+
"--model",
|
|
115
|
+
default=DEFAULT_MODEL2,
|
|
116
|
+
type=click.Choice(MODELS2, case_sensitive=True),
|
|
117
|
+
help=f"Model to use (default: {DEFAULT_MODEL2}).",
|
|
118
|
+
show_default=True,
|
|
119
|
+
)
|
|
120
|
+
@click.option(
|
|
121
|
+
"--action",
|
|
122
|
+
default="chat",
|
|
123
|
+
type=click.Choice(ACTIONS2),
|
|
124
|
+
help="Action to perform (default: chat).",
|
|
125
|
+
show_default=True,
|
|
126
|
+
)
|
|
127
|
+
@click.option(
|
|
128
|
+
"--id",
|
|
129
|
+
"conversation_id",
|
|
130
|
+
default=None,
|
|
131
|
+
help="Conversation ID to continue an existing conversation.",
|
|
132
|
+
)
|
|
133
|
+
@click.option(
|
|
134
|
+
"--preset",
|
|
135
|
+
default=None,
|
|
136
|
+
help="Preset model name.",
|
|
137
|
+
)
|
|
138
|
+
@click.option(
|
|
139
|
+
"--stateful/--no-stateful",
|
|
140
|
+
default=None,
|
|
141
|
+
help="Enable or disable stateful conversation (omitted by default; server default: true).",
|
|
142
|
+
)
|
|
143
|
+
@click.option(
|
|
144
|
+
"--ref",
|
|
145
|
+
"references",
|
|
146
|
+
multiple=True,
|
|
147
|
+
help="Reference URL or text to include as context (can be repeated).",
|
|
148
|
+
)
|
|
149
|
+
@click.option(
|
|
150
|
+
"--model-group",
|
|
151
|
+
default=None,
|
|
152
|
+
type=click.Choice(MODEL_GROUPS),
|
|
153
|
+
help="Model group to use (e.g. chatgpt, claude, gemini).",
|
|
154
|
+
)
|
|
155
|
+
@click.option(
|
|
156
|
+
"--max-turns",
|
|
157
|
+
default=None,
|
|
158
|
+
type=click.IntRange(min=1),
|
|
159
|
+
help="Maximum number of conversation turns.",
|
|
160
|
+
)
|
|
161
|
+
@click.option(
|
|
162
|
+
"--title",
|
|
163
|
+
default=None,
|
|
164
|
+
help="Title for the conversation.",
|
|
165
|
+
)
|
|
166
|
+
@click.option(
|
|
167
|
+
"--user-id",
|
|
168
|
+
default=None,
|
|
169
|
+
help="User ID for the conversation.",
|
|
170
|
+
)
|
|
171
|
+
@click.option(
|
|
172
|
+
"--callback-url",
|
|
173
|
+
default=None,
|
|
174
|
+
help="Callback URL for async results.",
|
|
175
|
+
)
|
|
176
|
+
@click.option(
|
|
177
|
+
"--async-mode",
|
|
178
|
+
"async_mode",
|
|
179
|
+
is_flag=True,
|
|
180
|
+
default=False,
|
|
181
|
+
help="Enable asynchronous processing.",
|
|
182
|
+
)
|
|
183
|
+
@click.option(
|
|
184
|
+
"--application-id",
|
|
185
|
+
default=None,
|
|
186
|
+
help="Application ID for the conversation.",
|
|
187
|
+
)
|
|
188
|
+
@click.option(
|
|
189
|
+
"--allowed-skill",
|
|
190
|
+
"allowed_skills",
|
|
191
|
+
multiple=True,
|
|
192
|
+
help="Allowed skill name (can be repeated).",
|
|
193
|
+
)
|
|
194
|
+
@click.option(
|
|
195
|
+
"--allowed-mcp-server",
|
|
196
|
+
"allowed_mcp_servers",
|
|
197
|
+
multiple=True,
|
|
198
|
+
help="Allowed MCP server name (can be repeated).",
|
|
199
|
+
)
|
|
200
|
+
@click.option(
|
|
201
|
+
"--offset",
|
|
202
|
+
default=None,
|
|
203
|
+
type=click.IntRange(min=0),
|
|
204
|
+
help="Offset for paginated retrieval (minimum: 0).",
|
|
205
|
+
)
|
|
206
|
+
@click.option(
|
|
207
|
+
"--limit",
|
|
208
|
+
default=None,
|
|
209
|
+
type=click.IntRange(min=1, max=100),
|
|
210
|
+
help="Limit for paginated retrieval (1-100).",
|
|
211
|
+
)
|
|
212
|
+
@click.option(
|
|
213
|
+
"--message",
|
|
214
|
+
default=None,
|
|
215
|
+
help="Single message value as a JSON string (alternative to --question for complex message types).",
|
|
216
|
+
)
|
|
217
|
+
@click.option(
|
|
218
|
+
"--messages",
|
|
219
|
+
default=None,
|
|
220
|
+
help='Conversation messages as a JSON array, e.g. \'[{"role":"user","content":"Hello"}]\'.',
|
|
221
|
+
)
|
|
222
|
+
@click.option(
|
|
223
|
+
"--tool-results",
|
|
224
|
+
default=None,
|
|
225
|
+
help='Tool call results as a JSON array, e.g. \'[{"tool_use_id":"id","output":"result"}]\'.',
|
|
226
|
+
)
|
|
227
|
+
@click.option(
|
|
228
|
+
"--unattended-policy",
|
|
229
|
+
default=None,
|
|
230
|
+
help=(
|
|
231
|
+
"Unattended agent policy as a JSON object, "
|
|
232
|
+
'e.g. \'{"allowed_skills":["web_search"],"allowed_mcp_servers":[],"expires_at":1790000000}\'.'
|
|
233
|
+
),
|
|
234
|
+
)
|
|
235
|
+
@click.option("--json", "output_json", is_flag=True, help="Output raw JSON.")
|
|
236
|
+
@click.pass_context
|
|
237
|
+
def chat2(
|
|
238
|
+
ctx: click.Context,
|
|
239
|
+
question: str | None,
|
|
240
|
+
model: str,
|
|
241
|
+
action: str,
|
|
242
|
+
conversation_id: str | None,
|
|
243
|
+
preset: str | None,
|
|
244
|
+
stateful: bool | None,
|
|
245
|
+
references: tuple[str, ...],
|
|
246
|
+
model_group: str | None,
|
|
247
|
+
max_turns: int | None,
|
|
248
|
+
title: str | None,
|
|
249
|
+
user_id: str | None,
|
|
250
|
+
callback_url: str | None,
|
|
251
|
+
async_mode: bool,
|
|
252
|
+
application_id: str | None,
|
|
253
|
+
allowed_skills: tuple[str, ...],
|
|
254
|
+
allowed_mcp_servers: tuple[str, ...],
|
|
255
|
+
offset: int | None,
|
|
256
|
+
limit: int | None,
|
|
257
|
+
message: str | None,
|
|
258
|
+
messages: str | None,
|
|
259
|
+
tool_results: str | None,
|
|
260
|
+
unattended_policy: str | None,
|
|
261
|
+
output_json: bool,
|
|
262
|
+
) -> None:
|
|
263
|
+
"""Send a question or conversation payload to an AI model via the aichat2 endpoint.
|
|
264
|
+
|
|
265
|
+
QUESTION is an optional prompt or question to send to the model.
|
|
266
|
+
Omit it for actions like retrieve, or when sending structured payloads
|
|
267
|
+
with --message or --messages.
|
|
268
|
+
|
|
269
|
+
\b
|
|
270
|
+
Examples:
|
|
271
|
+
aichat chat2 "What is the capital of France?"
|
|
272
|
+
aichat chat2 "Explain AI" -m claude-sonnet-5
|
|
273
|
+
aichat chat2 "Tell me more" --id 64a67fff-61dc-4801-8339-2c69334c61d6
|
|
274
|
+
aichat chat2 "Summarize this" --ref "https://example.com/doc.txt" --model-group claude
|
|
275
|
+
aichat chat2 "Hello" --allowed-skill web_search --allowed-mcp-server my-server
|
|
276
|
+
aichat chat2 --action retrieve --id 64a67fff-61dc-4801-8339-2c69334c61d6
|
|
277
|
+
"""
|
|
278
|
+
client = get_client(ctx.obj.get("token"))
|
|
279
|
+
try:
|
|
280
|
+
payload: dict[str, object] = {
|
|
281
|
+
"question": question,
|
|
282
|
+
"model": model,
|
|
283
|
+
"action": action,
|
|
284
|
+
"id": conversation_id,
|
|
285
|
+
"preset": preset,
|
|
286
|
+
"stateful": stateful,
|
|
287
|
+
"references": list(references) if references else None,
|
|
288
|
+
"model_group": model_group,
|
|
289
|
+
"max_turns": max_turns,
|
|
290
|
+
"title": title,
|
|
291
|
+
"user_id": user_id,
|
|
292
|
+
"application_id": application_id,
|
|
293
|
+
"callback_url": callback_url,
|
|
294
|
+
"async": async_mode if async_mode else None,
|
|
295
|
+
"allowed_skills": list(allowed_skills) if allowed_skills else None,
|
|
296
|
+
"allowed_mcp_servers": list(allowed_mcp_servers) if allowed_mcp_servers else None,
|
|
297
|
+
"offset": offset,
|
|
298
|
+
"limit": limit,
|
|
299
|
+
"message": _parse_json_option(message, "--message"),
|
|
300
|
+
"messages": _parse_json_option(messages, "--messages"),
|
|
301
|
+
"tool_results": _parse_json_option(tool_results, "--tool-results"),
|
|
302
|
+
"unattended_policy": _parse_json_option(unattended_policy, "--unattended-policy"),
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
result = client.converse2(**payload) # type: ignore[arg-type]
|
|
306
|
+
if output_json:
|
|
307
|
+
print_json(result)
|
|
308
|
+
else:
|
|
309
|
+
print_answer(result)
|
|
310
|
+
except AichatError as e:
|
|
311
|
+
print_error(e.message)
|
|
312
|
+
raise SystemExit(1) from e
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Info and utility commands."""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
from aichat_cli.core.config import settings
|
|
6
|
+
from aichat_cli.core.output import console, print_models, print_models2
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command()
|
|
10
|
+
def models() -> None:
|
|
11
|
+
"""List all available AI models for /aichat/conversations."""
|
|
12
|
+
print_models()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@click.command()
|
|
16
|
+
def models2() -> None:
|
|
17
|
+
"""List all available AI models for /aichat2/conversations."""
|
|
18
|
+
print_models2()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.command()
|
|
22
|
+
def config() -> None:
|
|
23
|
+
"""Show current configuration."""
|
|
24
|
+
from rich.table import Table
|
|
25
|
+
|
|
26
|
+
table = Table(title="AiChat CLI Configuration")
|
|
27
|
+
table.add_column("Setting", style="bold cyan")
|
|
28
|
+
table.add_column("Value")
|
|
29
|
+
|
|
30
|
+
table.add_row("API Base URL", settings.api_base_url)
|
|
31
|
+
table.add_row(
|
|
32
|
+
"API Token",
|
|
33
|
+
f"{settings.api_token[:8]}..." if settings.api_token else "[red]Not set[/red]",
|
|
34
|
+
)
|
|
35
|
+
table.add_row("Request Timeout", f"{settings.request_timeout}s")
|
|
36
|
+
|
|
37
|
+
console.print(table)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""AiChat CLI core package."""
|