kweaver-sdk 0.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 (68) hide show
  1. kweaver_sdk-0.4.0/.gitignore +22 -0
  2. kweaver_sdk-0.4.0/Makefile +25 -0
  3. kweaver_sdk-0.4.0/PKG-INFO +14 -0
  4. kweaver_sdk-0.4.0/README.md +207 -0
  5. kweaver_sdk-0.4.0/README.zh.md +207 -0
  6. kweaver_sdk-0.4.0/pyproject.toml +65 -0
  7. kweaver_sdk-0.4.0/src/kweaver/__init__.py +302 -0
  8. kweaver_sdk-0.4.0/src/kweaver/_auth.py +516 -0
  9. kweaver_sdk-0.4.0/src/kweaver/_client.py +84 -0
  10. kweaver_sdk-0.4.0/src/kweaver/_crypto.py +44 -0
  11. kweaver_sdk-0.4.0/src/kweaver/_errors.py +112 -0
  12. kweaver_sdk-0.4.0/src/kweaver/_http.py +185 -0
  13. kweaver_sdk-0.4.0/src/kweaver/cli/__init__.py +1 -0
  14. kweaver_sdk-0.4.0/src/kweaver/cli/_helpers.py +69 -0
  15. kweaver_sdk-0.4.0/src/kweaver/cli/action.py +82 -0
  16. kweaver_sdk-0.4.0/src/kweaver/cli/agent.py +98 -0
  17. kweaver_sdk-0.4.0/src/kweaver/cli/auth.py +106 -0
  18. kweaver_sdk-0.4.0/src/kweaver/cli/call.py +72 -0
  19. kweaver_sdk-0.4.0/src/kweaver/cli/context_loader.py +272 -0
  20. kweaver_sdk-0.4.0/src/kweaver/cli/ds.py +105 -0
  21. kweaver_sdk-0.4.0/src/kweaver/cli/kn.py +356 -0
  22. kweaver_sdk-0.4.0/src/kweaver/cli/main.py +40 -0
  23. kweaver_sdk-0.4.0/src/kweaver/cli/query.py +92 -0
  24. kweaver_sdk-0.4.0/src/kweaver/cli/token.py +27 -0
  25. kweaver_sdk-0.4.0/src/kweaver/config/__init__.py +3 -0
  26. kweaver_sdk-0.4.0/src/kweaver/config/store.py +248 -0
  27. kweaver_sdk-0.4.0/src/kweaver/resources/__init__.py +15 -0
  28. kweaver_sdk-0.4.0/src/kweaver/resources/action_types.py +108 -0
  29. kweaver_sdk-0.4.0/src/kweaver/resources/agents.py +109 -0
  30. kweaver_sdk-0.4.0/src/kweaver/resources/context_loader.py +301 -0
  31. kweaver_sdk-0.4.0/src/kweaver/resources/conversations.py +252 -0
  32. kweaver_sdk-0.4.0/src/kweaver/resources/datasources.py +211 -0
  33. kweaver_sdk-0.4.0/src/kweaver/resources/dataviews.py +214 -0
  34. kweaver_sdk-0.4.0/src/kweaver/resources/knowledge_networks.py +182 -0
  35. kweaver_sdk-0.4.0/src/kweaver/resources/object_types.py +152 -0
  36. kweaver_sdk-0.4.0/src/kweaver/resources/query.py +147 -0
  37. kweaver_sdk-0.4.0/src/kweaver/resources/relation_types.py +122 -0
  38. kweaver_sdk-0.4.0/src/kweaver/types.py +315 -0
  39. kweaver_sdk-0.4.0/tests/__init__.py +0 -0
  40. kweaver_sdk-0.4.0/tests/conftest.py +57 -0
  41. kweaver_sdk-0.4.0/tests/e2e/__init__.py +0 -0
  42. kweaver_sdk-0.4.0/tests/e2e/conftest.py +276 -0
  43. kweaver_sdk-0.4.0/tests/e2e/test_agents_e2e.py +89 -0
  44. kweaver_sdk-0.4.0/tests/e2e/test_build_e2e.py +111 -0
  45. kweaver_sdk-0.4.0/tests/e2e/test_context_loader_e2e.py +64 -0
  46. kweaver_sdk-0.4.0/tests/e2e/test_datasource_e2e.py +44 -0
  47. kweaver_sdk-0.4.0/tests/e2e/test_full_flow_e2e.py +103 -0
  48. kweaver_sdk-0.4.0/tests/e2e/test_query_e2e.py +97 -0
  49. kweaver_sdk-0.4.0/tests/run_tests.sh +56 -0
  50. kweaver_sdk-0.4.0/tests/unit/__init__.py +0 -0
  51. kweaver_sdk-0.4.0/tests/unit/test_action_types.py +75 -0
  52. kweaver_sdk-0.4.0/tests/unit/test_agents.py +125 -0
  53. kweaver_sdk-0.4.0/tests/unit/test_auth.py +15 -0
  54. kweaver_sdk-0.4.0/tests/unit/test_cli.py +1015 -0
  55. kweaver_sdk-0.4.0/tests/unit/test_config_auth.py +55 -0
  56. kweaver_sdk-0.4.0/tests/unit/test_config_store.py +128 -0
  57. kweaver_sdk-0.4.0/tests/unit/test_context_loader.py +325 -0
  58. kweaver_sdk-0.4.0/tests/unit/test_conversations.py +148 -0
  59. kweaver_sdk-0.4.0/tests/unit/test_datasources.py +93 -0
  60. kweaver_sdk-0.4.0/tests/unit/test_dataviews.py +90 -0
  61. kweaver_sdk-0.4.0/tests/unit/test_errors.py +72 -0
  62. kweaver_sdk-0.4.0/tests/unit/test_http.py +86 -0
  63. kweaver_sdk-0.4.0/tests/unit/test_knowledge_networks.py +77 -0
  64. kweaver_sdk-0.4.0/tests/unit/test_object_types.py +116 -0
  65. kweaver_sdk-0.4.0/tests/unit/test_query.py +100 -0
  66. kweaver_sdk-0.4.0/tests/unit/test_relation_types.py +61 -0
  67. kweaver_sdk-0.4.0/tests/unit/test_top_level_api.py +351 -0
  68. kweaver_sdk-0.4.0/uv.lock +790 -0
