caudate-cli 0.1.0__py3-none-any.whl
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.
- api/__init__.py +5 -0
- api/anthropic_compat.py +1518 -0
- api/artifact_viewer.py +366 -0
- api/caudate_middleware.py +618 -0
- api/forge_bootstrapper_routes.py +377 -0
- api/forge_routes.py +630 -0
- api/forge_system_routes.py +294 -0
- api/openai_compat.py +1993 -0
- api/server.py +667 -0
- api/storyboard_page.py +677 -0
- caudate_cli-0.1.0.dist-info/METADATA +354 -0
- caudate_cli-0.1.0.dist-info/RECORD +153 -0
- caudate_cli-0.1.0.dist-info/WHEEL +5 -0
- caudate_cli-0.1.0.dist-info/entry_points.txt +2 -0
- caudate_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- caudate_cli-0.1.0.dist-info/top_level.txt +14 -0
- cognos_mcp/__init__.py +4 -0
- cognos_mcp/bridge.py +41 -0
- cognos_mcp/client.py +70 -0
- cognos_mcp/config.py +49 -0
- cognos_mcp/server.py +66 -0
- config.py +82 -0
- core/__init__.py +0 -0
- core/agent.py +468 -0
- core/agentic_loop.py +731 -0
- core/anthropic_auth.py +91 -0
- core/background.py +113 -0
- core/banner.py +134 -0
- core/bootstrap.py +292 -0
- core/citations.py +131 -0
- core/compaction.py +109 -0
- core/constitution.py +198 -0
- core/diff_viewer.py +87 -0
- core/export.py +85 -0
- core/file_refs.py +119 -0
- core/files.py +199 -0
- core/hooks.py +209 -0
- core/image.py +599 -0
- core/input.py +91 -0
- core/loop.py +238 -0
- core/memory_md.py +147 -0
- core/notifications.py +99 -0
- core/ownership.py +181 -0
- core/paste.py +81 -0
- core/permissions.py +210 -0
- core/plan_mode.py +215 -0
- core/sandbox_prompt.py +185 -0
- core/scheduler.py +195 -0
- core/schemas.py +202 -0
- core/session.py +90 -0
- core/settings.py +132 -0
- core/skills.py +398 -0
- core/slash_commands.py +977 -0
- core/statusline.py +61 -0
- core/subagent.py +300 -0
- core/thinking.py +50 -0
- core/updater.py +122 -0
- core/usage.py +109 -0
- core/worktree.py +93 -0
- execution/__init__.py +0 -0
- execution/executor.py +329 -0
- execution/plugins.py +108 -0
- execution/tools/__init__.py +0 -0
- execution/tools/agent_tool.py +107 -0
- execution/tools/agentic_tool.py +297 -0
- execution/tools/artifact_tool.py +191 -0
- execution/tools/ask_user_question_tool.py +137 -0
- execution/tools/base.py +81 -0
- execution/tools/calculator_tool.py +137 -0
- execution/tools/cognos_card_tool.py +124 -0
- execution/tools/cron_tool.py +215 -0
- execution/tools/datetime_tool.py +215 -0
- execution/tools/describe_image_tool.py +161 -0
- execution/tools/draw_tool.py +164 -0
- execution/tools/edit_image_tool.py +262 -0
- execution/tools/edit_tool.py +245 -0
- execution/tools/file_tool.py +90 -0
- execution/tools/find_anywhere_tool.py +255 -0
- execution/tools/forge_feature_tools.py +377 -0
- execution/tools/glob_tool.py +59 -0
- execution/tools/grep_tool.py +89 -0
- execution/tools/http_request_tool.py +224 -0
- execution/tools/load_skill_tool.py +104 -0
- execution/tools/longcat_avatar_tool.py +384 -0
- execution/tools/mcp_tool.py +100 -0
- execution/tools/notebook_tool.py +279 -0
- execution/tools/openapi_tool.py +440 -0
- execution/tools/plan_mode_tool.py +95 -0
- execution/tools/push_notification_tool.py +157 -0
- execution/tools/python_tool.py +61 -0
- execution/tools/respond_tool.py +40 -0
- execution/tools/sandbox_tool.py +378 -0
- execution/tools/search_tool.py +153 -0
- execution/tools/semantic_search_tool.py +106 -0
- execution/tools/shell_tool.py +283 -0
- execution/tools/speak_tool.py +134 -0
- execution/tools/storyboard_tool.py +727 -0
- execution/tools/system_info_tool.py +212 -0
- execution/tools/task_tool.py +323 -0
- execution/tools/think_tool.py +49 -0
- execution/tools/transcribe_audio_tool.py +86 -0
- execution/tools/update_memory_tool.py +92 -0
- execution/tools/web_fetch_tool.py +82 -0
- execution/tools/worktree_tool.py +174 -0
- llm/__init__.py +0 -0
- llm/fallback.py +116 -0
- llm/models.py +320 -0
- llm/provider.py +1356 -0
- llm/router.py +373 -0
- main.py +1889 -0
- memory/__init__.py +0 -0
- memory/episodic.py +99 -0
- memory/procedural.py +145 -0
- memory/semantic.py +71 -0
- memory/working.py +64 -0
- nn/__init__.py +43 -0
- nn/auto_evolve.py +245 -0
- nn/caudate.py +136 -0
- nn/config.py +141 -0
- nn/consolidator.py +81 -0
- nn/data.py +1635 -0
- nn/encoder.py +258 -0
- nn/forge_advisor.py +303 -0
- nn/format.py +235 -0
- nn/heads.py +432 -0
- nn/observer.py +994 -0
- nn/policy.py +214 -0
- nn/runtime.py +343 -0
- nn/scorer.py +175 -0
- nn/trainer.py +515 -0
- nn/vision.py +352 -0
- personality/__init__.py +23 -0
- personality/engine.py +129 -0
- personality/identity.py +144 -0
- personality/inner_voice.py +100 -0
- personality/mood.py +205 -0
- planning/__init__.py +0 -0
- planning/dev_server.py +221 -0
- planning/forge_models.py +718 -0
- planning/orchestrator.py +1363 -0
- planning/planner.py +451 -0
- planning/task_graph.py +61 -0
- reflection/__init__.py +0 -0
- reflection/meta_learner.py +156 -0
- reflection/reflector.py +127 -0
- ui/__init__.py +5 -0
- ui/display.py +88 -0
- voice/__init__.py +0 -0
- voice/conversation.py +125 -0
- voice/listener.py +111 -0
- voice/speaker.py +59 -0
- voice/stt.py +126 -0
- voice/tts.py +214 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: caudate-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local-first cognitive agent with a learned router (Caudate) and Claude-SDK-shaped tool palette.
|
|
5
|
+
Author-email: Rave Manji <rahimtz93@googlemail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/raveuk/cognos
|
|
8
|
+
Project-URL: Repository, https://github.com/raveuk/cognos
|
|
9
|
+
Keywords: llm,agent,agentic,cognitive,local-first,tool-use
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: litellm>=1.40.0
|
|
21
|
+
Requires-Dist: chromadb>=0.5.0
|
|
22
|
+
Requires-Dist: pydantic>=2.0.0
|
|
23
|
+
Requires-Dist: SQLAlchemy>=2.0.0
|
|
24
|
+
Requires-Dist: rich>=13.0.0
|
|
25
|
+
Requires-Dist: click>=8.0.0
|
|
26
|
+
Requires-Dist: prompt_toolkit>=3.0.0
|
|
27
|
+
Requires-Dist: fastapi>=0.110.0
|
|
28
|
+
Requires-Dist: uvicorn>=0.29.0
|
|
29
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
30
|
+
Requires-Dist: mcp>=1.0.0
|
|
31
|
+
Requires-Dist: numpy>=1.24.0
|
|
32
|
+
Requires-Dist: httpx>=0.27.0
|
|
33
|
+
Requires-Dist: huggingface_hub>=0.20.0
|
|
34
|
+
Provides-Extra: anthropic
|
|
35
|
+
Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
|
|
36
|
+
Provides-Extra: pdf
|
|
37
|
+
Requires-Dist: pypdf>=4.0.0; extra == "pdf"
|
|
38
|
+
Provides-Extra: voice
|
|
39
|
+
Requires-Dist: useful-moonshine-onnx>=0.2.0; extra == "voice"
|
|
40
|
+
Requires-Dist: kokoro>=0.3.0; extra == "voice"
|
|
41
|
+
Requires-Dist: soundfile>=0.12.0; extra == "voice"
|
|
42
|
+
Requires-Dist: piper-tts>=1.4.0; extra == "voice"
|
|
43
|
+
Requires-Dist: sounddevice>=0.5.0; extra == "voice"
|
|
44
|
+
Requires-Dist: webrtcvad-wheels>=2.0.10; extra == "voice"
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
47
|
+
Provides-Extra: all
|
|
48
|
+
Requires-Dist: anthropic>=0.40.0; extra == "all"
|
|
49
|
+
Requires-Dist: pypdf>=4.0.0; extra == "all"
|
|
50
|
+
Requires-Dist: useful-moonshine-onnx>=0.2.0; extra == "all"
|
|
51
|
+
Requires-Dist: kokoro>=0.3.0; extra == "all"
|
|
52
|
+
Requires-Dist: soundfile>=0.12.0; extra == "all"
|
|
53
|
+
Requires-Dist: piper-tts>=1.4.0; extra == "all"
|
|
54
|
+
Requires-Dist: sounddevice>=0.5.0; extra == "all"
|
|
55
|
+
Requires-Dist: webrtcvad-wheels>=2.0.10; extra == "all"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
# Cognos
|
|
59
|
+
|
|
60
|
+
A local-first cognitive agent with Claude-SDK feature parity, built on
|
|
61
|
+
Ollama via LiteLLM. Cognos runs entirely on your hardware by default — no
|
|
62
|
+
API keys, no network calls — but switches to Anthropic, OpenAI, or any
|
|
63
|
+
LiteLLM-supported provider with a one-line config change.
|
|
64
|
+
|
|
65
|
+
It's not a thin chat wrapper. The architecture explicitly separates:
|
|
66
|
+
|
|
67
|
+
- **Memory** — episodic, semantic, procedural, working
|
|
68
|
+
- **Planning** — DAG-based goal decomposition with replanning
|
|
69
|
+
- **Reflection** — meta-learning from past goal outcomes
|
|
70
|
+
- **Personality** — identity, mood, inner voice
|
|
71
|
+
- **Dual-process routing** — fast/slow models picked per call (System 1 / System 2)
|
|
72
|
+
|
|
73
|
+
…with a Claude-Code-style agentic loop on top: real-time tool calls,
|
|
74
|
+
streaming, sessions, hooks, MCP, subagents, permissions, and a
|
|
75
|
+
fully-featured CLI + HTTP API.
|
|
76
|
+
|
|
77
|
+
> Status: feature-complete against its original five-phase roadmap plus
|
|
78
|
+
> Claude SDK extras and Claude Code UX parity. See
|
|
79
|
+
> [`NEXT_ACTIONS.md`](NEXT_ACTIONS.md) for what's done and what's deferred.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Quickstart
|
|
84
|
+
|
|
85
|
+
### Install from PyPI (recommended)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pipx install caudate-cli
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
On first launch, `cognos` runs a one-time setup wizard that picks your
|
|
92
|
+
fast/slow models, downloads Caudate's weights from HuggingFace, and writes
|
|
93
|
+
`~/.cognos/settings.json`. After that:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cognos # banner + REPL
|
|
97
|
+
cognos doctor # diagnose what's wired (Ollama, Caudate, API keys)
|
|
98
|
+
cognos init --force # re-run the wizard if you change your mind
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Requirements:
|
|
102
|
+
|
|
103
|
+
- Python ≥ 3.10
|
|
104
|
+
- [Ollama](https://ollama.com) running locally if you want the local-only or
|
|
105
|
+
hybrid preset (skip if you go hosted-only)
|
|
106
|
+
- An `ANTHROPIC_API_KEY` in your shell *only* if you pick a preset that uses an
|
|
107
|
+
`anthropic/...` model
|
|
108
|
+
|
|
109
|
+
### Install from source (for development)
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
git clone https://github.com/raveuk/cognos.git
|
|
113
|
+
cd cognos
|
|
114
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
115
|
+
pip install -e .
|
|
116
|
+
cognos init
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Talk to it
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cognos # default — drops into REPL
|
|
123
|
+
cognos interactive --model fast # preset model
|
|
124
|
+
cognos interactive \
|
|
125
|
+
--system1 ollama/qwen2.5-coder:1.5b \
|
|
126
|
+
--system2 ollama/gemma3:27b # explicit dual-brain
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
A REPL opens. Type to chat. Type `/help` for slash commands.
|
|
130
|
+
|
|
131
|
+
### 4. Or hit it over HTTP
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cognos serve --port 8000
|
|
135
|
+
# in another terminal:
|
|
136
|
+
curl -X POST http://127.0.0.1:8000/chat \
|
|
137
|
+
-H 'content-type: application/json' \
|
|
138
|
+
-d '{"message":"what is in this directory?"}'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The HTTP server also hosts a [Web UI](#web-ui) at `http://127.0.0.1:8000/ui`.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## What you get out of the box
|
|
146
|
+
|
|
147
|
+
### CLI
|
|
148
|
+
|
|
149
|
+
| Command | What it does |
|
|
150
|
+
| --------------------------------- | ------------ |
|
|
151
|
+
| `cognos interactive` | REPL with streaming, slash commands, history, multi-line input |
|
|
152
|
+
| `cognos run <goal>` | Single-shot DAG planner — decomposes a goal, runs it, reflects |
|
|
153
|
+
| `cognos talk` | Voice mode (Moonshine STT + Kokoro TTS, Whisper/Piper fallback) |
|
|
154
|
+
| `cognos draw "<prompt>"` | Generate an image (diffusers / FLUX.1-schnell or SDXL-Turbo) |
|
|
155
|
+
| `cognos caudate {train,eval,status,export}` | Train/inspect Caudate, the learned router/advisor NN |
|
|
156
|
+
| `cognos serve [--port 8000]` | FastAPI HTTP server with SSE streaming |
|
|
157
|
+
| `cognos sessions {list,delete,rename,export}` | Manage saved conversations |
|
|
158
|
+
| `cognos personality {show,set,reset}` | Inspect or tune identity / mood |
|
|
159
|
+
| `cognos models` | List detected Ollama models with capability flags |
|
|
160
|
+
| `cognos router` | Preview routing decisions without calling the LLM |
|
|
161
|
+
| `cognos bench` | Run the benchmark suite |
|
|
162
|
+
| `cognos cron {add,list,remove,run}` | Schedule recurring prompts |
|
|
163
|
+
| `cognos mcp-serve` | Run Cognos as an MCP server |
|
|
164
|
+
| `cognos update` | Self-update (git pull or pip upgrade) |
|
|
165
|
+
| `cognos info` | List registered tools and learned strategies |
|
|
166
|
+
|
|
167
|
+
### Slash commands (inside the REPL)
|
|
168
|
+
|
|
169
|
+
`/help`, `/clear`, `/compact`, `/model <id|fast|balanced|powerful>`,
|
|
170
|
+
`/cost`, `/tools`, `/sessions`, `/export <md|json|html>`, `/files`,
|
|
171
|
+
`/permissions <mode>`, `/personality`, `/router`, `/diff <path>`,
|
|
172
|
+
`/status`, `/cron`, `/bg`, `/notify`, `/think on|off`, `/save`,
|
|
173
|
+
`/quit`. Type `/help` for the full list with descriptions.
|
|
174
|
+
|
|
175
|
+
### Tools the agent can call
|
|
176
|
+
|
|
177
|
+
~38 built-in tools, including: `Bash`, `Read`, `Write`, `Edit`, `Glob`,
|
|
178
|
+
`Grep`, `WebSearch`, `WebFetch`, `PythonExec`, `Think`, `Respond`,
|
|
179
|
+
`Agent` (subagents), `Draw`, `EditImage`, `DescribeImage`, `Speak`,
|
|
180
|
+
`TranscribeAudio`, `Storyboard`, `Sandbox`, `Calculator`, `DateTime`,
|
|
181
|
+
`HttpRequest`, `OpenAPI`, `Notebook`, `Cron`, `PushNotification`,
|
|
182
|
+
`AskUserQuestion`, `LoadSkill`, `UpdateMemory`, `MCP`, `Worktree`,
|
|
183
|
+
`PlanMode`, `FindAnywhere`, `SemanticSearch`, `SystemInfo`, `Task`,
|
|
184
|
+
`CognosCard`, `Artifact`, `Agentic`. Drop a `plugins/*.py` exposing
|
|
185
|
+
`PLUGIN = ToolInstance` to add your own.
|
|
186
|
+
|
|
187
|
+
### Caudate — the learned brain
|
|
188
|
+
|
|
189
|
+
Cognos ships with **Caudate**, a small PyTorch transformer that learns
|
|
190
|
+
your tool-use patterns turn-by-turn. It observes every conversation,
|
|
191
|
+
auto-trains in the background once it has enough samples, and graduates
|
|
192
|
+
through trust levels (SILENT → OBSERVER → WHISPER → ADVISOR → CONTROLLER)
|
|
193
|
+
based on rolling accuracy. At WHISPER it whispers a hint into the LLM
|
|
194
|
+
prompt; at ADVISOR it can override tier routing.
|
|
195
|
+
|
|
196
|
+
See `CAUDATE.md` for the full architecture, `nn/` for the code,
|
|
197
|
+
`data/nn/` for the live checkpoint and replay buffer.
|
|
198
|
+
|
|
199
|
+
### Multi-modal in / out
|
|
200
|
+
|
|
201
|
+
- **`@file` references** — `look at @config.py` inlines or attaches the file.
|
|
202
|
+
- **Drag-and-drop images / PDFs** — paths in the prompt are auto-uploaded via the Files API.
|
|
203
|
+
- **`POST /files`** — same Files API exposed over HTTP.
|
|
204
|
+
- **Citations** — pass `documents=[{id,title,text}]` and the model can emit `[[cite:doc:Lx]]` markers, post-processed into structured `CitationBlock` objects.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Architecture
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
┌──────────────────────────────────────────────────┐
|
|
212
|
+
│ CognosAgent │
|
|
213
|
+
│ │
|
|
214
|
+
user input ─┼─► AgenticLoop ◄──► Executor ──► tools/ │
|
|
215
|
+
│ │ ▲ │
|
|
216
|
+
│ │ │ │
|
|
217
|
+
│ ▼ │ │
|
|
218
|
+
│ Personality ─► hooks ──┘ │
|
|
219
|
+
│ │ │
|
|
220
|
+
│ ▼ │
|
|
221
|
+
│ LLM Router (DualLLMProvider) │
|
|
222
|
+
│ ├── System 1: fast model │
|
|
223
|
+
│ └── System 2: slow model │
|
|
224
|
+
│ │
|
|
225
|
+
│ Memory: episodic | semantic | procedural | working
|
|
226
|
+
│ Session persistence + context compaction │
|
|
227
|
+
│ Permissions (modes + allow/deny rules + audit) │
|
|
228
|
+
│ MCP clients (cognos_mcp/) │
|
|
229
|
+
│ Subagents (workspace-isolated via git worktrees)│
|
|
230
|
+
└──────────────────────────────────────────────────┘
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Each subsystem is documented in `BUILD_LOG.md`. The
|
|
234
|
+
[Claude SDK Extras](NEXT_ACTIONS.md#claude-sdk-extras-done) and
|
|
235
|
+
[Claude Code UX Parity](NEXT_ACTIONS.md#claude-code-ux-parity-done) sections
|
|
236
|
+
in `NEXT_ACTIONS.md` enumerate what's wired and where.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Configuration
|
|
241
|
+
|
|
242
|
+
Three layers, last wins:
|
|
243
|
+
|
|
244
|
+
1. Built-in defaults in `core/settings.py`
|
|
245
|
+
2. `~/.cognos/settings.json` — per-user
|
|
246
|
+
3. `./.cognos/settings.json` — per-project
|
|
247
|
+
|
|
248
|
+
Example:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"model": "ollama/gemma3:27b",
|
|
253
|
+
"permission_mode": "default",
|
|
254
|
+
"fallback_models": ["ollama/qwen2.5-coder:1.5b"],
|
|
255
|
+
"permissions": {
|
|
256
|
+
"allow": [{"tool": "Bash", "pattern": "^(ls|cat|grep)"}],
|
|
257
|
+
"deny": [{"tool": "Bash", "pattern": "rm -rf"}]
|
|
258
|
+
},
|
|
259
|
+
"statusline": "{model} | {mood} | tok={tokens} | ${cost:.4f}",
|
|
260
|
+
"notifications": {"enabled": true, "on_long_task_seconds": 30}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
CLI flags always override settings (`--model fast`, `--permissions plan`).
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Web UI
|
|
269
|
+
|
|
270
|
+
A zero-build single-page UI ships with the HTTP server:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
cognos serve --port 8000
|
|
274
|
+
# open http://127.0.0.1:8000/ui
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
It speaks to `POST /chat/stream` (SSE), supports session resume,
|
|
278
|
+
file attachments, and slash-style commands. Source: `ui/web/`.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## IDE plugins
|
|
283
|
+
|
|
284
|
+
- `ide/vscode/` — TypeScript extension. Sidebar webview, "Ask about
|
|
285
|
+
selection" right-click, configurable API URL / model / permission mode.
|
|
286
|
+
- `ide/jetbrains/` — Kotlin plugin for IntelliJ-platform IDEs (IDEA,
|
|
287
|
+
PyCharm, GoLand, WebStorm, RustRover, …). Tool window, editor action,
|
|
288
|
+
settings page.
|
|
289
|
+
|
|
290
|
+
Both are thin clients — they make HTTP calls to a running `cognos serve`
|
|
291
|
+
process, no LLM runs in the IDE.
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Optional extras
|
|
296
|
+
|
|
297
|
+
`pip install`-flagged features that are no-ops without their dep:
|
|
298
|
+
|
|
299
|
+
| Extra | Unlocks |
|
|
300
|
+
| ------------ | ------- |
|
|
301
|
+
| `anthropic` | Real prompt caching, native extended thinking, native `response_format` for `claude-*` model ids |
|
|
302
|
+
| `pypdf` | PDF text extraction in the Files API |
|
|
303
|
+
| `prompt_toolkit` | Multi-line input + persistent history + Ctrl+R + slash completion |
|
|
304
|
+
| `fastapi` + `uvicorn` | The HTTP server (`cognos serve`) |
|
|
305
|
+
| `mcp` | The MCP server / client (`cognos mcp-serve`) |
|
|
306
|
+
| `useful-moonshine-onnx` + `kokoro` + `piper-tts` + `sounddevice` | Voice mode (`cognos talk`) |
|
|
307
|
+
| `diffusers` + `transformers` + `torch` | Image generation (`cognos draw`) |
|
|
308
|
+
| `torch` + `sentence-transformers` | Caudate (the learned router NN) |
|
|
309
|
+
|
|
310
|
+
Cognos runs without any of them — they degrade gracefully.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Project layout
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
core/ agent, agentic loop, sessions, hooks, permissions, files,
|
|
318
|
+
citations, settings, slash commands, …
|
|
319
|
+
execution/ tool registry + 12 built-in tools + plugin loader
|
|
320
|
+
llm/ LiteLLM provider, model registry, dual-process router,
|
|
321
|
+
fallback chains
|
|
322
|
+
memory/ episodic / semantic / procedural / working
|
|
323
|
+
planning/ DAG planner, task graph
|
|
324
|
+
reflection/ reflector, meta-learner
|
|
325
|
+
personality/ identity, mood, inner voice
|
|
326
|
+
cognos_mcp/ MCP server, client, bridge
|
|
327
|
+
api/ FastAPI HTTP server
|
|
328
|
+
bench/ benchmark suite
|
|
329
|
+
plugins/ drop-in tools (`PLUGIN = ToolInstance`)
|
|
330
|
+
ide/vscode/ VS Code extension
|
|
331
|
+
ide/jetbrains/ JetBrains plugin
|
|
332
|
+
ui/ terminal display + web UI
|
|
333
|
+
data/ local state — sessions, files, manifests, audit log
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Why local-first?
|
|
339
|
+
|
|
340
|
+
Three reasons:
|
|
341
|
+
|
|
342
|
+
1. **Privacy.** Code, conversations, and learned strategies live on disk.
|
|
343
|
+
2. **Cost.** A small Ollama model runs at $0/turn and answers in milliseconds for routine work.
|
|
344
|
+
3. **Sovereignty.** No vendor outage takes you offline; no rate limit slows you down.
|
|
345
|
+
|
|
346
|
+
The dual-process router exists so you can keep most turns on a small
|
|
347
|
+
local model and only escalate hard turns to a heavy one (which can
|
|
348
|
+
itself be local — or Anthropic/OpenAI when you're online).
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## License
|
|
353
|
+
|
|
354
|
+
TBD.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
config.py,sha256=7NmYZ0_2FmooWZHKkcsqldGToZizUF9I0co8oSOLmYY,2964
|
|
2
|
+
main.py,sha256=tucKd2Wt5TTYE5I_wFH7u0fAS788a0TLXbDsmQ4-rDM,72568
|
|
3
|
+
api/__init__.py,sha256=bwumos5R0GW0fTlre4HKVjSOXfLL55T9vQl9rDJAqR4,139
|
|
4
|
+
api/anthropic_compat.py,sha256=mEZ0Ok0n1yipKeotzQNRl8PaCu2wBWxhewAX5zqQBzI,63527
|
|
5
|
+
api/artifact_viewer.py,sha256=FuaOtLB3YRiicXIWt9ikZwQvnk0sx-_QDL2wntYgSX4,14313
|
|
6
|
+
api/caudate_middleware.py,sha256=XIxqODqMfajgH7edOavZPlb9389p9vcacKHV5iVXlms,26784
|
|
7
|
+
api/forge_bootstrapper_routes.py,sha256=djUv-eI5yrq_RSb2LRyvwcK1hbJ5ZLnKT3XEoB440B8,14796
|
|
8
|
+
api/forge_routes.py,sha256=S5Zt7bGI97BSzLbeBqaS0zsPPFuV-oNp-VeCZzSEQQI,25046
|
|
9
|
+
api/forge_system_routes.py,sha256=VA1OT0679g1QBfUMLBoiMKzdlOR25fXk5t9eKG2pDSg,9327
|
|
10
|
+
api/openai_compat.py,sha256=le56dAUv_hyJ-yb3CQRPcj7Br7f-OVw3F805rKDHFMk,89487
|
|
11
|
+
api/server.py,sha256=xygdwzADM6vy7ZpANi2TGZtfmCMtDwb3aT0Gm6GM7_8,26356
|
|
12
|
+
api/storyboard_page.py,sha256=cKaEvQxOO-4Zyb-mT5Boe9Sb-K3TnNedmhrHn242P7s,23715
|
|
13
|
+
caudate_cli-0.1.0.dist-info/licenses/LICENSE,sha256=W2SOZMdGsBZOgyt7dsJiL7RwZgyHF3Hm-w7IcghYttE,1067
|
|
14
|
+
cognos_mcp/__init__.py,sha256=1_TiUzArIIT-z8BvDlxqS4lsGgmb1rTpybJ8Kmecb5o,179
|
|
15
|
+
cognos_mcp/bridge.py,sha256=aAb7_2K3whEr8cCAUM2IOT2fylfkY6kaT_sKnCBbhq4,1321
|
|
16
|
+
cognos_mcp/client.py,sha256=I16HcJNXLHPjMq12uQCydXcNsMHARgxWne3XNRu9o-4,2329
|
|
17
|
+
cognos_mcp/config.py,sha256=1siNeKrIF5TCrpkTVwWnRRQZKF_FXb3dDJeGiA4XN1Q,1234
|
|
18
|
+
cognos_mcp/server.py,sha256=oiWPyb_KqTaW_FRlCBgBGBKhD83AOTxM8jH7V3_jIzA,1903
|
|
19
|
+
core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
core/agent.py,sha256=n_Z9FRvBBFSXSa-4VaY5LLnNY17tVthsq_xq3rXDiGw,19383
|
|
21
|
+
core/agentic_loop.py,sha256=zaapJqTaSCUrpYFyRADmVB_w3awOrm-yBcoWEYzKSJI,29385
|
|
22
|
+
core/anthropic_auth.py,sha256=SiD2hzgY-_fNzy484GXfrI6Iym-VFpv6AR5Tm4hNEKs,3101
|
|
23
|
+
core/background.py,sha256=Fp2jT2-E5kffemLNroiugf-eLx3e_aOkmS5_WyBa6Uw,3583
|
|
24
|
+
core/banner.py,sha256=lzcfhK91YrB7pxxkGQFekNnBA0HFf-qpdDRBwUKpV8U,3965
|
|
25
|
+
core/bootstrap.py,sha256=hD8s0WqYyTUVV3WieljnUQDE9UY0oOt1E-76VJuqzW8,9940
|
|
26
|
+
core/citations.py,sha256=nMz4YDGVWrp6wcvVMB6zHfweOpQh9juV2n7xowm0bzs,4170
|
|
27
|
+
core/compaction.py,sha256=QprJj0shu8-puxAEMPfdBfupDTX9-mgppKugrWeszdA,3650
|
|
28
|
+
core/constitution.py,sha256=VCE6uLUiQKorqpu8Pw65f-NmH6wMVga10kR0cKmMHoY,7200
|
|
29
|
+
core/diff_viewer.py,sha256=qsXWyffScvWemif9JfYtXRYgjoh_UG5GXAM1DvSnIjQ,2896
|
|
30
|
+
core/export.py,sha256=mkeIaEGg0h3IFn68_MioryySyDGjDEcNolCu168G0Q0,3035
|
|
31
|
+
core/file_refs.py,sha256=r0ZgOLTUu86_NUW9d1WsQcHy07_8kJFWrwShmeFSkPw,4266
|
|
32
|
+
core/files.py,sha256=rQwzC0xrEGftY1gbCEj2NC82W5DZI0lZkl2teBzFCIc,6915
|
|
33
|
+
core/hooks.py,sha256=Yv6v2ecS6KxxnOKw3xlL6OGM7TdO3h-G0WX0w1lJXXw,7120
|
|
34
|
+
core/image.py,sha256=7CT6b7XMBcWXk92jlp5fqUr8OfuKbpDiY5lvKWDBvTg,21703
|
|
35
|
+
core/input.py,sha256=Xl_DalNstfspxkPpCLhqKBu_LA8TcduzYUGc7Hsndhk,3189
|
|
36
|
+
core/loop.py,sha256=pMuffoXq7661RQD_PpGjtYgFGXqncSzqU9CSntFBlVw,9512
|
|
37
|
+
core/memory_md.py,sha256=u4xOe6MY6TsVI4GdEeZ6bnfDhg9gderw8sFy9UBEYho,5526
|
|
38
|
+
core/notifications.py,sha256=F7QXXH8fNIFnqvAKHRnzc-TEDt3E-k1TfuYvr_-DN5M,3057
|
|
39
|
+
core/ownership.py,sha256=7G0FKUnpo20ZWlzw_JwDgpC-NxkETyCXQQ4wT44fxWc,5308
|
|
40
|
+
core/paste.py,sha256=a7no8fq4e0PKme-CJESgT3rOAv5Mv_CWhJg9o_OUueE,2588
|
|
41
|
+
core/permissions.py,sha256=qc-Omtjob188oJqKmL_ooIfPFlOwqrhqH4uxYxWdlT8,7159
|
|
42
|
+
core/plan_mode.py,sha256=NTzWAuNZCBKWgv2H96EEXBBtTCWcAEjITJPP4IFkflw,7550
|
|
43
|
+
core/sandbox_prompt.py,sha256=Gp6GYUcRRck2b6Hh_mdmD0ubEm6P-LCAu_IAuBZ47k8,7874
|
|
44
|
+
core/scheduler.py,sha256=Cjvk8hXe7zvEZxEo9s117_8G8W2LyWHpOxwXdAhfSPw,6503
|
|
45
|
+
core/schemas.py,sha256=4AhJuKEyv9OoITnzJqI7n-Eb_T7UrqHsrsClLPbTC_A,5750
|
|
46
|
+
core/session.py,sha256=YvFfmhA1LjG5QQCeyTMLe8w21PKyBS-5fTg1c9bWnaQ,2856
|
|
47
|
+
core/settings.py,sha256=pm1qNcz4P6x7HrD647rj7vksoVrFko_64H9ERo1Jy4o,4333
|
|
48
|
+
core/skills.py,sha256=0UC8tu9952KDeM7r6drjE6_dolxnlc4A6D0ozhz-gmY,14088
|
|
49
|
+
core/slash_commands.py,sha256=SMHULLiwlKkYX8pCdOyDgofCEuESifuJpZPyWrgmZZE,37509
|
|
50
|
+
core/statusline.py,sha256=Blu3cm2VYZQRYqQz6qlUuPFwuGcV7MJDbKSD2qtK9ao,1818
|
|
51
|
+
core/subagent.py,sha256=kYAFOSk24wfYUW8q4dJnfxkH3P6jFWHWx3vZ3je5pDQ,11276
|
|
52
|
+
core/thinking.py,sha256=baXQtlYf9Tk1EzAIq8WfZdJ0MWg7xA260FtSIngG05E,1835
|
|
53
|
+
core/updater.py,sha256=lIkywaiigESiN3qn2gbk6nw2FyZkQztr-VHy60MD4T8,3686
|
|
54
|
+
core/usage.py,sha256=EiL0UyUnag7K_rUKpaHC26K-eFNC4O7uKlBthBhh_P0,3659
|
|
55
|
+
core/worktree.py,sha256=kEA5-B7ga7edwjfByurWmMycbFKhYl3eZUGjmxPZHPE,3155
|
|
56
|
+
execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
+
execution/executor.py,sha256=rGJiqwr6BYIkTXCrsa4PXEGElTaWWbRUbXbC2DpJe0o,13168
|
|
58
|
+
execution/plugins.py,sha256=p2kp2BuhsizM6MmUyM5pqjaQBv7yv4EK8THAQQdLWjs,3634
|
|
59
|
+
execution/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
|
+
execution/tools/agent_tool.py,sha256=PyeXVl-1Vx6Nk04mun75pfPVrpQMoLzbFDVvCHu6CuQ,4334
|
|
61
|
+
execution/tools/agentic_tool.py,sha256=xG7PTaEfqZEvmy6SMyg8Cx9zZA0F1flTzza_FHB5Vh4,10917
|
|
62
|
+
execution/tools/artifact_tool.py,sha256=YFGDyoJ1RMhFzwfAxSQJcT6NKahOKhQzaNO5BC4hX9U,7296
|
|
63
|
+
execution/tools/ask_user_question_tool.py,sha256=QK-WH4iIWqO11cyzxG4cweoCyaRGl1L5h02ibsIe-B8,4983
|
|
64
|
+
execution/tools/base.py,sha256=YykL_SCovGCA8Cl0kBdAwgCjXUD4JqUA4a1wOrblIls,2689
|
|
65
|
+
execution/tools/calculator_tool.py,sha256=OwzxfqPMzbiryED4j04QMIsbny798gnEhFij8yuB6vE,5071
|
|
66
|
+
execution/tools/cognos_card_tool.py,sha256=ZyXktDwKix9jEicRlOPDob4lcsmUQHeH869c-xhFB48,4690
|
|
67
|
+
execution/tools/cron_tool.py,sha256=kKtFxoWtcb6q3ndulPjtimiwYtZmXD6doOFA8zMePkc,7344
|
|
68
|
+
execution/tools/datetime_tool.py,sha256=7mazxi0Qea1MZoFRlqz1v9Z20xXBVwoYfk80sx0CiJ0,8236
|
|
69
|
+
execution/tools/describe_image_tool.py,sha256=EMv3_jiXc8_1lRrhR3elFcC10Cx0DKMAD7vSIk1gqx8,6024
|
|
70
|
+
execution/tools/draw_tool.py,sha256=LOYHy6wkRVfUpzG78jKyN7GruAw1JZxXi5qVpzWEqk4,6435
|
|
71
|
+
execution/tools/edit_image_tool.py,sha256=Cso89zUKtbZrpgGMeLt8l2_j7ikYJvmf6kJu21yYSls,10601
|
|
72
|
+
execution/tools/edit_tool.py,sha256=56Px60ClhpIKbySDsLp1rxLmgIcQWsNjTq589LW-brA,9309
|
|
73
|
+
execution/tools/file_tool.py,sha256=NxM0skh7PhGGUWVVq0NiYwuXZvg-cl6WVytkvue_BT4,2994
|
|
74
|
+
execution/tools/find_anywhere_tool.py,sha256=5Oxsk6VP702BFk6EWiIhriYRk4ecNSMIJwdWaMfsa8w,8876
|
|
75
|
+
execution/tools/forge_feature_tools.py,sha256=1gF7LtNgCt6GKyGCgVAFDviUhxHS42vPci735a7bAxI,13368
|
|
76
|
+
execution/tools/glob_tool.py,sha256=YbpFGLEfsNmdtblt2DQVCvEBqkXOfoMMnUVgGp-mdz8,1845
|
|
77
|
+
execution/tools/grep_tool.py,sha256=o8v3QutMmTVqYAOGu6iaksO5GNRNf1l7pdAmpDLvEW8,3019
|
|
78
|
+
execution/tools/http_request_tool.py,sha256=ImGyz01O7dMXhXehjsApN93tf83VdfD2oFTOtjPQu1k,8431
|
|
79
|
+
execution/tools/load_skill_tool.py,sha256=jsbYiatEHSV51Oo1yRQDQzYXfO-pGTT3QptXa6Lb1-A,3537
|
|
80
|
+
execution/tools/longcat_avatar_tool.py,sha256=T8B18bc5Rphl5lddmiCuhbttOztyWgavA1nByNiPyLI,17501
|
|
81
|
+
execution/tools/mcp_tool.py,sha256=Ne-IPNV-ZqHjkVWF74ZdT7bQygGrQA1fhpdYQ-jZsSg,3731
|
|
82
|
+
execution/tools/notebook_tool.py,sha256=dWvmz1os4jV7RBZYxglTe0a-92Lr60MBpaq1UcLXzuY,10820
|
|
83
|
+
execution/tools/openapi_tool.py,sha256=TgZmox84s83Q8NogBJ2lfdoBJwPRoSW3pEaBqoxQFxM,16703
|
|
84
|
+
execution/tools/plan_mode_tool.py,sha256=-N86Iijg6vM-KPui7B1p21vhwOuQTJRZmTsPbBYwz4A,3498
|
|
85
|
+
execution/tools/push_notification_tool.py,sha256=YDOSf3jfgnLjaVfcvVpveoe-gfmd6_FNEhBO8KfoBRg,5635
|
|
86
|
+
execution/tools/python_tool.py,sha256=3yHqb7MSFwA7YHQZefoLRF5S1Q8bCVAfEQF5vByvI4A,2022
|
|
87
|
+
execution/tools/respond_tool.py,sha256=Jvw2YfcvDbpiRFZSbrPDt-dm5FAzh4vlyjHUERbzJzc,1201
|
|
88
|
+
execution/tools/sandbox_tool.py,sha256=yJ2sqwOm8OmPjZ7RraDCFpbrG0UbgrOlaPOfmUp2NpU,13919
|
|
89
|
+
execution/tools/search_tool.py,sha256=WE0NNpUjHPitrfe88cnrL5_f1DnZEHNsUXenrSwG62Y,5299
|
|
90
|
+
execution/tools/semantic_search_tool.py,sha256=nL8blFpAdYhC2glmT3ubhWcX24SI7A9Xf2wRV8N0s7o,3975
|
|
91
|
+
execution/tools/shell_tool.py,sha256=14BBHh6_HAQdVXQIA7p3pzWrURtir2VAFyYY3viK6yI,10407
|
|
92
|
+
execution/tools/speak_tool.py,sha256=NTmtMUTzVP3aazOv72RHHaWQuvntWxleienMHBR0pj4,4599
|
|
93
|
+
execution/tools/storyboard_tool.py,sha256=H7MzNGGVdfMitE9jpFPOLbkAPHhK9yJlaPLQmYPKSQ0,28686
|
|
94
|
+
execution/tools/system_info_tool.py,sha256=D9iiHn3LuYHuDOryYHqSjZDsBKJaoEh8TgAMSMIMdKM,6910
|
|
95
|
+
execution/tools/task_tool.py,sha256=usgVoP-IDd1gMQrURSkR9CsQcrv6v_ilbIDRb_OHqQA,11122
|
|
96
|
+
execution/tools/think_tool.py,sha256=RF7Xtuqa7oaIr19ZnGOGqYVHzP3PA_Z9o9Q9ClKjqII,1636
|
|
97
|
+
execution/tools/transcribe_audio_tool.py,sha256=yPBqjnqraBIg8ubkEVKNDJDoV7pvQAHMiIXgHzTBGBM,2719
|
|
98
|
+
execution/tools/update_memory_tool.py,sha256=X_U9s-a3ghDSLqnquQig5f5VBVFkLc8RmHCuDnlSv1A,3598
|
|
99
|
+
execution/tools/web_fetch_tool.py,sha256=SHzqBiKd4wQ116TCvCgZqUUXeTgZWeZnjOHYGAlzoXc,2652
|
|
100
|
+
execution/tools/worktree_tool.py,sha256=USuABEhGNU6VSr9tN8YhNfzuCSaVncC-d13mixjX65I,6399
|
|
101
|
+
llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
102
|
+
llm/fallback.py,sha256=ioBRcYY7QssStkYGKB7Y-dlOjrvk5blKUyWv_zOJ9Ko,4218
|
|
103
|
+
llm/models.py,sha256=OK80-zCqvP_cmw62-Bt83Lzo9ABoUsIFFc3aJmmUCPY,10704
|
|
104
|
+
llm/provider.py,sha256=_PRgwD00k2e5NuITf5qXFIoHLwnGQOH8KPNdVc5mn9M,54351
|
|
105
|
+
llm/router.py,sha256=RibZHl2azebZGx94ZFIi_Epjj_2gzN-hxR66-bE3hgc,13452
|
|
106
|
+
memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
107
|
+
memory/episodic.py,sha256=MZIbE2Dt6WFLs9_oX7mwszpIo_-Ocv_QhZBqkSFsCpA,3353
|
|
108
|
+
memory/procedural.py,sha256=vsg7wpCfSZFjjE8qFg7lByxBTlfJe-Vg3isnwox3-dw,5471
|
|
109
|
+
memory/semantic.py,sha256=oDa6F8RYwR2hH6y2rPRrVfuydQTxE4YEgPKBC7gYH9Q,2246
|
|
110
|
+
memory/working.py,sha256=ogQ5CyPQvdoV7DJ9aIYjDnl_kT1D0d2k9Bk2v1tIxfs,2025
|
|
111
|
+
nn/__init__.py,sha256=Z7tm6_odLkcbJF70SKY7UPLIDJJ14_6B58yJBbOvuIg,1521
|
|
112
|
+
nn/auto_evolve.py,sha256=pSts8698uPEV8X2mAYBgeOFJW3Ttfc19myIcSwsYtMA,9320
|
|
113
|
+
nn/caudate.py,sha256=cikf7nR1bCKAKLQHgKlUM2zrYZGg4C2WAo71owuzJTU,6042
|
|
114
|
+
nn/config.py,sha256=lsgePaqzXklQXkUQdQ1APj4Tioe7yrc4o8SZFOSx9uI,6168
|
|
115
|
+
nn/consolidator.py,sha256=GRSVeMIJsfKtv9VeDvSPnlDLyUh_0_sp1hCLqXaB_PY,2946
|
|
116
|
+
nn/data.py,sha256=VIg9Coenptn8pTF1hnVYvRE50TPCp2QP1H_e_j8ywSo,64463
|
|
117
|
+
nn/encoder.py,sha256=uroG8CtbZYVDMjVJjHC73iVpt5udH5--FFHaYnNTs18,10622
|
|
118
|
+
nn/forge_advisor.py,sha256=KzYaAG_YtqrPTgv-Q4WwQgxJXC7nT3w6Bd5po72j4_0,10870
|
|
119
|
+
nn/format.py,sha256=DCa63qWKOZExBIAZdrud1BQAQE9JU5_kkrIzXzdTz04,8170
|
|
120
|
+
nn/heads.py,sha256=BGz-mmKr0Vz8ZjWcE5aVhpN8Euui_98bWj3S1A6Fw1U,19512
|
|
121
|
+
nn/observer.py,sha256=1qmwFWaAwuivB0HdScfvCP81RQF4okh3SFCfScAZf44,42887
|
|
122
|
+
nn/policy.py,sha256=tIxOgRjuUd9nkDxNbFVcRyXEcsSVxjponEfUvo6PqW8,7645
|
|
123
|
+
nn/runtime.py,sha256=x42VsVn6Ub1FZt6OL0KcbjqBVxWjH2GAb3E08I42PDM,14368
|
|
124
|
+
nn/scorer.py,sha256=Cp-Nc6IbO5XgNRZD0yCdsuKd5ac5XhFZfR8vSbwyye8,6036
|
|
125
|
+
nn/trainer.py,sha256=g7JqGBOMS5Fy0bgnJuHihoaJpfG980xjbdno_-qJ6tw,22036
|
|
126
|
+
nn/vision.py,sha256=oTr3uMF68gxYF5nlO8oj6y22OtnkjIikn3hQMuxDoY0,12767
|
|
127
|
+
personality/__init__.py,sha256=R0bWhuF3ZVBXbejYLM7-q3y-9JT-Ob1JJhavnx6yanM,1024
|
|
128
|
+
personality/engine.py,sha256=wlLA4TdGZs1NfobL0Jq-1Wp8NCkNQi7_CwWCF77IDUA,4865
|
|
129
|
+
personality/identity.py,sha256=yTfoCgxhqLb4wuuZQO6amWISX_qcTTJuGMGMcW39lio,5748
|
|
130
|
+
personality/inner_voice.py,sha256=Pnn9JEKylpSG1oqlLxxEhzy5JtTLX8UIQRn5eOJFDRw,3681
|
|
131
|
+
personality/mood.py,sha256=XFt-9qC3BX-kc7g9BZljcC0C9ZaX4llFWKWCeOfpQOU,7933
|
|
132
|
+
planning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
|
+
planning/dev_server.py,sha256=8nMu4YJHAytqkbNHfDQzHf8b9BYVuUub8Rt7dMWK6jk,6711
|
|
134
|
+
planning/forge_models.py,sha256=P7WMiwArtlhLperj9BZ3IXmkH_wxoZO3o8HgjW_sf6k,25066
|
|
135
|
+
planning/orchestrator.py,sha256=APQczVrxxghiphbkV_sJpSXK04bMNI9uaeozOt8xl84,52076
|
|
136
|
+
planning/planner.py,sha256=W9GooJmNzSyuN_I8aKltTjHyeAAmsWGKoFYDEv9O4Nk,17109
|
|
137
|
+
planning/task_graph.py,sha256=nTFwAEh_KlImGyUFVhWTnwXrxJOIQCHWKryM6vCFpho,2137
|
|
138
|
+
reflection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
139
|
+
reflection/meta_learner.py,sha256=98QbKN3BgTJf-mJEPwgbdeeDwa8bbrdXXH6FGZ57aT0,5166
|
|
140
|
+
reflection/reflector.py,sha256=Ux-kiY887J053sYSHpwfRmTLly3R48kPv6wVY8YCqFs,4431
|
|
141
|
+
ui/__init__.py,sha256=Gcs3nvXG2Ijjrofq2m-KrOpdUbdXGH9j6svJEiFllcA,124
|
|
142
|
+
ui/display.py,sha256=ms4_cfmWYRcy-woC8zqIQ8M1Mb0gMeKHV1QnIKxEWu4,3156
|
|
143
|
+
voice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
144
|
+
voice/conversation.py,sha256=D8Xc22Rg1oRfl6GVLfV6EV7GAzv9_--zA71Lze8qc-0,4515
|
|
145
|
+
voice/listener.py,sha256=J449m6bFkg1WZDnWaxZ68rU-_dqOClqSepo1x338haU,3574
|
|
146
|
+
voice/speaker.py,sha256=wL_t80FgYWgI_WAP-0JUdTyJluZQdpW0rKax-sUcUPM,1803
|
|
147
|
+
voice/stt.py,sha256=o_Zfm_mPVvUCGUocelkY3vQaNEB_YCPqrnuAnGF54qY,4460
|
|
148
|
+
voice/tts.py,sha256=BAXQxSXHMyGBLWf7zTJCruc2KMHRENk5nI6lhyxAA74,7651
|
|
149
|
+
caudate_cli-0.1.0.dist-info/METADATA,sha256=PgNa5AaPj22Oat579sH53TxNyjfGZ5TIGjZTeVPLYL4,13976
|
|
150
|
+
caudate_cli-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
151
|
+
caudate_cli-0.1.0.dist-info/entry_points.txt,sha256=JMN9KakShDkHIlNwWlfaTT1721lYrZ9pfku67UXk6Vs,36
|
|
152
|
+
caudate_cli-0.1.0.dist-info/top_level.txt,sha256=wkg0eHZ4nXN7AdmsM090oqDphAO1V-xnOW6QVNDwa6g,97
|
|
153
|
+
caudate_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rave Manji
|
|
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.
|
cognos_mcp/__init__.py
ADDED
cognos_mcp/bridge.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""MCP bridge — wrap a remote MCP tool as a local Cognos BaseTool."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from core.schemas import ToolResult
|
|
8
|
+
from execution.tools.base import BaseTool
|
|
9
|
+
from cognos_mcp.client import MCPClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MCPToolBridge(BaseTool):
|
|
13
|
+
"""Adapter: presents a remote MCP tool as a Cognos BaseTool."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client: MCPClient, remote_tool: Any):
|
|
16
|
+
self._client = client
|
|
17
|
+
self._remote = remote_tool
|
|
18
|
+
# Prefix name with server to avoid collisions
|
|
19
|
+
self._name = f"{client.name}__{remote_tool.name}"
|
|
20
|
+
self._description = remote_tool.description or f"MCP tool from {client.name}"
|
|
21
|
+
# MCP tool objects expose input_schema as a dict
|
|
22
|
+
self._schema = dict(remote_tool.inputSchema or {"type": "object", "properties": {}})
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def name(self) -> str:
|
|
26
|
+
return self._name
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def description(self) -> str:
|
|
30
|
+
return self._description
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def input_schema(self) -> dict[str, Any]:
|
|
34
|
+
return self._schema
|
|
35
|
+
|
|
36
|
+
async def execute(self, **kwargs: Any) -> ToolResult:
|
|
37
|
+
try:
|
|
38
|
+
output = await self._client.call(self._remote.name, kwargs)
|
|
39
|
+
return self._success(output)
|
|
40
|
+
except Exception as e:
|
|
41
|
+
return self._error(str(e))
|
cognos_mcp/client.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""MCP Client — connect to external MCP servers and list/call their tools."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from contextlib import AsyncExitStack
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from mcp import ClientSession, StdioServerParameters
|
|
10
|
+
from mcp.client.stdio import stdio_client
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MCPClient:
|
|
16
|
+
"""A single connection to one MCP server over stdio."""
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
name: str,
|
|
21
|
+
command: str,
|
|
22
|
+
args: list[str] | None = None,
|
|
23
|
+
env: dict[str, str] | None = None,
|
|
24
|
+
):
|
|
25
|
+
self.name = name
|
|
26
|
+
self.command = command
|
|
27
|
+
self.args = args or []
|
|
28
|
+
self.env = env or {}
|
|
29
|
+
self._session: ClientSession | None = None
|
|
30
|
+
self._stack: AsyncExitStack | None = None
|
|
31
|
+
self._tools: list[Any] = []
|
|
32
|
+
|
|
33
|
+
async def connect(self) -> None:
|
|
34
|
+
"""Open the stdio connection and initialize the MCP session."""
|
|
35
|
+
params = StdioServerParameters(
|
|
36
|
+
command=self.command,
|
|
37
|
+
args=self.args,
|
|
38
|
+
env=self.env or None,
|
|
39
|
+
)
|
|
40
|
+
self._stack = AsyncExitStack()
|
|
41
|
+
read, write = await self._stack.enter_async_context(stdio_client(params))
|
|
42
|
+
self._session = await self._stack.enter_async_context(
|
|
43
|
+
ClientSession(read, write)
|
|
44
|
+
)
|
|
45
|
+
await self._session.initialize()
|
|
46
|
+
result = await self._session.list_tools()
|
|
47
|
+
self._tools = list(result.tools)
|
|
48
|
+
logger.info(f"MCP[{self.name}] connected with {len(self._tools)} tools")
|
|
49
|
+
|
|
50
|
+
async def close(self) -> None:
|
|
51
|
+
if self._stack is not None:
|
|
52
|
+
await self._stack.aclose()
|
|
53
|
+
self._stack = None
|
|
54
|
+
self._session = None
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def tools(self) -> list[Any]:
|
|
58
|
+
return self._tools
|
|
59
|
+
|
|
60
|
+
async def call(self, tool_name: str, arguments: dict[str, Any]) -> str:
|
|
61
|
+
if self._session is None:
|
|
62
|
+
raise RuntimeError(f"MCP client {self.name!r} not connected")
|
|
63
|
+
result = await self._session.call_tool(tool_name, arguments)
|
|
64
|
+
# Extract text from MCP content blocks
|
|
65
|
+
out_parts: list[str] = []
|
|
66
|
+
for block in result.content or []:
|
|
67
|
+
text = getattr(block, "text", None)
|
|
68
|
+
if text:
|
|
69
|
+
out_parts.append(text)
|
|
70
|
+
return "\n".join(out_parts) if out_parts else "(no output)"
|