gaunt-sloth-assistant 0.8.4 → 0.8.6
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 +19 -0
- package/assets/release-notes/RELEASE-NOTES-HOWTO.md +12 -0
- package/assets/release-notes/v0_8_5.md +12 -0
- package/assets/release-notes/v0_8_6.md +12 -0
- package/dist/consoleUtils.d.ts +1 -1
- package/dist/core/GthAgentRunner.d.ts +17 -0
- package/dist/core/GthAgentRunner.js +66 -0
- package/dist/core/GthAgentRunner.js.map +1 -0
- package/dist/core/{Invocation.d.ts → GthLangChainAgent.d.ts} +18 -6
- package/dist/core/{Invocation.js → GthLangChainAgent.js} +91 -54
- package/dist/core/GthLangChainAgent.js.map +1 -0
- package/dist/core/types.d.ts +11 -0
- package/dist/llmUtils.d.ts +12 -3
- package/dist/llmUtils.js +24 -7
- package/dist/llmUtils.js.map +1 -1
- package/dist/modules/interactiveSessionModule.js +14 -18
- package/dist/modules/interactiveSessionModule.js.map +1 -1
- package/dist/presets/openai.js +2 -0
- package/dist/presets/openai.js.map +1 -1
- package/dist/systemUtils.d.ts +1 -1
- package/dist/systemUtils.js +1 -1
- package/dist/systemUtils.js.map +1 -1
- package/it.js +2 -1
- package/package.json +7 -7
- package/src/consoleUtils.ts +1 -1
- package/src/core/GthAgentRunner.ts +85 -0
- package/src/core/{Invocation.ts → GthLangChainAgent.ts} +101 -63
- package/src/core/types.ts +20 -0
- package/src/llmUtils.ts +26 -11
- package/src/modules/interactiveSessionModule.ts +15 -19
- package/src/presets/openai.ts +2 -0
- package/src/systemUtils.ts +1 -1
- package/vitest-it.config.ts +1 -0
- package/dist/core/Invocation.js.map +0 -1
package/README.md
CHANGED
|
@@ -87,11 +87,30 @@ gsloth pr 42 23 # Review PR #42 with GitHub issue #23
|
|
|
87
87
|
git --no-pager diff | gsloth review
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
**Review changes between a specific tag and the HEAD:**
|
|
91
|
+
```shell
|
|
92
|
+
git --no-pager diff v0.8.3..HEAD | gth review
|
|
93
|
+
```
|
|
94
|
+
|
|
90
95
|
**Ask questions:**
|
|
91
96
|
```shell
|
|
92
97
|
gsloth ask "What does this function do?" -f utils.js
|
|
93
98
|
```
|
|
94
99
|
|
|
100
|
+
**Write release notes:**
|
|
101
|
+
```shell
|
|
102
|
+
git --no-pager diff v0.8.3..HEAD | gth ask "inspect existing release notes in assets/release-notes/v0_8_2.md; inspect provided diff and write release notes to v0_8_4.md"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
To write this to filesystem, you'd need to add filesystem access to the *ask* command in `.gsloth.config.json`.
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{"llm": {"type": "vertexai", "model": "gemini-2.5-pro"}, "commands": {"ask": {"filesystem": "all"}}}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
*You can improve this significantly by modifying project guidelines in `.gsloth.guidelines.md` or maybe with keeping instructions in file and feeding it in with `-f`.
|
|
112
|
+
|
|
113
|
+
|
|
95
114
|
**Interactive sessions:**
|
|
96
115
|
```shell
|
|
97
116
|
gsloth chat # Start chat session
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Release notes howto
|
|
2
|
+
|
|
3
|
+
Maintain dry technical language similar to assets/release-notes/v0_8_0.md.
|
|
4
|
+
|
|
5
|
+
## Process
|
|
6
|
+
- Review changes from the latest tag to HEAD.
|
|
7
|
+
- List assets/release-notes/ and review a few recent release notes.
|
|
8
|
+
- Create a new release notes file for the next patch version if the user didn't specify to write release notes for minor.
|
|
9
|
+
- Don't include information about unit tests, integration tests and other development specific nuances
|
|
10
|
+
- Present release notes to user and ask for confirmation
|
|
11
|
+
- call `git commit -m"release notes for {new_version_number}"`
|
|
12
|
+
- call `npm version patch` for a patch or `npm version minor` appropriately.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# v0.8.5 Async Readline Interface
|
|
2
|
+
|
|
3
|
+
## Improvements
|
|
4
|
+
|
|
5
|
+
### Async Readline Interface Migration
|
|
6
|
+
Interactive sessions now use Node.js's promise-based non-blocking readline interface.
|
|
7
|
+
|
|
8
|
+
### Other minor improvements
|
|
9
|
+
The core agent functionality has been restructured with improved separation of concerns:
|
|
10
|
+
- Renamed `Invocation` class to `GthAgentRunner` for better clarity
|
|
11
|
+
- Extracted React agent logic into a dedicated module
|
|
12
|
+
- Improved initialization flow and dependency management
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# v0.8.6 Fix Regressions and Update Deps
|
|
2
|
+
|
|
3
|
+
## Fixed bugs
|
|
4
|
+
|
|
5
|
+
- Fixed a regression with --verbose app parameter not producing verbose output
|
|
6
|
+
- Fixed a regression with system prompt ending up as user prompt
|
|
7
|
+
|
|
8
|
+
## Updated dependencies
|
|
9
|
+
Bump @langchain/core from 0.3.61 to 0.3.62
|
|
10
|
+
Bump @langchain/anthropic from 0.3.23 to 0.3.24
|
|
11
|
+
Bump @langchain/mcp-adapters from 0.5.2 to 0.5.3
|
|
12
|
+
Bump @langchain/openai from 0.5.16 to 0.5.18
|
package/dist/consoleUtils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StatusUpdateCallback } from '#src/core/
|
|
1
|
+
import { StatusUpdateCallback } from '#src/core/GthLangChainAgent.js';
|
|
2
2
|
export declare function displayError(message: string): void;
|
|
3
3
|
export declare function displayWarning(message: string): void;
|
|
4
4
|
export declare function displaySuccess(message: string): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Message } from '#src/modules/types.js';
|
|
2
|
+
import { SlothConfig } from '#src/config.js';
|
|
3
|
+
import { BaseCheckpointSaver } from '@langchain/langgraph';
|
|
4
|
+
import { GthAgentInterface, GthCommand } from '#src/core/types.js';
|
|
5
|
+
import { StatusUpdateCallback } from '#src/core/GthLangChainAgent.js';
|
|
6
|
+
import { RunnableConfig } from '@langchain/core/runnables';
|
|
7
|
+
export declare class GthAgentRunner {
|
|
8
|
+
private statusUpdate;
|
|
9
|
+
private verbose;
|
|
10
|
+
private agent;
|
|
11
|
+
private config;
|
|
12
|
+
constructor(statusUpdate: StatusUpdateCallback, agent?: GthAgentInterface);
|
|
13
|
+
setVerbose(verbose: boolean): void;
|
|
14
|
+
init(command: GthCommand | undefined, configIn: SlothConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<void>;
|
|
15
|
+
processMessages(messages: Message[], runConfig: RunnableConfig): Promise<string>;
|
|
16
|
+
cleanup(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { GthLangChainAgent } from '#src/core/GthLangChainAgent.js';
|
|
2
|
+
export class GthAgentRunner {
|
|
3
|
+
statusUpdate;
|
|
4
|
+
verbose = false;
|
|
5
|
+
agent = null;
|
|
6
|
+
config = null;
|
|
7
|
+
constructor(statusUpdate, agent) {
|
|
8
|
+
this.statusUpdate = statusUpdate;
|
|
9
|
+
this.agent = agent || null;
|
|
10
|
+
}
|
|
11
|
+
setVerbose(verbose) {
|
|
12
|
+
this.verbose = verbose;
|
|
13
|
+
}
|
|
14
|
+
async init(command, configIn, checkpointSaver) {
|
|
15
|
+
this.config = configIn;
|
|
16
|
+
// Create default agent if none provided
|
|
17
|
+
if (!this.agent) {
|
|
18
|
+
this.agent = new GthLangChainAgent(this.statusUpdate);
|
|
19
|
+
}
|
|
20
|
+
// Set verbose mode before initialization so it can be used during init
|
|
21
|
+
if (this.verbose) {
|
|
22
|
+
this.agent.setVerbose(this.verbose);
|
|
23
|
+
}
|
|
24
|
+
// Initialize the agent if it has an init method
|
|
25
|
+
await this.agent.init(command, configIn, checkpointSaver);
|
|
26
|
+
}
|
|
27
|
+
async processMessages(messages, runConfig) {
|
|
28
|
+
if (!this.agent || !this.config) {
|
|
29
|
+
throw new Error('AgentRunner not initialized. Call init() first.');
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
// Decision: Use streaming or non-streaming based on config
|
|
33
|
+
if (this.config.streamOutput) {
|
|
34
|
+
// Use streaming
|
|
35
|
+
const stream = await this.agent.stream(messages, runConfig);
|
|
36
|
+
let result = '';
|
|
37
|
+
try {
|
|
38
|
+
for await (const chunk of stream) {
|
|
39
|
+
result += chunk;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (streamError) {
|
|
43
|
+
// Handle streaming-specific errors
|
|
44
|
+
throw new Error(`Stream processing failed: ${streamError instanceof Error ? streamError.message : String(streamError)}`);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Use non-streaming
|
|
50
|
+
return await this.agent.invoke(messages, runConfig);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// Handle agent invocation errors
|
|
55
|
+
throw new Error(`Agent processing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async cleanup() {
|
|
59
|
+
if (this.agent && 'cleanup' in this.agent && typeof this.agent.cleanup === 'function') {
|
|
60
|
+
await this.agent.cleanup();
|
|
61
|
+
}
|
|
62
|
+
this.agent = null;
|
|
63
|
+
this.config = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=GthAgentRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GthAgentRunner.js","sourceRoot":"","sources":["../../src/core/GthAgentRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { Message } from '#src/modules/types.js';
|
|
2
1
|
import { SlothConfig } from '#src/config.js';
|
|
3
2
|
import type { Connection } from '@langchain/mcp-adapters';
|
|
4
3
|
import { MultiServerMCPClient } from '@langchain/mcp-adapters';
|
|
5
4
|
import { BaseCheckpointSaver } from '@langchain/langgraph';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { GthAgentInterface, GthCommand, StatusLevel } from '#src/core/types.js';
|
|
6
|
+
import { IterableReadableStream } from '@langchain/core/utils/stream';
|
|
7
|
+
import { RunnableConfig } from '@langchain/core/runnables';
|
|
8
|
+
import type { Message } from '#src/modules/types.js';
|
|
8
9
|
export type StatusUpdateCallback = (level: StatusLevel, message: string) => void;
|
|
9
|
-
export declare class
|
|
10
|
+
export declare class GthLangChainAgent implements GthAgentInterface {
|
|
10
11
|
private statusUpdate;
|
|
11
12
|
private verbose;
|
|
12
13
|
private mcpClient;
|
|
@@ -15,9 +16,20 @@ export declare class Invocation {
|
|
|
15
16
|
constructor(statusUpdate: StatusUpdateCallback);
|
|
16
17
|
setVerbose(verbose: boolean): void;
|
|
17
18
|
init(command: GthCommand | undefined, configIn: SlothConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<void>;
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Invoke LLM with a message and runnable config.
|
|
21
|
+
* For streaming use {@link #stream} method, streaming is preferred if model API supports it.
|
|
22
|
+
* Please note that this when tools are involved, this method will anyway do multiple LLM
|
|
23
|
+
* calls within LangChain dependency.
|
|
24
|
+
*/
|
|
25
|
+
invoke(messages: Message[], runConfig: RunnableConfig): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Induce LLM to stream AI messages with a user message and runnable config.
|
|
28
|
+
* When stream is not appropriate use {@link invoke}.
|
|
29
|
+
*/
|
|
30
|
+
stream(messages: Message[], runConfig: RunnableConfig): Promise<IterableReadableStream<string>>;
|
|
20
31
|
cleanup(): Promise<void>;
|
|
32
|
+
getEffectiveConfig(config: SlothConfig, command: GthCommand | undefined): SlothConfig;
|
|
21
33
|
/**
|
|
22
34
|
* Extract and flatten tools from toolkits
|
|
23
35
|
*/
|
|
@@ -5,7 +5,8 @@ import { formatToolCalls, ProgressIndicator } from '#src/utils.js';
|
|
|
5
5
|
import { getDefaultTools } from '#src/builtInToolsConfig.js';
|
|
6
6
|
import { createAuthProviderAndAuthenticate } from '#src/mcp/OAuthClientProviderImpl.js';
|
|
7
7
|
import { displayInfo } from '#src/consoleUtils.js';
|
|
8
|
-
|
|
8
|
+
import { IterableReadableStream } from '@langchain/core/utils/stream';
|
|
9
|
+
export class GthLangChainAgent {
|
|
9
10
|
statusUpdate;
|
|
10
11
|
verbose = false;
|
|
11
12
|
mcpClient = null;
|
|
@@ -19,6 +20,7 @@ export class Invocation {
|
|
|
19
20
|
this.verbose = verbose;
|
|
20
21
|
}
|
|
21
22
|
async init(command, configIn, checkpointSaver) {
|
|
23
|
+
// Set verbose mode on LLM
|
|
22
24
|
if (this.verbose) {
|
|
23
25
|
configIn.llm.verbose = true;
|
|
24
26
|
}
|
|
@@ -47,76 +49,96 @@ export class Invocation {
|
|
|
47
49
|
checkpointSaver,
|
|
48
50
|
});
|
|
49
51
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
...config,
|
|
57
|
-
filesystem: command && config.commands?.[command]?.filesystem !== undefined
|
|
58
|
-
? config.commands[command].filesystem
|
|
59
|
-
: config.filesystem,
|
|
60
|
-
builtInTools: command && config.commands?.[command]?.builtInTools !== undefined
|
|
61
|
-
? config.commands[command].builtInTools
|
|
62
|
-
: config.builtInTools,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
52
|
+
/**
|
|
53
|
+
* Invoke LLM with a message and runnable config.
|
|
54
|
+
* For streaming use {@link #stream} method, streaming is preferred if model API supports it.
|
|
55
|
+
* Please note that this when tools are involved, this method will anyway do multiple LLM
|
|
56
|
+
* calls within LangChain dependency.
|
|
57
|
+
*/
|
|
65
58
|
async invoke(messages, runConfig) {
|
|
66
59
|
if (!this.agent || !this.config) {
|
|
67
|
-
throw new Error('
|
|
60
|
+
throw new Error('Agent not initialized. Call init() first.');
|
|
68
61
|
}
|
|
69
|
-
// Run the agent
|
|
70
62
|
try {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (toolCalls && toolCalls.length > 0) {
|
|
82
|
-
this.statusUpdate('info', `\nUsed tools: ${formatToolCalls(toolCalls)}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
63
|
+
const progress = new ProgressIndicator('Thinking.');
|
|
64
|
+
try {
|
|
65
|
+
const response = await this.agent.invoke({ messages }, runConfig);
|
|
66
|
+
const aiMessage = response.messages[response.messages.length - 1].content;
|
|
67
|
+
const toolCalls = response.messages
|
|
68
|
+
.filter((msg) => msg.tool_calls && msg.tool_calls.length > 0)
|
|
69
|
+
.flatMap((msg) => msg.tool_calls ?? [])
|
|
70
|
+
.filter((tc) => tc.name);
|
|
71
|
+
if (toolCalls.length > 0) {
|
|
72
|
+
this.statusUpdate('info', `\nUsed tools: ${formatToolCalls(toolCalls)}`);
|
|
85
73
|
}
|
|
74
|
+
this.statusUpdate('display', aiMessage);
|
|
75
|
+
return aiMessage;
|
|
86
76
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const response = await this.agent.invoke({ messages }, runConfig);
|
|
92
|
-
output.aiMessage = response.messages[response.messages.length - 1].content;
|
|
93
|
-
const toolCalls = response.messages
|
|
94
|
-
.filter((msg) => msg.tool_calls && msg.tool_calls.length > 0)
|
|
95
|
-
.flatMap((msg) => msg.tool_calls ?? [])
|
|
96
|
-
.filter((tc) => tc.name);
|
|
97
|
-
if (toolCalls.length > 0) {
|
|
98
|
-
this.statusUpdate('info', `\nUsed tools: ${formatToolCalls(toolCalls)}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch (e) {
|
|
102
|
-
this.statusUpdate('warning', `Something went wrong ${e.message}`);
|
|
103
|
-
}
|
|
104
|
-
finally {
|
|
105
|
-
progress.stop();
|
|
77
|
+
catch (e) {
|
|
78
|
+
if (e instanceof Error && e?.name === 'ToolException') {
|
|
79
|
+
throw e; // Re-throw ToolException to be handled by outer catch
|
|
106
80
|
}
|
|
107
|
-
this.statusUpdate('
|
|
81
|
+
this.statusUpdate('warning', `Something went wrong ${e.message}`);
|
|
82
|
+
return '';
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
progress.stop();
|
|
108
86
|
}
|
|
109
|
-
return output.aiMessage;
|
|
110
87
|
}
|
|
111
88
|
catch (error) {
|
|
112
89
|
if (error instanceof Error) {
|
|
113
90
|
if (error?.name === 'ToolException') {
|
|
114
91
|
this.statusUpdate('error', `Tool execution failed: ${error?.message}`);
|
|
92
|
+
return `Tool execution failed: ${error?.message}`;
|
|
115
93
|
}
|
|
116
94
|
}
|
|
117
95
|
throw error;
|
|
118
96
|
}
|
|
119
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Induce LLM to stream AI messages with a user message and runnable config.
|
|
100
|
+
* When stream is not appropriate use {@link invoke}.
|
|
101
|
+
*/
|
|
102
|
+
async stream(messages, runConfig) {
|
|
103
|
+
if (!this.agent || !this.config) {
|
|
104
|
+
throw new Error('Agent not initialized. Call init() first.');
|
|
105
|
+
}
|
|
106
|
+
this.statusUpdate('info', '\nThinking...\n');
|
|
107
|
+
const stream = await this.agent.stream({ messages }, { ...runConfig, streamMode: 'messages' });
|
|
108
|
+
const statusUpdate = this.statusUpdate;
|
|
109
|
+
return new IterableReadableStream({
|
|
110
|
+
async start(controller) {
|
|
111
|
+
try {
|
|
112
|
+
for await (const [chunk, _metadata] of stream) {
|
|
113
|
+
if (isAIMessage(chunk)) {
|
|
114
|
+
const text = chunk.text;
|
|
115
|
+
statusUpdate('stream', text);
|
|
116
|
+
controller.enqueue(text);
|
|
117
|
+
const toolCalls = chunk.tool_calls?.filter((tc) => tc.name);
|
|
118
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
119
|
+
statusUpdate('info', `\nUsed tools: ${formatToolCalls(toolCalls)}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
controller.close();
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (error instanceof Error) {
|
|
127
|
+
if (error?.name === 'ToolException') {
|
|
128
|
+
statusUpdate('error', `Tool execution failed: ${error?.message}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
controller.error(error);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
async cancel() {
|
|
135
|
+
// Clean up the underlying stream if it has a cancel method
|
|
136
|
+
if (stream && typeof stream.cancel === 'function') {
|
|
137
|
+
await stream.cancel();
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
120
142
|
async cleanup() {
|
|
121
143
|
if (this.mcpClient) {
|
|
122
144
|
await this.mcpClient.close();
|
|
@@ -125,6 +147,21 @@ export class Invocation {
|
|
|
125
147
|
this.agent = null;
|
|
126
148
|
this.config = null;
|
|
127
149
|
}
|
|
150
|
+
getEffectiveConfig(config, command) {
|
|
151
|
+
const supportsTools = !!config.llm.bindTools;
|
|
152
|
+
if (!supportsTools) {
|
|
153
|
+
this.statusUpdate('warning', 'Model does not seem to support tools.');
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
...config,
|
|
157
|
+
filesystem: command && config.commands?.[command]?.filesystem !== undefined
|
|
158
|
+
? config.commands[command].filesystem
|
|
159
|
+
: config.filesystem,
|
|
160
|
+
builtInTools: command && config.commands?.[command]?.builtInTools !== undefined
|
|
161
|
+
? config.commands[command].builtInTools
|
|
162
|
+
: config.builtInTools,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
128
165
|
/**
|
|
129
166
|
* Extract and flatten tools from toolkits
|
|
130
167
|
*/
|
|
@@ -180,4 +217,4 @@ export class Invocation {
|
|
|
180
217
|
}
|
|
181
218
|
}
|
|
182
219
|
}
|
|
183
|
-
//# sourceMappingURL=
|
|
220
|
+
//# sourceMappingURL=GthLangChainAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GthLangChainAgent.js","sourceRoot":"","sources":["../../src/core/GthLangChainAgent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,oBAAoB,EAA4B,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAInE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAMtE,MAAM,OAAO,iBAAiB;IACpB,YAAY,CAAuB;IACnC,OAAO,GAAY,KAAK,CAAC;IACzB,SAAS,GAAgC,IAAI,CAAC;IACtD,8DAA8D;IACtD,KAAK,GAAwC,IAAI,CAAC;IAClD,MAAM,GAAuB,IAAI,CAAC;IAE1C,YAAY,YAAkC;QAC5C,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,OAA+B,EAC/B,QAAqB,EACrB,eAAiD;QAEjD,0BAA0B;QAC1B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,QAAQ,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9B,CAAC;QAED,uDAAuD;QACvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEtD,0DAA0D;QAC1D,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAExD,wBAAwB;QACxB,MAAM,oBAAoB,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAElF,gBAAgB;QAChB,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAE1D,oBAAoB;QACpB,MAAM,KAAK,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,oBAAoB,EAAE,GAAG,QAAQ,CAAC,CAAC;QAEtE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,KAAK;iBACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;iBACxB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;iBACtB,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,SAAS,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,KAAK,GAAG,gBAAgB,CAAC;YAC5B,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG;YACpB,KAAK;YACL,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,QAAmB,EAAE,SAAyB;QACzD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC;gBAClE,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAiB,CAAC;gBACpF,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ;qBAChC,MAAM,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;qBACvE,OAAO,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;qBACjD,MAAM,CAAC,CAAC,EAAY,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC3E,CAAC;gBACD,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBACxC,OAAO,SAAS,CAAC;YACnB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;oBACtD,MAAM,CAAC,CAAC,CAAC,sDAAsD;gBACjE,CAAC;gBACD,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,wBAAyB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7E,OAAO,EAAE,CAAC;YACZ,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,IAAI,KAAK,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;oBACpC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,0BAA0B,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;oBACvE,OAAO,0BAA0B,KAAK,EAAE,OAAO,EAAE,CAAC;gBACpD,CAAC;YACH,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CACV,QAAmB,EACnB,SAAyB;QAEzB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/F,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACvC,OAAO,IAAI,sBAAsB,CAAC;YAChC,KAAK,CAAC,KAAK,CAAC,UAAU;gBACpB,IAAI,CAAC;oBACH,IAAI,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,EAAE,CAAC;wBAC9C,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;4BACvB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAc,CAAC;4BAClC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAC7B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;4BACzB,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;4BAC5D,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACtC,YAAY,CAAC,MAAM,EAAE,iBAAiB,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;4BACtE,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,UAAU,CAAC,KAAK,EAAE,CAAC;gBACrB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;wBAC3B,IAAI,KAAK,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;4BACpC,YAAY,CAAC,OAAO,EAAE,0BAA0B,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;wBACpE,CAAC;oBACH,CAAC;oBACD,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YACD,KAAK,CAAC,MAAM;gBACV,2DAA2D;gBAC3D,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBAClD,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;gBACxB,CAAC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,kBAAkB,CAAC,MAAmB,EAAE,OAA+B;QACrE,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,uCAAuC,CAAC,CAAC;QACxE,CAAC;QACD,OAAO;YACL,GAAG,MAAM;YACT,UAAU,EACR,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,KAAK,SAAS;gBAC7D,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAW;gBACtC,CAAC,CAAC,MAAM,CAAC,UAAU;YACvB,YAAY,EACV,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,SAAS;gBAC/D,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,YAAa;gBACxC,CAAC,CAAC,MAAM,CAAC,YAAY;SAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,sBAAsB,CAC5B,KAAgD;QAEhD,MAAM,cAAc,GAA8B,EAAE,CAAC;QACrD,KAAK,MAAM,aAAa,IAAI,KAAK,EAAE,CAAC;YAClC,2BAA2B;YAC3B,IAAK,aAAqB,CAAC,UAAU,CAAC,YAAY,QAAQ,EAAE,CAAC;gBAC3D,oBAAoB;gBACpB,cAAc,CAAC,IAAI,CAAC,GAAI,aAA6B,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,yBAAyB;gBACzB,cAAc,CAAC,IAAI,CAAC,aAAwC,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAES,oBAAoB;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,KAAK,CAAC,YAAY,CAAC,MAAmB;QAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAEnD,+BAA+B;QAC/B,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;QAE1E,MAAM,UAAU,GAAG,EAA8C,CAAC;QAClE,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAA6B,CAAC;YACrE,8DAA8D;YAC9D,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,IAAK,MAAM,CAAC,YAAoB,KAAK,OAAO,EAAE,CAAC;gBACrE,WAAW,CAAC,0BAA0B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;gBACpD,MAAM,YAAY,GAAG,MAAM,iCAAiC,CAAC,MAAM,CAAC,CAAC;gBACrE,UAAU,CAAC,UAAU,CAAC,GAAG;oBACvB,GAAG,MAAM;oBACT,YAAY;iBACb,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,8BAA8B;gBAC9B,UAAU,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC;YAClC,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,oBAAoB,CAAC;gBAC9B,gBAAgB,EAAE,IAAI;gBACtB,4BAA4B,EAAE,IAAI;gBAClC,wBAAwB,EAAE,KAAK;gBAC/B,UAAU,EAAE,UAAU;aACvB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
+
import { IterableReadableStream } from '@langchain/core/utils/stream';
|
|
3
|
+
import { SlothConfig } from '#src/config.js';
|
|
4
|
+
import { BaseCheckpointSaver } from '@langchain/langgraph';
|
|
5
|
+
import { Message } from '#src/modules/types.js';
|
|
1
6
|
export type StatusLevel = 'info' | 'warning' | 'error' | 'success' | 'debug' | 'display' | 'stream';
|
|
2
7
|
export type GthCommand = 'ask' | 'pr' | 'review' | 'chat' | 'code';
|
|
8
|
+
export interface GthAgentInterface {
|
|
9
|
+
init(command: GthCommand | undefined, configIn: SlothConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<void>;
|
|
10
|
+
invoke(messages: Message[], runConfig: RunnableConfig): Promise<string>;
|
|
11
|
+
stream(messages: Message[], runConfig: RunnableConfig): Promise<IterableReadableStream<string>>;
|
|
12
|
+
setVerbose(verbose: boolean): void;
|
|
13
|
+
}
|
package/dist/llmUtils.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { Message } from '#src/modules/types.js';
|
|
2
2
|
import { SlothConfig } from '#src/config.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { RunnableConfig } from '@langchain/core/runnables';
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated prefer using src/core/GthAgentRunner.ts directly
|
|
6
|
+
*/
|
|
7
|
+
export declare function invoke(command: 'ask' | 'pr' | 'review' | 'chat' | 'code' | undefined, messages: Message[], config: SlothConfig): Promise<string>;
|
|
6
8
|
export declare function setVerbose(debug: boolean): void;
|
|
9
|
+
/**
|
|
10
|
+
* Creates new runnable config.
|
|
11
|
+
* configurable.thread_id is an important part of that because it helps to distinguish different chat sessions.
|
|
12
|
+
* We normally do not have multiple sessions in the terminal, but I had bad stuff happening in tests
|
|
13
|
+
* and in another prototype project where I was importing Gaunt Sloth.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getNewRunnableConfig(): RunnableConfig;
|
package/dist/llmUtils.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { display, displayError, displayInfo, displayWarning } from '#src/consoleUtils.js';
|
|
2
2
|
import { stdout } from '#src/systemUtils.js';
|
|
3
|
-
import {
|
|
3
|
+
import { GthAgentRunner } from '#src/core/GthAgentRunner.js';
|
|
4
|
+
import { randomUUID } from 'crypto';
|
|
4
5
|
const llmGlobalSettings = {
|
|
5
6
|
verbose: false,
|
|
6
7
|
};
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated prefer using src/core/GthAgentRunner.ts directly
|
|
10
|
+
*/
|
|
11
|
+
export async function invoke(command, messages, config) {
|
|
8
12
|
const statusUpdate = (level, message) => {
|
|
9
13
|
switch (level) {
|
|
10
14
|
case 'display':
|
|
@@ -27,17 +31,30 @@ export async function invoke(command, messages, config, runConfig, checkpointSav
|
|
|
27
31
|
break;
|
|
28
32
|
}
|
|
29
33
|
};
|
|
30
|
-
const
|
|
31
|
-
|
|
34
|
+
const runner = new GthAgentRunner(statusUpdate);
|
|
35
|
+
runner.setVerbose(llmGlobalSettings.verbose);
|
|
32
36
|
try {
|
|
33
|
-
await
|
|
34
|
-
return await
|
|
37
|
+
await runner.init(command, config);
|
|
38
|
+
return await runner.processMessages(messages, getNewRunnableConfig());
|
|
35
39
|
}
|
|
36
40
|
finally {
|
|
37
|
-
await
|
|
41
|
+
await runner.cleanup();
|
|
38
42
|
}
|
|
39
43
|
}
|
|
44
|
+
// TODO make sure that it still works after refactoring
|
|
40
45
|
export function setVerbose(debug) {
|
|
41
46
|
llmGlobalSettings.verbose = debug;
|
|
42
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Creates new runnable config.
|
|
50
|
+
* configurable.thread_id is an important part of that because it helps to distinguish different chat sessions.
|
|
51
|
+
* We normally do not have multiple sessions in the terminal, but I had bad stuff happening in tests
|
|
52
|
+
* and in another prototype project where I was importing Gaunt Sloth.
|
|
53
|
+
*/
|
|
54
|
+
export function getNewRunnableConfig() {
|
|
55
|
+
return {
|
|
56
|
+
recursionLimit: 250,
|
|
57
|
+
configurable: { thread_id: randomUUID() },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
43
60
|
//# sourceMappingURL=llmUtils.js.map
|
package/dist/llmUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../src/llmUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../src/llmUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGpC,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,KAAK;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAA8D,EAC9D,QAAmB,EACnB,MAAmB;IAEnB,MAAM,YAAY,GAAG,CAAC,KAAkB,EAAE,OAAe,EAAE,EAAE;QAC3D,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,SAAS;gBACZ,OAAO,CAAC,OAAO,CAAC,CAAC;gBACjB,MAAM;YACR,KAAK,MAAM;gBACT,WAAW,CAAC,OAAO,CAAC,CAAC;gBACrB,MAAM;YACR,KAAK,SAAS;gBACZ,cAAc,CAAC,OAAO,CAAC,CAAC;gBACxB,MAAM;YACR,KAAK,OAAO;gBACV,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC/B,MAAM;YACR;gBACE,OAAO,CAAC,OAAO,CAAC,CAAC;gBACjB,MAAM;QACV,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,MAAM,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;IACxE,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,iBAAiB,CAAC,OAAO,GAAG,KAAK,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,cAAc,EAAE,GAAG;QACnB,YAAY,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;KAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { initConfig } from '#src/config.js';
|
|
2
2
|
import { defaultStatusCallbacks, display, displayInfo, formatInputPrompt, } from '#src/consoleUtils.js';
|
|
3
|
-
import * as crypto from 'crypto';
|
|
4
3
|
import { MemorySaver } from '@langchain/langgraph';
|
|
5
4
|
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
6
|
-
import {
|
|
5
|
+
import { error, exit, stdin as input, stdout as output, createInterface, } from '#src/systemUtils.js';
|
|
7
6
|
import { getGslothFilePath } from '#src/filePathUtils.js';
|
|
8
7
|
import { appendToFile, generateStandardFileName } from '#src/utils.js';
|
|
9
8
|
import { readBackstory, readGuidelines, readSystemPrompt } from '#src/prompt.js';
|
|
10
|
-
import {
|
|
9
|
+
import { GthAgentRunner } from '#src/core/GthAgentRunner.js';
|
|
10
|
+
import { getNewRunnableConfig } from '#src/llmUtils.js';
|
|
11
11
|
export async function createInteractiveSession(sessionConfig, message) {
|
|
12
12
|
const config = { ...(await initConfig()) };
|
|
13
13
|
const checkpointSaver = new MemorySaver();
|
|
14
14
|
// Initialize Invocation once
|
|
15
|
-
const invocation = new
|
|
15
|
+
const invocation = new GthAgentRunner(defaultStatusCallbacks);
|
|
16
16
|
await invocation.init(sessionConfig.mode, config, checkpointSaver);
|
|
17
|
+
const runConfig = getNewRunnableConfig();
|
|
17
18
|
try {
|
|
18
19
|
const rl = createInterface({ input, output });
|
|
19
20
|
let isFirstMessage = true;
|
|
20
21
|
let shouldExit = false;
|
|
21
|
-
const thread_id = crypto.randomUUID();
|
|
22
22
|
const logFileName = getGslothFilePath(generateStandardFileName(sessionConfig.mode.toUpperCase()));
|
|
23
23
|
displayInfo(`${sessionConfig.mode} session will be logged to ${logFileName}\n`);
|
|
24
24
|
const processMessage = async (userInput) => {
|
|
@@ -36,32 +36,28 @@ export async function createInteractiveSession(sessionConfig, message) {
|
|
|
36
36
|
messages.push(new SystemMessage(systemPromptParts.join('\n')));
|
|
37
37
|
}
|
|
38
38
|
messages.push(new HumanMessage(userInput));
|
|
39
|
-
const
|
|
40
|
-
configurable: { thread_id },
|
|
41
|
-
};
|
|
42
|
-
const aiResponse = await invocation.invoke(messages, runConfig);
|
|
39
|
+
const aiResponse = await invocation.processMessages(messages, runConfig);
|
|
43
40
|
const logEntry = `## User\n\n${userInput}\n\n## Assistant\n\n${aiResponse}\n\n`;
|
|
44
41
|
appendToFile(logFileName, logEntry);
|
|
45
42
|
isFirstMessage = false;
|
|
46
43
|
};
|
|
47
|
-
const askQuestion = () => {
|
|
48
|
-
|
|
44
|
+
const askQuestion = async () => {
|
|
45
|
+
while (!shouldExit) {
|
|
46
|
+
const userInput = await rl.question(formatInputPrompt(' > '));
|
|
49
47
|
if (!userInput.trim()) {
|
|
50
|
-
|
|
51
|
-
return;
|
|
48
|
+
continue; // Skip inference if no input
|
|
52
49
|
}
|
|
53
50
|
if (userInput.toLowerCase() === 'exit') {
|
|
54
|
-
rl.close();
|
|
55
51
|
shouldExit = true;
|
|
56
52
|
await invocation.cleanup();
|
|
53
|
+
rl.close();
|
|
57
54
|
return;
|
|
58
55
|
}
|
|
59
56
|
await processMessage(userInput);
|
|
60
57
|
display('\n\n');
|
|
61
58
|
displayInfo(sessionConfig.exitMessage);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
59
|
+
}
|
|
60
|
+
rl.close();
|
|
65
61
|
};
|
|
66
62
|
if (message) {
|
|
67
63
|
await processMessage(message);
|
|
@@ -71,7 +67,7 @@ export async function createInteractiveSession(sessionConfig, message) {
|
|
|
71
67
|
displayInfo(sessionConfig.exitMessage);
|
|
72
68
|
}
|
|
73
69
|
if (!shouldExit)
|
|
74
|
-
askQuestion();
|
|
70
|
+
await askQuestion();
|
|
75
71
|
}
|
|
76
72
|
catch (err) {
|
|
77
73
|
await invocation.cleanup();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactiveSessionModule.js","sourceRoot":"","sources":["../../src/modules/interactiveSessionModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EACL,sBAAsB,EACtB,OAAO,EACP,WAAW,EACX,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"interactiveSessionModule.js","sourceRoot":"","sources":["../../src/modules/interactiveSessionModule.ts"],"names":[],"mappings":"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"}
|
package/dist/presets/openai.js
CHANGED
|
@@ -13,7 +13,9 @@ export async function processJsonConfig(llmConfig) {
|
|
|
13
13
|
apiKey: openaiApiKey,
|
|
14
14
|
model: llmConfig.model || 'gpt-4o',
|
|
15
15
|
};
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
17
|
delete configFields.type;
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
19
|
delete configFields.apiKeyEnvironmentVariable;
|
|
18
20
|
return new ChatOpenAI(configFields);
|
|
19
21
|
}
|