thatgfsj-code 0.7.0 → 0.7.2
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/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +5 -0
- package/dist/app/index.js.map +1 -1
- package/dist/cmd/index.d.ts +0 -5
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +36 -56
- package/dist/cmd/index.js.map +1 -1
- package/dist/session/index.d.ts +5 -21
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +26 -22
- package/dist/session/index.js.map +1 -1
- package/dist/tools/nwt.d.ts +5 -0
- package/dist/tools/nwt.d.ts.map +1 -1
- package/dist/tools/nwt.js +68 -0
- package/dist/tools/nwt.js.map +1 -1
- package/dist/tui/app.js +1 -1
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components/ChatList.d.ts +1 -1
- package/dist/tui/components/ChatList.d.ts.map +1 -1
- package/dist/tui/components/ChatList.js +5 -3
- package/dist/tui/components/ChatList.js.map +1 -1
- package/dist/tui/components/ChatMessage.d.ts +1 -1
- package/dist/tui/components/ChatMessage.d.ts.map +1 -1
- package/dist/tui/components/ChatMessage.js +4 -2
- package/dist/tui/components/ChatMessage.js.map +1 -1
- package/dist/tui/components/Header.d.ts +1 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +5 -3
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/StatusBar.d.ts +1 -1
- package/dist/tui/components/StatusBar.d.ts.map +1 -1
- package/dist/tui/components/StatusBar.js +4 -2
- package/dist/tui/components/StatusBar.js.map +1 -1
- package/dist/tui/components/Thinking.d.ts +2 -1
- package/dist/tui/components/Thinking.d.ts.map +1 -1
- package/dist/tui/components/Thinking.js +5 -1
- package/dist/tui/components/Thinking.js.map +1 -1
- package/dist/tui/components/UserInput.d.ts +1 -1
- package/dist/tui/components/UserInput.d.ts.map +1 -1
- package/dist/tui/components/UserInput.js +5 -22
- package/dist/tui/components/UserInput.js.map +1 -1
- package/package.json +1 -1
- package/src/app/index.ts +6 -0
- package/src/cmd/index.tsx +38 -51
- package/src/session/index.ts +28 -22
- package/src/tools/nwt.ts +68 -0
- package/src/tui/app.tsx +1 -1
- package/src/tui/components/ChatList.tsx +4 -4
- package/src/tui/components/ChatMessage.tsx +2 -2
- package/src/tui/components/Header.tsx +3 -3
- package/src/tui/components/StatusBar.tsx +2 -2
- package/src/tui/components/Thinking.tsx +7 -1
- package/src/tui/components/UserInput.tsx +8 -24
- package/dist/app/agent.d.ts +0 -31
- package/dist/app/agent.d.ts.map +0 -1
- package/dist/app/agent.js +0 -106
- package/dist/app/agent.js.map +0 -1
- package/dist/tui/input.d.ts +0 -13
- package/dist/tui/input.d.ts.map +0 -1
- package/dist/tui/input.js +0 -47
- package/dist/tui/input.js.map +0 -1
- package/dist/tui/output.d.ts +0 -44
- package/dist/tui/output.d.ts.map +0 -1
- package/dist/tui/output.js +0 -202
- package/dist/tui/output.js.map +0 -1
- package/dist/tui/repl.d.ts +0 -15
- package/dist/tui/repl.d.ts.map +0 -1
- package/dist/tui/repl.js +0 -162
- package/dist/tui/repl.js.map +0 -1
- package/install.bat +0 -63
- package/install.ps1 +0 -217
- package/install.sh +0 -113
- package/src/tui/input.ts +0 -53
- package/src/tui/output.ts +0 -235
- package/src/tui/repl.ts +0 -181
package/src/tools/nwt.ts
CHANGED
|
@@ -107,6 +107,9 @@ export class NwtTool implements Tool {
|
|
|
107
107
|
if (!existsSync(eventsDir)) mkdirSync(eventsDir, { recursive: true });
|
|
108
108
|
if (!existsSync(archiveDir)) mkdirSync(archiveDir, { recursive: true });
|
|
109
109
|
|
|
110
|
+
// Auto-archive events older than 30 days on every init
|
|
111
|
+
this.autoArchiveIfNeeded(cwd);
|
|
112
|
+
|
|
110
113
|
// Write metadata
|
|
111
114
|
const meta = {
|
|
112
115
|
version: '1.0.0',
|
|
@@ -340,6 +343,71 @@ export class NwtTool implements Tool {
|
|
|
340
343
|
};
|
|
341
344
|
}
|
|
342
345
|
|
|
346
|
+
// ── Auto Archive ──────────────────────────────────────
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Auto-archive events older than 30 days.
|
|
350
|
+
* Runs silently on init - no output unless something was archived.
|
|
351
|
+
*/
|
|
352
|
+
private autoArchiveIfNeeded(cwd: string): void {
|
|
353
|
+
try {
|
|
354
|
+
const nwtDir = join(cwd, NWT_DIR);
|
|
355
|
+
const eventsDir = join(nwtDir, EVENTS_DIR);
|
|
356
|
+
const archiveDir = join(nwtDir, ARCHIVE_DIR);
|
|
357
|
+
|
|
358
|
+
if (!existsSync(eventsDir)) return;
|
|
359
|
+
|
|
360
|
+
const files = readdirSync(eventsDir).filter(f => f.endsWith('.json'));
|
|
361
|
+
if (files.length === 0) return;
|
|
362
|
+
|
|
363
|
+
const cutoff = new Date();
|
|
364
|
+
cutoff.setDate(cutoff.getDate() - ARCHIVE_AFTER_DAYS);
|
|
365
|
+
|
|
366
|
+
const toArchive: string[] = [];
|
|
367
|
+
const toKeep: string[] = [];
|
|
368
|
+
|
|
369
|
+
for (const file of files) {
|
|
370
|
+
try {
|
|
371
|
+
const event = JSON.parse(readFileSync(join(eventsDir, file), 'utf-8'));
|
|
372
|
+
const eventDate = new Date(event.timestamp);
|
|
373
|
+
if (eventDate < cutoff) {
|
|
374
|
+
toArchive.push(file);
|
|
375
|
+
} else {
|
|
376
|
+
toKeep.push(file);
|
|
377
|
+
}
|
|
378
|
+
} catch {
|
|
379
|
+
toKeep.push(file);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (toArchive.length === 0) return;
|
|
384
|
+
|
|
385
|
+
// Create monthly archive file
|
|
386
|
+
const archiveName = `archive-${new Date().toISOString().split('T')[0]}.json`;
|
|
387
|
+
const archiveEvents = toArchive.map(f => {
|
|
388
|
+
return JSON.parse(readFileSync(join(eventsDir, f), 'utf-8'));
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
if (!existsSync(archiveDir)) mkdirSync(archiveDir, { recursive: true });
|
|
392
|
+
|
|
393
|
+
// Append to existing archive or create new
|
|
394
|
+
const archivePath = join(archiveDir, archiveName);
|
|
395
|
+
let existing: any[] = [];
|
|
396
|
+
if (existsSync(archivePath)) {
|
|
397
|
+
try { existing = JSON.parse(readFileSync(archivePath, 'utf-8')); } catch {}
|
|
398
|
+
}
|
|
399
|
+
existing.push(...archiveEvents);
|
|
400
|
+
writeFileSync(archivePath, JSON.stringify(existing, null, 2));
|
|
401
|
+
|
|
402
|
+
// Remove archived files from events dir
|
|
403
|
+
for (const file of toArchive) {
|
|
404
|
+
try { renameSync(join(eventsDir, file), join(archiveDir, file)); } catch {}
|
|
405
|
+
}
|
|
406
|
+
} catch {
|
|
407
|
+
// Silent fail - don't break init
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
343
411
|
// ── Helpers ───────────────────────────────────────────
|
|
344
412
|
|
|
345
413
|
private loadEvents(cwd: string): TimelineEvent[] {
|
package/src/tui/app.tsx
CHANGED
|
@@ -53,7 +53,7 @@ export function TuiApp({ app }: Props) {
|
|
|
53
53
|
streamingToolCalls={streamingToolCalls}
|
|
54
54
|
width={terminalWidth - 4}
|
|
55
55
|
/>
|
|
56
|
-
{isThinking
|
|
56
|
+
<Thinking active={isThinking} />
|
|
57
57
|
<UserInput onSubmit={onSubmit} disabled={isThinking} />
|
|
58
58
|
<StatusBar messageCount={allMessages.length} skills={activeSkills} />
|
|
59
59
|
</Box>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsxImportSource react */
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { memo } from 'react';
|
|
3
3
|
import { Box } from 'ink';
|
|
4
4
|
import { ChatMessage, type MessageData } from './ChatMessage.js';
|
|
5
5
|
import type { ToolCallData } from './ToolCall.js';
|
|
@@ -11,9 +11,9 @@ interface Props {
|
|
|
11
11
|
width?: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export function ChatList({ messages, streaming, streamingToolCalls, width }: Props) {
|
|
14
|
+
export const ChatList = memo(function ChatList({ messages, streaming, streamingToolCalls, width }: Props) {
|
|
15
15
|
return (
|
|
16
|
-
<Box flexDirection="column"
|
|
16
|
+
<Box flexDirection="column">
|
|
17
17
|
{messages.map((msg, i) => (
|
|
18
18
|
<ChatMessage key={i} message={msg} width={width} />
|
|
19
19
|
))}
|
|
@@ -29,4 +29,4 @@ export function ChatList({ messages, streaming, streamingToolCalls, width }: Pro
|
|
|
29
29
|
)}
|
|
30
30
|
</Box>
|
|
31
31
|
);
|
|
32
|
-
}
|
|
32
|
+
});
|
|
@@ -44,11 +44,11 @@ function AssistantMessage({ content, toolCalls, width }: { content: string; tool
|
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export function ChatMessage({ message, width }: Props) {
|
|
47
|
+
export const ChatMessage = React.memo(function ChatMessage({ message, width }: Props) {
|
|
48
48
|
if (message.role === 'user') {
|
|
49
49
|
return <UserMessage content={message.content} width={width} />;
|
|
50
50
|
}
|
|
51
51
|
return <AssistantMessage content={message.content} toolCalls={message.toolCalls} width={width} />;
|
|
52
|
-
}
|
|
52
|
+
});
|
|
53
53
|
|
|
54
54
|
export type { MessageData };
|
|
@@ -7,14 +7,14 @@ interface Props {
|
|
|
7
7
|
model: string;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function Header({ provider, model }: Props) {
|
|
10
|
+
export const Header = React.memo(function Header({ provider, model }: Props) {
|
|
11
11
|
return (
|
|
12
12
|
<Box flexDirection="column" marginBottom={0}>
|
|
13
13
|
<Box justifyContent="space-between" width="100%">
|
|
14
14
|
<Box>
|
|
15
15
|
<Text color="#06B6D4" bold> ⚡ </Text>
|
|
16
16
|
<Text color="#22D3EE" bold>THATGFSJ CODE</Text>
|
|
17
|
-
<Text dimColor> v0.7.
|
|
17
|
+
<Text dimColor> v0.7.2</Text>
|
|
18
18
|
</Box>
|
|
19
19
|
<Box>
|
|
20
20
|
<Text color="#06B6D4" bold> {provider} </Text>
|
|
@@ -25,4 +25,4 @@ export function Header({ provider, model }: Props) {
|
|
|
25
25
|
<Text color="#374151">{'─'.repeat(80)}</Text>
|
|
26
26
|
</Box>
|
|
27
27
|
);
|
|
28
|
-
}
|
|
28
|
+
});
|
|
@@ -7,7 +7,7 @@ interface Props {
|
|
|
7
7
|
skills: string[];
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function StatusBar({ messageCount, skills }: Props) {
|
|
10
|
+
export const StatusBar = React.memo(function StatusBar({ messageCount, skills }: Props) {
|
|
11
11
|
const activeSkills = skills.slice(0, 3).join(', ');
|
|
12
12
|
const moreSkills = skills.length > 3 ? ` +${skills.length - 3}` : '';
|
|
13
13
|
|
|
@@ -27,4 +27,4 @@ export function StatusBar({ messageCount, skills }: Props) {
|
|
|
27
27
|
</Box>
|
|
28
28
|
</Box>
|
|
29
29
|
);
|
|
30
|
-
}
|
|
30
|
+
});
|
|
@@ -4,10 +4,16 @@ import { Box, Text } from 'ink';
|
|
|
4
4
|
import Spinner from 'ink-spinner';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
+
active?: boolean;
|
|
7
8
|
message?: string;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export function Thinking({ message = 'Thinking' }: Props) {
|
|
11
|
+
export function Thinking({ active = true, message = 'Thinking' }: Props) {
|
|
12
|
+
if (!active) {
|
|
13
|
+
// Keep layout stable - render empty space
|
|
14
|
+
return <Box paddingY={0}><Text> </Text></Box>;
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
return (
|
|
12
18
|
<Box paddingLeft={1}>
|
|
13
19
|
<Text color="#06B6D4">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsxImportSource react */
|
|
2
|
-
import React, { useState } from 'react';
|
|
2
|
+
import React, { useState, memo } from 'react';
|
|
3
3
|
import { Box, Text, useInput, useApp } from 'ink';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
@@ -7,9 +7,8 @@ interface Props {
|
|
|
7
7
|
disabled?: boolean;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function UserInput({ onSubmit, disabled }: Props) {
|
|
10
|
+
export const UserInput = memo(function UserInput({ onSubmit, disabled }: Props) {
|
|
11
11
|
const [value, setValue] = useState('');
|
|
12
|
-
const [cursorPos, setCursorPos] = useState(0);
|
|
13
12
|
const [history, setHistory] = useState<string[]>([]);
|
|
14
13
|
const [historyIdx, setHistoryIdx] = useState(-1);
|
|
15
14
|
const { exit } = useApp();
|
|
@@ -20,15 +19,11 @@ export function UserInput({ onSubmit, disabled }: Props) {
|
|
|
20
19
|
if (key.return) {
|
|
21
20
|
const trimmed = value.trim();
|
|
22
21
|
if (trimmed) {
|
|
23
|
-
if (trimmed === 'exit' || trimmed === 'quit') {
|
|
24
|
-
exit();
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
22
|
+
if (trimmed === 'exit' || trimmed === 'quit') { exit(); return; }
|
|
27
23
|
setHistory(prev => [...prev, trimmed]);
|
|
28
24
|
setHistoryIdx(-1);
|
|
29
25
|
onSubmit(trimmed);
|
|
30
26
|
setValue('');
|
|
31
|
-
setCursorPos(0);
|
|
32
27
|
}
|
|
33
28
|
return;
|
|
34
29
|
}
|
|
@@ -37,39 +32,28 @@ export function UserInput({ onSubmit, disabled }: Props) {
|
|
|
37
32
|
const newIdx = historyIdx === -1 ? history.length - 1 : Math.max(0, historyIdx - 1);
|
|
38
33
|
setHistoryIdx(newIdx);
|
|
39
34
|
setValue(history[newIdx]);
|
|
40
|
-
setCursorPos(history[newIdx].length);
|
|
41
35
|
return;
|
|
42
36
|
}
|
|
43
37
|
|
|
44
38
|
if (key.downArrow && historyIdx >= 0) {
|
|
45
39
|
const newIdx = historyIdx + 1;
|
|
46
40
|
if (newIdx >= history.length) {
|
|
47
|
-
setHistoryIdx(-1);
|
|
48
|
-
setValue('');
|
|
49
|
-
setCursorPos(0);
|
|
41
|
+
setHistoryIdx(-1); setValue('');
|
|
50
42
|
} else {
|
|
51
|
-
setHistoryIdx(newIdx);
|
|
52
|
-
setValue(history[newIdx]);
|
|
53
|
-
setCursorPos(history[newIdx].length);
|
|
43
|
+
setHistoryIdx(newIdx); setValue(history[newIdx]);
|
|
54
44
|
}
|
|
55
45
|
return;
|
|
56
46
|
}
|
|
57
47
|
|
|
58
48
|
if (key.backspace || key.delete) {
|
|
59
|
-
|
|
60
|
-
setValue(v => v.slice(0, cursorPos - 1) + v.slice(cursorPos));
|
|
61
|
-
setCursorPos(p => p - 1);
|
|
62
|
-
}
|
|
49
|
+
setValue(v => v.slice(0, -1));
|
|
63
50
|
return;
|
|
64
51
|
}
|
|
65
52
|
|
|
66
|
-
if (key.leftArrow) { setCursorPos(p => Math.max(0, p - 1)); return; }
|
|
67
|
-
if (key.rightArrow) { setCursorPos(p => Math.min(value.length, p + 1)); return; }
|
|
68
53
|
if (key.ctrl && input === 'c') { exit(); return; }
|
|
69
54
|
|
|
70
55
|
if (input && !key.ctrl && !key.meta) {
|
|
71
|
-
setValue(v => v
|
|
72
|
-
setCursorPos(p => p + input.length);
|
|
56
|
+
setValue(v => v + input);
|
|
73
57
|
}
|
|
74
58
|
});
|
|
75
59
|
|
|
@@ -80,4 +64,4 @@ export function UserInput({ onSubmit, disabled }: Props) {
|
|
|
80
64
|
{!disabled && <Text color="#06B6D4">█</Text>}
|
|
81
65
|
</Box>
|
|
82
66
|
);
|
|
83
|
-
}
|
|
67
|
+
});
|
package/dist/app/agent.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Loop - Core agent logic with streaming and tool execution
|
|
3
|
-
* Extracted from old src/core/ai-engine.ts
|
|
4
|
-
*
|
|
5
|
-
* The agent loop: while(true) { stream response → check tool calls → execute → repeat }
|
|
6
|
-
*/
|
|
7
|
-
import type { ChatMessage, ChatResponse } from '../types.js';
|
|
8
|
-
import type { HookManager } from '../hooks/index.js';
|
|
9
|
-
import { LLMService } from '../llm/index.js';
|
|
10
|
-
import { ToolRegistry } from '../tools/index.js';
|
|
11
|
-
export interface AgentConfig {
|
|
12
|
-
maxIterations?: number;
|
|
13
|
-
hooks?: HookManager;
|
|
14
|
-
}
|
|
15
|
-
export declare class Agent {
|
|
16
|
-
private llm;
|
|
17
|
-
private registry;
|
|
18
|
-
private hooks?;
|
|
19
|
-
private maxIterations;
|
|
20
|
-
constructor(llm: LLMService, registry: ToolRegistry, config?: AgentConfig);
|
|
21
|
-
/**
|
|
22
|
-
* Run agent loop with streaming output
|
|
23
|
-
* Returns the final response
|
|
24
|
-
*/
|
|
25
|
-
run(messages: ChatMessage[]): AsyncGenerator<string, ChatResponse>;
|
|
26
|
-
/**
|
|
27
|
-
* Non-streaming chat (convenience method)
|
|
28
|
-
*/
|
|
29
|
-
chat(messages: ChatMessage[]): Promise<ChatResponse>;
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=agent.d.ts.map
|
package/dist/app/agent.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/app/agent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,KAAK,CAAC,CAAc;IAC5B,OAAO,CAAC,aAAa,CAAS;gBAElB,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAE,WAAgB;IAU7E;;;OAGG;IACI,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,YAAY,CAAC;IA0FzE;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;CAO3D"}
|
package/dist/app/agent.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Loop - Core agent logic with streaming and tool execution
|
|
3
|
-
* Extracted from old src/core/ai-engine.ts
|
|
4
|
-
*
|
|
5
|
-
* The agent loop: while(true) { stream response → check tool calls → execute → repeat }
|
|
6
|
-
*/
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
export class Agent {
|
|
9
|
-
llm;
|
|
10
|
-
registry;
|
|
11
|
-
hooks;
|
|
12
|
-
maxIterations;
|
|
13
|
-
constructor(llm, registry, config = {}) {
|
|
14
|
-
this.llm = llm;
|
|
15
|
-
this.registry = registry;
|
|
16
|
-
this.hooks = config.hooks;
|
|
17
|
-
this.maxIterations = config.maxIterations ?? 10;
|
|
18
|
-
// Register tools with LLM service
|
|
19
|
-
this.llm.registerTools(registry.list());
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Run agent loop with streaming output
|
|
23
|
-
* Returns the final response
|
|
24
|
-
*/
|
|
25
|
-
async *run(messages) {
|
|
26
|
-
let currentMessages = [...messages];
|
|
27
|
-
let iterations = 0;
|
|
28
|
-
while (iterations < this.maxIterations) {
|
|
29
|
-
iterations++;
|
|
30
|
-
// Hook: beforeAgentLoop
|
|
31
|
-
if (this.hooks) {
|
|
32
|
-
await this.hooks.emit('beforeAgentLoop', { messages: currentMessages, iteration: iterations });
|
|
33
|
-
}
|
|
34
|
-
// Stream the response
|
|
35
|
-
let fullContent = '';
|
|
36
|
-
for await (const chunk of this.llm.chatStream(currentMessages, { maxIterations: 1 })) {
|
|
37
|
-
fullContent += chunk;
|
|
38
|
-
yield chunk;
|
|
39
|
-
}
|
|
40
|
-
// Get the full response to check for tool calls
|
|
41
|
-
const response = {
|
|
42
|
-
content: fullContent,
|
|
43
|
-
role: 'assistant',
|
|
44
|
-
};
|
|
45
|
-
// Check if the response contains tool calls
|
|
46
|
-
// For now, we rely on the LLM service to handle tool calls internally
|
|
47
|
-
// If the LLM service returned tool_calls, we need to process them
|
|
48
|
-
if (response.tool_calls && response.tool_calls.length > 0) {
|
|
49
|
-
currentMessages.push({
|
|
50
|
-
role: 'assistant',
|
|
51
|
-
content: response.content,
|
|
52
|
-
tool_calls: response.tool_calls,
|
|
53
|
-
});
|
|
54
|
-
for (const toolCall of response.tool_calls) {
|
|
55
|
-
// Hook: beforeToolCall
|
|
56
|
-
if (this.hooks) {
|
|
57
|
-
await this.hooks.emit('beforeToolCall', {
|
|
58
|
-
toolName: toolCall.function.name,
|
|
59
|
-
toolParams: JSON.parse(toolCall.function.arguments || '{}'),
|
|
60
|
-
toolCallId: toolCall.id,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
const result = await this.registry.execute(toolCall.function.name, JSON.parse(toolCall.function.arguments || '{}'));
|
|
64
|
-
// Hook: afterToolCall
|
|
65
|
-
if (this.hooks) {
|
|
66
|
-
await this.hooks.emit('afterToolCall', {
|
|
67
|
-
toolName: toolCall.function.name,
|
|
68
|
-
toolParams: JSON.parse(toolCall.function.arguments || '{}'),
|
|
69
|
-
toolResult: result,
|
|
70
|
-
toolCallId: toolCall.id,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
currentMessages.push({
|
|
74
|
-
role: 'tool',
|
|
75
|
-
content: result.success ? (result.output || JSON.stringify(result.data)) : (result.error || 'Tool failed'),
|
|
76
|
-
tool_call_id: toolCall.id,
|
|
77
|
-
name: toolCall.function.name,
|
|
78
|
-
});
|
|
79
|
-
yield `\n${chalk.gray(`[tool: ${toolCall.function.name}]`)}`;
|
|
80
|
-
}
|
|
81
|
-
continue; // Next iteration
|
|
82
|
-
}
|
|
83
|
-
// No tool calls - done
|
|
84
|
-
if (response.content) {
|
|
85
|
-
currentMessages.push({ role: 'assistant', content: response.content });
|
|
86
|
-
}
|
|
87
|
-
// Hook: afterAgentLoop
|
|
88
|
-
if (this.hooks) {
|
|
89
|
-
await this.hooks.emit('afterAgentLoop', { messages: currentMessages, iteration: iterations });
|
|
90
|
-
}
|
|
91
|
-
return response;
|
|
92
|
-
}
|
|
93
|
-
return { content: '[Agent loop exceeded maximum iterations]', role: 'assistant' };
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Non-streaming chat (convenience method)
|
|
97
|
-
*/
|
|
98
|
-
async chat(messages) {
|
|
99
|
-
let fullContent = '';
|
|
100
|
-
for await (const chunk of this.run(messages)) {
|
|
101
|
-
fullContent += chunk;
|
|
102
|
-
}
|
|
103
|
-
return { content: fullContent, role: 'assistant' };
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=agent.js.map
|
package/dist/app/agent.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/app/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/tui/input.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* REPL Input Handler
|
|
3
|
-
*/
|
|
4
|
-
export declare class REPLInput {
|
|
5
|
-
private rl;
|
|
6
|
-
private history;
|
|
7
|
-
private historyIndex;
|
|
8
|
-
constructor();
|
|
9
|
-
prompt(prefix?: string): Promise<string>;
|
|
10
|
-
close(): void;
|
|
11
|
-
private completer;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=input.d.ts.map
|
package/dist/tui/input.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/tui/input.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAAqB;IAC/B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAc;;IAyB5B,MAAM,CAAC,MAAM,GAAE,MAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQhE,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,SAAS;CAKlB"}
|
package/dist/tui/input.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* REPL Input Handler
|
|
3
|
-
*/
|
|
4
|
-
import readline from 'readline';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
export class REPLInput {
|
|
7
|
-
rl;
|
|
8
|
-
history = [];
|
|
9
|
-
historyIndex = -1;
|
|
10
|
-
constructor() {
|
|
11
|
-
this.rl = readline.createInterface({
|
|
12
|
-
input: process.stdin,
|
|
13
|
-
output: process.stdout,
|
|
14
|
-
completer: this.completer.bind(this),
|
|
15
|
-
historySize: 100,
|
|
16
|
-
tabSize: 4,
|
|
17
|
-
});
|
|
18
|
-
this.rl.on('SIGINT', () => {
|
|
19
|
-
process.stdout.write(chalk.gray('\n Goodbye! 👋\n'));
|
|
20
|
-
process.exit(0);
|
|
21
|
-
});
|
|
22
|
-
this.rl.on('line', (line) => {
|
|
23
|
-
if (line.trim()) {
|
|
24
|
-
this.history.push(line);
|
|
25
|
-
if (this.history.length > 100)
|
|
26
|
-
this.history.shift();
|
|
27
|
-
}
|
|
28
|
-
this.historyIndex = this.history.length;
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
async prompt(prefix = chalk.cyan('❯ ')) {
|
|
32
|
-
return new Promise((resolve) => {
|
|
33
|
-
this.rl.question(prefix, (answer) => {
|
|
34
|
-
resolve(answer);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
close() {
|
|
39
|
-
this.rl.close();
|
|
40
|
-
}
|
|
41
|
-
completer(line) {
|
|
42
|
-
const commands = ['exit', 'quit', 'clear', 'help', 'tools', 'model'];
|
|
43
|
-
const hits = commands.filter(c => c.startsWith(line.toLowerCase()));
|
|
44
|
-
return [hits.length ? hits : [], line];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=input.js.map
|
package/dist/tui/input.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/tui/input.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,OAAO,SAAS;IACZ,EAAE,CAAqB;IACvB,OAAO,GAAa,EAAE,CAAC;IACvB,YAAY,GAAW,CAAC,CAAC,CAAC;IAElC;QACE,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YACjC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YACpC,WAAW,EAAE,GAAG;YAChB,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG;oBAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACtD,CAAC;YACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;CACF"}
|
package/dist/tui/output.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* REPL Output - Clean terminal UI
|
|
3
|
-
* Inspired by opencode: simple indentation for streaming, clean boundaries
|
|
4
|
-
*/
|
|
5
|
-
export declare class REPLOutput {
|
|
6
|
-
private spinner;
|
|
7
|
-
printBanner(): void;
|
|
8
|
-
getPrompt(): string;
|
|
9
|
-
printUserInput(input: string): void;
|
|
10
|
-
/**
|
|
11
|
-
* Begin assistant response - just print the header
|
|
12
|
-
*/
|
|
13
|
-
beginAssistant(): void;
|
|
14
|
-
/**
|
|
15
|
-
* Write streaming chunk - output as-is with indent.
|
|
16
|
-
* The chunk already contains proper newlines from the AI.
|
|
17
|
-
*/
|
|
18
|
-
writeChunk(chunk: string): void;
|
|
19
|
-
/**
|
|
20
|
-
* End assistant response
|
|
21
|
-
*/
|
|
22
|
-
endAssistant(): void;
|
|
23
|
-
printToolCall(name: string, args: string): void;
|
|
24
|
-
printToolResult(output: string, isError?: boolean): void;
|
|
25
|
-
printToolEnd(): void;
|
|
26
|
-
startThinking(): void;
|
|
27
|
-
startExecuting(toolName: string): void;
|
|
28
|
-
stopThinking(): void;
|
|
29
|
-
stopThinkingFail(msg: string): void;
|
|
30
|
-
info(msg: string): void;
|
|
31
|
-
success(msg: string): void;
|
|
32
|
-
error(msg: string): void;
|
|
33
|
-
warning(msg: string): void;
|
|
34
|
-
dim(msg: string): void;
|
|
35
|
-
divider(): void;
|
|
36
|
-
spacer(): void;
|
|
37
|
-
clear(): void;
|
|
38
|
-
section(title: string, items: Array<{
|
|
39
|
-
label: string;
|
|
40
|
-
value: string;
|
|
41
|
-
}>): void;
|
|
42
|
-
printHelp(): void;
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=output.d.ts.map
|
package/dist/tui/output.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/tui/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAoB;IAInC,WAAW,IAAI,IAAI;IAUnB,SAAS,IAAI,MAAM;IAMnB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAYnC;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAa/B;;OAEG;IACH,YAAY,IAAI,IAAI;IAOpB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwB/C,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,IAAI;IAoBtD,YAAY,IAAI,IAAI;IAMpB,aAAa,IAAI,IAAI;IAQrB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQtC,YAAY,IAAI,IAAI;IAOpB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IASnC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI1B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAUxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMtB,OAAO,IAAI,IAAI;IAIf,MAAM,IAAI,IAAI;IAId,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAY5E,SAAS,IAAI,IAAI;CAsBlB"}
|