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.
@@ -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,5 @@
1
+ """Allow running as python -m aichat_cli."""
2
+
3
+ from aichat_cli.main import cli
4
+
5
+ cli()
@@ -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."""