@sean.holung/minicode 0.2.2 → 0.2.4
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/README.md +20 -12
- package/dist/src/agent/config.js +14 -2
- package/dist/src/cli/args.js +31 -0
- package/dist/src/index.js +21 -2
- package/dist/src/indexer/code-map.js +52 -5
- package/dist/src/indexer/focus-tracker.js +63 -0
- package/dist/src/indexer/project-index.js +2 -2
- package/dist/src/serve/agent-bridge.js +233 -0
- package/dist/src/serve/openai-compat.js +144 -0
- package/dist/src/serve/server.js +251 -0
- package/dist/src/serve/types.js +2 -0
- package/dist/src/serve/websocket.js +28 -0
- package/dist/src/ui/cli-ink.js +22 -2
- package/dist/src/web/app.js +350 -0
- package/dist/src/web/index.html +49 -0
- package/dist/src/web/style.css +422 -0
- package/dist/tests/agent.test.js +62 -0
- package/dist/tests/cli-args.test.js +4 -2
- package/dist/tests/serve.integration.test.js +534 -0
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts +30 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js +212 -8
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/types.d.ts +10 -0
- package/node_modules/@minicode/agent-sdk/dist/src/agent/types.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.js +2 -0
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.d.ts +51 -1
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.js +210 -2
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tests/session.test.js +75 -0
- package/node_modules/@minicode/agent-sdk/dist/tests/session.test.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
*, *::before, *::after {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
--bg: #1a1b26;
|
|
9
|
+
--bg-surface: #222336;
|
|
10
|
+
--bg-hover: #2a2b3d;
|
|
11
|
+
--text: #c0caf5;
|
|
12
|
+
--text-dim: #565f89;
|
|
13
|
+
--accent: #7aa2f7;
|
|
14
|
+
--accent-dim: #3d59a1;
|
|
15
|
+
--green: #9ece6a;
|
|
16
|
+
--yellow: #e0af68;
|
|
17
|
+
--red: #f7768e;
|
|
18
|
+
--border: #33354a;
|
|
19
|
+
--font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace;
|
|
20
|
+
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
html, body {
|
|
24
|
+
height: 100%;
|
|
25
|
+
background: var(--bg);
|
|
26
|
+
color: var(--text);
|
|
27
|
+
font-family: var(--font-mono);
|
|
28
|
+
font-size: 14px;
|
|
29
|
+
line-height: 1.6;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#app {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
height: 100vh;
|
|
36
|
+
max-width: 900px;
|
|
37
|
+
margin: 0 auto;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Header */
|
|
41
|
+
header {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: space-between;
|
|
45
|
+
padding: 12px 16px;
|
|
46
|
+
border-bottom: 1px solid var(--border);
|
|
47
|
+
flex-shrink: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.header-left {
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: 12px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
h1 {
|
|
57
|
+
font-size: 16px;
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
color: var(--accent);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.header-right {
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 12px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#model-info {
|
|
69
|
+
font-size: 12px;
|
|
70
|
+
color: var(--text-dim);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Session menu */
|
|
74
|
+
.session-menu {
|
|
75
|
+
position: relative;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.header-btn {
|
|
79
|
+
background: var(--bg-surface);
|
|
80
|
+
border: 1px solid var(--border);
|
|
81
|
+
color: var(--text-dim);
|
|
82
|
+
font-family: var(--font-mono);
|
|
83
|
+
font-size: 12px;
|
|
84
|
+
padding: 4px 10px;
|
|
85
|
+
border-radius: 4px;
|
|
86
|
+
cursor: pointer;
|
|
87
|
+
transition: color 0.15s, border-color 0.15s;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.header-btn:hover {
|
|
91
|
+
color: var(--text);
|
|
92
|
+
border-color: var(--accent-dim);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.dropdown {
|
|
96
|
+
position: absolute;
|
|
97
|
+
top: calc(100% + 6px);
|
|
98
|
+
right: 0;
|
|
99
|
+
min-width: 260px;
|
|
100
|
+
background: var(--bg-surface);
|
|
101
|
+
border: 1px solid var(--border);
|
|
102
|
+
border-radius: 6px;
|
|
103
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
|
104
|
+
z-index: 100;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.dropdown-section {
|
|
109
|
+
padding: 8px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.dropdown-divider {
|
|
113
|
+
height: 1px;
|
|
114
|
+
background: var(--border);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.dropdown-row {
|
|
118
|
+
display: flex;
|
|
119
|
+
gap: 6px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.dropdown-row input {
|
|
123
|
+
flex: 1;
|
|
124
|
+
background: var(--bg);
|
|
125
|
+
border: 1px solid var(--border);
|
|
126
|
+
border-radius: 4px;
|
|
127
|
+
color: var(--text);
|
|
128
|
+
font-family: var(--font-mono);
|
|
129
|
+
font-size: 12px;
|
|
130
|
+
padding: 5px 8px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.dropdown-row input:focus {
|
|
134
|
+
outline: none;
|
|
135
|
+
border-color: var(--accent-dim);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.dropdown-action {
|
|
139
|
+
background: var(--accent-dim);
|
|
140
|
+
border: none;
|
|
141
|
+
color: var(--text);
|
|
142
|
+
font-family: var(--font-mono);
|
|
143
|
+
font-size: 12px;
|
|
144
|
+
padding: 5px 12px;
|
|
145
|
+
border-radius: 4px;
|
|
146
|
+
cursor: pointer;
|
|
147
|
+
flex-shrink: 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.dropdown-action:hover {
|
|
151
|
+
background: var(--accent);
|
|
152
|
+
color: var(--bg);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.dropdown-empty {
|
|
156
|
+
font-size: 12px;
|
|
157
|
+
color: var(--text-dim);
|
|
158
|
+
text-align: center;
|
|
159
|
+
padding: 8px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.session-item {
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: center;
|
|
165
|
+
justify-content: space-between;
|
|
166
|
+
padding: 6px 8px;
|
|
167
|
+
border-radius: 4px;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
transition: background 0.15s;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.session-item:hover {
|
|
174
|
+
background: var(--bg-hover);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.session-label {
|
|
178
|
+
color: var(--text);
|
|
179
|
+
overflow: hidden;
|
|
180
|
+
text-overflow: ellipsis;
|
|
181
|
+
white-space: nowrap;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.session-meta {
|
|
185
|
+
color: var(--text-dim);
|
|
186
|
+
font-size: 11px;
|
|
187
|
+
flex-shrink: 0;
|
|
188
|
+
margin-left: 8px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.badge {
|
|
192
|
+
font-size: 11px;
|
|
193
|
+
padding: 2px 8px;
|
|
194
|
+
border-radius: 10px;
|
|
195
|
+
font-weight: 500;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.badge.ready {
|
|
199
|
+
background: rgba(158, 206, 106, 0.15);
|
|
200
|
+
color: var(--green);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.badge.busy {
|
|
204
|
+
background: rgba(224, 175, 104, 0.15);
|
|
205
|
+
color: var(--yellow);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.badge.error {
|
|
209
|
+
background: rgba(247, 118, 142, 0.15);
|
|
210
|
+
color: var(--red);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Messages */
|
|
214
|
+
main {
|
|
215
|
+
flex: 1;
|
|
216
|
+
overflow-y: auto;
|
|
217
|
+
padding: 16px;
|
|
218
|
+
display: flex;
|
|
219
|
+
flex-direction: column;
|
|
220
|
+
gap: 10px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.message {
|
|
224
|
+
padding: 10px 14px;
|
|
225
|
+
border-radius: 8px;
|
|
226
|
+
max-width: 100%;
|
|
227
|
+
word-wrap: break-word;
|
|
228
|
+
white-space: pre-wrap;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.message.user {
|
|
232
|
+
background: var(--accent-dim);
|
|
233
|
+
color: #fff;
|
|
234
|
+
align-self: flex-end;
|
|
235
|
+
max-width: 80%;
|
|
236
|
+
border-radius: 8px 8px 2px 8px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.message.assistant {
|
|
240
|
+
background: var(--bg-surface);
|
|
241
|
+
border: 1px solid var(--border);
|
|
242
|
+
border-radius: 8px 8px 8px 2px;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.message.error {
|
|
246
|
+
background: rgba(247, 118, 142, 0.1);
|
|
247
|
+
border: 1px solid rgba(247, 118, 142, 0.3);
|
|
248
|
+
color: var(--red);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.message.thinking {
|
|
252
|
+
color: var(--text-dim);
|
|
253
|
+
font-style: italic;
|
|
254
|
+
font-size: 13px;
|
|
255
|
+
padding: 6px 14px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* Tool call group — clusters consecutive tool calls */
|
|
259
|
+
.tool-group {
|
|
260
|
+
display: flex;
|
|
261
|
+
flex-direction: column;
|
|
262
|
+
gap: 2px;
|
|
263
|
+
margin: 2px 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* Tool calls — compact inline pills */
|
|
267
|
+
.tool-call {
|
|
268
|
+
font-size: 12px;
|
|
269
|
+
padding: 4px 10px;
|
|
270
|
+
border-radius: 4px;
|
|
271
|
+
color: var(--text-dim);
|
|
272
|
+
cursor: pointer;
|
|
273
|
+
transition: background 0.15s;
|
|
274
|
+
line-height: 1.4;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.tool-call:hover {
|
|
278
|
+
background: rgba(122, 162, 247, 0.08);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.tool-call .tool-header {
|
|
282
|
+
display: flex;
|
|
283
|
+
align-items: baseline;
|
|
284
|
+
gap: 6px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.tool-call .tool-name {
|
|
288
|
+
color: var(--accent);
|
|
289
|
+
font-weight: 600;
|
|
290
|
+
flex-shrink: 0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.tool-call .tool-arg {
|
|
294
|
+
color: var(--text-dim);
|
|
295
|
+
overflow: hidden;
|
|
296
|
+
text-overflow: ellipsis;
|
|
297
|
+
white-space: nowrap;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.tool-call .tool-time {
|
|
301
|
+
color: var(--text-dim);
|
|
302
|
+
margin-left: auto;
|
|
303
|
+
flex-shrink: 0;
|
|
304
|
+
font-size: 11px;
|
|
305
|
+
opacity: 0.7;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.tool-call .tool-result {
|
|
309
|
+
display: none;
|
|
310
|
+
margin-top: 6px;
|
|
311
|
+
padding: 6px 8px;
|
|
312
|
+
border-radius: 3px;
|
|
313
|
+
background: rgba(0, 0, 0, 0.2);
|
|
314
|
+
white-space: pre-wrap;
|
|
315
|
+
max-height: 200px;
|
|
316
|
+
overflow-y: auto;
|
|
317
|
+
font-size: 11px;
|
|
318
|
+
color: var(--text-dim);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.tool-call.expanded .tool-result {
|
|
322
|
+
display: block;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Streaming cursor */
|
|
326
|
+
.streaming-cursor::after {
|
|
327
|
+
content: '\25CC';
|
|
328
|
+
animation: blink 0.8s step-end infinite;
|
|
329
|
+
color: var(--accent);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@keyframes blink {
|
|
333
|
+
50% { opacity: 0; }
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* Usage info */
|
|
337
|
+
.usage-info {
|
|
338
|
+
font-size: 11px;
|
|
339
|
+
color: var(--text-dim);
|
|
340
|
+
opacity: 0.6;
|
|
341
|
+
text-align: right;
|
|
342
|
+
padding: 2px 4px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* Footer / Input */
|
|
346
|
+
footer {
|
|
347
|
+
padding: 12px 16px;
|
|
348
|
+
border-top: 1px solid var(--border);
|
|
349
|
+
flex-shrink: 0;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#chat-form {
|
|
353
|
+
display: flex;
|
|
354
|
+
gap: 8px;
|
|
355
|
+
align-items: flex-end;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
#chat-input {
|
|
359
|
+
flex: 1;
|
|
360
|
+
background: var(--bg-surface);
|
|
361
|
+
border: 1px solid var(--border);
|
|
362
|
+
border-radius: 6px;
|
|
363
|
+
color: var(--text);
|
|
364
|
+
font-family: var(--font-mono);
|
|
365
|
+
font-size: 14px;
|
|
366
|
+
padding: 10px 12px;
|
|
367
|
+
resize: none;
|
|
368
|
+
max-height: 150px;
|
|
369
|
+
line-height: 1.5;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
#chat-input:focus {
|
|
373
|
+
outline: none;
|
|
374
|
+
border-color: var(--accent);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
#send-btn, #cancel-btn {
|
|
378
|
+
padding: 10px 18px;
|
|
379
|
+
border: none;
|
|
380
|
+
border-radius: 6px;
|
|
381
|
+
font-family: var(--font-mono);
|
|
382
|
+
font-size: 13px;
|
|
383
|
+
font-weight: 600;
|
|
384
|
+
cursor: pointer;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
#send-btn {
|
|
388
|
+
background: var(--accent);
|
|
389
|
+
color: var(--bg);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
#send-btn:hover {
|
|
393
|
+
opacity: 0.9;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
#send-btn:disabled {
|
|
397
|
+
opacity: 0.4;
|
|
398
|
+
cursor: not-allowed;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
#cancel-btn {
|
|
402
|
+
background: var(--red);
|
|
403
|
+
color: #fff;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.hidden {
|
|
407
|
+
display: none !important;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* Scrollbar */
|
|
411
|
+
main::-webkit-scrollbar {
|
|
412
|
+
width: 6px;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
main::-webkit-scrollbar-track {
|
|
416
|
+
background: transparent;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
main::-webkit-scrollbar-thumb {
|
|
420
|
+
background: var(--border);
|
|
421
|
+
border-radius: 3px;
|
|
422
|
+
}
|
package/dist/tests/agent.test.js
CHANGED
|
@@ -102,6 +102,68 @@ test("agent omits code map when projectIndex is not provided", async () => {
|
|
|
102
102
|
await agent.runTurn("Hello");
|
|
103
103
|
assert.ok(!capturedSystem.includes("[Project Code Map]"));
|
|
104
104
|
});
|
|
105
|
+
test("agent caps thinking text in session but preserves final response", async () => {
|
|
106
|
+
const longThinking = "I need to analyze this carefully. ".repeat(20); // ~660 chars, well over 200
|
|
107
|
+
const finalResponse = "Here is the complete and detailed answer that should not be truncated at all. ".repeat(10); // ~780 chars
|
|
108
|
+
const responses = [
|
|
109
|
+
{
|
|
110
|
+
text: longThinking,
|
|
111
|
+
toolCalls: [{ id: "tool-1", name: "echo_tool", input: { value: "ok" } }],
|
|
112
|
+
stopReason: "tool_use",
|
|
113
|
+
usage: { inputTokens: 10, outputTokens: 8 },
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
text: finalResponse,
|
|
117
|
+
toolCalls: [],
|
|
118
|
+
stopReason: "end_turn",
|
|
119
|
+
usage: { inputTokens: 12, outputTokens: 6 },
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
const agent = new CodingAgent({
|
|
123
|
+
config: createTestAgentConfig("/tmp"),
|
|
124
|
+
modelClient: new SequenceModelClient(responses),
|
|
125
|
+
toolRegistry: new ToolRegistry([createEchoTool()]),
|
|
126
|
+
});
|
|
127
|
+
const { text } = await agent.runTurn("Do something complex");
|
|
128
|
+
const messages = agent.getSession().getMessages();
|
|
129
|
+
// Thinking message (assistant with toolCalls) should be capped at ~200 chars + "..."
|
|
130
|
+
const thinkingMsg = messages[1];
|
|
131
|
+
assert.equal(thinkingMsg?.role, "assistant");
|
|
132
|
+
assert.ok(thinkingMsg?.role === "assistant" && thinkingMsg.content.length <= 204, `Thinking should be capped but was ${thinkingMsg?.role === "assistant" ? thinkingMsg.content.length : "?"} chars`);
|
|
133
|
+
assert.ok(thinkingMsg?.role === "assistant" && thinkingMsg.content.endsWith("..."), "Capped thinking should end with ellipsis");
|
|
134
|
+
// Final response (assistant without toolCalls) should be preserved in full
|
|
135
|
+
const finalMsg = messages[3];
|
|
136
|
+
assert.equal(finalMsg?.role, "assistant");
|
|
137
|
+
assert.equal(text, finalResponse);
|
|
138
|
+
assert.ok(finalMsg?.role === "assistant" && finalMsg.content === finalResponse, "Final response should not be truncated");
|
|
139
|
+
});
|
|
140
|
+
test("agent preserves short thinking text without capping", async () => {
|
|
141
|
+
const shortThinking = "Let me check.";
|
|
142
|
+
const responses = [
|
|
143
|
+
{
|
|
144
|
+
text: shortThinking,
|
|
145
|
+
toolCalls: [{ id: "tool-1", name: "echo_tool", input: { value: "ok" } }],
|
|
146
|
+
stopReason: "tool_use",
|
|
147
|
+
usage: { inputTokens: 10, outputTokens: 8 },
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
text: "Done.",
|
|
151
|
+
toolCalls: [],
|
|
152
|
+
stopReason: "end_turn",
|
|
153
|
+
usage: { inputTokens: 12, outputTokens: 6 },
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
const agent = new CodingAgent({
|
|
157
|
+
config: createTestAgentConfig("/tmp"),
|
|
158
|
+
modelClient: new SequenceModelClient(responses),
|
|
159
|
+
toolRegistry: new ToolRegistry([createEchoTool()]),
|
|
160
|
+
});
|
|
161
|
+
await agent.runTurn("Quick task");
|
|
162
|
+
const messages = agent.getSession().getMessages();
|
|
163
|
+
const thinkingMsg = messages[1];
|
|
164
|
+
assert.equal(thinkingMsg?.role, "assistant");
|
|
165
|
+
assert.ok(thinkingMsg?.role === "assistant" && thinkingMsg.content === shortThinking, "Short thinking should be preserved verbatim");
|
|
166
|
+
});
|
|
105
167
|
test("agent includes code map in system prompt when projectIndex is provided", async () => {
|
|
106
168
|
const root = path.resolve(import.meta.dirname, "..");
|
|
107
169
|
const projectIndex = await buildProjectIndex(root);
|
|
@@ -58,16 +58,18 @@ test("parseCliArgs rejects --out without value", () => {
|
|
|
58
58
|
assert.throws(() => parseCliArgs(["node", "src/index.ts", "--oneshot", "--out"]), CliUsageError);
|
|
59
59
|
});
|
|
60
60
|
test("validateCliArgs rejects oneshot without task", () => {
|
|
61
|
-
assert.throws(() => validateCliArgs({ verbose: false, oneshot: true, json: false, task: "" }), /--oneshot requires a task prompt/);
|
|
61
|
+
assert.throws(() => validateCliArgs({ verbose: false, oneshot: true, json: false, serve: false, port: 4567, task: "" }), /--oneshot requires a task prompt/);
|
|
62
62
|
});
|
|
63
63
|
test("validateCliArgs rejects json without oneshot", () => {
|
|
64
64
|
assert.throws(() => validateCliArgs({
|
|
65
65
|
verbose: false,
|
|
66
66
|
oneshot: false,
|
|
67
67
|
json: true,
|
|
68
|
+
serve: false,
|
|
69
|
+
port: 4567,
|
|
68
70
|
task: "hello",
|
|
69
71
|
}), /only supported with --oneshot/);
|
|
70
72
|
});
|
|
71
73
|
test("validateCliArgs allows non-oneshot empty task", () => {
|
|
72
|
-
assert.doesNotThrow(() => validateCliArgs({ verbose: false, oneshot: false, json: false, task: "" }));
|
|
74
|
+
assert.doesNotThrow(() => validateCliArgs({ verbose: false, oneshot: false, json: false, serve: false, port: 4567, task: "" }));
|
|
73
75
|
});
|