cellcog 2.2.0__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {cellcog-2.2.0 → cellcog-2.4.0}/PKG-INFO +78 -21
  2. cellcog-2.4.0/README.md +260 -0
  3. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/__init__.py +1 -1
  4. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/chat.py +76 -9
  5. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/client.py +242 -32
  6. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/daemon/main.py +5 -4
  7. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/daemon/state.py +3 -1
  8. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/docs/api_reference.md +79 -9
  9. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/files.py +2 -1
  10. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/message_processor.py +2 -1
  11. cellcog-2.4.0/cellcog/state_paths.py +83 -0
  12. {cellcog-2.2.0 → cellcog-2.4.0}/pyproject.toml +1 -1
  13. cellcog-2.2.0/README.md +0 -203
  14. {cellcog-2.2.0 → cellcog-2.4.0}/.convex/.gitignore +0 -0
  15. {cellcog-2.2.0 → cellcog-2.4.0}/.convex/local/default/config.json +0 -0
  16. {cellcog-2.2.0 → cellcog-2.4.0}/.convex/local/default/convex_local_backend.sqlite3 +0 -0
  17. {cellcog-2.2.0 → cellcog-2.4.0}/.convex/local/default/convex_local_storage/modules/18330a2b-2cf5-4f51-89a5-8d97a422e7a2.blob +0 -0
  18. {cellcog-2.2.0 → cellcog-2.4.0}/.gitignore +0 -0
  19. {cellcog-2.2.0 → cellcog-2.4.0}/LICENSE +0 -0
  20. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/auth.py +0 -0
  21. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/config.py +0 -0
  22. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/daemon/__init__.py +0 -0
  23. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/daemon/delivery.py +0 -0
  24. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/docs/__init__.py +0 -0
  25. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/docs/support.md +0 -0
  26. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/exceptions.py +0 -0
  27. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/message_formatter.py +0 -0
  28. {cellcog-2.2.0 → cellcog-2.4.0}/cellcog/version_detection.py +0 -0
  29. {cellcog-2.2.0 → cellcog-2.4.0}/examples/basic_usage.py +0 -0
  30. {cellcog-2.2.0 → cellcog-2.4.0}/examples/file_handling.py +0 -0
  31. {cellcog-2.2.0 → cellcog-2.4.0}/examples/streaming_usage.py +0 -0
  32. {cellcog-2.2.0 → cellcog-2.4.0}/examples/sync_usage.py +0 -0
  33. {cellcog-2.2.0 → cellcog-2.4.0}/examples/workflow_usage.py +0 -0
  34. {cellcog-2.2.0 → cellcog-2.4.0}/tests/test_gs_url_handling.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: cellcog
3
- Version: 2.2.0
3
+ Version: 2.4.0
4
4
  Summary: Python SDK for CellCog - Any-to-Any AI for agents. Fire-and-forget pattern with WebSocket notifications.
5
5
  Project-URL: Homepage, https://cellcog.ai
6
6
  Project-URL: Documentation, https://cellcog.ai/developer/docs
