knowledge-worker 0.6.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.
- knowledge_worker-0.6.0.dist-info/METADATA +365 -0
- knowledge_worker-0.6.0.dist-info/RECORD +27 -0
- knowledge_worker-0.6.0.dist-info/WHEEL +5 -0
- knowledge_worker-0.6.0.dist-info/entry_points.txt +3 -0
- knowledge_worker-0.6.0.dist-info/licenses/LICENSE +21 -0
- knowledge_worker-0.6.0.dist-info/top_level.txt +2 -0
- mygraph/__init__.py +23 -0
- mygraph/anthropic_client.py +199 -0
- mygraph/audit.py +137 -0
- mygraph/check.py +273 -0
- mygraph/discover.py +654 -0
- mygraph/eval_log.py +36 -0
- mygraph/export_context.py +124 -0
- mygraph/extractor.py +243 -0
- mygraph/extractor_openai.py +165 -0
- mygraph/ingest.py +170 -0
- mygraph/memory_audit.py +1094 -0
- mygraph/merge.py +133 -0
- mygraph/mygraph.py +773 -0
- mygraph/owl_io.py +202 -0
- mygraph/review.py +151 -0
- mygraph/validator.py +149 -0
- mygraph/viz.py +409 -0
- ollama_proxy/eval_compare.py +185 -0
- ollama_proxy/extractor_adapter.py +168 -0
- ollama_proxy/proxy.py +143 -0
- ollama_proxy/server.py +194 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: knowledge-worker
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Provenance-backed personal knowledge graph for local AI workflows
|
|
5
|
+
Author-email: Rahul Rangarao <rahulmranga@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rahulmranga/knowledge-worker
|
|
8
|
+
Project-URL: Repository, https://github.com/rahulmranga/knowledge-worker
|
|
9
|
+
Project-URL: Issues, https://github.com/rahulmranga/knowledge-worker/issues
|
|
10
|
+
Keywords: knowledge-graph,llm-memory,local-first,provenance,personal-knowledge-management,ai,claude
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Provides-Extra: rdf
|
|
23
|
+
Requires-Dist: rdflib>=7.0.0; extra == "rdf"
|
|
24
|
+
Provides-Extra: anthropic
|
|
25
|
+
Requires-Dist: anthropic>=0.39.0; extra == "anthropic"
|
|
26
|
+
Requires-Dist: rdflib>=7.0.0; extra == "anthropic"
|
|
27
|
+
Provides-Extra: openai
|
|
28
|
+
Requires-Dist: openai>=1.68.0; extra == "openai"
|
|
29
|
+
Requires-Dist: rdflib>=7.0.0; extra == "openai"
|
|
30
|
+
Provides-Extra: llm
|
|
31
|
+
Requires-Dist: anthropic>=0.39.0; extra == "llm"
|
|
32
|
+
Requires-Dist: openai>=1.68.0; extra == "llm"
|
|
33
|
+
Requires-Dist: rdflib>=7.0.0; extra == "llm"
|
|
34
|
+
Provides-Extra: ollama
|
|
35
|
+
Requires-Dist: httpx>=0.27.0; extra == "ollama"
|
|
36
|
+
Requires-Dist: rdflib>=7.0.0; extra == "ollama"
|
|
37
|
+
Provides-Extra: proxy
|
|
38
|
+
Requires-Dist: fastapi>=0.110.0; extra == "proxy"
|
|
39
|
+
Requires-Dist: httpx>=0.27.0; extra == "proxy"
|
|
40
|
+
Requires-Dist: mcp[cli]>=1.0.0; extra == "proxy"
|
|
41
|
+
Requires-Dist: uvicorn[standard]>=0.27.0; extra == "proxy"
|
|
42
|
+
Provides-Extra: all
|
|
43
|
+
Requires-Dist: anthropic>=0.39.0; extra == "all"
|
|
44
|
+
Requires-Dist: openai>=1.68.0; extra == "all"
|
|
45
|
+
Requires-Dist: httpx>=0.27.0; extra == "all"
|
|
46
|
+
Requires-Dist: rdflib>=7.0.0; extra == "all"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# knowledge-worker
|
|
50
|
+
|
|
51
|
+
[](https://pypi.org/project/knowledge-worker/)
|
|
52
|
+
|
|
53
|
+
**A personal knowledge graph that survives between AI conversations.**
|
|
54
|
+
User-centered (not conversation-centered). Provenance-or-bust. Built on boring infrastructure.
|
|
55
|
+
|
|
56
|
+
> *Your AI is only as smart as what it remembers about you.*
|
|
57
|
+
|
|
58
|
+
<p align="center">
|
|
59
|
+
<img src="docs/assets/knowledge-worker-demo.gif" alt="knowledge-worker graph visualizer demo" width="900">
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
`knowledge-worker` is a local-first personal knowledge graph for carrying context across AI sessions. It turns notes into reviewable concepts, decisions, goals, and relationships, keeps source excerpts attached, and exports compact context you can paste into Claude, GPT, Ollama, or any other LLM workflow.
|
|
63
|
+
|
|
64
|
+
Your private graph stays on your machine, enabling you to preserve the thread of your own reasoning across AI sessions.
|
|
65
|
+
|
|
66
|
+
## Why
|
|
67
|
+
|
|
68
|
+
AI conversations usually start from zero. You clarify a decision, name a constraint, sketch a goal, and then the next session forgets it. RAG can be heavy, full-note prompts are noisy, and most note apps do not plug cleanly into chat workflows.
|
|
69
|
+
|
|
70
|
+
Stop dumping context. Build memory. `knowledge-worker` turns chats, notes, decisions, and sources into a local provenance-backed knowledge graph, then uses graph analytics to show what matters, what connects, what is weak, and what context an AI should see.
|
|
71
|
+
|
|
72
|
+
`knowledge-worker` keeps the useful parts: cited claims, explicit relationships, human review, and a small context snapshot when you need continuity.
|
|
73
|
+
|
|
74
|
+
## How It Compares
|
|
75
|
+
|
|
76
|
+
`knowledge-worker` is personal AI memory with source-backed claims, not a team
|
|
77
|
+
chat-to-wiki system. It keeps reasoning local, reviewable, and tied to literal
|
|
78
|
+
provenance excerpts before claims become durable graph knowledge.
|
|
79
|
+
|
|
80
|
+
See [Competitive Analysis](docs/COMPETITIVE_ANALYSIS.md) for the category
|
|
81
|
+
matrix and [Benchmarks](docs/BENCHMARKS.md) for the offline demo-graph checks.
|
|
82
|
+
|
|
83
|
+
## What It Does
|
|
84
|
+
|
|
85
|
+
- Ingests markdown notes into candidate graph nodes and edges.
|
|
86
|
+
- Requires provenance excerpts before claims become durable memory.
|
|
87
|
+
- Lets you review, accept, reject, or edit LLM proposals before merge.
|
|
88
|
+
- Searches by term, lists nodes by type, and finds paths between ideas.
|
|
89
|
+
- Exports an LLM-ready context snapshot for a fresh chat session.
|
|
90
|
+
- Audits memory shape with PageRank, betweenness, k-core, communities, weak
|
|
91
|
+
claims, and provenance coverage.
|
|
92
|
+
- Generates an offline HTML graph viewer for exploration and demos.
|
|
93
|
+
|
|
94
|
+
## Design Principles
|
|
95
|
+
|
|
96
|
+
**Provenance first.** Every durable claim points back to a source document and literal excerpt.
|
|
97
|
+
|
|
98
|
+
**Local first.** The graph is a file on your machine. No cloud sync, accounts, or telemetry.
|
|
99
|
+
|
|
100
|
+
**Review before merge.** The LLM proposes. You decide. Deterministic validation runs before anything enters the graph.
|
|
101
|
+
|
|
102
|
+
**Boring persistence.** Plain JSON until it becomes the limiting factor. The schema stays stable across storage backends.
|
|
103
|
+
|
|
104
|
+
## Quick Start
|
|
105
|
+
|
|
106
|
+
Requirements: Python 3.10+ on macOS, Linux, or Windows.
|
|
107
|
+
|
|
108
|
+
### Install from PyPI
|
|
109
|
+
|
|
110
|
+
The core CLI has no runtime dependencies beyond the standard library. Optional
|
|
111
|
+
extras pull in LLM backends and RDF export only when you need them:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
python -m pip install knowledge-worker # core CLI, stdlib only (mykg / mygraph)
|
|
115
|
+
python -m pip install "knowledge-worker[rdf]" # + Turtle/RDF export (rdflib)
|
|
116
|
+
python -m pip install "knowledge-worker[anthropic]" # + Claude-backed ingest
|
|
117
|
+
python -m pip install "knowledge-worker[openai]" # + OpenAI-backed ingest
|
|
118
|
+
python -m pip install "knowledge-worker[ollama]" # + local Ollama ingest
|
|
119
|
+
python -m pip install "knowledge-worker[all]" # all ingest backends + RDF
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Verify the install (no clone needed — `seed` generates its own demo graph):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
mykg --help
|
|
126
|
+
MYGRAPH_PATH=/tmp/knowledge-worker-demo.json mykg seed
|
|
127
|
+
MYGRAPH_PATH=/tmp/knowledge-worker-demo.json mykg summary
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Using a virtual environment avoids Homebrew/system Python's externally-managed
|
|
131
|
+
install errors:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
python3 -m venv .venv
|
|
135
|
+
source .venv/bin/activate
|
|
136
|
+
python -m pip install knowledge-worker
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Run from a clone (no install)
|
|
140
|
+
|
|
141
|
+
The core demo CLI uses only the standard library, so you can run it straight
|
|
142
|
+
from a checkout without installing anything:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
git clone https://github.com/rahulmranga/knowledge-worker
|
|
146
|
+
cd knowledge-worker
|
|
147
|
+
|
|
148
|
+
# Run the public demo graph, no API key needed
|
|
149
|
+
MYGRAPH_PATH=examples/demo_graph.json python3 mygraph/mygraph.py summary
|
|
150
|
+
MYGRAPH_PATH=examples/demo_graph.json python3 mygraph/mygraph.py query "provenance"
|
|
151
|
+
|
|
152
|
+
# Generate an LLM-ready context snapshot
|
|
153
|
+
MYGRAPH_PATH=examples/demo_graph.json python3 mygraph/mygraph.py context
|
|
154
|
+
|
|
155
|
+
# Audit memory structure and proof coverage
|
|
156
|
+
MYGRAPH_PATH=examples/demo_graph.json python3 mygraph/mygraph.py audit --out /tmp/analytics.json --html /tmp/memory_audit.html
|
|
157
|
+
|
|
158
|
+
# Visualize the graph as a self-contained HTML file
|
|
159
|
+
python3 mygraph/mygraph.py viz --graph examples/demo_graph.json --out /tmp/demo.html
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
For the shorter `mykg` command from a clone, install it editable inside a
|
|
163
|
+
virtual environment:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
python3 -m venv .venv
|
|
167
|
+
source .venv/bin/activate
|
|
168
|
+
python -m pip install -e .
|
|
169
|
+
MYGRAPH_PATH=examples/demo_graph.json mykg query provenance
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
On Windows PowerShell:
|
|
173
|
+
|
|
174
|
+
```powershell
|
|
175
|
+
py -3 -m venv .venv
|
|
176
|
+
.\.venv\Scripts\Activate.ps1
|
|
177
|
+
python -m pip install knowledge-worker
|
|
178
|
+
|
|
179
|
+
$env:MYGRAPH_PATH = "$env:TEMP\knowledge-worker-demo.json"
|
|
180
|
+
mykg seed
|
|
181
|
+
mykg summary
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
From a clone, install editable instead:
|
|
185
|
+
|
|
186
|
+
```powershell
|
|
187
|
+
python -m pip install -e .
|
|
188
|
+
|
|
189
|
+
$env:MYGRAPH_PATH = "examples\demo_graph.json"
|
|
190
|
+
mykg query provenance
|
|
191
|
+
mykg audit --out "$env:TEMP\analytics.json" --html "$env:TEMP\memory_audit.html"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
If PowerShell blocks activation scripts, run this for the current terminal
|
|
195
|
+
session and activate again:
|
|
196
|
+
|
|
197
|
+
```powershell
|
|
198
|
+
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
## Commands
|
|
203
|
+
|
|
204
|
+
| Command | What it does |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `seed` | Populate a fictional demo graph |
|
|
207
|
+
| `summary` | Show node and edge counts by type |
|
|
208
|
+
| `query <term>` | Search nodes, neighbors, and provenance |
|
|
209
|
+
| `list <type>` | List nodes of a given type |
|
|
210
|
+
| `path <a> <b>` | Find the shortest path between two nodes |
|
|
211
|
+
| `ingest <file.md>` | Extract, validate, review, merge, and eval candidates |
|
|
212
|
+
| `check --provenance` | Flag nodes with missing source citations |
|
|
213
|
+
| `export --ttl` | Emit Turtle/RDF |
|
|
214
|
+
| `context` | Print a compact LLM-ready context snapshot |
|
|
215
|
+
| `viz` | Generate an offline single-file HTML viewer |
|
|
216
|
+
| `audit` | Emit graph analytics, directed idea-flow queues, and optional Memory Audit HTML |
|
|
217
|
+
| `discover` | Propose derived edges and second-order insights (read-only, promotion queue) |
|
|
218
|
+
| `state "<entry>"` | Append a mood/state sidecar entry |
|
|
219
|
+
| `dump` | Print the raw graph JSON |
|
|
220
|
+
| `reset` | Delete the active graph file |
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
## Use Your Own Notes
|
|
224
|
+
|
|
225
|
+
You can ingest your notes with or without an API key.
|
|
226
|
+
|
|
227
|
+
### Claude or Codex App, No API Key
|
|
228
|
+
|
|
229
|
+
If you are already working with Claude, Codex, or ChatGPT in an app session, you do **not** need an API key. Ask the assistant to produce a `*.candidates.json` file that follows the schema in `mygraph/extractor.py`, then let the local CLI validate, review, and merge it. In Claude Code, the bundled [`/ingest-notes`](.claude/skills/ingest-notes/SKILL.md) skill runs this flow for you:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
python3 -m venv .venv
|
|
233
|
+
source .venv/bin/activate
|
|
234
|
+
python -m pip install -e .
|
|
235
|
+
|
|
236
|
+
mykg ingest path/to/your/notes.md --candidates-file path/to/your/notes.candidates.json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The app subscription helps you create the candidates file. The repo still keeps graph validation and merge local.
|
|
240
|
+
|
|
241
|
+
### Automated API-Backed Ingest
|
|
242
|
+
|
|
243
|
+
If you want the CLI to call an LLM directly, use a provider API key or local Ollama.
|
|
244
|
+
|
|
245
|
+
For Anthropic API:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
python3 -m venv .venv
|
|
249
|
+
source .venv/bin/activate
|
|
250
|
+
python -m pip install -e ".[anthropic]"
|
|
251
|
+
export ANTHROPIC_API_KEY=...
|
|
252
|
+
|
|
253
|
+
mykg ingest path/to/your/notes.md
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The Claude backend also auto-detects Anthropic-compatible provider env:
|
|
257
|
+
|
|
258
|
+
- Anthropic API: `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`
|
|
259
|
+
- Foundry: `ANTHROPIC_FOUNDRY_API_KEY` plus `ANTHROPIC_FOUNDRY_RESOURCE` or `ANTHROPIC_FOUNDRY_BASE_URL`
|
|
260
|
+
- Bedrock: `AWS_BEARER_TOKEN_BEDROCK`, or AWS credentials plus `AWS_REGION`/`AWS_DEFAULT_REGION`
|
|
261
|
+
|
|
262
|
+
For OpenAI API:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
python3 -m venv .venv
|
|
266
|
+
source .venv/bin/activate
|
|
267
|
+
python -m pip install -e ".[openai]"
|
|
268
|
+
export OPENAI_API_KEY=...
|
|
269
|
+
|
|
270
|
+
mykg ingest path/to/your/notes.md --backend openai --model gpt-5.2
|
|
271
|
+
```
|
|
272
|
+
## Graph Workflow
|
|
273
|
+
|
|
274
|
+
The public repo ships code, docs, and a fictional demo graph. Your real graph should live outside the repo or in the ignored default path, then be loaded explicitly:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
MYGRAPH_PATH=~/my-private-graph/mygraph.json mykg summary
|
|
278
|
+
MYGRAPH_PATH=~/my-private-graph/mygraph.json mykg query "architecture"
|
|
279
|
+
MYGRAPH_PATH=~/my-private-graph/mygraph.json mykg context
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Your private `mygraph.json`, generated private viewers, TTL exports, eval logs, state logs, and local env files are ignored by default.
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
## Memory Audit
|
|
286
|
+
|
|
287
|
+
`mykg audit` is a read-only layer over the graph. It ranks important concepts
|
|
288
|
+
with PageRank, bridge ideas with betweenness, structural strength with k-core,
|
|
289
|
+
communities with deterministic graph splitting, and weak claims from confidence
|
|
290
|
+
and provenance gaps. It also includes directed idea-flow queues:
|
|
291
|
+
`idea_attractors` for concepts that many edges point into, `idea_generators`
|
|
292
|
+
for ideas that branch outward, and a `weak_claim_queue` that asks for human
|
|
293
|
+
review actions instead of auto-promoting conclusions.
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
MYGRAPH_PATH=examples/demo_graph.json mykg audit \
|
|
297
|
+
--out /tmp/analytics.json \
|
|
298
|
+
--html /tmp/memory_audit.html
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The generated HTML puts ranked panels and legwork queues first, with the graph
|
|
302
|
+
canvas second. This keeps the feature focused on memory governance instead of
|
|
303
|
+
making the raw graph view the product.
|
|
304
|
+
|
|
305
|
+
## Discovery Layer
|
|
306
|
+
|
|
307
|
+
Where `audit` ranks what the graph already says, `mykg discover` infers what it
|
|
308
|
+
implies but does not yet say — and turns every inference into a reviewable
|
|
309
|
+
proposal:
|
|
310
|
+
|
|
311
|
+
- **Staleness radar**: important nodes whose evidence trail has gone cold,
|
|
312
|
+
scored by importance × days since the graph last touched them.
|
|
313
|
+
- **Co-mention candidates**: pairs that recur together across multiple sources
|
|
314
|
+
but were never linked (`CO_MENTIONED_WITH`).
|
|
315
|
+
- **Goal-alignment candidates**: ideas and decisions structurally entangled
|
|
316
|
+
with a goal they have no contribution path to (`SERVES_CANDIDATE`).
|
|
317
|
+
- **Link prediction**: Adamic-Adar over the semantic graph (`RELATES_TO`).
|
|
318
|
+
- **Question debt**: open questions ranked by age, centrality, and missing
|
|
319
|
+
evidence; answered questions are detected via decision `ABOUT` edges.
|
|
320
|
+
- **Corroboration**: claims that hang on a single source (`SINGLE_SOURCE`).
|
|
321
|
+
- **Bridge finder**: cross-community connectors that remain after removing
|
|
322
|
+
dominant hub "spines" that mask real bridges (`BRIDGES`).
|
|
323
|
+
- **Tension detector**: claims that are both supported and challenged, and
|
|
324
|
+
goal contributions that inherit a challenge to the goal (`TENSION_WITH`).
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
MYGRAPH_PATH=examples/demo_graph.json mykg discover \
|
|
328
|
+
--out /tmp/discovery.json \
|
|
329
|
+
--candidates /tmp/discovery.candidates.json
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Discover never mutates the graph. Derived edges land in a candidates file — a
|
|
333
|
+
promotion queue for human review. AI proposes, provenance verifies, the owner
|
|
334
|
+
promotes. Committed sample output: [`examples/demo_discovery.json`](examples/demo_discovery.json).
|
|
335
|
+
|
|
336
|
+
## Local LLM Support
|
|
337
|
+
|
|
338
|
+
The `ollama_proxy/` package adds three local-model surfaces:
|
|
339
|
+
|
|
340
|
+
- `server.py`: MCP wrapper for Claude/Cowork-style tool use.
|
|
341
|
+
- `proxy.py`: Ollama-compatible logging passthrough for HTTP clients.
|
|
342
|
+
- `extractor_adapter.py`: drop-in extraction backend for `mykg ingest --backend ollama`.
|
|
343
|
+
|
|
344
|
+
See [ollama_proxy/README.md](ollama_proxy/README.md) for setup.
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
## Repository Layout
|
|
348
|
+
|
|
349
|
+
```text
|
|
350
|
+
mygraph/ Core CLI and pipeline modules
|
|
351
|
+
examples/ Fictional demo graph, TTL, and HTML viewer
|
|
352
|
+
docs/ Roadmap and public assets
|
|
353
|
+
ollama_proxy/ Adapter, MCP server, and proxy for local Ollama workflows
|
|
354
|
+
tests/ CLI smoke tests
|
|
355
|
+
SPEC.md Graph model specification
|
|
356
|
+
DESIGN.md Pipeline design notes
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Contributing
|
|
360
|
+
|
|
361
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). The core graph model is intentionally minimal; contributions that preserve that shape are preferred.
|
|
362
|
+
|
|
363
|
+
## License
|
|
364
|
+
|
|
365
|
+
MIT
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
knowledge_worker-0.6.0.dist-info/licenses/LICENSE,sha256=s82QuDIzTdGH65Kf32Mkc2GuRCGnrK2FL_adxFN3vJQ,1071
|
|
2
|
+
mygraph/__init__.py,sha256=ptEn74xScDr6Uf6IA-iIh0D5txOWI22yiRBeMXRvbrc,468
|
|
3
|
+
mygraph/anthropic_client.py,sha256=NbvBkfhRrNzIjhcFCCHogSrIS47S0iyqk5RHxCIqivA,6098
|
|
4
|
+
mygraph/audit.py,sha256=RwBgQJzAEo_YBamslCtcaZvdp9Gdlc-n9B9HH0jlAPI,4352
|
|
5
|
+
mygraph/check.py,sha256=kDkW2V8oJsPEwdA8OVfYAIVz_e5eEQzlVtW99rZ-IyE,9725
|
|
6
|
+
mygraph/discover.py,sha256=wl9L9Gd9S5f26Ag8lcbcIYC8CzqPnHmiZj2FMqW-dJg,25700
|
|
7
|
+
mygraph/eval_log.py,sha256=yKtK2a6C7NGFu79MK5ZNgurY_ECjEO3k3_i-hjTtrBI,1029
|
|
8
|
+
mygraph/export_context.py,sha256=A6mVDg-NkYDJl2JA0VogLyj27Np_91XLu9Hl2cHY_fQ,4008
|
|
9
|
+
mygraph/extractor.py,sha256=btCms_kUk9-IAF-5OxtFAuA2Bm2okL99Si3rL9P7tYw,8746
|
|
10
|
+
mygraph/extractor_openai.py,sha256=vCTT68VGqgMsMDK0OqH_Z_kQZlpdp65Ypb4ZY0Rh-fI,5420
|
|
11
|
+
mygraph/ingest.py,sha256=hDFhwedYXQcMKQcAN2wtgd6tqJ73tvtwFbcR3CwGZL8,6994
|
|
12
|
+
mygraph/memory_audit.py,sha256=-H_dgGfZqbcbGn0Nv2Pci9nh-wONV_CE4AS7_vFYNuw,42877
|
|
13
|
+
mygraph/merge.py,sha256=x2MTLaOa_2X7ii8jwD5s6Wm3A9WhDdeOJ5PDJwdRdN4,5225
|
|
14
|
+
mygraph/mygraph.py,sha256=6XxZm2P0sqe0NPYhhaySbqwjCtDn8D-jqHFa2h516Ks,36680
|
|
15
|
+
mygraph/owl_io.py,sha256=dKDWbgqikirXvW0aA1SKfzT5u25tl94FWkSzn14XQWg,7949
|
|
16
|
+
mygraph/review.py,sha256=RtIb81whxSfZjGHUmph9i1TjocOFkOOlH3QupPb5Zq8,5499
|
|
17
|
+
mygraph/validator.py,sha256=dej2eQGMKYzrTUhJEfcQOmeWKOh6Yvvp6FSMGr0kkHI,5511
|
|
18
|
+
mygraph/viz.py,sha256=ipxlo4NtCcxUR5wlIF7nJrvG1nFVGXVwnr1dBWNA21c,17144
|
|
19
|
+
ollama_proxy/eval_compare.py,sha256=B7pTPn8KPnAWX8UDBFJ4umZMqWbg0rHI9H38wsr6jPU,7429
|
|
20
|
+
ollama_proxy/extractor_adapter.py,sha256=cqncBGnVnoWUALuDtnrIFR_6O0HQtrpDuf4KnJ7zma4,6026
|
|
21
|
+
ollama_proxy/proxy.py,sha256=PIsfzXk2k9tKk2J725tXPopYehCfet63CdaEBWLCofM,5551
|
|
22
|
+
ollama_proxy/server.py,sha256=WANSfjlIQBq5hWDLco3-xokZAGmsC3_zWDEJOmLmunE,6269
|
|
23
|
+
knowledge_worker-0.6.0.dist-info/METADATA,sha256=ZiVE28j8OEl-BP91meNfB51u2a2oysG7igvuE63Arx8,14452
|
|
24
|
+
knowledge_worker-0.6.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
25
|
+
knowledge_worker-0.6.0.dist-info/entry_points.txt,sha256=e0Y2M2JRv7j0TMlJmZr_5X2EFQWMih5sZeFhWoZbJI4,75
|
|
26
|
+
knowledge_worker-0.6.0.dist-info/top_level.txt,sha256=muCRp1A8_-S-D_FUxyrEG0ZmApFUYTuahl81Bajnst4,21
|
|
27
|
+
knowledge_worker-0.6.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rahul Rangarao
|
|
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.
|
mygraph/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Public package surface for the knowledge-worker graph toolkit."""
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"CONFIDENCE",
|
|
5
|
+
"DEFAULT_GRAPH_PATH",
|
|
6
|
+
"EDGE_TYPES",
|
|
7
|
+
"GRAPH_PATH",
|
|
8
|
+
"NODE_TYPES",
|
|
9
|
+
"Edge",
|
|
10
|
+
"Graph",
|
|
11
|
+
"Node",
|
|
12
|
+
"nid",
|
|
13
|
+
"resolve_graph_path",
|
|
14
|
+
"slug",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def __getattr__(name):
|
|
19
|
+
if name not in __all__:
|
|
20
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
21
|
+
from . import mygraph as _core
|
|
22
|
+
|
|
23
|
+
return getattr(_core, name)
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Anthropic client selection for mygraph LLM-bound commands.
|
|
3
|
+
|
|
4
|
+
The extractor and optional check probes support multiple Anthropic runtimes. Keep
|
|
5
|
+
provider detection in one place so Bedrock and Foundry env vars are treated as
|
|
6
|
+
valid Anthropic configuration, not as missing ANTHROPIC_API_KEY.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import shlex
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
_DOTENV_LOADED = False
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class AnthropicClientConfig:
|
|
23
|
+
provider: str
|
|
24
|
+
model: str
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def load_repo_env() -> None:
|
|
28
|
+
"""Load repo-local .env values without overriding the process environment."""
|
|
29
|
+
global _DOTENV_LOADED
|
|
30
|
+
if _DOTENV_LOADED:
|
|
31
|
+
return
|
|
32
|
+
_DOTENV_LOADED = True
|
|
33
|
+
|
|
34
|
+
candidates = [
|
|
35
|
+
Path.cwd() / ".env",
|
|
36
|
+
Path(__file__).resolve().parent.parent / ".env",
|
|
37
|
+
]
|
|
38
|
+
for env_path in candidates:
|
|
39
|
+
if not env_path.is_file():
|
|
40
|
+
continue
|
|
41
|
+
for raw_line in env_path.read_text(encoding="utf-8").splitlines():
|
|
42
|
+
line = raw_line.strip()
|
|
43
|
+
if not line or line.startswith("#"):
|
|
44
|
+
continue
|
|
45
|
+
if line.startswith("export "):
|
|
46
|
+
line = line[len("export "):].strip()
|
|
47
|
+
if "=" not in line:
|
|
48
|
+
continue
|
|
49
|
+
key, value = line.split("=", 1)
|
|
50
|
+
key = key.strip()
|
|
51
|
+
if not key or key in os.environ:
|
|
52
|
+
continue
|
|
53
|
+
os.environ[key] = _parse_env_value(value)
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _parse_env_value(value: str) -> str:
|
|
58
|
+
value = value.strip()
|
|
59
|
+
if not value:
|
|
60
|
+
return ""
|
|
61
|
+
try:
|
|
62
|
+
parsed = shlex.split(value, comments=False, posix=True)
|
|
63
|
+
except ValueError:
|
|
64
|
+
return value.strip("\"'")
|
|
65
|
+
if len(parsed) == 1:
|
|
66
|
+
return parsed[0]
|
|
67
|
+
return value.strip("\"'")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _configured_provider() -> str:
|
|
71
|
+
explicit = (
|
|
72
|
+
os.environ.get("MYGRAPH_ANTHROPIC_PROVIDER")
|
|
73
|
+
or os.environ.get("ANTHROPIC_PROVIDER")
|
|
74
|
+
or ""
|
|
75
|
+
).strip().lower()
|
|
76
|
+
aliases = {
|
|
77
|
+
"": "",
|
|
78
|
+
"auto": "",
|
|
79
|
+
"claude": "anthropic",
|
|
80
|
+
"default": "anthropic",
|
|
81
|
+
"native": "anthropic",
|
|
82
|
+
"anthropic": "anthropic",
|
|
83
|
+
"api": "anthropic",
|
|
84
|
+
"foundry": "foundry",
|
|
85
|
+
"azure": "foundry",
|
|
86
|
+
"azure-foundry": "foundry",
|
|
87
|
+
"bedrock": "bedrock",
|
|
88
|
+
"aws-bedrock": "bedrock",
|
|
89
|
+
"vertex": "vertex",
|
|
90
|
+
"google-vertex": "vertex",
|
|
91
|
+
}
|
|
92
|
+
if explicit not in aliases:
|
|
93
|
+
raise RuntimeError(
|
|
94
|
+
"unsupported Anthropic provider "
|
|
95
|
+
f"{explicit!r}; expected anthropic, foundry, bedrock, vertex, or auto"
|
|
96
|
+
)
|
|
97
|
+
provider = aliases[explicit]
|
|
98
|
+
if provider:
|
|
99
|
+
return provider
|
|
100
|
+
|
|
101
|
+
foundry_env = (
|
|
102
|
+
"ANTHROPIC_FOUNDRY_API_KEY",
|
|
103
|
+
"ANTHROPIC_FOUNDRY_RESOURCE",
|
|
104
|
+
"ANTHROPIC_FOUNDRY_BASE_URL",
|
|
105
|
+
)
|
|
106
|
+
if any(os.environ.get(name) for name in foundry_env):
|
|
107
|
+
return "foundry"
|
|
108
|
+
|
|
109
|
+
bedrock_specific_env = (
|
|
110
|
+
"AWS_BEARER_TOKEN_BEDROCK",
|
|
111
|
+
"ANTHROPIC_BEDROCK_BASE_URL",
|
|
112
|
+
)
|
|
113
|
+
if any(os.environ.get(name) for name in bedrock_specific_env):
|
|
114
|
+
return "bedrock"
|
|
115
|
+
|
|
116
|
+
anthropic_env = (
|
|
117
|
+
"ANTHROPIC_API_KEY",
|
|
118
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
119
|
+
"ANTHROPIC_PROFILE",
|
|
120
|
+
"ANTHROPIC_BASE_URL",
|
|
121
|
+
"ANTHROPIC_IDENTITY_TOKEN",
|
|
122
|
+
"ANTHROPIC_IDENTITY_TOKEN_FILE",
|
|
123
|
+
)
|
|
124
|
+
if any(os.environ.get(name) for name in anthropic_env):
|
|
125
|
+
return "anthropic"
|
|
126
|
+
|
|
127
|
+
vertex_env = (
|
|
128
|
+
"CLOUD_ML_REGION",
|
|
129
|
+
"ANTHROPIC_VERTEX_BASE_URL",
|
|
130
|
+
"GOOGLE_APPLICATION_CREDENTIALS",
|
|
131
|
+
)
|
|
132
|
+
if any(os.environ.get(name) for name in vertex_env):
|
|
133
|
+
return "vertex"
|
|
134
|
+
|
|
135
|
+
has_aws_region = bool(os.environ.get("AWS_REGION") or os.environ.get("AWS_DEFAULT_REGION"))
|
|
136
|
+
has_aws_auth = bool(
|
|
137
|
+
os.environ.get("AWS_PROFILE")
|
|
138
|
+
or (os.environ.get("AWS_ACCESS_KEY_ID") and os.environ.get("AWS_SECRET_ACCESS_KEY"))
|
|
139
|
+
)
|
|
140
|
+
if has_aws_region and has_aws_auth:
|
|
141
|
+
return "bedrock"
|
|
142
|
+
|
|
143
|
+
return ""
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _bedrock_kwargs() -> dict[str, str]:
|
|
147
|
+
if os.environ.get("AWS_PROFILE"):
|
|
148
|
+
return {"aws_profile": os.environ["AWS_PROFILE"]}
|
|
149
|
+
if os.environ.get("AWS_ACCESS_KEY_ID") and os.environ.get("AWS_SECRET_ACCESS_KEY"):
|
|
150
|
+
kwargs = {
|
|
151
|
+
"aws_access_key": os.environ["AWS_ACCESS_KEY_ID"],
|
|
152
|
+
"aws_secret_key": os.environ["AWS_SECRET_ACCESS_KEY"],
|
|
153
|
+
}
|
|
154
|
+
if os.environ.get("AWS_SESSION_TOKEN"):
|
|
155
|
+
kwargs["aws_session_token"] = os.environ["AWS_SESSION_TOKEN"]
|
|
156
|
+
return kwargs
|
|
157
|
+
return {}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def anthropic_configured() -> bool:
|
|
161
|
+
load_repo_env()
|
|
162
|
+
return bool(_configured_provider())
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def get_anthropic_client() -> tuple[Any, AnthropicClientConfig]:
|
|
166
|
+
"""Return a configured Anthropic-compatible client and its resolved config."""
|
|
167
|
+
load_repo_env()
|
|
168
|
+
try:
|
|
169
|
+
import anthropic # type: ignore
|
|
170
|
+
except ImportError as e:
|
|
171
|
+
raise RuntimeError(
|
|
172
|
+
"the `anthropic` package is not installed. Run: pip install anthropic"
|
|
173
|
+
) from e
|
|
174
|
+
|
|
175
|
+
provider = _configured_provider()
|
|
176
|
+
if not provider:
|
|
177
|
+
raise RuntimeError(
|
|
178
|
+
"no Anthropic provider configuration found. Set one of:\n"
|
|
179
|
+
" - ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN\n"
|
|
180
|
+
" - ANTHROPIC_FOUNDRY_API_KEY plus ANTHROPIC_FOUNDRY_RESOURCE or ANTHROPIC_FOUNDRY_BASE_URL\n"
|
|
181
|
+
" - AWS_BEARER_TOKEN_BEDROCK or AWS credentials plus AWS_REGION/AWS_DEFAULT_REGION"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
if provider == "foundry":
|
|
186
|
+
client = anthropic.AnthropicFoundry()
|
|
187
|
+
elif provider == "bedrock":
|
|
188
|
+
client = anthropic.AnthropicBedrock(**_bedrock_kwargs())
|
|
189
|
+
elif provider == "vertex":
|
|
190
|
+
client = anthropic.AnthropicVertex()
|
|
191
|
+
else:
|
|
192
|
+
client = anthropic.Anthropic()
|
|
193
|
+
except Exception as e:
|
|
194
|
+
raise RuntimeError(
|
|
195
|
+
f"failed to construct Anthropic {provider} client from environment: {e}"
|
|
196
|
+
) from e
|
|
197
|
+
|
|
198
|
+
model = os.environ.get("MYGRAPH_MODEL", "claude-sonnet-4-6")
|
|
199
|
+
return client, AnthropicClientConfig(provider=provider, model=model)
|