taskforceai-cli 0.6.4 → 0.10.0
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.
- package/bin/taskforceai-bin +0 -0
- package/bin/taskforceai.js +1 -1
- package/go.mod +19 -29
- package/go.sum +52 -48
- package/package.json +1 -1
- package/scripts/install.js +0 -1
- package/pkg/cli/benchmark.go +0 -37
- package/pkg/cli/benchmark_test.go +0 -47
- package/pkg/cli/make_it_heavy.go +0 -71
- package/pkg/cli/make_it_heavy_test.go +0 -153
- package/pkg/cli/orchestrator_cli.go +0 -250
- package/pkg/cli/orchestrator_cli_test.go +0 -400
- package/pkg/cli/shared_test.go +0 -28
package/bin/taskforceai-bin
CHANGED
|
Binary file
|
package/bin/taskforceai.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
4
5
|
import { join } from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { existsSync } from 'node:fs';
|
|
7
7
|
|
|
8
8
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
9
9
|
const binPath = join(__dirname, 'taskforceai-bin');
|
package/go.mod
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
module github.com/TaskForceAI/cli
|
|
2
2
|
|
|
3
|
-
go 1.25
|
|
3
|
+
go 1.25
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
replace github.com/TaskForceAI/infrastructure-llm => ../infrastructure-llm
|
|
8
|
-
|
|
9
|
-
replace github.com/TaskForceAI/infrastructure-search => ../infrastructure-search
|
|
10
|
-
|
|
11
|
-
replace github.com/TaskForceAI/shared => ../shared
|
|
5
|
+
toolchain go1.25.4
|
|
12
6
|
|
|
13
7
|
require (
|
|
14
|
-
github.com/TaskForceAI/core v0.0.0-00010101000000-000000000000
|
|
15
8
|
github.com/blang/semver v3.5.1+incompatible
|
|
16
9
|
github.com/charmbracelet/bubbles v0.21.0
|
|
17
10
|
github.com/charmbracelet/bubbletea v1.3.10
|
|
@@ -19,47 +12,44 @@ require (
|
|
|
19
12
|
github.com/getsentry/sentry-go v0.40.0
|
|
20
13
|
github.com/rhysd/go-github-selfupdate v1.2.3
|
|
21
14
|
github.com/sahilm/fuzzy v0.1.1
|
|
22
|
-
github.com/stretchr/testify v1.11.1
|
|
23
15
|
golang.org/x/oauth2 v0.34.0
|
|
24
16
|
modernc.org/sqlite v1.42.2
|
|
25
17
|
)
|
|
26
18
|
|
|
27
19
|
require (
|
|
28
|
-
github.com/TaskForceAI/shared v0.0.0 // indirect
|
|
29
20
|
github.com/atotto/clipboard v0.1.4 // indirect
|
|
30
21
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
|
31
|
-
github.com/charmbracelet/colorprofile v0.
|
|
32
|
-
github.com/charmbracelet/x/ansi v0.
|
|
33
|
-
github.com/charmbracelet/x/cellbuf v0.0.
|
|
34
|
-
github.com/charmbracelet/x/term v0.2.
|
|
35
|
-
github.com/
|
|
22
|
+
github.com/charmbracelet/colorprofile v0.4.1 // indirect
|
|
23
|
+
github.com/charmbracelet/x/ansi v0.11.3 // indirect
|
|
24
|
+
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
|
|
25
|
+
github.com/charmbracelet/x/term v0.2.2 // indirect
|
|
26
|
+
github.com/clipperhouse/displaywidth v0.6.2 // indirect
|
|
27
|
+
github.com/clipperhouse/stringish v0.1.1 // indirect
|
|
28
|
+
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
|
36
29
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
|
37
30
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
|
38
31
|
github.com/google/go-github/v30 v30.1.0 // indirect
|
|
39
|
-
github.com/google/go-querystring v1.
|
|
32
|
+
github.com/google/go-querystring v1.2.0 // indirect
|
|
40
33
|
github.com/google/uuid v1.6.0 // indirect
|
|
41
34
|
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect
|
|
42
|
-
github.com/lucasb-eyer/go-colorful v1.
|
|
35
|
+
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
|
43
36
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
44
37
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
|
45
|
-
github.com/mattn/go-runewidth v0.0.
|
|
38
|
+
github.com/mattn/go-runewidth v0.0.19 // indirect
|
|
46
39
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
|
47
40
|
github.com/muesli/cancelreader v0.2.2 // indirect
|
|
48
41
|
github.com/muesli/termenv v0.16.0 // indirect
|
|
49
|
-
github.com/ncruces/go-strftime
|
|
50
|
-
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
42
|
+
github.com/ncruces/go-strftime v1.0.0 // indirect
|
|
51
43
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
|
52
44
|
github.com/rivo/uniseg v0.4.7 // indirect
|
|
53
|
-
github.com/stretchr/objx v0.5.2 // indirect
|
|
54
45
|
github.com/tcnksm/go-gitconfig v0.1.2 // indirect
|
|
55
|
-
github.com/ulikunitz/xz v0.5.
|
|
46
|
+
github.com/ulikunitz/xz v0.5.15 // indirect
|
|
56
47
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
|
57
|
-
golang.org/x/crypto v0.
|
|
58
|
-
golang.org/x/exp v0.0.0-
|
|
59
|
-
golang.org/x/sys v0.
|
|
60
|
-
golang.org/x/text v0.
|
|
61
|
-
|
|
62
|
-
modernc.org/libc v1.66.10 // indirect
|
|
48
|
+
golang.org/x/crypto v0.46.0 // indirect
|
|
49
|
+
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
|
50
|
+
golang.org/x/sys v0.39.0 // indirect
|
|
51
|
+
golang.org/x/text v0.32.0 // indirect
|
|
52
|
+
modernc.org/libc v1.67.4 // indirect
|
|
63
53
|
modernc.org/mathutil v1.7.1 // indirect
|
|
64
54
|
modernc.org/memory v1.11.0 // indirect
|
|
65
55
|
)
|
package/go.sum
CHANGED
|
@@ -8,16 +8,22 @@ github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u
|
|
|
8
8
|
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
|
|
9
9
|
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
|
|
10
10
|
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
|
|
11
|
-
github.com/charmbracelet/colorprofile v0.
|
|
12
|
-
github.com/charmbracelet/colorprofile v0.
|
|
11
|
+
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
|
|
12
|
+
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
|
|
13
13
|
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
|
14
14
|
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
|
15
|
-
github.com/charmbracelet/x/ansi v0.
|
|
16
|
-
github.com/charmbracelet/x/ansi v0.
|
|
17
|
-
github.com/charmbracelet/x/cellbuf v0.0.
|
|
18
|
-
github.com/charmbracelet/x/cellbuf v0.0.
|
|
19
|
-
github.com/charmbracelet/x/term v0.2.
|
|
20
|
-
github.com/charmbracelet/x/term v0.2.
|
|
15
|
+
github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI=
|
|
16
|
+
github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI=
|
|
17
|
+
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
|
|
18
|
+
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
|
|
19
|
+
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
|
|
20
|
+
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
|
|
21
|
+
github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
|
|
22
|
+
github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
|
23
|
+
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
|
24
|
+
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
|
25
|
+
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
|
26
|
+
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
|
21
27
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
22
28
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
23
29
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
|
@@ -35,39 +41,39 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
|
|
35
41
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
36
42
|
github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo=
|
|
37
43
|
github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8=
|
|
38
|
-
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
|
39
44
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
|
45
|
+
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
|
|
46
|
+
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
|
40
47
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
|
41
48
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
|
42
49
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|
43
50
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
51
|
+
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
|
52
|
+
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
|
44
53
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
|
45
54
|
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
|
|
46
55
|
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
|
47
56
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
48
|
-
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
|
49
|
-
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
|
50
57
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
51
|
-
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
52
58
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
53
59
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
|
54
60
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
|
55
|
-
github.com/lucasb-eyer/go-colorful v1.
|
|
56
|
-
github.com/lucasb-eyer/go-colorful v1.
|
|
61
|
+
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
|
|
62
|
+
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
|
57
63
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
|
58
64
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
59
65
|
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
|
60
66
|
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
|
61
|
-
github.com/mattn/go-runewidth v0.0.
|
|
62
|
-
github.com/mattn/go-runewidth v0.0.
|
|
67
|
+
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
|
68
|
+
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
|
63
69
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
|
|
64
70
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
|
65
71
|
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
|
66
72
|
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
|
67
73
|
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
|
|
68
74
|
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
|
|
69
|
-
github.com/ncruces/go-strftime
|
|
70
|
-
github.com/ncruces/go-strftime
|
|
75
|
+
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
|
76
|
+
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
|
71
77
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
72
78
|
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
|
|
73
79
|
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
@@ -81,83 +87,81 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
|
|
|
81
87
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
|
82
88
|
github.com/rhysd/go-github-selfupdate v1.2.3 h1:iaa+J202f+Nc+A8zi75uccC8Wg3omaM7HDeimXA22Ag=
|
|
83
89
|
github.com/rhysd/go-github-selfupdate v1.2.3/go.mod h1:mp/N8zj6jFfBQy/XMYoWsmfzxazpPAODuqarmPDe2Rg=
|
|
84
|
-
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
85
90
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
|
86
91
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
|
87
|
-
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
|
88
|
-
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
|
89
92
|
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
|
|
90
93
|
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
|
91
|
-
github.com/stretchr/
|
|
92
|
-
github.com/stretchr/
|
|
93
|
-
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
|
94
|
-
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
|
94
|
+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
|
95
|
+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
|
95
96
|
github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw=
|
|
96
97
|
github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE=
|
|
97
|
-
github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I=
|
|
98
98
|
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
|
99
|
+
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
|
|
100
|
+
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
|
99
101
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
|
100
102
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
|
101
103
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
|
102
104
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
|
103
105
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
104
|
-
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
|
105
106
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
|
106
|
-
golang.org/x/
|
|
107
|
-
golang.org/x/
|
|
108
|
-
golang.org/x/
|
|
109
|
-
golang.org/x/
|
|
107
|
+
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
|
108
|
+
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
|
109
|
+
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
|
110
|
+
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
|
111
|
+
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
|
112
|
+
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
|
110
113
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
111
114
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
112
115
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
113
|
-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
|
114
116
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
117
|
+
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
|
118
|
+
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
|
115
119
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
116
120
|
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
117
121
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
|
118
122
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
|
119
123
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
120
|
-
golang.org/x/sync v0.
|
|
121
|
-
golang.org/x/sync v0.
|
|
124
|
+
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
|
125
|
+
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
|
122
126
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
123
127
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
124
128
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
125
129
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
126
130
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
127
|
-
golang.org/x/sys v0.
|
|
128
|
-
golang.org/x/sys v0.
|
|
131
|
+
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
|
132
|
+
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
|
129
133
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
|
130
134
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
131
135
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
132
|
-
golang.org/x/text v0.
|
|
133
|
-
golang.org/x/text v0.
|
|
136
|
+
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
|
137
|
+
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
|
134
138
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
135
|
-
golang.org/x/tools v0.
|
|
136
|
-
golang.org/x/tools v0.
|
|
139
|
+
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
|
140
|
+
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
|
137
141
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
138
142
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
139
143
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
140
144
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
141
|
-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
|
142
|
-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
143
145
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
|
144
146
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
|
145
147
|
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
|
146
148
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
147
149
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
148
150
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
149
|
-
modernc.org/cc/v4 v4.
|
|
150
|
-
modernc.org/cc/v4 v4.
|
|
151
|
-
modernc.org/ccgo/v4 v4.
|
|
152
|
-
modernc.org/ccgo/v4 v4.
|
|
151
|
+
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
|
|
152
|
+
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
|
153
|
+
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
|
|
154
|
+
modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=
|
|
153
155
|
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
|
|
154
156
|
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
|
155
157
|
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
|
156
158
|
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
|
159
|
+
modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=
|
|
160
|
+
modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
|
157
161
|
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
|
158
162
|
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
|
159
|
-
modernc.org/libc v1.
|
|
160
|
-
modernc.org/libc v1.
|
|
163
|
+
modernc.org/libc v1.67.4 h1:zZGmCMUVPORtKv95c2ReQN5VDjvkoRm9GWPTEPuvlWg=
|
|
164
|
+
modernc.org/libc v1.67.4/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
|
|
161
165
|
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
|
162
166
|
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
|
163
167
|
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
package/package.json
CHANGED
package/scripts/install.js
CHANGED
package/pkg/cli/benchmark.go
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"context"
|
|
5
|
-
"fmt"
|
|
6
|
-
"time"
|
|
7
|
-
|
|
8
|
-
"github.com/TaskForceAI/core/pkg/config"
|
|
9
|
-
"github.com/TaskForceAI/core/pkg/platform"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
// ConfigLoader is a function type for loading config (allows test injection)
|
|
13
|
-
type ConfigLoader func(path string) (config.Config, error)
|
|
14
|
-
|
|
15
|
-
// DefaultConfigLoader is the default config loader
|
|
16
|
-
var DefaultConfigLoader ConfigLoader = config.LoadConfig
|
|
17
|
-
|
|
18
|
-
func RunBenchmark(ctx context.Context) error {
|
|
19
|
-
return RunBenchmarkWithLoader(ctx, DefaultConfigLoader)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// RunBenchmarkWithLoader allows injecting a custom config loader for testing
|
|
23
|
-
func RunBenchmarkWithLoader(ctx context.Context, loader ConfigLoader) error {
|
|
24
|
-
_, err := loader("")
|
|
25
|
-
if err != nil {
|
|
26
|
-
return err
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
logger := platform.GetLogger()
|
|
30
|
-
logger.Info("Starting performance benchmark...")
|
|
31
|
-
|
|
32
|
-
start := time.Now()
|
|
33
|
-
// Mock implementation for benchmark
|
|
34
|
-
logger.Info(fmt.Sprintf("Benchmark completed in %v", time.Since(start)))
|
|
35
|
-
|
|
36
|
-
return nil
|
|
37
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"context"
|
|
5
|
-
"errors"
|
|
6
|
-
"testing"
|
|
7
|
-
|
|
8
|
-
"github.com/TaskForceAI/core/pkg/config"
|
|
9
|
-
"github.com/stretchr/testify/assert"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
func TestRunBenchmark(t *testing.T) {
|
|
13
|
-
cleanup := setupTestConfig(t)
|
|
14
|
-
defer cleanup()
|
|
15
|
-
|
|
16
|
-
ctx := context.Background()
|
|
17
|
-
err := RunBenchmark(ctx)
|
|
18
|
-
assert.NoError(t, err)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
func TestRunBenchmarkWithLoader(t *testing.T) {
|
|
22
|
-
ctx := context.Background()
|
|
23
|
-
|
|
24
|
-
// Test with successful loader
|
|
25
|
-
successLoader := func(path string) (config.Config, error) {
|
|
26
|
-
return config.Config{}, nil
|
|
27
|
-
}
|
|
28
|
-
err := RunBenchmarkWithLoader(ctx, successLoader)
|
|
29
|
-
assert.NoError(t, err)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
func TestRunBenchmarkWithLoader_ConfigError(t *testing.T) {
|
|
33
|
-
ctx := context.Background()
|
|
34
|
-
|
|
35
|
-
// Test with failing loader
|
|
36
|
-
failLoader := func(path string) (config.Config, error) {
|
|
37
|
-
return config.Config{}, errors.New("config load error")
|
|
38
|
-
}
|
|
39
|
-
err := RunBenchmarkWithLoader(ctx, failLoader)
|
|
40
|
-
assert.Error(t, err)
|
|
41
|
-
assert.Contains(t, err.Error(), "config load error")
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
func TestDefaultConfigLoader(t *testing.T) {
|
|
45
|
-
// Test that DefaultConfigLoader is set
|
|
46
|
-
assert.NotNil(t, DefaultConfigLoader)
|
|
47
|
-
}
|
package/pkg/cli/make_it_heavy.go
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"context"
|
|
5
|
-
"time"
|
|
6
|
-
|
|
7
|
-
"github.com/TaskForceAI/core/pkg/platform"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
type PersistConversationInput struct {
|
|
11
|
-
UserID *string
|
|
12
|
-
UserInput string
|
|
13
|
-
Result string
|
|
14
|
-
ExecutionTime *float64
|
|
15
|
-
Model string
|
|
16
|
-
AgentCount int
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
type PersistConversation func(input PersistConversationInput) error
|
|
20
|
-
|
|
21
|
-
// CLIFactory is a function that creates an OrchestratorCLI
|
|
22
|
-
type CLIFactory func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error)
|
|
23
|
-
|
|
24
|
-
// DefaultCLIFactory is the default factory using NewOrchestratorCLI
|
|
25
|
-
var DefaultCLIFactory CLIFactory = NewOrchestratorCLI
|
|
26
|
-
|
|
27
|
-
func MakeItHeavy(ctx context.Context, query string, modelID *string, userID *string, persist PersistConversation) (string, error) {
|
|
28
|
-
return MakeItHeavyWithFactory(ctx, query, modelID, userID, persist, DefaultCLIFactory)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// MakeItHeavyWithFactory allows injecting a custom CLI factory for testing
|
|
32
|
-
func MakeItHeavyWithFactory(ctx context.Context, query string, modelID *string, userID *string, persist PersistConversation, factory CLIFactory) (string, error) {
|
|
33
|
-
opts := OrchestratorCLIOptions{
|
|
34
|
-
Silent: true,
|
|
35
|
-
}
|
|
36
|
-
if modelID != nil {
|
|
37
|
-
opts.ModelID = *modelID
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
cli, err := factory(opts)
|
|
41
|
-
if err != nil {
|
|
42
|
-
return "", err
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
result, err := cli.RunTask(ctx, query)
|
|
46
|
-
if err != nil {
|
|
47
|
-
return "", err
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if persist != nil {
|
|
51
|
-
var execTime *float64
|
|
52
|
-
if !cli.startTime.IsZero() {
|
|
53
|
-
t := time.Since(cli.startTime).Seconds()
|
|
54
|
-
execTime = &t
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
err = persist(PersistConversationInput{
|
|
58
|
-
UserID: userID,
|
|
59
|
-
UserInput: query,
|
|
60
|
-
Result: result,
|
|
61
|
-
ExecutionTime: execTime,
|
|
62
|
-
Model: cli.modelDisplay,
|
|
63
|
-
AgentCount: cli.orchestrator.GetAgentCount(),
|
|
64
|
-
})
|
|
65
|
-
if err != nil {
|
|
66
|
-
platform.GetLogger().Error("Failed to persist result", "error", err)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return result, nil
|
|
71
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"bytes"
|
|
5
|
-
"context"
|
|
6
|
-
"errors"
|
|
7
|
-
"testing"
|
|
8
|
-
|
|
9
|
-
"github.com/stretchr/testify/assert"
|
|
10
|
-
"github.com/stretchr/testify/mock"
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
func TestMakeItHeavyWithFactory(t *testing.T) {
|
|
14
|
-
mockOrch := new(MockOrchestrator)
|
|
15
|
-
mockOrch.On("Orchestrate", mock.Anything, "test query").Return("test result", nil)
|
|
16
|
-
mockOrch.On("GetAgentCount").Return(3)
|
|
17
|
-
|
|
18
|
-
var buf bytes.Buffer
|
|
19
|
-
factory := func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
20
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
21
|
-
Orchestrator: mockOrch,
|
|
22
|
-
ModelDisplay: "Test Model",
|
|
23
|
-
Silent: true,
|
|
24
|
-
Stdout: &buf,
|
|
25
|
-
}), nil
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
modelID := "test-model"
|
|
29
|
-
userID := "user-123"
|
|
30
|
-
persistCalled := false
|
|
31
|
-
persist := func(input PersistConversationInput) error {
|
|
32
|
-
persistCalled = true
|
|
33
|
-
assert.Equal(t, "test query", input.UserInput)
|
|
34
|
-
assert.Equal(t, "test result", input.Result)
|
|
35
|
-
assert.Equal(t, "user-123", *input.UserID)
|
|
36
|
-
assert.Equal(t, "Test Model", input.Model)
|
|
37
|
-
assert.Equal(t, 3, input.AgentCount)
|
|
38
|
-
return nil
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
result, err := MakeItHeavyWithFactory(context.Background(), "test query", &modelID, &userID, persist, factory)
|
|
42
|
-
assert.NoError(t, err)
|
|
43
|
-
assert.Equal(t, "test result", result)
|
|
44
|
-
assert.True(t, persistCalled)
|
|
45
|
-
mockOrch.AssertExpectations(t)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
func TestMakeItHeavyWithFactory_FactoryError(t *testing.T) {
|
|
49
|
-
factory := func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
50
|
-
return nil, errors.New("factory error")
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
result, err := MakeItHeavyWithFactory(context.Background(), "query", nil, nil, nil, factory)
|
|
54
|
-
assert.Error(t, err)
|
|
55
|
-
assert.Equal(t, "", result)
|
|
56
|
-
assert.Contains(t, err.Error(), "factory error")
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
func TestMakeItHeavyWithFactory_OrchestrationError(t *testing.T) {
|
|
60
|
-
mockOrch := new(MockOrchestrator)
|
|
61
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("", errors.New("orchestration error"))
|
|
62
|
-
|
|
63
|
-
factory := func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
64
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
65
|
-
Orchestrator: mockOrch,
|
|
66
|
-
Silent: true,
|
|
67
|
-
}), nil
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
result, err := MakeItHeavyWithFactory(context.Background(), "query", nil, nil, nil, factory)
|
|
71
|
-
assert.Error(t, err)
|
|
72
|
-
assert.Equal(t, "", result)
|
|
73
|
-
assert.Contains(t, err.Error(), "orchestration error")
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
func TestMakeItHeavyWithFactory_PersistError(t *testing.T) {
|
|
77
|
-
mockOrch := new(MockOrchestrator)
|
|
78
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("result", nil)
|
|
79
|
-
mockOrch.On("GetAgentCount").Return(1)
|
|
80
|
-
|
|
81
|
-
factory := func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
82
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
83
|
-
Orchestrator: mockOrch,
|
|
84
|
-
Silent: true,
|
|
85
|
-
}), nil
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
persist := func(input PersistConversationInput) error {
|
|
89
|
-
return errors.New("persist error")
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Should still return result even if persist fails
|
|
93
|
-
result, err := MakeItHeavyWithFactory(context.Background(), "query", nil, nil, persist, factory)
|
|
94
|
-
assert.NoError(t, err)
|
|
95
|
-
assert.Equal(t, "result", result)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
func TestMakeItHeavyWithFactory_NilPersist(t *testing.T) {
|
|
99
|
-
mockOrch := new(MockOrchestrator)
|
|
100
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("result", nil)
|
|
101
|
-
|
|
102
|
-
factory := func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
103
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
104
|
-
Orchestrator: mockOrch,
|
|
105
|
-
Silent: true,
|
|
106
|
-
}), nil
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
result, err := MakeItHeavyWithFactory(context.Background(), "query", nil, nil, nil, factory)
|
|
110
|
-
assert.NoError(t, err)
|
|
111
|
-
assert.Equal(t, "result", result)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
func TestMakeItHeavy_Types(t *testing.T) {
|
|
115
|
-
// Test type definitions
|
|
116
|
-
var persist PersistConversation = nil
|
|
117
|
-
assert.Nil(t, persist)
|
|
118
|
-
|
|
119
|
-
// Test PersistConversationInput
|
|
120
|
-
input := PersistConversationInput{
|
|
121
|
-
UserInput: "test",
|
|
122
|
-
Result: "result",
|
|
123
|
-
Model: "model",
|
|
124
|
-
AgentCount: 1,
|
|
125
|
-
}
|
|
126
|
-
assert.Equal(t, "test", input.UserInput)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
func TestCLIFactory(t *testing.T) {
|
|
130
|
-
// Test that DefaultCLIFactory is set
|
|
131
|
-
assert.NotNil(t, DefaultCLIFactory)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
func TestMakeItHeavy(t *testing.T) {
|
|
135
|
-
// Save and restore DefaultCLIFactory
|
|
136
|
-
origFactory := DefaultCLIFactory
|
|
137
|
-
defer func() { DefaultCLIFactory = origFactory }()
|
|
138
|
-
|
|
139
|
-
mockOrch := new(MockOrchestrator)
|
|
140
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("result", nil)
|
|
141
|
-
mockOrch.On("GetAgentCount").Return(1)
|
|
142
|
-
|
|
143
|
-
DefaultCLIFactory = func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
144
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
145
|
-
Orchestrator: mockOrch,
|
|
146
|
-
Silent: true,
|
|
147
|
-
}), nil
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
result, err := MakeItHeavy(context.Background(), "query", nil, nil, nil)
|
|
151
|
-
assert.NoError(t, err)
|
|
152
|
-
assert.Equal(t, "result", result)
|
|
153
|
-
}
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"bufio"
|
|
5
|
-
"context"
|
|
6
|
-
"fmt"
|
|
7
|
-
"io"
|
|
8
|
-
"os"
|
|
9
|
-
"strings"
|
|
10
|
-
"time"
|
|
11
|
-
|
|
12
|
-
"github.com/TaskForceAI/core/pkg/agent"
|
|
13
|
-
"github.com/TaskForceAI/core/pkg/config"
|
|
14
|
-
"github.com/TaskForceAI/core/pkg/orchestrator"
|
|
15
|
-
"github.com/TaskForceAI/core/pkg/platform"
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
const (
|
|
19
|
-
colorOrange = "\x1b[38;5;208m"
|
|
20
|
-
colorRed = "\x1b[91m"
|
|
21
|
-
colorEnd = "\x1b[0m"
|
|
22
|
-
progressBarLen = 70
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
func buildProgressBar(status string) string {
|
|
26
|
-
switch status {
|
|
27
|
-
case "QUEUED":
|
|
28
|
-
return "○ " + strings.Repeat("·", progressBarLen)
|
|
29
|
-
case "INITIALIZING...":
|
|
30
|
-
return fmt.Sprintf("%s◐%s ", colorOrange, colorEnd) + strings.Repeat("·", progressBarLen)
|
|
31
|
-
case "PROCESSING...":
|
|
32
|
-
return fmt.Sprintf("%s●%s ", colorOrange, colorEnd) + fmt.Sprintf("%s:%s", colorOrange, colorEnd) + strings.Repeat("·", 10) + strings.Repeat("·", progressBarLen-11)
|
|
33
|
-
case "COMPLETED":
|
|
34
|
-
return fmt.Sprintf("%s●%s ", colorOrange, colorEnd) + strings.Repeat(fmt.Sprintf("%s:%s", colorOrange, colorEnd), progressBarLen)
|
|
35
|
-
default:
|
|
36
|
-
if strings.HasPrefix(status, "FAILED") {
|
|
37
|
-
return fmt.Sprintf("%s✗%s ", colorRed, colorEnd) + strings.Repeat(fmt.Sprintf("%s×%s", colorRed, colorEnd), progressBarLen)
|
|
38
|
-
}
|
|
39
|
-
return fmt.Sprintf("%s◐%s ", colorOrange, colorEnd) + strings.Repeat("·", progressBarLen)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// IOrchestrator defines the interface for task orchestration
|
|
44
|
-
type IOrchestrator interface {
|
|
45
|
-
Orchestrate(ctx context.Context, input string) (string, error)
|
|
46
|
-
GetAgentCount() int
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// ModelSelector is a function type for resolving model selection (allows test injection)
|
|
50
|
-
type ModelSelector func(cfg config.Config, modelID string) (*orchestrator.ResolvedModelSelection, error)
|
|
51
|
-
|
|
52
|
-
// DefaultModelSelector is the default model selector
|
|
53
|
-
var DefaultModelSelector ModelSelector = orchestrator.ResolveModelSelection
|
|
54
|
-
|
|
55
|
-
type OrchestratorCLIOptions struct {
|
|
56
|
-
Silent bool
|
|
57
|
-
ModelID string
|
|
58
|
-
Client agent.ILLMClient
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
type OrchestratorCLI struct {
|
|
62
|
-
orchestrator IOrchestrator
|
|
63
|
-
startTime time.Time
|
|
64
|
-
running bool
|
|
65
|
-
modelDisplay string
|
|
66
|
-
modelID string
|
|
67
|
-
modelLabel string
|
|
68
|
-
silent bool
|
|
69
|
-
stdin io.Reader
|
|
70
|
-
stdout io.Writer
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// OrchestratorCLIDeps allows injecting dependencies for testing
|
|
74
|
-
type OrchestratorCLIDeps struct {
|
|
75
|
-
Orchestrator IOrchestrator
|
|
76
|
-
ModelDisplay string
|
|
77
|
-
ModelID string
|
|
78
|
-
ModelLabel string
|
|
79
|
-
Silent bool
|
|
80
|
-
Stdin io.Reader
|
|
81
|
-
Stdout io.Writer
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
func NewOrchestratorCLI(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
85
|
-
cfg, err := config.LoadConfig("")
|
|
86
|
-
if err != nil {
|
|
87
|
-
return nil, err
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
modelSelection, err := DefaultModelSelector(cfg, opts.ModelID)
|
|
91
|
-
if err != nil {
|
|
92
|
-
return nil, err
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
deps := orchestrator.OrchestratorDeps{
|
|
96
|
-
Client: opts.Client,
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
orch := orchestrator.New(modelSelection.Config, deps, map[string]interface{}{
|
|
100
|
-
"silent": opts.Silent,
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
return &OrchestratorCLI{
|
|
104
|
-
orchestrator: orch,
|
|
105
|
-
modelDisplay: modelSelection.SelectedModel.Badge,
|
|
106
|
-
modelID: modelSelection.SelectedModel.ID,
|
|
107
|
-
modelLabel: modelSelection.SelectedModel.Label,
|
|
108
|
-
silent: opts.Silent,
|
|
109
|
-
stdin: os.Stdin,
|
|
110
|
-
stdout: os.Stdout,
|
|
111
|
-
}, nil
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// NewOrchestratorCLIWithDeps creates a CLI with injected dependencies for testing
|
|
115
|
-
func NewOrchestratorCLIWithDeps(deps OrchestratorCLIDeps) *OrchestratorCLI {
|
|
116
|
-
stdin := deps.Stdin
|
|
117
|
-
if stdin == nil {
|
|
118
|
-
stdin = os.Stdin
|
|
119
|
-
}
|
|
120
|
-
stdout := deps.Stdout
|
|
121
|
-
if stdout == nil {
|
|
122
|
-
stdout = os.Stdout
|
|
123
|
-
}
|
|
124
|
-
return &OrchestratorCLI{
|
|
125
|
-
orchestrator: deps.Orchestrator,
|
|
126
|
-
modelDisplay: deps.ModelDisplay,
|
|
127
|
-
modelID: deps.ModelID,
|
|
128
|
-
modelLabel: deps.ModelLabel,
|
|
129
|
-
silent: deps.Silent,
|
|
130
|
-
stdin: stdin,
|
|
131
|
-
stdout: stdout,
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
func (c *OrchestratorCLI) clearScreen() {
|
|
136
|
-
fmt.Fprint(c.stdout, "\033[H\033[2J")
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
func (c *OrchestratorCLI) updateDisplay() {
|
|
140
|
-
if !c.running {
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
elapsed := time.Since(c.startTime).Seconds()
|
|
145
|
-
|
|
146
|
-
c.clearScreen()
|
|
147
|
-
logger := platform.GetLogger()
|
|
148
|
-
logger.Info(c.modelDisplay)
|
|
149
|
-
status := "COMPLETED"
|
|
150
|
-
if c.running {
|
|
151
|
-
status = "RUNNING"
|
|
152
|
-
}
|
|
153
|
-
logger.Info(fmt.Sprintf("● %s • %.2fs\n", status, elapsed))
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
func (c *OrchestratorCLI) RunTask(ctx context.Context, input string) (string, error) {
|
|
157
|
-
c.startTime = time.Now()
|
|
158
|
-
c.running = true
|
|
159
|
-
|
|
160
|
-
if !c.silent {
|
|
161
|
-
done := make(chan struct{})
|
|
162
|
-
// Use a done channel to signal the ticker goroutine to exit immediately
|
|
163
|
-
// preventing goroutine leaks/deadlocks in synctest
|
|
164
|
-
defer close(done)
|
|
165
|
-
|
|
166
|
-
go func() {
|
|
167
|
-
ticker := time.NewTicker(1 * time.Second)
|
|
168
|
-
defer ticker.Stop()
|
|
169
|
-
for {
|
|
170
|
-
select {
|
|
171
|
-
case <-done:
|
|
172
|
-
return
|
|
173
|
-
case <-ticker.C:
|
|
174
|
-
c.updateDisplay()
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}()
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
res, err := c.orchestrator.Orchestrate(ctx, input)
|
|
181
|
-
c.running = false
|
|
182
|
-
|
|
183
|
-
if c.silent {
|
|
184
|
-
platform.GetLogger().Info(fmt.Sprintf("Orchestration completed in %.2fs", time.Since(c.startTime).Seconds()))
|
|
185
|
-
} else {
|
|
186
|
-
c.updateDisplay()
|
|
187
|
-
fmt.Fprintf(c.stdout, "%s\nFINAL RESULTS\n%s\n\n%s\n\n%s\n", strings.Repeat("=", 80), strings.Repeat("=", 80), res, strings.Repeat("=", 80))
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return res, err
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
func (c *OrchestratorCLI) InteractiveMode(ctx context.Context) error {
|
|
194
|
-
logger := platform.GetLogger()
|
|
195
|
-
logger.Info(fmt.Sprintf("Multi-Agent Orchestrator\nConfigured for %d parallel agents\nType 'quit', 'exit', or 'bye' to exit\n%s", c.orchestrator.GetAgentCount(), strings.Repeat("-", 50)))
|
|
196
|
-
logger.Info(fmt.Sprintf("Using model: %s (%s)\nOrchestrator initialized successfully!\n%s", c.modelLabel, c.modelID, strings.Repeat("-", 50)))
|
|
197
|
-
|
|
198
|
-
scanner := bufio.NewScanner(c.stdin)
|
|
199
|
-
for {
|
|
200
|
-
fmt.Fprint(c.stdout, "\nUser: ")
|
|
201
|
-
if !scanner.Scan() {
|
|
202
|
-
break
|
|
203
|
-
}
|
|
204
|
-
input := scanner.Text()
|
|
205
|
-
lowerInput := strings.ToLower(strings.TrimSpace(input))
|
|
206
|
-
if lowerInput == "quit" || lowerInput == "exit" || lowerInput == "bye" {
|
|
207
|
-
break
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
logger.Info("\nOrchestrator: Starting multi-agent analysis...\n")
|
|
211
|
-
_, err := c.RunTask(ctx, input)
|
|
212
|
-
if err != nil {
|
|
213
|
-
logger.Error("Orchestration failed", "error", err)
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return scanner.Err()
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// GetOrchestrator returns the underlying orchestrator for testing
|
|
221
|
-
func (c *OrchestratorCLI) GetOrchestrator() IOrchestrator {
|
|
222
|
-
return c.orchestrator
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// GetStartTime returns the start time for testing
|
|
226
|
-
func (c *OrchestratorCLI) GetStartTime() time.Time {
|
|
227
|
-
return c.startTime
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// GetModelDisplay returns the model display string for testing
|
|
231
|
-
func (c *OrchestratorCLI) GetModelDisplay() string {
|
|
232
|
-
return c.modelDisplay
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Global functions for audit script (use DefaultCLIFactory for testability)
|
|
236
|
-
func InteractiveMode(ctx context.Context) error {
|
|
237
|
-
c, err := DefaultCLIFactory(OrchestratorCLIOptions{})
|
|
238
|
-
if err != nil {
|
|
239
|
-
return err
|
|
240
|
-
}
|
|
241
|
-
return c.InteractiveMode(ctx)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
func RunTask(ctx context.Context, input string) (string, error) {
|
|
245
|
-
c, err := DefaultCLIFactory(OrchestratorCLIOptions{})
|
|
246
|
-
if err != nil {
|
|
247
|
-
return "", err
|
|
248
|
-
}
|
|
249
|
-
return c.RunTask(ctx, input)
|
|
250
|
-
}
|
|
@@ -1,400 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"bytes"
|
|
5
|
-
"context"
|
|
6
|
-
"errors"
|
|
7
|
-
"strings"
|
|
8
|
-
"testing"
|
|
9
|
-
"testing/synctest"
|
|
10
|
-
"time"
|
|
11
|
-
|
|
12
|
-
"github.com/TaskForceAI/core/pkg/config"
|
|
13
|
-
"github.com/TaskForceAI/core/pkg/orchestrator"
|
|
14
|
-
"github.com/stretchr/testify/assert"
|
|
15
|
-
"github.com/stretchr/testify/mock"
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
// MockOrchestrator implements IOrchestrator for testing
|
|
19
|
-
type MockOrchestrator struct {
|
|
20
|
-
mock.Mock
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
func (m *MockOrchestrator) Orchestrate(ctx context.Context, input string) (string, error) {
|
|
24
|
-
args := m.Called(ctx, input)
|
|
25
|
-
return args.String(0), args.Error(1)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
func (m *MockOrchestrator) GetAgentCount() int {
|
|
29
|
-
args := m.Called()
|
|
30
|
-
return args.Int(0)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
func TestBuildProgressBar(t *testing.T) {
|
|
34
|
-
tests := []struct {
|
|
35
|
-
name string
|
|
36
|
-
status string
|
|
37
|
-
contains string
|
|
38
|
-
}{
|
|
39
|
-
{"QUEUED", "QUEUED", "○"},
|
|
40
|
-
{"INITIALIZING", "INITIALIZING...", "◐"},
|
|
41
|
-
{"PROCESSING", "PROCESSING...", "●"},
|
|
42
|
-
{"COMPLETED", "COMPLETED", "●"},
|
|
43
|
-
{"FAILED", "FAILED 123", "✗"},
|
|
44
|
-
{"UNKNOWN", "UNKNOWN", "◐"},
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
for _, tt := range tests {
|
|
48
|
-
t.Run(tt.name, func(t *testing.T) {
|
|
49
|
-
result := buildProgressBar(tt.status)
|
|
50
|
-
assert.Contains(t, result, tt.contains)
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
func TestOrchestratorCLI_ClearScreen(t *testing.T) {
|
|
56
|
-
var buf bytes.Buffer
|
|
57
|
-
mockOrch := new(MockOrchestrator)
|
|
58
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
59
|
-
Orchestrator: mockOrch,
|
|
60
|
-
Stdout: &buf,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
cli.clearScreen()
|
|
64
|
-
assert.Contains(t, buf.String(), "\033[H\033[2J")
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
func TestOrchestratorCLI_UpdateDisplay(t *testing.T) {
|
|
68
|
-
mockOrch := new(MockOrchestrator)
|
|
69
|
-
var buf bytes.Buffer
|
|
70
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
71
|
-
Orchestrator: mockOrch,
|
|
72
|
-
Silent: false,
|
|
73
|
-
Stdout: &buf,
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
// Not running - should return immediately
|
|
77
|
-
cli.running = false
|
|
78
|
-
cli.updateDisplay()
|
|
79
|
-
|
|
80
|
-
// Running - should update display
|
|
81
|
-
cli.running = true
|
|
82
|
-
cli.startTime = time.Now()
|
|
83
|
-
cli.updateDisplay()
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
func TestOrchestratorCLI_RunTask(t *testing.T) {
|
|
87
|
-
mockOrch := new(MockOrchestrator)
|
|
88
|
-
var buf bytes.Buffer
|
|
89
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
90
|
-
Orchestrator: mockOrch,
|
|
91
|
-
Silent: true,
|
|
92
|
-
Stdout: &buf,
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
mockOrch.On("Orchestrate", mock.Anything, "test query").Return("test result", nil)
|
|
96
|
-
|
|
97
|
-
result, err := cli.RunTask(context.Background(), "test query")
|
|
98
|
-
assert.NoError(t, err)
|
|
99
|
-
assert.Equal(t, "test result", result)
|
|
100
|
-
mockOrch.AssertExpectations(t)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
func TestOrchestratorCLI_RunTask_NotSilent(t *testing.T) {
|
|
104
|
-
mockOrch := new(MockOrchestrator)
|
|
105
|
-
var buf bytes.Buffer
|
|
106
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
107
|
-
Orchestrator: mockOrch,
|
|
108
|
-
Silent: false,
|
|
109
|
-
Stdout: &buf,
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
mockOrch.On("Orchestrate", mock.Anything, "test query").Return("test result", nil)
|
|
113
|
-
|
|
114
|
-
result, err := cli.RunTask(context.Background(), "test query")
|
|
115
|
-
assert.NoError(t, err)
|
|
116
|
-
assert.Equal(t, "test result", result)
|
|
117
|
-
assert.Contains(t, buf.String(), "FINAL RESULTS")
|
|
118
|
-
mockOrch.AssertExpectations(t)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
func TestOrchestratorCLI_RunTask_OrchestrationError(t *testing.T) {
|
|
122
|
-
mockOrch := new(MockOrchestrator)
|
|
123
|
-
var buf bytes.Buffer
|
|
124
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
125
|
-
Orchestrator: mockOrch,
|
|
126
|
-
Silent: true,
|
|
127
|
-
Stdout: &buf,
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("", errors.New("orchestration error"))
|
|
131
|
-
|
|
132
|
-
result, err := cli.RunTask(context.Background(), "query")
|
|
133
|
-
assert.Error(t, err)
|
|
134
|
-
assert.Equal(t, "", result)
|
|
135
|
-
mockOrch.AssertExpectations(t)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
func TestOrchestratorCLI_InteractiveMode(t *testing.T) {
|
|
139
|
-
mockOrch := new(MockOrchestrator)
|
|
140
|
-
mockOrch.On("GetAgentCount").Return(3)
|
|
141
|
-
mockOrch.On("Orchestrate", mock.Anything, "hello").Return("response", nil)
|
|
142
|
-
|
|
143
|
-
input := "hello\nexit\n"
|
|
144
|
-
var buf bytes.Buffer
|
|
145
|
-
|
|
146
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
147
|
-
Orchestrator: mockOrch,
|
|
148
|
-
ModelLabel: "Test Model",
|
|
149
|
-
ModelID: "test-model",
|
|
150
|
-
Silent: true,
|
|
151
|
-
Stdin: strings.NewReader(input),
|
|
152
|
-
Stdout: &buf,
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
err := cli.InteractiveMode(context.Background())
|
|
156
|
-
assert.NoError(t, err)
|
|
157
|
-
mockOrch.AssertExpectations(t)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
func TestOrchestratorCLI_InteractiveMode_ExitCommands(t *testing.T) {
|
|
161
|
-
tests := []string{"quit", "exit", "bye"}
|
|
162
|
-
|
|
163
|
-
for _, cmd := range tests {
|
|
164
|
-
t.Run(cmd, func(t *testing.T) {
|
|
165
|
-
mockOrch := new(MockOrchestrator)
|
|
166
|
-
mockOrch.On("GetAgentCount").Return(1)
|
|
167
|
-
|
|
168
|
-
var buf bytes.Buffer
|
|
169
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
170
|
-
Orchestrator: mockOrch,
|
|
171
|
-
Silent: true,
|
|
172
|
-
Stdin: strings.NewReader(cmd + "\n"),
|
|
173
|
-
Stdout: &buf,
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
err := cli.InteractiveMode(context.Background())
|
|
177
|
-
assert.NoError(t, err)
|
|
178
|
-
})
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
func TestOrchestratorCLI_InteractiveMode_EOF(t *testing.T) {
|
|
183
|
-
mockOrch := new(MockOrchestrator)
|
|
184
|
-
mockOrch.On("GetAgentCount").Return(1)
|
|
185
|
-
|
|
186
|
-
// Empty input will cause scanner to return false immediately
|
|
187
|
-
var buf bytes.Buffer
|
|
188
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
189
|
-
Orchestrator: mockOrch,
|
|
190
|
-
Silent: true,
|
|
191
|
-
Stdin: strings.NewReader(""),
|
|
192
|
-
Stdout: &buf,
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
err := cli.InteractiveMode(context.Background())
|
|
196
|
-
assert.NoError(t, err)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
func TestOrchestratorCLI_Getters(t *testing.T) {
|
|
200
|
-
mockOrch := new(MockOrchestrator)
|
|
201
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
202
|
-
Orchestrator: mockOrch,
|
|
203
|
-
ModelDisplay: "Test Display",
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
assert.Equal(t, mockOrch, cli.GetOrchestrator())
|
|
207
|
-
assert.Equal(t, "Test Display", cli.GetModelDisplay())
|
|
208
|
-
assert.True(t, cli.GetStartTime().IsZero())
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
func TestNewOrchestratorCLI(t *testing.T) {
|
|
212
|
-
cleanup := setupTestConfig(t)
|
|
213
|
-
defer cleanup()
|
|
214
|
-
|
|
215
|
-
opts := OrchestratorCLIOptions{
|
|
216
|
-
Silent: true,
|
|
217
|
-
ModelID: "test-model",
|
|
218
|
-
Client: nil,
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
cli, err := NewOrchestratorCLI(opts)
|
|
222
|
-
assert.NoError(t, err)
|
|
223
|
-
assert.NotNil(t, cli)
|
|
224
|
-
assert.True(t, cli.silent)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
func TestNewOrchestratorCLIWithDeps_Defaults(t *testing.T) {
|
|
228
|
-
mockOrch := new(MockOrchestrator)
|
|
229
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
230
|
-
Orchestrator: mockOrch,
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
assert.NotNil(t, cli.stdin)
|
|
234
|
-
assert.NotNil(t, cli.stdout)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
func TestOrchestratorCLI_InteractiveMode_OrchestrationError(t *testing.T) {
|
|
238
|
-
mockOrch := new(MockOrchestrator)
|
|
239
|
-
mockOrch.On("GetAgentCount").Return(1)
|
|
240
|
-
mockOrch.On("Orchestrate", mock.Anything, "test").Return("", errors.New("orchestration error"))
|
|
241
|
-
|
|
242
|
-
input := "test\nexit\n"
|
|
243
|
-
var buf bytes.Buffer
|
|
244
|
-
|
|
245
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
246
|
-
Orchestrator: mockOrch,
|
|
247
|
-
Silent: true,
|
|
248
|
-
Stdin: strings.NewReader(input),
|
|
249
|
-
Stdout: &buf,
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
err := cli.InteractiveMode(context.Background())
|
|
253
|
-
assert.NoError(t, err) // Should handle orchestration error gracefully
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
func TestPersistConversationInput(t *testing.T) {
|
|
257
|
-
userID := "user-123"
|
|
258
|
-
execTime := 1.5
|
|
259
|
-
|
|
260
|
-
input := PersistConversationInput{
|
|
261
|
-
UserID: &userID,
|
|
262
|
-
UserInput: "test input",
|
|
263
|
-
Result: "test result",
|
|
264
|
-
ExecutionTime: &execTime,
|
|
265
|
-
Model: "test-model",
|
|
266
|
-
AgentCount: 3,
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
assert.Equal(t, "user-123", *input.UserID)
|
|
270
|
-
assert.Equal(t, "test input", input.UserInput)
|
|
271
|
-
assert.Equal(t, "test result", input.Result)
|
|
272
|
-
assert.Equal(t, 1.5, *input.ExecutionTime)
|
|
273
|
-
assert.Equal(t, "test-model", input.Model)
|
|
274
|
-
assert.Equal(t, 3, input.AgentCount)
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Tests for global wrapper functions
|
|
278
|
-
func TestGlobalInteractiveMode(t *testing.T) {
|
|
279
|
-
// Save and restore DefaultCLIFactory
|
|
280
|
-
origFactory := DefaultCLIFactory
|
|
281
|
-
defer func() { DefaultCLIFactory = origFactory }()
|
|
282
|
-
|
|
283
|
-
mockOrch := new(MockOrchestrator)
|
|
284
|
-
mockOrch.On("GetAgentCount").Return(1)
|
|
285
|
-
|
|
286
|
-
DefaultCLIFactory = func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
287
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
288
|
-
Orchestrator: mockOrch,
|
|
289
|
-
Silent: true,
|
|
290
|
-
Stdin: strings.NewReader("exit\n"),
|
|
291
|
-
Stdout: &bytes.Buffer{},
|
|
292
|
-
}), nil
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
err := InteractiveMode(context.Background())
|
|
296
|
-
assert.NoError(t, err)
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
func TestGlobalInteractiveMode_FactoryError(t *testing.T) {
|
|
300
|
-
origFactory := DefaultCLIFactory
|
|
301
|
-
defer func() { DefaultCLIFactory = origFactory }()
|
|
302
|
-
|
|
303
|
-
DefaultCLIFactory = func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
304
|
-
return nil, errors.New("factory error")
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
err := InteractiveMode(context.Background())
|
|
308
|
-
assert.Error(t, err)
|
|
309
|
-
assert.Contains(t, err.Error(), "factory error")
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
func TestGlobalRunTask(t *testing.T) {
|
|
313
|
-
origFactory := DefaultCLIFactory
|
|
314
|
-
defer func() { DefaultCLIFactory = origFactory }()
|
|
315
|
-
|
|
316
|
-
mockOrch := new(MockOrchestrator)
|
|
317
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("result", nil)
|
|
318
|
-
|
|
319
|
-
DefaultCLIFactory = func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
320
|
-
return NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
321
|
-
Orchestrator: mockOrch,
|
|
322
|
-
Silent: true,
|
|
323
|
-
}), nil
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
result, err := RunTask(context.Background(), "query")
|
|
327
|
-
assert.NoError(t, err)
|
|
328
|
-
assert.Equal(t, "result", result)
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
func TestGlobalRunTask_FactoryError(t *testing.T) {
|
|
332
|
-
origFactory := DefaultCLIFactory
|
|
333
|
-
defer func() { DefaultCLIFactory = origFactory }()
|
|
334
|
-
|
|
335
|
-
DefaultCLIFactory = func(opts OrchestratorCLIOptions) (*OrchestratorCLI, error) {
|
|
336
|
-
return nil, errors.New("factory error")
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
result, err := RunTask(context.Background(), "query")
|
|
340
|
-
assert.Error(t, err)
|
|
341
|
-
assert.Equal(t, "", result)
|
|
342
|
-
assert.Contains(t, err.Error(), "factory error")
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
func TestNewOrchestratorCLI_ConfigError(t *testing.T) {
|
|
346
|
-
// Don't setup config - should fail to load
|
|
347
|
-
opts := OrchestratorCLIOptions{
|
|
348
|
-
Silent: true,
|
|
349
|
-
ModelID: "test-model",
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
_, err := NewOrchestratorCLI(opts)
|
|
353
|
-
assert.Error(t, err) // Should fail because config doesn't exist
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
func TestNewOrchestratorCLI_ModelSelectionError(t *testing.T) {
|
|
357
|
-
cleanup := setupTestConfig(t)
|
|
358
|
-
defer cleanup()
|
|
359
|
-
|
|
360
|
-
// Save and restore DefaultModelSelector
|
|
361
|
-
origSelector := DefaultModelSelector
|
|
362
|
-
defer func() { DefaultModelSelector = origSelector }()
|
|
363
|
-
|
|
364
|
-
// Make model selection return an error
|
|
365
|
-
DefaultModelSelector = func(cfg config.Config, modelID string) (*orchestrator.ResolvedModelSelection, error) {
|
|
366
|
-
return nil, errors.New("model selection error")
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
opts := OrchestratorCLIOptions{
|
|
370
|
-
Silent: true,
|
|
371
|
-
ModelID: "test-model",
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
_, err := NewOrchestratorCLI(opts)
|
|
375
|
-
assert.Error(t, err)
|
|
376
|
-
assert.Contains(t, err.Error(), "model selection error")
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
func TestOrchestratorCLI_RunTask_NotSilent_WithTicker(t *testing.T) {
|
|
380
|
-
synctest.Test(t, func(t *testing.T) {
|
|
381
|
-
// Test the ticker goroutine branch by running without silent mode
|
|
382
|
-
// and giving it a chance to tick (ticker fires every 1 second)
|
|
383
|
-
mockOrch := new(MockOrchestrator)
|
|
384
|
-
var buf bytes.Buffer
|
|
385
|
-
cli := NewOrchestratorCLIWithDeps(OrchestratorCLIDeps{
|
|
386
|
-
Orchestrator: mockOrch,
|
|
387
|
-
Silent: false,
|
|
388
|
-
Stdout: &buf,
|
|
389
|
-
})
|
|
390
|
-
|
|
391
|
-
// Make orchestration take longer than 1 second so ticker can fire
|
|
392
|
-
mockOrch.On("Orchestrate", mock.Anything, "query").Return("result", nil).Run(func(args mock.Arguments) {
|
|
393
|
-
time.Sleep(1100 * time.Millisecond) // Just over 1 second to let ticker fire
|
|
394
|
-
})
|
|
395
|
-
|
|
396
|
-
result, err := cli.RunTask(context.Background(), "query")
|
|
397
|
-
assert.NoError(t, err)
|
|
398
|
-
assert.Equal(t, "result", result)
|
|
399
|
-
})
|
|
400
|
-
}
|
package/pkg/cli/shared_test.go
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
package cli
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"os"
|
|
5
|
-
"testing"
|
|
6
|
-
|
|
7
|
-
"github.com/stretchr/testify/require"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
func setupTestConfig(t *testing.T) func() {
|
|
11
|
-
// LoadConfig defaults to "config/config.yaml" relative to CWD
|
|
12
|
-
// We need to create this file in the test directory
|
|
13
|
-
yamlContent := `
|
|
14
|
-
gateway:
|
|
15
|
-
model: test-model
|
|
16
|
-
orchestrator:
|
|
17
|
-
parallel_agents: 1
|
|
18
|
-
`
|
|
19
|
-
err := os.MkdirAll("config", 0755)
|
|
20
|
-
require.NoError(t, err)
|
|
21
|
-
|
|
22
|
-
err = os.WriteFile("config/config.yaml", []byte(yamlContent), 0644)
|
|
23
|
-
require.NoError(t, err)
|
|
24
|
-
|
|
25
|
-
return func() {
|
|
26
|
-
os.RemoveAll("config")
|
|
27
|
-
}
|
|
28
|
-
}
|