kader 0.1.5__py3-none-any.whl → 1.0.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.
- cli/app.py +98 -61
- cli/app.tcss +27 -382
- cli/utils.py +1 -6
- cli/widgets/conversation.py +50 -4
- kader/__init__.py +2 -0
- kader/agent/agents.py +8 -0
- kader/agent/base.py +68 -5
- kader/memory/types.py +60 -0
- kader/prompts/__init__.py +9 -1
- kader/prompts/agent_prompts.py +28 -0
- kader/prompts/templates/executor_agent.j2 +70 -0
- kader/prompts/templates/kader_planner.j2 +71 -0
- kader/providers/ollama.py +2 -2
- kader/tools/__init__.py +26 -0
- kader/tools/agent.py +452 -0
- kader/tools/filesys.py +1 -1
- kader/tools/todo.py +43 -2
- kader/utils/__init__.py +10 -0
- kader/utils/checkpointer.py +371 -0
- kader/utils/context_aggregator.py +347 -0
- kader/workflows/__init__.py +13 -0
- kader/workflows/base.py +71 -0
- kader/workflows/planner_executor.py +251 -0
- {kader-0.1.5.dist-info → kader-1.0.0.dist-info}/METADATA +38 -1
- {kader-0.1.5.dist-info → kader-1.0.0.dist-info}/RECORD +27 -18
- {kader-0.1.5.dist-info → kader-1.0.0.dist-info}/WHEEL +0 -0
- {kader-0.1.5.dist-info → kader-1.0.0.dist-info}/entry_points.txt +0 -0
cli/app.tcss
CHANGED
|
@@ -132,6 +132,26 @@ ConversationView {
|
|
|
132
132
|
scrollbar-size: 1 1;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
.message-footer {
|
|
136
|
+
height: auto;
|
|
137
|
+
margin-top: 0;
|
|
138
|
+
padding: 0 1;
|
|
139
|
+
border-top: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.footer-left {
|
|
143
|
+
color: $secondary;
|
|
144
|
+
text-style: italic;
|
|
145
|
+
width: 1fr;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.footer-right {
|
|
149
|
+
color: $success;
|
|
150
|
+
text-style: bold;
|
|
151
|
+
text-align: right;
|
|
152
|
+
width: auto;
|
|
153
|
+
}
|
|
154
|
+
|
|
135
155
|
/* ===== Welcome Message ===== */
|
|
136
156
|
|
|
137
157
|
#welcome {
|
|
@@ -274,391 +294,16 @@ ScrollbarSlider:hover {
|
|
|
274
294
|
color: $secondary;
|
|
275
295
|
}
|
|
276
296
|
|
|
277
|
-
/* =====
|
|
278
|
-
|
|
279
|
-
/* Ocean Theme */
|
|
280
|
-
.theme-ocean Screen {
|
|
281
|
-
background: #0f172a;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
.theme-ocean Header {
|
|
285
|
-
background: #3b82f6;
|
|
286
|
-
color: #f1f5f9;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
.theme-ocean Footer {
|
|
290
|
-
background: #1e293b;
|
|
291
|
-
color: #94a3b8;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
.theme-ocean FooterKey > .footer-key--key {
|
|
295
|
-
background: #3b82f6;
|
|
296
|
-
color: #f1f5f9;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
.theme-ocean #sidebar {
|
|
300
|
-
background: #1e293b;
|
|
301
|
-
border-right: thick #3b82f6;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
.theme-ocean #sidebar-title {
|
|
305
|
-
background: #3b82f6 20%;
|
|
306
|
-
color: #f1f5f9;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.theme-ocean DirectoryTree > .directory-tree--folder {
|
|
310
|
-
color: #06b6d4;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.theme-ocean DirectoryTree > .directory-tree--file {
|
|
314
|
-
color: #f1f5f9;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
.theme-ocean DirectoryTree > .directory-tree--extension {
|
|
318
|
-
color: #94a3b8;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
.theme-ocean DirectoryTree:focus > .directory-tree--cursor {
|
|
322
|
-
background: #3b82f6 40%;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
.theme-ocean #conversation {
|
|
326
|
-
background: #0f172a;
|
|
327
|
-
border-bottom: thick #1e293b;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
.theme-ocean #input-container {
|
|
331
|
-
background: #1e293b;
|
|
332
|
-
border-top: thick #3b82f6;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
.theme-ocean #prompt-input {
|
|
336
|
-
background: #0f172a;
|
|
337
|
-
border: round #3b82f6;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
.theme-ocean #prompt-input:focus {
|
|
341
|
-
border: round #06b6d4;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
.theme-ocean Input.-valid {
|
|
345
|
-
border: round #10b981;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
.theme-ocean Input > .input--placeholder {
|
|
349
|
-
color: #94a3b8;
|
|
350
|
-
text-style: italic;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
.theme-ocean LoadingSpinner {
|
|
354
|
-
background: #1e293b;
|
|
355
|
-
border-left: thick #f59e0b;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
.theme-ocean #command-hints {
|
|
359
|
-
background: #1e293b;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
.theme-ocean .command-hint {
|
|
363
|
-
color: #94a3b8;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
.theme-ocean .command-key {
|
|
367
|
-
color: #3b82f6;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
.theme-ocean MarkdownH1 {
|
|
371
|
-
color: #3b82f6;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
.theme-ocean MarkdownH2 {
|
|
375
|
-
color: #06b6d4;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
.theme-ocean MarkdownH3 {
|
|
379
|
-
color: #10b981;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
.theme-ocean MarkdownFence {
|
|
383
|
-
background: #1e293b;
|
|
384
|
-
border: round #94a3b8;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
.theme-ocean MarkdownBlockQuote {
|
|
388
|
-
background: #3b82f6 10%;
|
|
389
|
-
border-left: thick #3b82f6;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
.theme-ocean MarkdownTH {
|
|
393
|
-
background: #3b82f6 20%;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
.theme-ocean Scrollbar {
|
|
397
|
-
background: #1e293b;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
.theme-ocean ScrollbarSlider {
|
|
401
|
-
color: #3b82f6;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
.theme-ocean ScrollbarSlider:hover {
|
|
405
|
-
color: #06b6d4;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/* Forest Theme */
|
|
409
|
-
.theme-forest Screen {
|
|
410
|
-
background: #0d1f0d;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
.theme-forest Header {
|
|
414
|
-
background: #16a34a;
|
|
415
|
-
color: #dcfce7;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
.theme-forest Footer {
|
|
419
|
-
background: #0f2f0f;
|
|
420
|
-
color: #6ee7b7;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
.theme-forest FooterKey > .footer-key--key {
|
|
424
|
-
background: #16a34a;
|
|
425
|
-
color: #dcfce7;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
.theme-forest #sidebar {
|
|
429
|
-
background: #0f2f0f;
|
|
430
|
-
border-right: thick #16a34a;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
.theme-forest #sidebar-title {
|
|
434
|
-
background: #16a34a 20%;
|
|
435
|
-
color: #dcfce7;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
.theme-forest DirectoryTree > .directory-tree--folder {
|
|
439
|
-
color: #0891b2;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
.theme-forest DirectoryTree > .directory-tree--file {
|
|
443
|
-
color: #dcfce7;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
.theme-forest DirectoryTree > .directory-tree--extension {
|
|
447
|
-
color: #6ee7b7;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
.theme-forest DirectoryTree:focus > .directory-tree--cursor {
|
|
451
|
-
background: #16a34a 40%;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
.theme-forest #conversation {
|
|
455
|
-
background: #0d1f0d;
|
|
456
|
-
border-bottom: thick #0f2f0f;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
.theme-forest #input-container {
|
|
460
|
-
background: #0f2f0f;
|
|
461
|
-
border-top: thick #16a34a;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
.theme-forest #prompt-input {
|
|
465
|
-
background: #0d1f0d;
|
|
466
|
-
border: round #16a34a;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
.theme-forest #prompt-input:focus {
|
|
470
|
-
border: round #0891b2;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
.theme-forest Input.-valid {
|
|
474
|
-
border: round #22c55e;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
.theme-forest Input > .input--placeholder {
|
|
478
|
-
color: #6ee7b7;
|
|
479
|
-
text-style: italic;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.theme-forest LoadingSpinner {
|
|
483
|
-
background: #0f2f0f;
|
|
484
|
-
border-left: thick #eab308;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
.theme-forest #command-hints {
|
|
488
|
-
background: #0f2f0f;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
.theme-forest .command-hint {
|
|
492
|
-
color: #6ee7b7;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
.theme-forest .command-key {
|
|
496
|
-
color: #16a34a;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
.theme-forest MarkdownH1 {
|
|
500
|
-
color: #16a34a;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
.theme-forest MarkdownH2 {
|
|
504
|
-
color: #0891b2;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
.theme-forest MarkdownH3 {
|
|
508
|
-
color: #22c55e;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
.theme-forest MarkdownFence {
|
|
512
|
-
background: #0f2f0f;
|
|
513
|
-
border: round #6ee7b7;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
.theme-forest MarkdownBlockQuote {
|
|
517
|
-
background: #16a34a 10%;
|
|
518
|
-
border-left: thick #16a34a;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
.theme-forest MarkdownTH {
|
|
522
|
-
background: #16a34a 20%;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
.theme-forest Scrollbar {
|
|
526
|
-
background: #0f2f0f;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
.theme-forest ScrollbarSlider {
|
|
530
|
-
color: #16a34a;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
.theme-forest ScrollbarSlider:hover {
|
|
534
|
-
color: #0891b2;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/* Sunset Theme */
|
|
538
|
-
.theme-sunset Screen {
|
|
539
|
-
background: #1f1315;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
.theme-sunset Header {
|
|
543
|
-
background: #dc2626;
|
|
544
|
-
color: #fef2f2;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
.theme-sunset Footer {
|
|
548
|
-
background: #2f171a;
|
|
549
|
-
color: #fecaca;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
.theme-sunset FooterKey > .footer-key--key {
|
|
553
|
-
background: #dc2626;
|
|
554
|
-
color: #fef2f2;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
.theme-sunset #sidebar {
|
|
558
|
-
background: #2f171a;
|
|
559
|
-
border-right: thick #dc2626;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
.theme-sunset #sidebar-title {
|
|
563
|
-
background: #dc2626 20%;
|
|
564
|
-
color: #fef2f2;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
.theme-sunset DirectoryTree > .directory-tree--folder {
|
|
568
|
-
color: #ea580c;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
.theme-sunset DirectoryTree > .directory-tree--file {
|
|
572
|
-
color: #fef2f2;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
.theme-sunset DirectoryTree > .directory-tree--extension {
|
|
576
|
-
color: #fecaca;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
.theme-sunset DirectoryTree:focus > .directory-tree--cursor {
|
|
580
|
-
background: #dc2626 40%;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
.theme-sunset #conversation {
|
|
584
|
-
background: #1f1315;
|
|
585
|
-
border-bottom: thick #2f171a;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
.theme-sunset #input-container {
|
|
589
|
-
background: #2f171a;
|
|
590
|
-
border-top: thick #dc2626;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
.theme-sunset #prompt-input {
|
|
594
|
-
background: #1f1315;
|
|
595
|
-
border: round #dc2626;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
.theme-sunset #prompt-input:focus {
|
|
599
|
-
border: round #ea580c;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
.theme-sunset Input.-valid {
|
|
603
|
-
border: round #16a34a;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
.theme-sunset Input > .input--placeholder {
|
|
607
|
-
color: #fecaca;
|
|
608
|
-
text-style: italic;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
.theme-sunset LoadingSpinner {
|
|
612
|
-
background: #2f171a;
|
|
613
|
-
border-left: thick #eab308;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
.theme-sunset #command-hints {
|
|
617
|
-
background: #2f171a;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
.theme-sunset .command-hint {
|
|
621
|
-
color: #fecaca;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
.theme-sunset .command-key {
|
|
625
|
-
color: #dc2626;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
.theme-sunset MarkdownH1 {
|
|
629
|
-
color: #dc2626;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
.theme-sunset MarkdownH2 {
|
|
633
|
-
color: #ea580c;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
.theme-sunset MarkdownH3 {
|
|
637
|
-
color: #16a34a;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
.theme-sunset MarkdownFence {
|
|
641
|
-
background: #2f171a;
|
|
642
|
-
border: round #fecaca;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
.theme-sunset MarkdownBlockQuote {
|
|
646
|
-
background: #dc2626 10%;
|
|
647
|
-
border-left: thick #dc2626;
|
|
648
|
-
}
|
|
297
|
+
/* ===== Scrollbars ===== */
|
|
649
298
|
|
|
650
|
-
|
|
651
|
-
background:
|
|
299
|
+
Scrollbar {
|
|
300
|
+
background: $surface;
|
|
652
301
|
}
|
|
653
302
|
|
|
654
|
-
|
|
655
|
-
|
|
303
|
+
ScrollbarSlider {
|
|
304
|
+
color: $primary;
|
|
656
305
|
}
|
|
657
306
|
|
|
658
|
-
|
|
659
|
-
color:
|
|
307
|
+
ScrollbarSlider:hover {
|
|
308
|
+
color: $secondary;
|
|
660
309
|
}
|
|
661
|
-
|
|
662
|
-
.theme-sunset ScrollbarSlider:hover {
|
|
663
|
-
color: #ea580c;
|
|
664
|
-
}
|
cli/utils.py
CHANGED
|
@@ -2,18 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
from kader.providers import OllamaProvider
|
|
4
4
|
|
|
5
|
-
# Theme names for cycling
|
|
6
|
-
THEME_NAMES = ["dark", "ocean", "forest", "sunset"]
|
|
7
|
-
|
|
8
5
|
# Default model
|
|
9
|
-
DEFAULT_MODEL = "
|
|
6
|
+
DEFAULT_MODEL = "kimi-k2.5:cloud"
|
|
10
7
|
|
|
11
8
|
HELP_TEXT = """## Kader CLI Commands
|
|
12
9
|
|
|
13
10
|
| Command | Description |
|
|
14
11
|
|---------|-------------|
|
|
15
12
|
| `/models` | Show available LLM models |
|
|
16
|
-
| `/theme` | Cycle through color themes |
|
|
17
13
|
| `/help` | Show this help message |
|
|
18
14
|
| `/clear` | Clear the conversation |
|
|
19
15
|
| `/save` | Save current session |
|
|
@@ -28,7 +24,6 @@ HELP_TEXT = """## Kader CLI Commands
|
|
|
28
24
|
| Shortcut | Action |
|
|
29
25
|
|----------|--------|
|
|
30
26
|
| `Ctrl+L` | Clear conversation |
|
|
31
|
-
| `Ctrl+T` | Cycle theme |
|
|
32
27
|
| `Ctrl+S` | Save session |
|
|
33
28
|
| `Ctrl+R` | Refresh file tree |
|
|
34
29
|
| `Ctrl+Q` | Quit |
|
cli/widgets/conversation.py
CHANGED
|
@@ -1,23 +1,43 @@
|
|
|
1
1
|
"""Conversation display widget for Kader CLI."""
|
|
2
2
|
|
|
3
3
|
from textual.app import ComposeResult
|
|
4
|
-
from textual.containers import VerticalScroll
|
|
4
|
+
from textual.containers import Horizontal, VerticalScroll
|
|
5
5
|
from textual.widgets import Markdown, Static
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Message(Static):
|
|
9
9
|
"""A single message in the conversation."""
|
|
10
10
|
|
|
11
|
-
def __init__(
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
content: str,
|
|
14
|
+
role: str = "user",
|
|
15
|
+
model_name: str | None = None,
|
|
16
|
+
usage_cost: float | None = None,
|
|
17
|
+
) -> None:
|
|
12
18
|
super().__init__()
|
|
13
19
|
self.content = content
|
|
14
20
|
self.role = role
|
|
21
|
+
self.model_name = model_name
|
|
22
|
+
self.usage_cost = usage_cost
|
|
15
23
|
self.add_class(f"message-{role}")
|
|
16
24
|
|
|
17
25
|
def compose(self) -> ComposeResult:
|
|
18
26
|
prefix = "(**) **You:**" if self.role == "user" else "(^^) **Kader:**"
|
|
19
27
|
yield Markdown(f"{prefix}\n\n{self.content}")
|
|
20
28
|
|
|
29
|
+
if self.role == "assistant" and (
|
|
30
|
+
self.model_name or self.usage_cost is not None
|
|
31
|
+
):
|
|
32
|
+
with Horizontal(classes="message-footer"):
|
|
33
|
+
model_label = f"[*] {self.model_name}" if self.model_name else ""
|
|
34
|
+
yield Static(model_label, classes="footer-left")
|
|
35
|
+
|
|
36
|
+
usage_label = (
|
|
37
|
+
f"($) {self.usage_cost:.6f}" if self.usage_cost is not None else ""
|
|
38
|
+
)
|
|
39
|
+
yield Static(usage_label, classes="footer-right")
|
|
40
|
+
|
|
21
41
|
|
|
22
42
|
class ConversationView(VerticalScroll):
|
|
23
43
|
"""Scrollable conversation history with markdown rendering."""
|
|
@@ -41,11 +61,37 @@ class ConversationView(VerticalScroll):
|
|
|
41
61
|
background: $surface-darken-1;
|
|
42
62
|
border-left: thick $success;
|
|
43
63
|
}
|
|
64
|
+
|
|
65
|
+
.message-footer {
|
|
66
|
+
height: auto;
|
|
67
|
+
margin-top: 0;
|
|
68
|
+
padding: 0 1;
|
|
69
|
+
border-top: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.footer-left {
|
|
73
|
+
color: $secondary;
|
|
74
|
+
text-style: italic;
|
|
75
|
+
width: 1fr;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.footer-right {
|
|
79
|
+
color: $success;
|
|
80
|
+
text-style: bold;
|
|
81
|
+
text-align: right;
|
|
82
|
+
width: auto;
|
|
83
|
+
}
|
|
44
84
|
"""
|
|
45
85
|
|
|
46
|
-
def add_message(
|
|
86
|
+
def add_message(
|
|
87
|
+
self,
|
|
88
|
+
content: str,
|
|
89
|
+
role: str = "user",
|
|
90
|
+
model_name: str | None = None,
|
|
91
|
+
usage_cost: float | None = None,
|
|
92
|
+
) -> None:
|
|
47
93
|
"""Add a message to the conversation."""
|
|
48
|
-
message = Message(content, role)
|
|
94
|
+
message = Message(content, role, model_name, usage_cost)
|
|
49
95
|
self.mount(message)
|
|
50
96
|
self.scroll_end(animate=True)
|
|
51
97
|
|
kader/__init__.py
CHANGED
|
@@ -8,6 +8,7 @@ creating the .kader directory in the user's home directory.
|
|
|
8
8
|
from .config import ENV_FILE_PATH, KADER_DIR, initialize_kader_config
|
|
9
9
|
from .providers import * # noqa: F401, F403
|
|
10
10
|
from .tools import * # noqa: F401, F403
|
|
11
|
+
from .utils import Checkpointer
|
|
11
12
|
|
|
12
13
|
# Initialize the configuration when the module is imported
|
|
13
14
|
initialize_kader_config()
|
|
@@ -18,5 +19,6 @@ __all__ = [
|
|
|
18
19
|
"KADER_DIR",
|
|
19
20
|
"ENV_FILE_PATH",
|
|
20
21
|
"initialize_kader_config",
|
|
22
|
+
"Checkpointer",
|
|
21
23
|
# Export everything from providers and tools
|
|
22
24
|
]
|
kader/agent/agents.py
CHANGED
|
@@ -31,6 +31,8 @@ class ReActAgent(BaseAgent):
|
|
|
31
31
|
use_persistence: bool = False,
|
|
32
32
|
interrupt_before_tool: bool = True,
|
|
33
33
|
tool_confirmation_callback: Optional[callable] = None,
|
|
34
|
+
direct_execution_callback: Optional[callable] = None,
|
|
35
|
+
tool_execution_result_callback: Optional[callable] = None,
|
|
34
36
|
) -> None:
|
|
35
37
|
# Resolve tools for prompt context if necessary
|
|
36
38
|
# The base agent handles tool registration, but for the prompt template
|
|
@@ -67,6 +69,8 @@ class ReActAgent(BaseAgent):
|
|
|
67
69
|
use_persistence=use_persistence,
|
|
68
70
|
interrupt_before_tool=interrupt_before_tool,
|
|
69
71
|
tool_confirmation_callback=tool_confirmation_callback,
|
|
72
|
+
direct_execution_callback=direct_execution_callback,
|
|
73
|
+
tool_execution_result_callback=tool_execution_result_callback,
|
|
70
74
|
)
|
|
71
75
|
|
|
72
76
|
|
|
@@ -90,6 +94,8 @@ class PlanningAgent(BaseAgent):
|
|
|
90
94
|
use_persistence: bool = False,
|
|
91
95
|
interrupt_before_tool: bool = True,
|
|
92
96
|
tool_confirmation_callback: Optional[callable] = None,
|
|
97
|
+
direct_execution_callback: Optional[callable] = None,
|
|
98
|
+
tool_execution_result_callback: Optional[callable] = None,
|
|
93
99
|
) -> None:
|
|
94
100
|
# Ensure TodoTool is available
|
|
95
101
|
_todo_tool = TodoTool()
|
|
@@ -123,4 +129,6 @@ class PlanningAgent(BaseAgent):
|
|
|
123
129
|
use_persistence=use_persistence,
|
|
124
130
|
interrupt_before_tool=interrupt_before_tool,
|
|
125
131
|
tool_confirmation_callback=tool_confirmation_callback,
|
|
132
|
+
direct_execution_callback=direct_execution_callback,
|
|
133
|
+
tool_execution_result_callback=tool_execution_result_callback,
|
|
126
134
|
)
|