codeer-cli 0.1.2__py3-none-any.whl → 0.1.3__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.
- codeer_cli/commands/kb.py +28 -2
- codeer_cli/kb.py +8 -4
- {codeer_cli-0.1.2.dist-info → codeer_cli-0.1.3.dist-info}/METADATA +5 -3
- {codeer_cli-0.1.2.dist-info → codeer_cli-0.1.3.dist-info}/RECORD +6 -6
- {codeer_cli-0.1.2.dist-info → codeer_cli-0.1.3.dist-info}/WHEEL +0 -0
- {codeer_cli-0.1.2.dist-info → codeer_cli-0.1.3.dist-info}/entry_points.txt +0 -0
codeer_cli/commands/kb.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import argparse
|
|
3
4
|
import json
|
|
4
5
|
import time
|
|
5
6
|
from pathlib import Path
|
|
@@ -106,6 +107,8 @@ def register(subparsers):
|
|
|
106
107
|
p.add_argument("--context-object-id", type=int, required=True,
|
|
107
108
|
help="KB file snapshot_object_id from `codeer kb files`")
|
|
108
109
|
p.add_argument("--question", required=True)
|
|
110
|
+
p.add_argument("--range", dest="ranges", action="append", type=_parse_faq_range, default=None,
|
|
111
|
+
help="Reserve matching chunks that overlap START_LINE:END_LINE; repeatable")
|
|
109
112
|
p.add_argument("--dry-run", action="store_true",
|
|
110
113
|
help="Print intended request without writing server state.")
|
|
111
114
|
p.add_argument("--out", default=None, help="Write result JSON to this file too")
|
|
@@ -116,6 +119,8 @@ def register(subparsers):
|
|
|
116
119
|
p.add_argument("--context-object-id", type=int, default=None,
|
|
117
120
|
help="Move FAQ to a different KB file snapshot_object_id")
|
|
118
121
|
p.add_argument("--question", default=None)
|
|
122
|
+
p.add_argument("--range", dest="ranges", action="append", type=_parse_faq_range, default=None,
|
|
123
|
+
help="Replace reserved ranges with START_LINE:END_LINE; repeatable")
|
|
119
124
|
p.add_argument("--dry-run", action="store_true",
|
|
120
125
|
help="Print intended request without writing server state.")
|
|
121
126
|
p.add_argument("--out", default=None, help="Write result JSON to this file too")
|
|
@@ -195,6 +200,7 @@ def _faq_summary(faq: dict) -> dict:
|
|
|
195
200
|
"id": faq.get("id"),
|
|
196
201
|
"context_object_id": faq.get("context_object_id"),
|
|
197
202
|
"question": faq.get("question"),
|
|
203
|
+
"ranges": faq.get("ranges") or [],
|
|
198
204
|
"has_question_embedding": faq.get("has_question_embedding"),
|
|
199
205
|
"updated_at": faq.get("updated_at"),
|
|
200
206
|
}
|
|
@@ -211,6 +217,20 @@ def _dry_run(path: str | None, result: dict) -> int:
|
|
|
211
217
|
return 0
|
|
212
218
|
|
|
213
219
|
|
|
220
|
+
def _parse_faq_range(value: str) -> dict[str, int]:
|
|
221
|
+
try:
|
|
222
|
+
start_raw, end_raw = value.split(":", 1)
|
|
223
|
+
start_line = int(start_raw)
|
|
224
|
+
end_line = int(end_raw)
|
|
225
|
+
except ValueError as exc:
|
|
226
|
+
raise argparse.ArgumentTypeError("expected START_LINE:END_LINE") from exc
|
|
227
|
+
if start_line < 1 or end_line < 1:
|
|
228
|
+
raise argparse.ArgumentTypeError("line numbers must be >= 1")
|
|
229
|
+
if end_line < start_line:
|
|
230
|
+
raise argparse.ArgumentTypeError("END_LINE must be >= START_LINE")
|
|
231
|
+
return {"start_line": start_line, "end_line": end_line}
|
|
232
|
+
|
|
233
|
+
|
|
214
234
|
def _parse_config_json(config_json: str | None) -> dict | None:
|
|
215
235
|
if not config_json:
|
|
216
236
|
return None
|
|
@@ -384,6 +404,8 @@ def run_faq_get(args, client) -> int:
|
|
|
384
404
|
|
|
385
405
|
def run_faq_create(args, client) -> int:
|
|
386
406
|
body = {"context_object_id": args.context_object_id, "question": args.question}
|
|
407
|
+
if args.ranges is not None:
|
|
408
|
+
body["ranges"] = args.ranges
|
|
387
409
|
if args.dry_run:
|
|
388
410
|
return _dry_run(
|
|
389
411
|
args.out,
|
|
@@ -403,6 +425,7 @@ def run_faq_create(args, client) -> int:
|
|
|
403
425
|
client,
|
|
404
426
|
context_object_id=args.context_object_id,
|
|
405
427
|
question=args.question,
|
|
428
|
+
ranges=args.ranges,
|
|
406
429
|
)
|
|
407
430
|
)
|
|
408
431
|
_print_and_write(args.out, faq)
|
|
@@ -410,8 +433,8 @@ def run_faq_create(args, client) -> int:
|
|
|
410
433
|
|
|
411
434
|
|
|
412
435
|
def run_faq_update(args, client) -> int:
|
|
413
|
-
if args.context_object_id is None and args.question is None:
|
|
414
|
-
log("error: provide --context-object-id or --
|
|
436
|
+
if args.context_object_id is None and args.question is None and args.ranges is None:
|
|
437
|
+
log("error: provide --context-object-id, --question, or --range")
|
|
415
438
|
return 2
|
|
416
439
|
|
|
417
440
|
body: dict[str, object] = {}
|
|
@@ -419,6 +442,8 @@ def run_faq_update(args, client) -> int:
|
|
|
419
442
|
body["context_object_id"] = args.context_object_id
|
|
420
443
|
if args.question is not None:
|
|
421
444
|
body["question"] = args.question
|
|
445
|
+
if args.ranges is not None:
|
|
446
|
+
body["ranges"] = args.ranges
|
|
422
447
|
|
|
423
448
|
if args.dry_run:
|
|
424
449
|
return _dry_run(
|
|
@@ -440,6 +465,7 @@ def run_faq_update(args, client) -> int:
|
|
|
440
465
|
faq_id=args.faq_id,
|
|
441
466
|
context_object_id=args.context_object_id,
|
|
442
467
|
question=args.question,
|
|
468
|
+
ranges=args.ranges,
|
|
443
469
|
)
|
|
444
470
|
)
|
|
445
471
|
_print_and_write(args.out, faq)
|
codeer_cli/kb.py
CHANGED
|
@@ -252,11 +252,12 @@ def create_context_obj_faq(
|
|
|
252
252
|
*,
|
|
253
253
|
context_object_id: int,
|
|
254
254
|
question: str,
|
|
255
|
+
ranges: Optional[list[dict[str, int]]] = None,
|
|
255
256
|
) -> dict:
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
)
|
|
257
|
+
body: dict[str, Any] = {"context_object_id": context_object_id, "question": question}
|
|
258
|
+
if ranges is not None:
|
|
259
|
+
body["ranges"] = ranges
|
|
260
|
+
return client.post(_faq_base(), json=body)
|
|
260
261
|
|
|
261
262
|
|
|
262
263
|
def update_context_obj_faq(
|
|
@@ -265,12 +266,15 @@ def update_context_obj_faq(
|
|
|
265
266
|
faq_id: int,
|
|
266
267
|
context_object_id: Optional[int] = None,
|
|
267
268
|
question: Optional[str] = None,
|
|
269
|
+
ranges: Optional[list[dict[str, int]]] = None,
|
|
268
270
|
) -> dict:
|
|
269
271
|
body: dict[str, Any] = {}
|
|
270
272
|
if context_object_id is not None:
|
|
271
273
|
body["context_object_id"] = context_object_id
|
|
272
274
|
if question is not None:
|
|
273
275
|
body["question"] = question
|
|
276
|
+
if ranges is not None:
|
|
277
|
+
body["ranges"] = ranges
|
|
274
278
|
return client.patch(f"{_faq_base()}/{faq_id}", json=body)
|
|
275
279
|
|
|
276
280
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeer-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Command line tools for managing Codeer agents over the Codeer API.
|
|
5
5
|
Project-URL: Homepage, https://www.codeer.ai
|
|
6
6
|
Author: Codeer.AI
|
|
@@ -184,12 +184,14 @@ override matching JSON keys.
|
|
|
184
184
|
|
|
185
185
|
Use Context Object FAQ entries to route high-value questions to a canonical KB
|
|
186
186
|
file when semantic retrieval misses the right source. The FAQ target is a KB
|
|
187
|
-
file's `snapshot_object_id`, shown by `codeer kb files`.
|
|
187
|
+
file's `snapshot_object_id`, shown by `codeer kb files`. Add `--range
|
|
188
|
+
START_LINE:END_LINE` when the route should reserve chunks overlapping a stable
|
|
189
|
+
line range inside that file.
|
|
188
190
|
|
|
189
191
|
```bash
|
|
190
192
|
codeer kb files --kb-id <kb-id>
|
|
191
193
|
codeer kb faq-list --context-object-id <snapshot-object-id>
|
|
192
|
-
codeer kb faq-create --context-object-id <snapshot-object-id> --question "..." --dry-run
|
|
194
|
+
codeer kb faq-create --context-object-id <snapshot-object-id> --question "..." --range 12:18 --dry-run
|
|
193
195
|
```
|
|
194
196
|
|
|
195
197
|
After reviewing the dry-run output, rerun the create/update/delete command
|
|
@@ -7,7 +7,7 @@ codeer_cli/client.py,sha256=LpHVqf1IYNg1wFfIHnO9q4xg2h3IiGOitzCnvwB-Bcw,9809
|
|
|
7
7
|
codeer_cli/constants.py,sha256=D1pV3wCoqYybrKGKeoupYjjFWLfaFviKp1yL7oh6Qso,2323
|
|
8
8
|
codeer_cli/eval_.py,sha256=EsH8f8nT8x9MFlUhpHWSAU4aNPkNceD-Tw5GM15Ae1I,14157
|
|
9
9
|
codeer_cli/histories.py,sha256=tk28git_peX4x703CIDU8u72JtlGaytyrtlHfxlK-7A,5979
|
|
10
|
-
codeer_cli/kb.py,sha256
|
|
10
|
+
codeer_cli/kb.py,sha256=--0MvZJ2OsIbzLh-4TQ-wR7dVK42eaXw-L0qDGFOaxg,10417
|
|
11
11
|
codeer_cli/parse.py,sha256=qrjZn0MUTjGfucp4cwxy8Pt7WS-0x15kK5F7kWTY8Ps,21818
|
|
12
12
|
codeer_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
codeer_cli/commands/_util.py,sha256=VOB_HMWYzHFNY1ElLOED1HB6fpFpsniqH6Yx3VUlMrY,1644
|
|
@@ -15,9 +15,9 @@ codeer_cli/commands/agent.py,sha256=amvfVVrbPOkbYKCGvA6EJB30C-aY6WSdfR7u7FklXbs,
|
|
|
15
15
|
codeer_cli/commands/check.py,sha256=lTxolx1mIJ8jldPhJ5FXqie9nbCLVOO-sDPOHTSy1-w,3817
|
|
16
16
|
codeer_cli/commands/eval_cmd.py,sha256=yvqjPXMOE7V0Hv53iEW5HvIo610dgiIG4BpKGWzZY4I,46965
|
|
17
17
|
codeer_cli/commands/history.py,sha256=Jv7t0GhSZcbZ8OuIXZT34CixXt7ECEVP3nZ-WW_Ya9E,12026
|
|
18
|
-
codeer_cli/commands/kb.py,sha256=
|
|
18
|
+
codeer_cli/commands/kb.py,sha256=vXwgiGHYrLywm3O41-D__7m3d1uZUcw3YYuxKH-08i0,24528
|
|
19
19
|
codeer_cli/commands/profile.py,sha256=IdlXC_6cqobsfN3JRrAnt-1OgBUsIFneS9QtR4Un6Kc,6521
|
|
20
|
-
codeer_cli-0.1.
|
|
21
|
-
codeer_cli-0.1.
|
|
22
|
-
codeer_cli-0.1.
|
|
23
|
-
codeer_cli-0.1.
|
|
20
|
+
codeer_cli-0.1.3.dist-info/METADATA,sha256=lI76CTicsBTRGXZStaOs6I5kK98Pwf7-PV3XtIlxFsA,5291
|
|
21
|
+
codeer_cli-0.1.3.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
22
|
+
codeer_cli-0.1.3.dist-info/entry_points.txt,sha256=-nXIrlm5SR5r7gg3y8AS0tN66MwmvNHsrlwLNQNGD50,47
|
|
23
|
+
codeer_cli-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|