@@ -78,11 +78,13 @@ result = client.create_chat(
78
78
 
79
79
  ## How It Works
80
80
 
81
- **Two delivery modes:**
81
+ **Three delivery modes:**
82
82
 
83
83
  - **Wait for Completion (default)** — Blocks until CellCog finishes and returns the full result. Works with any agent — OpenClaw, Claude Code, Cursor, or any Python environment.
84
84
 
85
- - **Fire-and-Forget (OpenClaw)** — Returns immediately. A background daemon monitors via WebSocket and delivers results to your OpenClaw session when done. Requires `sessions_send` on OpenClaw Gateway.
85
+ - **Send-only (`delivery="send_only"`)** — Fire-and-forget for ANY agent: returns the moment the chat/message is accepted (`status="accepted"`). Poll `get_status()` and fetch results with `wait_for_completion()`/`get_history()`. Use this when orchestrating several chats in parallel — the blocking default would hang on each chat's whole run. Works on `create_chat()` AND `send_message()`.
86
+
87
+ - **Notify on Completion (OpenClaw)** — Returns immediately. A background daemon monitors via WebSocket and delivers results to your OpenClaw session when done. Requires `sessions_send` on OpenClaw Gateway.
86
88
 
87
89
  All methods return the same unified shape:
88
90
 
@@ -90,15 +92,23 @@ All methods return the same unified shape:
90
92
  {
91
93
  "chat_id": str,
92
94
  "is_operating": bool,
93
- "status": str, # "completed" | "tracking" | "timeout" | "operating"
95
+ "status": str, # "completed" | "tracking" | "accepted" | "operating"
94
96
  "message": str, # Always print this in full
95
97
  }
96
98
  ```
97
99
 
100
+ A wait that gives up returns `status="operating"` with `timed_out=True` — the chat is still
101
+ running server-side; resume with `wait_for_completion()`.
102
+
98
103
  ## Configuration
99
104
 
100
105
  ```bash
101
106
  export CELLCOG_API_KEY="sk_..."
107
+
108
+ # Optional: where SDK state lives (tracked chats, downloads, daemon files).
109
+ # Default ~/.cellcog; in headless/container environments where HOME isn't
110
+ # writable, the SDK falls back to a temp directory automatically.
111
+ export CELLCOG_STATE_DIR="/path/to/state"
102
112
  ```
103
113
 
104
114
  **Get your API key:**
@@ -115,7 +125,8 @@ export CELLCOG_API_KEY="sk_..."
115
125
  result = client.create_chat(
116
126
  prompt="Your task...",
117
127
  task_label="my-task",
118
- chat_mode="agent", # "agent" | "agent core" | "agent team" | "agent team max"
128
+ chat_mode="agent", # "agent" | "creative" | "team" (legacy names still work)
129
+ chat_tier="core", # "flash" | "core" | "max" (omit for the mode's default)
119
130
  timeout=1800, # 30 min default; use 3600 for complex jobs
120
131
  )
121
132
 
@@ -147,13 +158,48 @@ result = client.create_chat(
147
158
  prompt="...",
148
159
  task_label="...",
149
160
  chat_mode="agent",
161
+ chat_tier="max", # "flash" | "core" | "max" — omit for the SDK default
162
+ delivery="send_only", # fire-and-forget; default blocks until done
150
163
  project_id="...", # CellCog project for document context
151
164
  agent_role_id="...", # Specialized agent role
152
165
  enable_cowork=True, # Direct machine access via CellCog Desktop
153
166
  cowork_working_directory="/Users/...", # Working directory for co-work
167
+ enable_browse=True, # Drive the user's REAL Chrome (needs Desktop + extension)
168
+ browser_profile_id="Default", # from client.get_browser_status()
169
+ enable_tools=True, # the user's connected SaaS tools
170
+ tools_selection=["gmail", "notion"], # toolkit slugs (omit for ALL); from client.list_toolkits()
154
171
  )
155
172
  ```
156
173
 
174
+ ## Browse & Tools
175
+
176
+ CellCog chats can drive the user's **real Chrome** (Browse) and call their **connected
177
+ SaaS tools** (Gmail, Notion, Slack, ... — Tools). Discover what's available, then enable
178
+ at chat creation:
179
+
180
+ ```python
181
+ # Browse: discover Chrome profiles, then enable with one
182
+ status = client.get_browser_status()
183
+ profile = status["active_profile"] # or let the user pick from available_profiles
184
+ result = client.create_chat(
185
+ prompt="Log into the dashboard and screenshot the weekly report",
186
+ enable_browse=True,
187
+ browser_profile_id=profile["profileDir"],
188
+ )
189
+
190
+ # Tools: discover connected toolkits, then enable a selection (omit for ALL)
191
+ toolkits = client.list_toolkits(connected_only=True)
192
+ result = client.create_chat(
193
+ prompt="Summarize this week's unread emails",
194
+ enable_tools=True,
195
+ tools_selection=["gmail"], # toolkit slugs
196
+ )
197
+ ```
198
+
199
+ Notes: Browse requires CellCog Desktop + the Chrome extension on the user's machine and
200
+ auto-enables co-work server-side. `tools_selection` takes TOOLKIT slugs (the granularity
201
+ users pick in the product UI); `list_toolkit_tools(slug)` shows what a toolkit unlocks.
202
+
157
203
  ## File Handling
158
204
 
159
205
  ```python
@@ -172,27 +218,38 @@ result = client.create_chat(
172
218
 
173
219
  Generated files auto-download to `~/.cellcog/chats/{chat_id}/` or to `GENERATE_FILE` paths if specified.
174
220
 
175
- ## Chat Modes
221
+ ## Chat Modes & Tiers
222
+
223
+ Every chat runs at a (mode, tier) operating point. Pick a mode for the KIND of work,
224
+ a tier for the DEPTH (omit `chat_tier` for the mode's default).
225
+
226
+ | Mode | Best For | Tiers |
227
+ |------|----------|-------|
228
+ | `"agent"` | Most tasks — assets, documents, production pipelines, coding/co-work | `flash` (SDK default) · `core` · `max` |
229
+ | `"creative"` | Design, brand, frontend craft — taste-first work | `core` (default) · `max` |
230
+ | `"team"` | Deep research ONLY — multi-source synthesis, citations (multi-agent) | `flash` · `core` (default) · `max` |
231
+
232
+ **Tier guidance for agent mode:** omit `chat_tier` and the SDK sends `"flash"` — right for
233
+ simple asset generation and light tasks. **Coding / co-work needs `"max"`** (applied
234
+ automatically when `enable_cowork=True`). Heavy multi-step production (video, data
235
+ analysis, financial models, legal drafting) → pass `chat_tier="max"` explicitly. Quality
236
+ disappointing on flash? Re-run with `chat_tier="max"`. Use `"team"` only for deep research.
176
237
 
177
- | Mode | Speed | Min Credits | Best For |
178
- |------|-------|-------------|----------|
179
- | `"agent"` | Fast | 100 | Most tasks — research, images, audio, documents |
180
- | `"agent core"` | Fast | 50 | Coding, co-work, terminal operations |
181
- | `"agent team"` | 5–60 min | 500 | Deep research & multi-angled reasoning |
182
- | `"agent team max"` | Slowest | 2,000 | High-stakes — legal, financial, academic |
238
+ Legacy mode names (`"agent core"`, `"agent team"`, `"agent team max"`) keep working
239
+ forever — the server normalizes them to their historical operating points.
183
240
 
184
241
  ## 35 Skills — The Cog Family
185
242
 
186
243
  | Category | Skills |
187
244
  |----------|--------|
188
- | **Research & Analysis** | `research-cog` `fin-cog` `crypto-cog` `data-cog` `news-cog` |
189
- | **Video & Cinema** | `video-cog` `cine-cog` `insta-cog` `tube-cog` `seedance-cog` |
190
- | **Images & Design** | `image-cog` `brand-cog` `meme-cog` `banana-cog` `3d-cog` |
191
- | **Audio & Music** | `audio-cog` `music-cog` `pod-cog` |
192
- | **Documents & Slides** | `docs-cog` `slides-cog` `spreadsheets-cog` `resume-cog` `legal-cog` |
193
- | **Apps & Prototypes** | `dash-cog` `game-cog` `proto-cog` |
194
- | **Creative** | `comi-cog` `story-cog` `learn-cog` `travel-cog` |
195
- | **Development** | `code-cog` `cowork-cog` `project-cog` `think-cog` |
245
+ | **Research & Analysis** | `deep-research-cellcog` `stock-analysis-cellcog` `crypto-research-cellcog` `data-analysis-cellcog` `news-briefing-cellcog` |
246
+ | **Video & Cinema** | `video-generation-cellcog` `cinematic-video-cellcog` `instagram-reels-tiktok-cellcog` `youtube-video-cellcog` `seedance-video-generation-cellcog` |
247
+ | **Images & Design** | `image-generation-cellcog` `logo-brand-identity-cellcog` `meme-generator-cellcog` `nano-banana-image-cellcog` `3d-model-generation-cellcog` |
248
+ | **Audio & Music** | `audio-generation-cellcog` `music-generation-cellcog` `podcast-generation-cellcog` |
249
+ | **Documents & Slides** | `pdf-document-generation-cellcog` `presentation-slides-cellcog` `excel-spreadsheet-cellcog` `resume-cover-letter-cellcog` `legal-documents-cellcog` |
250
+ | **Apps & Prototypes** | `dashboard-web-app-cellcog` `game-asset-generation-cellcog` `ui-prototype-wireframe-cellcog` |
251
+ | **Creative** | `comic-manga-generator-cellcog` `creative-writing-cellcog` `tutoring-education-cellcog` `travel-planning-cellcog` |
252
+ | **Development** | `coding-agent-cellcog` `pair-programming-cellcog` `project-management-cellcog` `brainstorming-strategy-cellcog` |
196
253
 
197
254
  Browse all skills: https://cellcog.ai/skills
198
255
 
@@ -0,0 +1,260 @@
1
+ # CellCog Python SDK
2
+
3
+ **CellCog: Any-to-Any AI for Agents** — Your sub-agent for quality work.
4
+
5
+ When you need depth, accuracy, or complex deliverables — research reports, interactive apps, videos, images, podcasts, documents, spreadsheets, and more — use CellCog.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install cellcog
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ export CELLCOG_API_KEY="sk_..." # Get from https://cellcog.ai/profile?tab=api-keys
17
+ ```
18
+
19
+ **Any agent (blocks until done):**
20
+
21
+ ```python
22
+ from cellcog import CellCogClient
23
+
24
+ client = CellCogClient(agent_provider="openclaw")
25
+
26
+ result = client.create_chat(
27
+ prompt="Research quantum computing advances in 2026",
28
+ task_label="quantum-research",
29
+ chat_mode="agent",
30
+ )
31
+ # Blocks until done — result contains everything
32
+ print(result["message"])
33
+ ```
34
+
35
+ **OpenClaw agents (fire-and-forget):**
36
+
37
+ ```python
38
+ result = client.create_chat(
39
+ prompt="Research quantum computing advances in 2026",
40
+ notify_session_key="agent:main:main", # OpenClaw session key
41
+ task_label="quantum-research",
42
+ chat_mode="agent",
43
+ )
44
+ # Returns immediately — daemon delivers results to your session
45
+ ```
46
+
47
+ ## How It Works
48
+
49
+ **Three delivery modes:**
50
+
51
+ - **Wait for Completion (default)** — Blocks until CellCog finishes and returns the full result. Works with any agent — OpenClaw, Claude Code, Cursor, or any Python environment.
52
+
53
+ - **Send-only (`delivery="send_only"`)** — Fire-and-forget for ANY agent: returns the moment the chat/message is accepted (`status="accepted"`). Poll `get_status()` and fetch results with `wait_for_completion()`/`get_history()`. Use this when orchestrating several chats in parallel — the blocking default would hang on each chat's whole run. Works on `create_chat()` AND `send_message()`.
54
+
55
+ - **Notify on Completion (OpenClaw)** — Returns immediately. A background daemon monitors via WebSocket and delivers results to your OpenClaw session when done. Requires `sessions_send` on OpenClaw Gateway.
56
+
57
+ All methods return the same unified shape:
58
+
59
+ ```python
60
+ {
61
+ "chat_id": str,
62
+ "is_operating": bool,
63
+ "status": str, # "completed" | "tracking" | "accepted" | "operating"
64
+ "message": str, # Always print this in full
65
+ }
66
+ ```
67
+
68
+ A wait that gives up returns `status="operating"` with `timed_out=True` — the chat is still
69
+ running server-side; resume with `wait_for_completion()`.
70
+
71
+ ## Configuration
72
+
73
+ ```bash
74
+ export CELLCOG_API_KEY="sk_..."
75
+
76
+ # Optional: where SDK state lives (tracked chats, downloads, daemon files).
77
+ # Default ~/.cellcog; in headless/container environments where HOME isn't
78
+ # writable, the SDK falls back to a temp directory automatically.
79
+ export CELLCOG_STATE_DIR="/path/to/state"
80
+ ```
81
+
82
+ **Get your API key:**
83
+ 1. Create account: https://cellcog.ai/signup
84
+ 2. Add payment: https://cellcog.ai/profile?tab=billing
85
+ 3. Get API key: https://cellcog.ai/profile?tab=api-keys
86
+
87
+ ## API Reference
88
+
89
+ ### Core Methods
90
+
91
+ ```python
92
+ # Create chat — wait mode (default, universal)
93
+ result = client.create_chat(
94
+ prompt="Your task...",
95
+ task_label="my-task",
96
+ chat_mode="agent", # "agent" | "creative" | "team" (legacy names still work)
97
+ chat_tier="core", # "flash" | "core" | "max" (omit for the mode's default)
98
+ timeout=1800, # 30 min default; use 3600 for complex jobs
99
+ )
100
+
101
+ # Create chat — notify mode (OpenClaw only)
102
+ result = client.create_chat(
103
+ prompt="Your task...",
104
+ notify_session_key="agent:main:main",
105
+ task_label="my-task",
106
+ chat_mode="agent",
107
+ )
108
+
109
+ # Send follow-up message
110
+ result = client.send_message(chat_id="abc123", message="Now create a PDF summary")
111
+
112
+ # Get full history
113
+ result = client.get_history(chat_id="abc123")
114
+
115
+ # Quick status check
116
+ status = client.get_status(chat_id="abc123")
117
+
118
+ # Resume waiting after timeout
119
+ result = client.wait_for_completion(chat_id="abc123", timeout=1800)
120
+ ```
121
+
122
+ ### Optional Parameters
123
+
124
+ ```python
125
+ result = client.create_chat(
126
+ prompt="...",
127
+ task_label="...",
128
+ chat_mode="agent",
129
+ chat_tier="max", # "flash" | "core" | "max" — omit for the SDK default
130
+ delivery="send_only", # fire-and-forget; default blocks until done
131
+ project_id="...", # CellCog project for document context
132
+ agent_role_id="...", # Specialized agent role
133
+ enable_cowork=True, # Direct machine access via CellCog Desktop
134
+ cowork_working_directory="/Users/...", # Working directory for co-work
135
+ enable_browse=True, # Drive the user's REAL Chrome (needs Desktop + extension)
136
+ browser_profile_id="Default", # from client.get_browser_status()
137
+ enable_tools=True, # the user's connected SaaS tools
138
+ tools_selection=["gmail", "notion"], # toolkit slugs (omit for ALL); from client.list_toolkits()
139
+ )
140
+ ```
141
+
142
+ ## Browse & Tools
143
+
144
+ CellCog chats can drive the user's **real Chrome** (Browse) and call their **connected
145
+ SaaS tools** (Gmail, Notion, Slack, ... — Tools). Discover what's available, then enable
146
+ at chat creation:
147
+
148
+ ```python
149
+ # Browse: discover Chrome profiles, then enable with one
150
+ status = client.get_browser_status()
151
+ profile = status["active_profile"] # or let the user pick from available_profiles
152
+ result = client.create_chat(
153
+ prompt="Log into the dashboard and screenshot the weekly report",
154
+ enable_browse=True,
155
+ browser_profile_id=profile["profileDir"],
156
+ )
157
+
158
+ # Tools: discover connected toolkits, then enable a selection (omit for ALL)
159
+ toolkits = client.list_toolkits(connected_only=True)
160
+ result = client.create_chat(
161
+ prompt="Summarize this week's unread emails",
162
+ enable_tools=True,
163
+ tools_selection=["gmail"], # toolkit slugs
164
+ )
165
+ ```
166
+
167
+ Notes: Browse requires CellCog Desktop + the Chrome extension on the user's machine and
168
+ auto-enables co-work server-side. `tools_selection` takes TOOLKIT slugs (the granularity
169
+ users pick in the product UI); `list_toolkit_tools(slug)` shows what a toolkit unlocks.
170
+
171
+ ## File Handling
172
+
173
+ ```python
174
+ # Send files to CellCog
175
+ result = client.create_chat(
176
+ prompt='Analyze this data: <SHOW_FILE>/path/to/sales.csv</SHOW_FILE>',
177
+ task_label="data-analysis",
178
+ )
179
+
180
+ # Request output at specific path
181
+ result = client.create_chat(
182
+ prompt='Create a report: <GENERATE_FILE>/output/report.pdf</GENERATE_FILE>',
183
+ task_label="report",
184
+ )
185
+ ```
186
+
187
+ Generated files auto-download to `~/.cellcog/chats/{chat_id}/` or to `GENERATE_FILE` paths if specified.
188
+
189
+ ## Chat Modes & Tiers
190
+
191
+ Every chat runs at a (mode, tier) operating point. Pick a mode for the KIND of work,
192
+ a tier for the DEPTH (omit `chat_tier` for the mode's default).
193
+
194
+ | Mode | Best For | Tiers |
195
+ |------|----------|-------|
196
+ | `"agent"` | Most tasks — assets, documents, production pipelines, coding/co-work | `flash` (SDK default) · `core` · `max` |
197
+ | `"creative"` | Design, brand, frontend craft — taste-first work | `core` (default) · `max` |
198
+ | `"team"` | Deep research ONLY — multi-source synthesis, citations (multi-agent) | `flash` · `core` (default) · `max` |
199
+
200
+ **Tier guidance for agent mode:** omit `chat_tier` and the SDK sends `"flash"` — right for
201
+ simple asset generation and light tasks. **Coding / co-work needs `"max"`** (applied
202
+ automatically when `enable_cowork=True`). Heavy multi-step production (video, data
203
+ analysis, financial models, legal drafting) → pass `chat_tier="max"` explicitly. Quality
204
+ disappointing on flash? Re-run with `chat_tier="max"`. Use `"team"` only for deep research.
205
+
206
+ Legacy mode names (`"agent core"`, `"agent team"`, `"agent team max"`) keep working
207
+ forever — the server normalizes them to their historical operating points.
208
+
209
+ ## 35 Skills — The Cog Family
210
+
211
+ | Category | Skills |
212
+ |----------|--------|
213
+ | **Research & Analysis** | `deep-research-cellcog` `stock-analysis-cellcog` `crypto-research-cellcog` `data-analysis-cellcog` `news-briefing-cellcog` |
214
+ | **Video & Cinema** | `video-generation-cellcog` `cinematic-video-cellcog` `instagram-reels-tiktok-cellcog` `youtube-video-cellcog` `seedance-video-generation-cellcog` |
215
+ | **Images & Design** | `image-generation-cellcog` `logo-brand-identity-cellcog` `meme-generator-cellcog` `nano-banana-image-cellcog` `3d-model-generation-cellcog` |
216
+ | **Audio & Music** | `audio-generation-cellcog` `music-generation-cellcog` `podcast-generation-cellcog` |
217
+ | **Documents & Slides** | `pdf-document-generation-cellcog` `presentation-slides-cellcog` `excel-spreadsheet-cellcog` `resume-cover-letter-cellcog` `legal-documents-cellcog` |
218
+ | **Apps & Prototypes** | `dashboard-web-app-cellcog` `game-asset-generation-cellcog` `ui-prototype-wireframe-cellcog` |
219
+ | **Creative** | `comic-manga-generator-cellcog` `creative-writing-cellcog` `tutoring-education-cellcog` `travel-planning-cellcog` |
220
+ | **Development** | `coding-agent-cellcog` `pair-programming-cellcog` `project-management-cellcog` `brainstorming-strategy-cellcog` |
221
+
222
+ Browse all skills: https://cellcog.ai/skills
223
+
224
+ ## Error Handling
225
+
226
+ ```python
227
+ from cellcog import (
228
+ CellCogClient,
229
+ PaymentRequiredError,
230
+ MaxConcurrencyError,
231
+ GatewayConfigError,
232
+ SDKUpgradeRequiredError,
233
+ )
234
+
235
+ client = CellCogClient(agent_provider="openclaw")
236
+
237
+ try:
238
+ result = client.create_chat(...)
239
+ except PaymentRequiredError as e:
240
+ print(f"Add credits: {e.billing_url}")
241
+ except MaxConcurrencyError as e:
242
+ print(f"Too many parallel chats: {e.operating_count}/{e.max_parallel}")
243
+ except GatewayConfigError as e:
244
+ print(f"Fix: {e.fix_command}") # OpenClaw notify mode only
245
+ except SDKUpgradeRequiredError as e:
246
+ print(f"Upgrade: pip install cellcog>={e.minimum_version}")
247
+ ```
248
+
249
+ ## Links
250
+
251
+ - **CellCog Platform:** https://cellcog.ai
252
+ - **Skills Catalog:** https://cellcog.ai/skills
253
+ - **GitHub:** https://github.com/CellCog/cellcog_python
254
+ - **ClawHub Skills:** https://clawhub.ai
255
+ - **API Docs:** https://cellcog.ai/developer/docs
256
+ - **Get API Key:** https://cellcog.ai/profile?tab=api-keys
257
+
258
+ ## License
259
+
260
+ MIT License — see [LICENSE](LICENSE) for details.
@@ -48,7 +48,7 @@ from .exceptions import (
48
48
  SDKUpgradeRequiredError,
49
49
  )
50
50
 
51
- __version__ = "2.2.0"
51
+ __version__ = "2.4.0"
52
52
  __all__ = [
53
53
  "CellCogClient",
54
54
  "CellCogError",
@@ -19,6 +19,49 @@ from .exceptions import (
19
19
  PaymentRequiredError,
20
20
  )
21
21
  from .files import FileProcessor
22
+ from .state_paths import state_path
23
+
24
+ # ── Mode × Tier resolution (Mode × Tier redesign, 2026-08) ──────────────────
25
+ # Friendly SDK names -> API chat_mode values. The server accepts BOTH current
26
+ # API values and legacy ones forever (they normalize server-side to their
27
+ # historical operating points), so unknown strings pass through untouched and
28
+ # the server returns a clear 400 for genuinely invalid values.
29
+ _MODE_ALIASES = {
30
+ # Current modes
31
+ "agent": "human_in_the_loop",
32
+ "creative": "agent_creative",
33
+ "agent creative": "agent_creative",
34
+ "team": "agent_in_the_loop",
35
+ "agent team": "agent_in_the_loop",
36
+ # Legacy names (kept working forever; server normalizes)
37
+ "agent core": "agent_core",
38
+ "agent team max": "agent_team_max",
39
+ }
40
+
41
+ _VALID_TIERS = ("flash", "core", "max")
42
+
43
+
44
+ def resolve_chat_mode(chat_mode: Optional[str]) -> str:
45
+ """Map a friendly mode name to its API value; pass raw API/unknown values through."""
46
+ if not chat_mode:
47
+ return "human_in_the_loop"
48
+ key = str(chat_mode).strip().lower()
49
+ return _MODE_ALIASES.get(key, chat_mode)
50
+
51
+
52
+ def resolve_chat_tier(chat_tier: Optional[str]) -> Optional[str]:
53
+ """Normalize a tier string ('flash' | 'core' | 'max'); None passes through (server
54
+ applies the mode's default tier). Unknown values raise immediately — a typo'd tier
55
+ silently falling back to a default would misroute spend."""
56
+ if chat_tier is None or str(chat_tier).strip() == "":
57
+ return None
58
+ tier = str(chat_tier).strip().lower()
59
+ if tier not in _VALID_TIERS:
60
+ raise ValueError(
61
+ f"Invalid chat_tier: {chat_tier!r}. Use 'flash', 'core', or 'max' "
62
+ "(or omit it for the mode's default). Note: 'creative' has no 'flash' tier."
63
+ )
64
+ return tier
22
65
 
23
66
 
24
67
  class ChatManager:
@@ -38,7 +81,7 @@ class ChatManager:
38
81
  def __init__(self, config: Config, file_processor: FileProcessor):
39
82
  self.config = config
40
83
  self.files = file_processor
41
- self._chats_dir = Path("~/.cellcog/chats").expanduser()
84
+ self._chats_dir = state_path("chats")
42
85
 
43
86
  def create(
44
87
  self,
@@ -48,6 +91,11 @@ class ChatManager:
48
91
  agent_role_id: Optional[str] = None,
49
92
  hc_enabled: bool = False,
50
93
  hc_working_directory: Optional[str] = None,
94
+ chat_tier: Optional[str] = None,
95
+ browser_enabled: bool = False,
96
+ browser_profile_id: Optional[str] = None,
97
+ personal_tools_enabled: bool = False,
98
+ personal_tools_selection: Optional[list] = None,
51
99
  ) -> dict:
52
100
  """
53
101
  Create a new CellCog chat (without streaming).
@@ -55,10 +103,22 @@ class ChatManager:
55
103
  Args:
56
104
  prompt: Initial prompt (can include SHOW_FILE tags for file uploads)
57
105
  project_id: Optional CellCog project ID for document context
58
- chat_mode: "agent" (fast, iterative), "agent core" (coding/co-work), "agent team" (deep reasoning), or "agent team max" (high-stakes)
106
+ chat_mode: "agent" (fast, iterative), "creative" (design/craft-first), or
107
+ "team" (deep multi-angled research). Legacy names — "agent core",
108
+ "agent team", "agent team max" — keep working forever (normalized
109
+ server-side to their historical operating points).
110
+ chat_tier: "flash" | "core" | "max" — depth/spend within the mode.
111
+ None -> the mode's default tier. "creative" has no "flash" tier.
59
112
  agent_role_id: Optional agent role ID within the project. Requires project_id.
60
113
  hc_enabled: Enable Human Computer (co-work) for this chat
61
114
  hc_working_directory: Working directory on user's machine for HC commands
115
+ browser_enabled: Enable Browse (the user's real Chrome). Server-side this
116
+ auto-enables co-work (Browse rides the Desktop connection).
117
+ browser_profile_id: Chrome profile dir (from the browser-status endpoint's
118
+ available_profiles[].profileDir). None -> "Default".
119
+ personal_tools_enabled: Enable the user's connected SaaS tools for this chat
120
+ personal_tools_selection: Toolkit slugs to restrict the chat to (e.g.
121
+ ["gmail", "notion"]). None -> ALL connected tools.
62
122
 
63
123
  Returns:
64
124
  {
@@ -69,17 +129,14 @@ class ChatManager:
69
129
  """
70
130
  self.config.require_configured()
71
131
 
72
- mode_mapping = {
73
- "agent team max": "agent_team_max",
74
- "agent team": "agent_in_the_loop",
75
- "agent core": "agent_core",
76
- "agent": "human_in_the_loop",
77
- }
78
- api_chat_mode = mode_mapping.get(chat_mode, chat_mode)
132
+ api_chat_mode = resolve_chat_mode(chat_mode)
133
+ api_chat_tier = resolve_chat_tier(chat_tier)
79
134
 
80
135
  transformed, uploaded = self.files.transform_outgoing(prompt)
81
136
 
82
137
  data = {"message": transformed, "chat_mode": api_chat_mode}
138
+ if api_chat_tier:
139
+ data["chat_tier"] = api_chat_tier
83
140
  if project_id:
84
141
  data["project_id"] = project_id
85
142
  if agent_role_id:
@@ -88,6 +145,13 @@ class ChatManager:
88
145
  data["hc_enabled"] = True
89
146
  if hc_working_directory:
90
147
  data["hc_working_directory"] = hc_working_directory
148
+ if browser_enabled:
149
+ data["browser_enabled"] = True
150
+ data["browser_profile_id"] = browser_profile_id or "Default"
151
+ if personal_tools_enabled:
152
+ data["personal_tools_enabled"] = True
153
+ if personal_tools_selection is not None:
154
+ data["personal_tools_selection"] = [str(s).strip().lower() for s in personal_tools_selection]
91
155
 
92
156
  resp = self._request("POST", "/cellcog/chat/new", data)
93
157
 
@@ -147,6 +211,9 @@ class ChatManager:
147
211
  "name": resp["name"],
148
212
  "is_operating": resp["operating"],
149
213
  "error_type": error_type,
214
+ # Most recent agent progress one-liner (server: ChatMeta.latest_status_update,
215
+ # CEL-1300 item 6). None until the agent posts its first update of a run.
216
+ "latest_update": resp.get("latest_status_update"),
150
217
  }
151
218
 
152
219
  def get_history(self, chat_id: str, session_id: str) -> dict: