gaunt-sloth-assistant 0.8.3 → 0.8.5
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 -1
- package/assets/release-notes/RELEASE-NOTES-HOWTO.md +12 -0
- package/assets/release-notes/v0_8_5.md +12 -0
- package/dist/consoleUtils.d.ts +1 -1
- package/dist/core/GthAgentRunner.d.ts +17 -0
- package/dist/core/GthAgentRunner.js +68 -0
- package/dist/core/GthAgentRunner.js.map +1 -0
- package/dist/core/{Invocation.d.ts → GthLangChainAgent.d.ts} +17 -6
- package/dist/core/{Invocation.js → GthLangChainAgent.js} +95 -55
- package/dist/core/GthLangChainAgent.js.map +1 -0
- package/dist/core/types.d.ts +10 -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/anthropic.js +2 -2
- package/dist/presets/anthropic.js.map +1 -1
- package/dist/presets/deepseek.js +2 -2
- package/dist/presets/deepseek.js.map +1 -1
- package/dist/presets/groq.js +2 -2
- package/dist/presets/groq.js.map +1 -1
- package/dist/presets/openai.js +3 -1
- 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 +3 -1
- package/src/consoleUtils.ts +1 -1
- package/src/core/GthAgentRunner.ts +88 -0
- package/src/core/{Invocation.ts → GthLangChainAgent.ts} +105 -63
- package/src/core/types.ts +19 -0
- package/src/llmUtils.ts +26 -11
- package/src/modules/interactiveSessionModule.ts +15 -19
- package/src/presets/anthropic.ts +2 -2
- package/src/presets/deepseek.ts +2 -2
- package/src/presets/groq.ts +2 -2
- package/src/presets/openai.ts +3 -1
- package/src/systemUtils.ts +1 -1
- package/dist/core/Invocation.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Gaunt Sloth Assistant
|
|
2
|
-
[](https://github.com/andruhon/gaunt-sloth-assistant/actions/workflows/unit-tests.yml) [](https://github.com/andruhon/gaunt-sloth-assistant/actions/workflows/integration-tests.yml)
|
|
3
3
|
|
|
4
4
|
Gaunt GSloth Assistant is a lightweight **command line AI assistant**
|
|
5
5
|
built with TypeScript (JavaScript) and distributed via NPM with minimum dependencies.
|
|
@@ -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
|
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,68 @@
|
|
|
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
|
+
// Initialize the agent if it has an init method
|
|
21
|
+
await this.agent.init(command, configIn, checkpointSaver);
|
|
22
|
+
// Set verbose mode
|
|
23
|
+
if (this.verbose) {
|
|
24
|
+
this.agent.setVerbose(this.verbose);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async processMessages(messages, runConfig) {
|
|
28
|
+
if (!this.agent || !this.config) {
|
|
29
|
+
throw new Error('AgentRunner not initialized. Call init() first.');
|
|
30
|
+
}
|
|
31
|
+
// Convert Message[] to a single string for the agent interface
|
|
32
|
+
const message = messages.map((msg) => msg.content).join('\n');
|
|
33
|
+
try {
|
|
34
|
+
// Decision: Use streaming or non-streaming based on config
|
|
35
|
+
if (this.config.streamOutput) {
|
|
36
|
+
// Use streaming
|
|
37
|
+
const stream = await this.agent.stream(message, runConfig);
|
|
38
|
+
let result = '';
|
|
39
|
+
try {
|
|
40
|
+
for await (const chunk of stream) {
|
|
41
|
+
result += chunk;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (streamError) {
|
|
45
|
+
// Handle streaming-specific errors
|
|
46
|
+
throw new Error(`Stream processing failed: ${streamError instanceof Error ? streamError.message : String(streamError)}`);
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Use non-streaming
|
|
52
|
+
return await this.agent.invoke(message, runConfig);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// Handle agent invocation errors
|
|
57
|
+
throw new Error(`Agent processing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async cleanup() {
|
|
61
|
+
if (this.agent && 'cleanup' in this.agent && typeof this.agent.cleanup === 'function') {
|
|
62
|
+
await this.agent.cleanup();
|
|
63
|
+
}
|
|
64
|
+
this.agent = null;
|
|
65
|
+
this.config = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# 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,12 @@
|
|
|
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
8
|
export type StatusUpdateCallback = (level: StatusLevel, message: string) => void;
|
|
9
|
-
export declare class
|
|
9
|
+
export declare class GthLangChainAgent implements GthAgentInterface {
|
|
10
10
|
private statusUpdate;
|
|
11
11
|
private verbose;
|
|
12
12
|
private mcpClient;
|
|
@@ -15,9 +15,20 @@ export declare class Invocation {
|
|
|
15
15
|
constructor(statusUpdate: StatusUpdateCallback);
|
|
16
16
|
setVerbose(verbose: boolean): void;
|
|
17
17
|
init(command: GthCommand | undefined, configIn: SlothConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<void>;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Invoke LLM with a message and runnable config.
|
|
20
|
+
* For streaming use {@link #stream} method, streaming is preferred if model API supports it.
|
|
21
|
+
* Please note that this when tools are involved, this method will anyway do multiple LLM
|
|
22
|
+
* calls within LangChain dependency.
|
|
23
|
+
*/
|
|
24
|
+
invoke(message: string, runConfig: RunnableConfig): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Induce LLM to stream AI messages with a user message and runnable config.
|
|
27
|
+
* When stream is not appropriate use {@link invoke}.
|
|
28
|
+
*/
|
|
29
|
+
stream(message: string, runConfig: RunnableConfig): Promise<IterableReadableStream<string>>;
|
|
20
30
|
cleanup(): Promise<void>;
|
|
31
|
+
getEffectiveConfig(config: SlothConfig, command: GthCommand | undefined): SlothConfig;
|
|
21
32
|
/**
|
|
22
33
|
* Extract and flatten tools from toolkits
|
|
23
34
|
*/
|
|
@@ -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;
|
|
@@ -47,76 +48,100 @@ export class Invocation {
|
|
|
47
48
|
checkpointSaver,
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
}
|
|
65
|
-
async invoke(messages, runConfig) {
|
|
51
|
+
/**
|
|
52
|
+
* Invoke LLM with a message and runnable config.
|
|
53
|
+
* For streaming use {@link #stream} method, streaming is preferred if model API supports it.
|
|
54
|
+
* Please note that this when tools are involved, this method will anyway do multiple LLM
|
|
55
|
+
* calls within LangChain dependency.
|
|
56
|
+
*/
|
|
57
|
+
async invoke(message, runConfig) {
|
|
66
58
|
if (!this.agent || !this.config) {
|
|
67
|
-
throw new Error('
|
|
59
|
+
throw new Error('Agent not initialized. Call init() first.');
|
|
68
60
|
}
|
|
69
|
-
//
|
|
61
|
+
// Convert string to Message format expected by the agent
|
|
62
|
+
const messages = [{ role: 'user', content: message }];
|
|
70
63
|
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
|
-
}
|
|
64
|
+
const progress = new ProgressIndicator('Thinking.');
|
|
65
|
+
try {
|
|
66
|
+
const response = await this.agent.invoke({ messages }, runConfig);
|
|
67
|
+
const aiMessage = response.messages[response.messages.length - 1].content;
|
|
68
|
+
const toolCalls = response.messages
|
|
69
|
+
.filter((msg) => msg.tool_calls && msg.tool_calls.length > 0)
|
|
70
|
+
.flatMap((msg) => msg.tool_calls ?? [])
|
|
71
|
+
.filter((tc) => tc.name);
|
|
72
|
+
if (toolCalls.length > 0) {
|
|
73
|
+
this.statusUpdate('info', `\nUsed tools: ${formatToolCalls(toolCalls)}`);
|
|
85
74
|
}
|
|
75
|
+
this.statusUpdate('display', aiMessage);
|
|
76
|
+
return aiMessage;
|
|
86
77
|
}
|
|
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();
|
|
78
|
+
catch (e) {
|
|
79
|
+
if (e instanceof Error && e?.name === 'ToolException') {
|
|
80
|
+
throw e; // Re-throw ToolException to be handled by outer catch
|
|
106
81
|
}
|
|
107
|
-
this.statusUpdate('
|
|
82
|
+
this.statusUpdate('warning', `Something went wrong ${e.message}`);
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
progress.stop();
|
|
108
87
|
}
|
|
109
|
-
return output.aiMessage;
|
|
110
88
|
}
|
|
111
89
|
catch (error) {
|
|
112
90
|
if (error instanceof Error) {
|
|
113
91
|
if (error?.name === 'ToolException') {
|
|
114
92
|
this.statusUpdate('error', `Tool execution failed: ${error?.message}`);
|
|
93
|
+
return `Tool execution failed: ${error?.message}`;
|
|
115
94
|
}
|
|
116
95
|
}
|
|
117
96
|
throw error;
|
|
118
97
|
}
|
|
119
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Induce LLM to stream AI messages with a user message and runnable config.
|
|
101
|
+
* When stream is not appropriate use {@link invoke}.
|
|
102
|
+
*/
|
|
103
|
+
async stream(message, runConfig) {
|
|
104
|
+
if (!this.agent || !this.config) {
|
|
105
|
+
throw new Error('Agent not initialized. Call init() first.');
|
|
106
|
+
}
|
|
107
|
+
// Convert string to Message format expected by the agent
|
|
108
|
+
const messages = [{ role: 'user', content: message }];
|
|
109
|
+
this.statusUpdate('info', '\nThinking...\n');
|
|
110
|
+
const stream = await this.agent.stream({ messages }, { ...runConfig, streamMode: 'messages' });
|
|
111
|
+
const statusUpdate = this.statusUpdate;
|
|
112
|
+
return new IterableReadableStream({
|
|
113
|
+
async start(controller) {
|
|
114
|
+
try {
|
|
115
|
+
for await (const [chunk, _metadata] of stream) {
|
|
116
|
+
if (isAIMessage(chunk)) {
|
|
117
|
+
const text = chunk.text;
|
|
118
|
+
statusUpdate('stream', text);
|
|
119
|
+
controller.enqueue(text);
|
|
120
|
+
const toolCalls = chunk.tool_calls?.filter((tc) => tc.name);
|
|
121
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
122
|
+
statusUpdate('info', `\nUsed tools: ${formatToolCalls(toolCalls)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
controller.close();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (error instanceof Error) {
|
|
130
|
+
if (error?.name === 'ToolException') {
|
|
131
|
+
statusUpdate('error', `Tool execution failed: ${error?.message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
controller.error(error);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
async cancel() {
|
|
138
|
+
// Clean up the underlying stream if it has a cancel method
|
|
139
|
+
if (stream && typeof stream.cancel === 'function') {
|
|
140
|
+
await stream.cancel();
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
120
145
|
async cleanup() {
|
|
121
146
|
if (this.mcpClient) {
|
|
122
147
|
await this.mcpClient.close();
|
|
@@ -125,6 +150,21 @@ export class Invocation {
|
|
|
125
150
|
this.agent = null;
|
|
126
151
|
this.config = null;
|
|
127
152
|
}
|
|
153
|
+
getEffectiveConfig(config, command) {
|
|
154
|
+
const supportsTools = !!config.llm.bindTools;
|
|
155
|
+
if (!supportsTools) {
|
|
156
|
+
this.statusUpdate('warning', 'Model does not seem to support tools.');
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
...config,
|
|
160
|
+
filesystem: command && config.commands?.[command]?.filesystem !== undefined
|
|
161
|
+
? config.commands[command].filesystem
|
|
162
|
+
: config.filesystem,
|
|
163
|
+
builtInTools: command && config.commands?.[command]?.builtInTools !== undefined
|
|
164
|
+
? config.commands[command].builtInTools
|
|
165
|
+
: config.builtInTools,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
128
168
|
/**
|
|
129
169
|
* Extract and flatten tools from toolkits
|
|
130
170
|
*/
|
|
@@ -180,4 +220,4 @@ export class Invocation {
|
|
|
180
220
|
}
|
|
181
221
|
}
|
|
182
222
|
}
|
|
183
|
-
//# sourceMappingURL=
|
|
223
|
+
//# sourceMappingURL=GthLangChainAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GthLangChainAgent.js","sourceRoot":"","sources":["../../src/core/GthLangChainAgent.ts"],"names":[],"mappings":"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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
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';
|
|
1
5
|
export type StatusLevel = 'info' | 'warning' | 'error' | 'success' | 'debug' | 'display' | 'stream';
|
|
2
6
|
export type GthCommand = 'ask' | 'pr' | 'review' | 'chat' | 'code';
|
|
7
|
+
export interface GthAgentInterface {
|
|
8
|
+
init(command: GthCommand | undefined, configIn: SlothConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<void>;
|
|
9
|
+
invoke(message: string, runConfig: RunnableConfig): Promise<string>;
|
|
10
|
+
stream(message: string, runConfig: RunnableConfig): Promise<IterableReadableStream<string>>;
|
|
11
|
+
setVerbose(verbose: boolean): void;
|
|
12
|
+
}
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EACL,sBAAsB,EACtB,OAAO,EACP,WAAW,EACX,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAoB,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzF,OAAO,EACL,KAAK,EACL,IAAI,EACJ,KAAK,IAAI,KAAK,EACd,MAAM,IAAI,MAAM,EAChB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAUxD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,aAA4B,EAAE,OAAgB;IAC3F,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,MAAM,UAAU,EAAE,CAAC,EAAE,CAAC;IAC3C,MAAM,eAAe,GAAG,IAAI,WAAW,EAAE,CAAC;IAC1C,6BAA6B;IAC7B,MAAM,UAAU,GAAG,IAAI,cAAc,CAAC,sBAAsB,CAAC,CAAC;IAC9D,MAAM,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IACnE,MAAM,SAAS,GAAmB,oBAAoB,EAAE,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9C,IAAI,cAAc,GAAG,IAAI,CAAC;QAC1B,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,MAAM,WAAW,GAAG,iBAAiB,CACnC,wBAAwB,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAC3D,CAAC;QAEF,WAAW,CAAC,GAAG,aAAa,CAAC,IAAI,8BAA8B,WAAW,IAAI,CAAC,CAAC;QAEhF,MAAM,cAAc,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;YACjD,MAAM,QAAQ,GAAkB,EAAE,CAAC;YACnC,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,iBAAiB,GAAG,CAAC,aAAa,EAAE,EAAE,cAAc,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBACtF,MAAM,UAAU,GAAG,aAAa,CAAC,cAAc,EAAE,CAAC;gBAClD,IAAI,UAAU,EAAE,CAAC;oBACf,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACrC,CAAC;gBACD,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;gBACxC,IAAI,YAAY,EAAE,CAAC;oBACjB,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACvC,CAAC;gBACD,QAAQ,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;YAE3C,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAEzE,MAAM,QAAQ,GAAG,cAAc,SAAS,uBAAuB,UAAU,MAAM,CAAC;YAChF,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAEpC,cAAc,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;YAC7B,OAAO,CAAC,UAAU,EAAE,CAAC;gBACnB,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/D,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;oBACtB,SAAS,CAAC,6BAA6B;gBACzC,CAAC;gBACD,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;oBACvC,UAAU,GAAG,IAAI,CAAC;oBAClB,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;oBAC3B,EAAE,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO;gBACT,CAAC;gBACD,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;gBAChC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChB,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC;YACD,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC,CAAC;QAEF,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACpC,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,UAAU;YAAE,MAAM,WAAW,EAAE,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;QAC3B,KAAK,CAAC,YAAY,aAAa,CAAC,IAAI,aAAa,GAAG,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
|
|
@@ -5,8 +5,8 @@ import { writeFileIfNotExistsWithMessages } from '#src/utils.js';
|
|
|
5
5
|
// Function to process JSON config and create Anthropic LLM instance
|
|
6
6
|
export async function processJsonConfig(llmConfig) {
|
|
7
7
|
const anthropic = await import('@langchain/anthropic');
|
|
8
|
-
// Use
|
|
9
|
-
const anthropicApiKey =
|
|
8
|
+
// Use config value if available, otherwise use the environment variable
|
|
9
|
+
const anthropicApiKey = llmConfig.apiKey || env.ANTHROPIC_API_KEY;
|
|
10
10
|
return new anthropic.ChatAnthropic({
|
|
11
11
|
...llmConfig,
|
|
12
12
|
apiKey: anthropicApiKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/presets/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAOjE,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAA+C;IAE/C,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACvD,wEAAwE;IACxE,MAAM,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/presets/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAOjE,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAA+C;IAE/C,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACvD,wEAAwE;IACxE,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,iBAAiB,CAAC;IAClE,OAAO,IAAI,SAAS,CAAC,aAAa,CAAC;QACjC,GAAG,SAAS;QACZ,MAAM,EAAE,eAAe;QACvB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,0BAA0B;KACrD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,WAAW,GAAG;;;;;EAKlB,CAAC;AAEH,MAAM,UAAU,IAAI,CAAC,cAAsB;IACzC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAEtC,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,gCAAgC,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC9D,cAAc,CACZ,2BAA2B,cAAc,kCAAkC;QACzE,mDAAmD,CACtD,CAAC;AACJ,CAAC"}
|