cognits 0.0.1__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 (75) hide show
  1. cognits-0.0.1/.gitignore +30 -0
  2. cognits-0.0.1/LICENSE +21 -0
  3. cognits-0.0.1/PKG-INFO +54 -0
  4. cognits-0.0.1/README.md +38 -0
  5. cognits-0.0.1/frontend/src/App.tsx +180 -0
  6. cognits-0.0.1/frontend/src/FileTree.tsx +101 -0
  7. cognits-0.0.1/frontend/src/FileTreeWrapper.tsx +18 -0
  8. cognits-0.0.1/frontend/src/components/Chat.tsx +254 -0
  9. cognits-0.0.1/frontend/src/components/CollapsibleSection.tsx +34 -0
  10. cognits-0.0.1/frontend/src/components/ContextMenu.tsx +70 -0
  11. cognits-0.0.1/frontend/src/components/DragOverlay.tsx +103 -0
  12. cognits-0.0.1/frontend/src/components/Dropdown.tsx +104 -0
  13. cognits-0.0.1/frontend/src/components/LearnitView.tsx +168 -0
  14. cognits-0.0.1/frontend/src/components/MarkdownView.tsx +11 -0
  15. cognits-0.0.1/frontend/src/components/ReportView.tsx +67 -0
  16. cognits-0.0.1/frontend/src/components/Sessions.tsx +141 -0
  17. cognits-0.0.1/frontend/src/components/Settings.tsx +738 -0
  18. cognits-0.0.1/frontend/src/components/TabBar.tsx +93 -0
  19. cognits-0.0.1/frontend/src/components/Viewport.tsx +215 -0
  20. cognits-0.0.1/frontend/src/components/Write.tsx +33 -0
  21. cognits-0.0.1/frontend/src/drag/drag-state.ts +111 -0
  22. cognits-0.0.1/frontend/src/index.css +214 -0
  23. cognits-0.0.1/frontend/src/index.tsx +6 -0
  24. cognits-0.0.1/frontend/src/lib/chat-stream.ts +165 -0
  25. cognits-0.0.1/frontend/src/lib/clipboard.ts +21 -0
  26. cognits-0.0.1/frontend/src/lib/markdown.ts +132 -0
  27. cognits-0.0.1/frontend/src/stores/chat-store.ts +339 -0
  28. cognits-0.0.1/frontend/src/stores/desktop-store.ts +147 -0
  29. cognits-0.0.1/frontend/src/stores/learnit-store.ts +73 -0
  30. cognits-0.0.1/frontend/src/stores/report-store.ts +42 -0
  31. cognits-0.0.1/frontend/src/stores/session-store.ts +69 -0
  32. cognits-0.0.1/frontend/src/stores/settings-store.ts +150 -0
  33. cognits-0.0.1/frontend/src/stores/viewport-tree-store.ts +362 -0
  34. cognits-0.0.1/frontend/src/tabs.ts +26 -0
  35. cognits-0.0.1/frontend/src/types.ts +50 -0
  36. cognits-0.0.1/pyproject.toml +32 -0
  37. cognits-0.0.1/src/cognits/__init__.py +6 -0
  38. cognits-0.0.1/src/cognits/__main__.py +3 -0
  39. cognits-0.0.1/src/cognits/agent/__init__.py +0 -0
  40. cognits-0.0.1/src/cognits/agent/agent.py +148 -0
  41. cognits-0.0.1/src/cognits/agent/prompts.py +42 -0
  42. cognits-0.0.1/src/cognits/agent/subagents.py +268 -0
  43. cognits-0.0.1/src/cognits/agent/tool_deploy.py +180 -0
  44. cognits-0.0.1/src/cognits/agent/tool_rag.py +58 -0
  45. cognits-0.0.1/src/cognits/llm/__init__.py +0 -0
  46. cognits-0.0.1/src/cognits/llm/deepseek.py +99 -0
  47. cognits-0.0.1/src/cognits/llm/types.py +52 -0
  48. cognits-0.0.1/src/cognits/main.py +127 -0
  49. cognits-0.0.1/src/cognits/paths.py +65 -0
  50. cognits-0.0.1/src/cognits/rag/__init__.py +0 -0
  51. cognits-0.0.1/src/cognits/rag/chunker.py +110 -0
  52. cognits-0.0.1/src/cognits/rag/engine.py +172 -0
  53. cognits-0.0.1/src/cognits/server/__init__.py +0 -0
  54. cognits-0.0.1/src/cognits/server/app.py +123 -0
  55. cognits-0.0.1/src/cognits/server/browser.py +56 -0
  56. cognits-0.0.1/src/cognits/server/devproxy.py +105 -0
  57. cognits-0.0.1/src/cognits/server/frontend.py +64 -0
  58. cognits-0.0.1/src/cognits/server/routes_chat.py +334 -0
  59. cognits-0.0.1/src/cognits/server/routes_config.py +71 -0
  60. cognits-0.0.1/src/cognits/server/routes_misc.py +163 -0
  61. cognits-0.0.1/src/cognits/server/routes_reports.py +63 -0
  62. cognits-0.0.1/src/cognits/server/routes_sessions.py +94 -0
  63. cognits-0.0.1/src/cognits/server/routes_stream.py +133 -0
  64. cognits-0.0.1/src/cognits/server/session_agent.py +85 -0
  65. cognits-0.0.1/src/cognits/server/util.py +28 -0
  66. cognits-0.0.1/src/cognits/storage/__init__.py +0 -0
  67. cognits-0.0.1/src/cognits/storage/db.py +467 -0
  68. cognits-0.0.1/src/cognits/storage/files.py +280 -0
  69. cognits-0.0.1/src/cognits/tinyfish.py +53 -0
  70. cognits-0.0.1/src/cognits/tools.py +59 -0
  71. cognits-0.0.1/tests/test_agent.py +128 -0
  72. cognits-0.0.1/tests/test_chunker.py +57 -0
  73. cognits-0.0.1/tests/test_crypto.py +51 -0
  74. cognits-0.0.1/tests/test_db.py +145 -0
  75. cognits-0.0.1/tests/test_sse.py +163 -0