@@ -0,0 +1,22 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .pytest_cache/
10
+ .venv/
11
+ venv/
12
+ .env
13
+ .env.*
14
+ !.env.example
15
+ .coverage
16
+ test-result/
17
+ .worktrees/
18
+ node_modules/
19
+ *.tgz
20
+ .DS_Store
21
+ .ralph/
22
+ coverage/
@@ -0,0 +1,25 @@
1
+ .PHONY: test test-cover test-e2e lint ci
2
+
3
+ # UT: unit tests only, full mock, no external deps, < 60s
4
+ test:
5
+ uv run pytest tests/unit/ -q
6
+
7
+ # test-cover: UT + coverage report, output to test-result/
8
+ test-cover:
9
+ @mkdir -p test-result
10
+ uv run pytest tests/unit/ \
11
+ --cov=src/kweaver \
12
+ --cov-report=term-missing \
13
+ --cov-report=xml:test-result/coverage.xml \
14
+ -q
15
+
16
+ # test-e2e: full e2e suite (requires live KWeaver + DB env vars in ~/.env.secrets)
17
+ test-e2e:
18
+ uv run pytest tests/e2e/ -v --run-destructive
19
+
20
+ # lint: static type check
21
+ lint:
22
+ uv run python -m py_compile $$(find src/kweaver -name "*.py" | tr '\n' ' ')
23
+
24
+ # ci: lint + test-cover
25
+ ci: lint test-cover
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: kweaver-sdk
3
+ Version: 0.4.0
4
+ Summary: KWeaver Python SDK — CLI and client library for knowledge network construction and querying
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: cryptography>=42.0
7
+ Requires-Dist: httpx>=0.27
8
+ Requires-Dist: pydantic>=2.0
9
+ Provides-Extra: cli
10
+ Requires-Dist: click>=8.0; extra == 'cli'
11
+ Provides-Extra: dev
12
+ Requires-Dist: click>=8.0; extra == 'dev'
13
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
14
+ Requires-Dist: pytest>=8.0; extra == 'dev'
@@ -0,0 +1,207 @@
1
+ # KWeaver Python SDK
2
+
3
+ A clean Python interface for accessing KWeaver BKN (Business Knowledge Network) and Decision Agents.
4
+
5
+ [中文文档](README.zh.md)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install kweaver-sdk
11
+ ```
12
+
13
+ Requires **Python >= 3.10**.
14
+
15
+ ## Quick Start
16
+
17
+ ### Scenario 1: Read-only queries (connect to an existing BKN)
18
+
19
+ Use this mode when you only need to search or chat with an agent against an existing BKN. **No need to call `weaver()`.**
20
+
21
+ ```python
22
+ import kweaver
23
+
24
+ kweaver.configure(
25
+ url="https://kweaver.example.com",
26
+ token="my-token",
27
+ bkn_id="supply-chain-bkn-id",
28
+ agent_id="supply-chain-agent-id",
29
+ )
30
+
31
+ # Semantic search over the BKN
32
+ results = kweaver.search("What are the key risks in the supply chain?")
33
+ for concept in results.concepts:
34
+ print(concept.concept_name, concept.rerank_score)
35
+
36
+ # Chat with an agent
37
+ reply = kweaver.chat("Analyse the inventory risks for this year")
38
+ print(reply.content)
39
+
40
+ # Streaming output
41
+ for chunk in kweaver.chat("Generate a risk report", stream=True):
42
+ print(chunk.delta, end="", flush=True)
43
+ ```
44
+
45
+ ---
46
+
47
+ ### Scenario 2: Write data then rebuild the index
48
+
49
+ After connecting new datasources or adding object/relation types, call `weaver()` to rebuild the BKN index so changes become searchable by agents.
50
+
51
+ ```python
52
+ import kweaver
53
+ from kweaver import KWeaverClient, TokenAuth
54
+
55
+ kweaver.configure(
56
+ url="https://kweaver.example.com",
57
+ token="my-token",
58
+ bkn_id="supply-chain-bkn-id",
59
+ )
60
+
61
+ # Use the low-level client for write operations
62
+ client = kweaver._default_client
63
+ client.datasources.create(name="erp_db", type="mysql", ...)
64
+ client.object_types.create(bkn_id="supply-chain-bkn-id", ...)
65
+
66
+ # Trigger a full BKN build after writes (default timeout: 300s)
67
+ kweaver.weaver(wait=True)
68
+ print("BKN build complete — ready to search")
69
+
70
+ # Now search the newly indexed data
71
+ results = kweaver.search("Which suppliers are in the newly imported ERP data?")
72
+ ```
73
+
74
+ Async (non-blocking) build:
75
+
76
+ ```python
77
+ job = kweaver.weaver() # Returns a BuildJob immediately
78
+ status = job.poll() # Poll manually
79
+ print(status.state) # "running" / "completed" / "failed"
80
+
81
+ # Or wait later
82
+ status = job.wait(timeout=600)
83
+ ```
84
+
85
+ ---
86
+
87
+ ### Scenario 3: Manage multiple BKNs
88
+
89
+ When operating on multiple BKNs simultaneously, pass `bkn_id` explicitly to each call:
90
+
91
+ ```python
92
+ import kweaver
93
+
94
+ kweaver.configure(
95
+ url="https://kweaver.example.com",
96
+ token="my-token",
97
+ )
98
+
99
+ # List all BKNs
100
+ for bkn in kweaver.bkns():
101
+ print(bkn.id, bkn.name)
102
+
103
+ # Search different BKNs
104
+ results_sc = kweaver.search("inventory alert", bkn_id="supply-chain-bkn-id")
105
+ results_hr = kweaver.search("employee turnover", bkn_id="hr-bkn-id")
106
+
107
+ # Rebuild specific BKNs
108
+ kweaver.weaver(bkn_id="supply-chain-bkn-id", wait=True)
109
+ kweaver.weaver(bkn_id="hr-bkn-id", wait=True)
110
+ ```
111
+
112
+ ---
113
+
114
+ ### Scenario 4: Browse agents
115
+
116
+ ```python
117
+ import kweaver
118
+
119
+ kweaver.configure(url="https://kweaver.example.com", token="my-token")
120
+
121
+ # List all published agents
122
+ for agent in kweaver.agents(status="published"):
123
+ print(f"{agent.name} (id={agent.id}, bkn={agent.kn_ids})")
124
+
125
+ # Multi-turn conversation with a specific agent
126
+ conv_id = ""
127
+ for question in ["What can you do?", "Analyse recent inventory data", "Give improvement suggestions"]:
128
+ reply = kweaver.chat(question, agent_id="supply-chain-agent-id", conversation_id=conv_id)
129
+ conv_id = reply.conversation_id
130
+ print(f"Q: {question}")
131
+ print(f"A: {reply.content}\n")
132
+ ```
133
+
134
+ ---
135
+
136
+ ## API Reference
137
+
138
+ ### `kweaver.configure(url, *, token, bkn_id, agent_id, ...)`
139
+
140
+ Initialises the default client. Must be called before any other function.
141
+
142
+ | Parameter | Description |
143
+ |---|---|
144
+ | `url` | KWeaver service URL |
145
+ | `token` | Bearer token (recommended) |
146
+ | `username` / `password` | Username/password login (requires Playwright) |
147
+ | `config` | Load credentials from the local config file (`~/.kweaver/`) |
148
+ | `bkn_id` | Default BKN ID used by `search()` and `weaver()` |
149
+ | `agent_id` | Default Agent ID used by `chat()` |
150
+
151
+ ### `kweaver.search(query, *, bkn_id, mode, max_concepts)`
152
+
153
+ Semantic search over a BKN. Returns `SemanticSearchResult`.
154
+
155
+ ### `kweaver.chat(message, *, agent_id, stream, conversation_id)`
156
+
157
+ Send a message to an agent. Returns `Message` (or `Iterator[MessageChunk]` when `stream=True`).
158
+
159
+ ### `kweaver.weaver(*, bkn_id, wait, timeout)`
160
+
161
+ Trigger a full BKN build / index rebuild. **Only needed after write operations** — read-only use cases do not require this. Returns `BuildJob`.
162
+
163
+ ### `kweaver.agents(*, keyword, status, limit)`
164
+
165
+ List agents. Returns `list[Agent]`.
166
+
167
+ ### `kweaver.bkns(*, name, limit)`
168
+
169
+ List BKNs. Returns `list[KnowledgeNetwork]`.
170
+
171
+ ---
172
+
173
+ ## Low-level Client
174
+
175
+ The top-level API covers the most common operations. For full access (datasources, object types, relation types, actions, etc.), use the low-level client directly:
176
+
177
+ ```python
178
+ import kweaver
179
+
180
+ kweaver.configure(url="...", token="...")
181
+ client = kweaver._default_client # KWeaverClient instance
182
+
183
+ # Full API
184
+ client.datasources.list(bkn_id="...")
185
+ client.object_types.list(bkn_id="...")
186
+ client.action_types.execute(bkn_id="...", action_type_id="...")
187
+ ```
188
+
189
+ Or instantiate directly:
190
+
191
+ ```python
192
+ from kweaver import KWeaverClient, TokenAuth
193
+
194
+ client = KWeaverClient(
195
+ base_url="https://kweaver.example.com",
196
+ auth=TokenAuth("my-token"),
197
+ )
198
+ ```
199
+
200
+ ## Links
201
+
202
+ - [GitHub](https://github.com/kweaver-ai/kweaver-sdk)
203
+ - [TypeScript SDK on npm](https://www.npmjs.com/package/@kweaver-ai/kweaver-sdk)
204
+
205
+ ## License
206
+
207
+ MIT
@@ -0,0 +1,207 @@
1
+ # KWeaver Python SDK
2
+
3
+ 简洁的 Python 接口,用于访问 KWeaver BKN(Business Knowledge Network)和 Decision Agent。
4
+
5
+ [English](README.md)
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ pip install kweaver-sdk
11
+ ```
12
+
13
+ 需要 **Python >= 3.10**。
14
+
15
+ ## 快速上手
16
+
17
+ ### 场景一:只读查询(直连 BKN,无需构建)
18
+
19
+ 已有 BKN,只需搜索或与 Agent 对话时使用此模式。**不需要调用 `weaver()`。**
20
+
21
+ ```python
22
+ import kweaver
23
+
24
+ kweaver.configure(
25
+ url="https://kweaver.example.com",
26
+ token="my-token",
27
+ bkn_id="supply-chain-bkn-id",
28
+ agent_id="supply-chain-agent-id",
29
+ )
30
+
31
+ # 语义搜索 BKN
32
+ results = kweaver.search("供应链有哪些关键风险?")
33
+ for concept in results.concepts:
34
+ print(concept.concept_name, concept.rerank_score)
35
+
36
+ # 与 Agent 对话
37
+ reply = kweaver.chat("帮我分析一下今年的库存风险")
38
+ print(reply.content)
39
+
40
+ # 流式输出
41
+ for chunk in kweaver.chat("给我生成一份风险报告", stream=True):
42
+ print(chunk.delta, end="", flush=True)
43
+ ```
44
+
45
+ ---
46
+
47
+ ### 场景二:写入数据源后构建索引
48
+
49
+ 接入了新数据源、新增了对象类或关系类之后,需要调用 `weaver()` 重建 BKN 索引,才能让变更生效并被 Agent 检索到。
50
+
51
+ ```python
52
+ import kweaver
53
+ from kweaver import KWeaverClient, TokenAuth
54
+
55
+ kweaver.configure(
56
+ url="https://kweaver.example.com",
57
+ token="my-token",
58
+ bkn_id="supply-chain-bkn-id",
59
+ )
60
+
61
+ # 通过底层客户端做写操作(如接入数据源、定义对象类等)
62
+ client = kweaver._default_client
63
+ client.datasources.create(name="erp_db", type="mysql", ...)
64
+ client.object_types.create(bkn_id="supply-chain-bkn-id", ...)
65
+
66
+ # 写操作完成后,触发 BKN 全量构建(默认超时 300s)
67
+ kweaver.weaver(wait=True)
68
+ print("BKN 构建完成,可以开始搜索")
69
+
70
+ # 构建完成后即可搜索
71
+ results = kweaver.search("新接入的 ERP 数据中有哪些供应商?")
72
+ ```
73
+
74
+ 异步触发(不阻塞):
75
+
76
+ ```python
77
+ job = kweaver.weaver() # 立即返回 BuildJob
78
+ status = job.poll() # 手动轮询
79
+ print(status.state) # "running" / "completed" / "failed"
80
+
81
+ # 或稍后等待
82
+ status = job.wait(timeout=600)
83
+ ```
84
+
85
+ ---
86
+
87
+ ### 场景三:管理多个 BKN
88
+
89
+ 需要同时操作多个 BKN 时,在各函数中显式指定 `bkn_id`:
90
+
91
+ ```python
92
+ import kweaver
93
+
94
+ kweaver.configure(
95
+ url="https://kweaver.example.com",
96
+ token="my-token",
97
+ )
98
+
99
+ # 列出所有 BKN
100
+ for bkn in kweaver.bkns():
101
+ print(bkn.id, bkn.name)
102
+
103
+ # 分别搜索不同 BKN
104
+ results_sc = kweaver.search("库存预警", bkn_id="supply-chain-bkn-id")
105
+ results_hr = kweaver.search("员工离职率", bkn_id="hr-bkn-id")
106
+
107
+ # 对指定 BKN 触发构建
108
+ kweaver.weaver(bkn_id="supply-chain-bkn-id", wait=True)
109
+ kweaver.weaver(bkn_id="hr-bkn-id", wait=True)
110
+ ```
111
+
112
+ ---
113
+
114
+ ### 场景四:浏览 Agent
115
+
116
+ ```python
117
+ import kweaver
118
+
119
+ kweaver.configure(url="https://kweaver.example.com", token="my-token")
120
+
121
+ # 列出所有已发布的 Agent
122
+ for agent in kweaver.agents(status="published"):
123
+ print(f"{agent.name} (id={agent.id}, bkn={agent.kn_ids})")
124
+
125
+ # 与指定 Agent 多轮对话
126
+ conv_id = ""
127
+ for question in ["你能做什么?", "分析最近的库存数据", "给出改进建议"]:
128
+ reply = kweaver.chat(question, agent_id="supply-chain-agent-id", conversation_id=conv_id)
129
+ conv_id = reply.conversation_id
130
+ print(f"Q: {question}")
131
+ print(f"A: {reply.content}\n")
132
+ ```
133
+
134
+ ---
135
+
136
+ ## API 参考
137
+
138
+ ### `kweaver.configure(url, *, token, bkn_id, agent_id, ...)`
139
+
140
+ 初始化默认客户端。所有其他函数都需要先调用此函数。
141
+
142
+ | 参数 | 说明 |
143
+ |---|---|
144
+ | `url` | KWeaver 服务地址 |
145
+ | `token` | Bearer Token(推荐) |
146
+ | `username` / `password` | 用户名密码登录(需要 Playwright) |
147
+ | `config` | 使用本地配置文件中的凭证(`~/.kweaver/`) |
148
+ | `bkn_id` | 默认 BKN ID,供 `search()` 和 `weaver()` 使用 |
149
+ | `agent_id` | 默认 Agent ID,供 `chat()` 使用 |
150
+
151
+ ### `kweaver.search(query, *, bkn_id, mode, max_concepts)`
152
+
153
+ 对 BKN 做语义搜索,返回 `SemanticSearchResult`。
154
+
155
+ ### `kweaver.chat(message, *, agent_id, stream, conversation_id)`
156
+
157
+ 向 Agent 发送消息,返回 `Message`(或 `Iterator[MessageChunk]` 当 `stream=True`)。
158
+
159
+ ### `kweaver.weaver(*, bkn_id, wait, timeout)`
160
+
161
+ 触发 BKN 全量构建/重建索引。**只在写操作后需要调用**,纯只读场景无需调用。返回 `BuildJob`。
162
+
163
+ ### `kweaver.agents(*, keyword, status, limit)`
164
+
165
+ 列出 Agent,返回 `list[Agent]`。
166
+
167
+ ### `kweaver.bkns(*, name, limit)`
168
+
169
+ 列出 BKN,返回 `list[KnowledgeNetwork]`。
170
+
171
+ ---
172
+
173
+ ## 底层客户端
174
+
175
+ 顶层 API 封装了最常用的操作。如需访问完整功能(数据源、对象类、关系类、Action 等),直接使用底层客户端:
176
+
177
+ ```python
178
+ import kweaver
179
+
180
+ kweaver.configure(url="...", token="...")
181
+ client = kweaver._default_client # KWeaverClient 实例
182
+
183
+ # 完整 API
184
+ client.datasources.list(bkn_id="...")
185
+ client.object_types.list(bkn_id="...")
186
+ client.action_types.execute(bkn_id="...", action_type_id="...")
187
+ ```
188
+
189
+ 或直接实例化:
190
+
191
+ ```python
192
+ from kweaver import KWeaverClient, TokenAuth
193
+
194
+ client = KWeaverClient(
195
+ base_url="https://kweaver.example.com",
196
+ auth=TokenAuth("my-token"),
197
+ )
198
+ ```
199
+
200
+ ## 相关链接
201
+
202
+ - [GitHub](https://github.com/kweaver-ai/kweaver-sdk)
203
+ - [TypeScript SDK on npm](https://www.npmjs.com/package/@kweaver-ai/kweaver-sdk)
204
+
205
+ ## 许可证
206
+
207
+ MIT
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "kweaver-sdk"
7
+ version = "0.4.0"
8
+ description = "KWeaver Python SDK — CLI and client library for knowledge network construction and querying"
9
+ requires-python = ">=3.10"
10
+ dependencies = [
11
+ "httpx>=0.27",
12
+ "pydantic>=2.0",
13
+ "cryptography>=42.0",
14
+ ]
15
+
16
+ [project.optional-dependencies]
17
+ cli = [
18
+ "click>=8.0",
19
+ ]
20
+ dev = [
21
+ "pytest>=8.0",
22
+ "pytest-cov>=5.0",
23
+ "click>=8.0",
24
+ ]
25
+
26
+ [project.scripts]
27
+ kweaver = "kweaver.cli.main:main"
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["src/kweaver"]
31
+
32
+ [tool.pytest.ini_options]
33
+ testpaths = ["tests"]
34
+ pythonpath = ["src"]
35
+ markers = [
36
+ "e2e: end-to-end tests against a live KWeaver instance",
37
+ "destructive: tests that mutate KWeaver state (create/build/delete KN)",
38
+ ]
39
+ # Default: only run unit + integration; e2e requires explicit opt-in
40
+ addopts = "--ignore=tests/e2e"
41
+
42
+ # ═══════════════════════════════════════════════════════════════════════════
43
+ # Coverage
44
+ # ═══════════════════════════════════════════════════════════════════════════
45
+ [tool.coverage.run]
46
+ source = ["src/kweaver"]
47
+ omit = [
48
+ "*/tests/*",
49
+ "*/test_*",
50
+ ]
51
+ branch = true
52
+
53
+ [tool.coverage.report]
54
+ fail_under = 65
55
+ exclude_lines = [
56
+ "pragma: no cover",
57
+ "if TYPE_CHECKING:",
58
+ "raise NotImplementedError",
59
+ "\\.\\.\\.",
60
+ ]
61
+
62
+ [dependency-groups]
63
+ dev = [
64
+ "playwright>=1.58.0",
65
+ ]