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 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
@@ -1,4 +1,4 @@
1
- import { StatusUpdateCallback } from '#src/core/Invocation.js';
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 { type RunnableConfig } from '@langchain/core/runnables';
7
- import { GthCommand, StatusLevel } from '#src/core/types.js';
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 Invocation {
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
- getEffectiveConfig(config: SlothConfig, command: GthCommand | undefined): SlothConfig;
19
- invoke(messages: Message[], runConfig?: RunnableConfig): Promise<string>;
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
- export class Invocation {
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
- getEffectiveConfig(config, command) {
51
- const supportsTools = !!config.llm.bindTools;
52
- if (!supportsTools) {
53
- this.statusUpdate('warning', 'Model does not seem to support tools.');
54
- }
55
- return {
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('Invocation not initialized. Call init() first.');
60
+ throw new Error('Agent not initialized. Call init() first.');
68
61
  }
69
- // Run the agent
70
62
  try {
71
- const output = { aiMessage: '' };
72
- if (this.config.streamOutput) {
73
- // Streaming output
74
- this.statusUpdate('info', '\nThinking...\n');
75
- const stream = await this.agent.stream({ messages }, { ...runConfig, streamMode: 'messages' });
76
- for await (const [chunk, _metadata] of stream) {
77
- if (isAIMessage(chunk)) {
78
- this.statusUpdate('stream', chunk.text);
79
- output.aiMessage += chunk.text;
80
- const toolCalls = chunk.tool_calls?.filter((tc) => tc.name);
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
- else {
88
- // Not streaming output
89
- const progress = new ProgressIndicator('Thinking.');
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('display', output.aiMessage);
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=Invocation.js.map
220
+ //# 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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"}
@@ -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
+ }
@@ -1,6 +1,15 @@
1
1
  import type { Message } from '#src/modules/types.js';
2
2
  import { SlothConfig } from '#src/config.js';
3
- import { type RunnableConfig } from '@langchain/core/runnables';
4
- import { BaseCheckpointSaver } from '@langchain/langgraph';
5
- export declare function invoke(command: 'ask' | 'pr' | 'review' | 'chat' | 'code' | undefined, messages: Message[], config: SlothConfig, runConfig?: RunnableConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<string>;
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 { Invocation } from '#src/core/Invocation.js';
3
+ import { GthAgentRunner } from '#src/core/GthAgentRunner.js';
4
+ import { randomUUID } from 'crypto';
4
5
  const llmGlobalSettings = {
5
6
  verbose: false,
6
7
  };
7
- export async function invoke(command, messages, config, runConfig, checkpointSaver) {
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 invocation = new Invocation(statusUpdate);
31
- invocation.setVerbose(llmGlobalSettings.verbose);
34
+ const runner = new GthAgentRunner(statusUpdate);
35
+ runner.setVerbose(llmGlobalSettings.verbose);
32
36
  try {
33
- await invocation.init(command, config, checkpointSaver);
34
- return await invocation.invoke(messages, runConfig);
37
+ await runner.init(command, config);
38
+ return await runner.processMessages(messages, getNewRunnableConfig());
35
39
  }
36
40
  finally {
37
- await invocation.cleanup();
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
@@ -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;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,KAAK;CACf,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAA8D,EAC9D,QAAmB,EACnB,MAAmB,EACnB,SAA0B,EAC1B,eAAiD;IAEjD,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,UAAU,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IAChD,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;QACxD,OAAO,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;YAAS,CAAC;QACT,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,iBAAiB,CAAC,OAAO,GAAG,KAAK,CAAC;AACpC,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 { createInterface, error, exit, stdin as input, stdout as output, } from '#src/systemUtils.js';
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 { Invocation } from '#src/core/Invocation.js';
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 Invocation(defaultStatusCallbacks);
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 runConfig = {
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
- rl.question(formatInputPrompt(' > '), async (userInput) => {
44
+ const askQuestion = async () => {
45
+ while (!shouldExit) {
46
+ const userInput = await rl.question(formatInputPrompt(' > '));
49
47
  if (!userInput.trim()) {
50
- rl.close(); // This is not the end of the loop, simply skipping inference if no input
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
- if (!shouldExit)
63
- askQuestion();
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":"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"}
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"}
@@ -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
  }