@@ -0,0 +1,30 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ .venv/
5
+ .pytest_cache/
6
+ dist/
7
+
8
+ # Runtime data (sessions, DB, RAG index, encrypted keys)
9
+ .learnit/
10
+ .cognits/
11
+
12
+ # Frontend build artifacts
13
+ frontend/node_modules/
14
+ frontend/dist/
15
+ src/cognits/frontend_dist/
16
+
17
+ # Internal design docs and dev tooling
18
+ IDEA.md
19
+ CONVERSACION_CON_LA_IDEA.md
20
+ AGENTS.md
21
+ .opencode/
22
+ opencode.jsonc
23
+ .claude/
24
+
25
+ # Legacy Go code (pre-Python rewrite, kept for reference)
26
+ legacy/
27
+
28
+ # Local
29
+ nohup.out
30
+ *.log
cognits-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eduardo Suárez
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.
cognits-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: cognits
3
+ Version: 0.0.1
4
+ Summary: Cognits — Context-Oriented Generation for Neural Intelligent Tutoring Systems. Multi-agent AI personal tutor.
5
+ Author-email: Eduardo Suárez <edusrez@proton.me>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: <3.14,>=3.11
9
+ Requires-Dist: chromadb==1.5.9
10
+ Requires-Dist: cryptography>=42
11
+ Requires-Dist: fastapi>=0.115
12
+ Requires-Dist: fastembed==0.8.0
13
+ Requires-Dist: httpx>=0.27
14
+ Requires-Dist: uvicorn[standard]>=0.30
15
+ Description-Content-Type: text/markdown
16
+
17
+ # Cognits
18
+
19
+ **C**ontext-**O**riented **G**eneration for **N**eural **I**ntelligent **T**utoring **S**ystems.
20
+
21
+ Multi-agent AI personal tutor: a Socratic orchestrator coordinates subagents
22
+ (documentalist with local RAG, web researcher) to guide your learning from a
23
+ local web interface, anchored to the project folder you're learning about.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ uv tool install cognits
29
+ ```
30
+
31
+ > The installation includes the local RAG engine (onnxruntime + ChromaDB, ~600 MB).
32
+ > On first launch, the BGE-M3 embeddings model is downloaded (~2.3 GB).
33
+
34
+ ## Usage
35
+
36
+ ```bash
37
+ cd my-learning-project
38
+ cognits
39
+ ```
40
+
41
+ Starts a local server (port 5173 by default, `PORT` env var) and opens the
42
+ interface in your browser. State lives in `./.cognits/` (sessions, reports,
43
+ encrypted configuration, RAG index).
44
+
45
+ ## Development
46
+
47
+ ```bash
48
+ scripts/dev.sh # Vite (HMR) + uvicorn --reload
49
+ scripts/build.sh # frontend build + wheel
50
+ uv run pytest
51
+ ```
52
+
53
+ The frontend is a SolidJS SPA in `frontend/`; the backend is Python (FastAPI)
54
+ in `src/cognits/`.
@@ -0,0 +1,38 @@
1
+ # Cognits
2
+
3
+ **C**ontext-**O**riented **G**eneration for **N**eural **I**ntelligent **T**utoring **S**ystems.
4
+
5
+ Multi-agent AI personal tutor: a Socratic orchestrator coordinates subagents
6
+ (documentalist with local RAG, web researcher) to guide your learning from a
7
+ local web interface, anchored to the project folder you're learning about.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ uv tool install cognits
13
+ ```
14
+
15
+ > The installation includes the local RAG engine (onnxruntime + ChromaDB, ~600 MB).
16
+ > On first launch, the BGE-M3 embeddings model is downloaded (~2.3 GB).
17
+
18
+ ## Usage
19
+
20
+ ```bash
21
+ cd my-learning-project
22
+ cognits
23
+ ```
24
+
25
+ Starts a local server (port 5173 by default, `PORT` env var) and opens the
26
+ interface in your browser. State lives in `./.cognits/` (sessions, reports,
27
+ encrypted configuration, RAG index).
28
+
29
+ ## Development
30
+
31
+ ```bash
32
+ scripts/dev.sh # Vite (HMR) + uvicorn --reload
33
+ scripts/build.sh # frontend build + wheel
34
+ uv run pytest
35
+ ```
36
+
37
+ The frontend is a SolidJS SPA in `frontend/`; the backend is Python (FastAPI)
38
+ in `src/cognits/`.
@@ -0,0 +1,180 @@
1
+ import { createEffect, createMemo, Show, createSignal, onCleanup, onMount } from "solid-js"
2
+ import {
3
+ rootId,
4
+ getViewportData,
5
+ getSplitData,
6
+ setFraction,
7
+ moveTab,
8
+ placeSessionTabs,
9
+ removeSessionTabs,
10
+ type ViewportId,
11
+ } from "./stores/viewport-tree-store"
12
+ import { dragState, endDrag } from "./drag/drag-state"
13
+ import { activeSessionId } from "./stores/session-store"
14
+ import { loadConfig, defaultChatViewport, defaultWriteViewport, loadSessionConfig } from "./stores/settings-store"
15
+ import { loadSessionMessages } from "./stores/chat-store"
16
+ import { initDesktops, createDesktop, switchDesktop, closeDesktop, desktopCount, activeDesktopIndex } from "./stores/desktop-store"
17
+ import Viewport from "./components/Viewport"
18
+ import DragOverlay from "./components/DragOverlay"
19
+
20
+ initDesktops()
21
+
22
+ export default function App() {
23
+ createEffect(() => {
24
+ const sid = activeSessionId()
25
+ if (sid) {
26
+ placeSessionTabs(defaultChatViewport(), defaultWriteViewport())
27
+ loadSessionMessages(sid)
28
+ loadSessionConfig(sid)
29
+ } else {
30
+ removeSessionTabs()
31
+ }
32
+ })
33
+
34
+ const handleDrop = () => {
35
+ const ds = dragState()
36
+ if (ds.targetViewport !== null) {
37
+ moveTab(ds.tabId, ds.sourceViewport, ds.targetViewport, ds.insertIndex)
38
+ }
39
+ endDrag()
40
+ }
41
+
42
+ onCleanup(() => {
43
+ endDrag()
44
+ })
45
+
46
+ onMount(() => {
47
+ loadConfig()
48
+ const handler = (e: KeyboardEvent) => {
49
+ const tag = (e.target as HTMLElement).tagName
50
+ if (tag === "INPUT" || tag === "TEXTAREA") return
51
+
52
+ if (!e.ctrlKey && !e.shiftKey && !e.altKey) {
53
+ if (e.key === "n") {
54
+ e.preventDefault()
55
+ createDesktop()
56
+ return
57
+ }
58
+ const num = parseInt(e.key)
59
+ if (num >= 1 && num <= 9 && num <= desktopCount()) {
60
+ e.preventDefault()
61
+ switchDesktop(num - 1)
62
+ }
63
+ }
64
+ if (!e.ctrlKey && e.shiftKey && !e.altKey) {
65
+ if (e.key === "N") {
66
+ e.preventDefault()
67
+ closeDesktop(activeDesktopIndex())
68
+ }
69
+ }
70
+ }
71
+ document.addEventListener("keydown", handler)
72
+ onCleanup(() => document.removeEventListener("keydown", handler))
73
+ })
74
+
75
+ return (
76
+ <div
77
+ class="h-screen w-screen bg-black text-[#e0e0e0] select-none"
78
+ onContextMenu={(e) => e.preventDefault()}
79
+ >
80
+ <GridNode id={rootId()} />
81
+ <DragOverlay onDrop={handleDrop} />
82
+ </div>
83
+ )
84
+ }
85
+
86
+ function GridNode(props: { id: ViewportId }) {
87
+ const split = createMemo(() => getSplitData(props.id))
88
+ const leaf = createMemo(() => getViewportData(props.id))
89
+
90
+ return (
91
+ <Show when={split()} fallback={
92
+ <Show when={leaf()}>
93
+ {(vp) => (
94
+ <div style={{ width: "100%", height: "100%" }}>
95
+ <Viewport id={props.id} data={vp()} />
96
+ </div>
97
+ )}
98
+ </Show>
99
+ }>
100
+ <SplitView id={props.id} />
101
+ </Show>
102
+ )
103
+ }
104
+
105
+ function SplitView(props: { id: ViewportId }) {
106
+ const split = createMemo(() => getSplitData(props.id)!)
107
+ const children = createMemo(() => split().children)
108
+ const f0 = createMemo(() => split().fractions[0])
109
+ const f1 = createMemo(() => split().fractions[1])
110
+ const isH = createMemo(() => split().direction === "h")
111
+ const [dragging, setDragging] = createSignal(false)
112
+
113
+ const onResizerDown = (e: MouseEvent) => {
114
+ e.preventDefault()
115
+ // Capture the container here: during the drag the pointer can leave
116
+ // this split and ev.target would point to another container.
117
+ const gridRef = (e.currentTarget as HTMLElement).closest("[data-split]") as HTMLElement | null
118
+ if (!gridRef) return
119
+ setDragging(true)
120
+
121
+ const start = isH() ? e.clientX : e.clientY
122
+ const startF0 = f0()
123
+ const startF1 = f1()
124
+ const totalFr = startF0 + startF1
125
+
126
+ const onMove = (ev: MouseEvent) => {
127
+ const current = isH() ? ev.clientX : ev.clientY
128
+ const delta = current - start
129
+
130
+ const rect = gridRef.getBoundingClientRect()
131
+ const size = isH() ? rect.width - 4 : rect.height - 4
132
+
133
+ if (size <= 0) return
134
+ const p0 = (startF0 * size) / totalFr
135
+ const p1 = Math.max(10, Math.min(size - 10, p0 + delta))
136
+ const clamped = (p1 * totalFr) / size
137
+ setFraction(props.id, 0, Math.max(0.5, clamped))
138
+ setFraction(props.id, 1, Math.max(0.5, totalFr - clamped))
139
+ }
140
+
141
+ const onUp = () => {
142
+ setDragging(false)
143
+ document.removeEventListener("mousemove", onMove)
144
+ document.removeEventListener("mouseup", onUp)
145
+ }
146
+
147
+ document.addEventListener("mousemove", onMove)
148
+ document.addEventListener("mouseup", onUp)
149
+ }
150
+
151
+ return (
152
+ <div
153
+ data-split
154
+ style={{
155
+ display: "grid",
156
+ overflow: "hidden",
157
+ width: "100%",
158
+ height: "100%",
159
+ ...(isH()
160
+ ? {
161
+ "grid-template-columns": `minmax(0, ${f0()}fr) 4px minmax(0, ${f1()}fr)`,
162
+ "grid-template-rows": "minmax(0, 1fr)",
163
+ }
164
+ : {
165
+ "grid-template-columns": "minmax(0, 1fr)",
166
+ "grid-template-rows": `minmax(0, ${f0()}fr) 4px minmax(0, ${f1()}fr)`,
167
+ }),
168
+ }}
169
+ >
170
+ <GridNode id={children()[0]} />
171
+ <div
172
+ class="resizer"
173
+ classList={{ "resizer-dragging": dragging() }}
174
+ style={{ cursor: isH() ? "col-resize" : "row-resize" }}
175
+ onMouseDown={onResizerDown}
176
+ />
177
+ <GridNode id={children()[1]} />
178
+ </div>
179
+ )
180
+ }
@@ -0,0 +1,101 @@
1
+ import { createSignal, For, Show } from "solid-js"
2
+ import type { FileNode } from "./types"
3
+
4
+ function ChevronRight() {
5
+ return (
6
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
7
+ <path d="M9 18l6-6-6-6" />
8
+ </svg>
9
+ )
10
+ }
11
+
12
+ function ChevronDown() {
13
+ return (
14
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
15
+ <path d="M6 9l6 6 6-6" />
16
+ </svg>
17
+ )
18
+ }
19
+
20
+ function FolderIcon() {
21
+ return (
22
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
23
+ <path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" />
24
+ </svg>
25
+ )
26
+ }
27
+
28
+ function FileIcon() {
29
+ return (
30
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
31
+ <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
32
+ <polyline points="14 2 14 8 20 8" />
33
+ </svg>
34
+ )
35
+ }
36
+
37
+ export default function FileTree(props: { node: () => FileNode | null }) {
38
+ return (
39
+ <div style="padding: 4px 0">
40
+ <Show when={props.node()}>
41
+ {(n) => <NodeView node={n()} depth={0} />}
42
+ </Show>
43
+ </div>
44
+ )
45
+ }
46
+
47
+ function ToggleIcon(props: { expanded: boolean }) {
48
+ return (
49
+ <span style={{ display: "inline-flex", "align-items": "center", width: "14px", color: "#6a6a6a" }}>
50
+ {props.expanded ? <ChevronDown /> : <ChevronRight />}
51
+ </span>
52
+ )
53
+ }
54
+
55
+ function NodeView(props: { node: FileNode; depth: number }) {
56
+ const isRoot = props.depth === 0
57
+ const [expanded, setExpanded] = createSignal(isRoot)
58
+ const hasKids = props.node.isDir && props.node.children && props.node.children.length > 0
59
+
60
+ function handleClick() {
61
+ if (!isRoot && hasKids) setExpanded(!expanded())
62
+ }
63
+
64
+ return (
65
+ <>
66
+ <div
67
+ style={{
68
+ cursor: isRoot ? "default" : "pointer",
69
+ padding: `1px 8px 1px ${8 + props.depth * 14}px`,
70
+ "font-size": "13px",
71
+ "line-height": "1.5",
72
+ "white-space": "nowrap",
73
+ overflow: "hidden",
74
+ "text-overflow": "ellipsis",
75
+ display: "flex",
76
+ "align-items": "center",
77
+ gap: "4px",
78
+ }}
79
+ onClick={handleClick}
80
+ >
81
+ <Show when={!isRoot && hasKids} fallback={
82
+ <span style={{ display: "inline-flex", "align-items": "center", width: "14px" }}>
83
+ {props.node.isDir ? (
84
+ <span style={{ color: "#6a6a6a" }}><FolderIcon /></span>
85
+ ) : (
86
+ <span style={{ color: "#6a6a6a" }}><FileIcon /></span>
87
+ )}
88
+ </span>
89
+ }>
90
+ <ToggleIcon expanded={expanded()} />
91
+ </Show>
92
+ <span style={{ color: "#e0e0e0" }}>{props.node.name}</span>
93
+ </div>
94
+ <Show when={hasKids && (isRoot || expanded())}>
95
+ <For each={props.node.children}>
96
+ {(child) => <NodeView node={child} depth={props.depth + 1} />}
97
+ </For>
98
+ </Show>
99
+ </>
100
+ )
101
+ }
@@ -0,0 +1,18 @@
1
+ import { createSignal, onMount } from "solid-js"
2
+ import FileTree from "./FileTree"
3
+ import type { FileNode } from "./types"
4
+
5
+ export default function FileTreeWrapper() {
6
+ const [tree, setTree] = createSignal<FileNode | null>(null)
7
+
8
+ onMount(async () => {
9
+ try {
10
+ const res = await fetch("/api/tree")
11
+ setTree(await res.json())
12
+ } catch (err) {
13
+ console.error(err)
14
+ }
15
+ })
16
+
17
+ return <FileTree node={tree} />
18
+ }