gaunt-sloth-assistant 0.2.2 → 0.3.1
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/.gsloth.guidelines.md +127 -0
- package/.gsloth.review.md +13 -0
- package/README.md +1 -1
- package/dist/commands/askCommand.js +4 -4
- package/dist/commands/askCommand.js.map +1 -1
- package/dist/commands/reviewCommand.js +20 -8
- package/dist/commands/reviewCommand.js.map +1 -1
- package/dist/config.d.ts +8 -4
- package/dist/config.js +49 -19
- package/dist/config.js.map +1 -1
- package/dist/configs/anthropic.d.ts +2 -3
- package/dist/configs/anthropic.js.map +1 -1
- package/dist/configs/vertexai.d.ts +2 -2
- package/dist/configs/vertexai.js.map +1 -1
- package/dist/filePathUtils.d.ts +25 -0
- package/dist/filePathUtils.js +66 -0
- package/dist/filePathUtils.js.map +1 -0
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/llmUtils.d.ts +4 -0
- package/dist/llmUtils.js +39 -0
- package/dist/llmUtils.js.map +1 -0
- package/dist/modules/questionAnsweringModule.d.ts +0 -11
- package/dist/modules/questionAnsweringModule.js +8 -47
- package/dist/modules/questionAnsweringModule.js.map +1 -1
- package/dist/modules/reviewModule.d.ts +0 -3
- package/dist/modules/reviewModule.js +8 -38
- package/dist/modules/reviewModule.js.map +1 -1
- package/dist/prompt.d.ts +3 -2
- package/dist/prompt.js +28 -12
- package/dist/prompt.js.map +1 -1
- package/dist/systemUtils.d.ts +10 -0
- package/dist/systemUtils.js +34 -0
- package/dist/systemUtils.js.map +1 -1
- package/dist/utils.d.ts +15 -5
- package/dist/utils.js +74 -47
- package/dist/utils.js.map +1 -1
- package/docs/CONFIGURATION.md +25 -4
- package/docs/RELEASE-HOWTO.md +13 -5
- package/package.json +1 -1
- package/src/commands/askCommand.ts +4 -4
- package/src/commands/reviewCommand.ts +21 -9
- package/src/config.ts +59 -28
- package/src/configs/anthropic.ts +5 -3
- package/src/configs/vertexai.ts +2 -2
- package/src/filePathUtils.ts +79 -0
- package/src/index.ts +12 -3
- package/src/llmUtils.ts +54 -0
- package/src/modules/questionAnsweringModule.ts +10 -66
- package/src/modules/reviewModule.ts +8 -60
- package/src/prompt.ts +35 -17
- package/src/systemUtils.ts +38 -0
- package/src/utils.ts +82 -50
- package/.gsloth.preamble.review.md +0 -125
- package/UX-RESEARCH.md +0 -78
@@ -1,27 +1,17 @@
|
|
1
|
-
import type { SlothContext } from '#src/config.js';
|
2
1
|
import { slothContext } from '#src/config.js';
|
3
2
|
import { display, displayDebug, displayError, displaySuccess } from '#src/consoleUtils.js';
|
4
|
-
import
|
5
|
-
import {
|
6
|
-
import { fileSafeLocalDate, ProgressIndicator, toFileSafeString } from '#src/utils.js';
|
7
|
-
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
8
|
-
import { AIMessageChunk, HumanMessage, SystemMessage } from '@langchain/core/messages';
|
9
|
-
import { END, MemorySaver, MessagesAnnotation, START, StateGraph } from '@langchain/langgraph';
|
3
|
+
import { stdout } from '#src/systemUtils.js';
|
4
|
+
import { generateStandardFileName, ProgressIndicator } from '#src/utils.js';
|
10
5
|
import { writeFileSync } from 'node:fs';
|
11
|
-
import
|
6
|
+
import { invoke } from '#src/llmUtils.js';
|
7
|
+
import { getGslothFilePath } from '#src/filePathUtils.js';
|
12
8
|
|
13
9
|
export async function review(source: string, preamble: string, diff: string): Promise<void> {
|
14
10
|
const progressIndicator = new ProgressIndicator('Reviewing.');
|
15
|
-
const outputContent = await
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
diff
|
20
|
-
);
|
21
|
-
const filePath = path.resolve(
|
22
|
-
getCurrentDir(),
|
23
|
-
toFileSafeString(source) + '-' + fileSafeLocalDate() + '.md'
|
24
|
-
);
|
11
|
+
const outputContent = await invoke(slothContext.config.llm, slothContext.session, preamble, diff);
|
12
|
+
progressIndicator.stop();
|
13
|
+
const filename = generateStandardFileName(source);
|
14
|
+
const filePath = getGslothFilePath(filename);
|
25
15
|
stdout.write('\n');
|
26
16
|
display(`writing ${filePath}`);
|
27
17
|
stdout.write('\n');
|
@@ -37,45 +27,3 @@ export async function review(source: string, preamble: string, diff: string): Pr
|
|
37
27
|
// exit(1);
|
38
28
|
}
|
39
29
|
}
|
40
|
-
|
41
|
-
export async function reviewInner(
|
42
|
-
context: SlothContext,
|
43
|
-
indicateProgress: ProgressCallback,
|
44
|
-
preamble: string,
|
45
|
-
diff: string
|
46
|
-
): Promise<string> {
|
47
|
-
// This node receives the current state (messages) and invokes the LLM
|
48
|
-
const callModel = async (state: State): Promise<{ messages: AIMessageChunk }> => {
|
49
|
-
// state.messages will contain the list including the system preamble and user diff
|
50
|
-
const response = await (context.config.llm as BaseChatModel).invoke(state.messages);
|
51
|
-
// MessagesAnnotation expects the node to return the new message(s) to be added to the state.
|
52
|
-
// Wrap the response in an array if it's a single message object.
|
53
|
-
return { messages: response };
|
54
|
-
};
|
55
|
-
|
56
|
-
// Define the graph structure with MessagesAnnotation state
|
57
|
-
const workflow = new StateGraph(MessagesAnnotation)
|
58
|
-
// Define the node and edge
|
59
|
-
.addNode('model', callModel)
|
60
|
-
.addEdge(START, 'model') // Start at the 'model' node
|
61
|
-
.addEdge('model', END); // End after the 'model' node completes
|
62
|
-
|
63
|
-
// Set up memory (optional but good practice for potential future multi-turn interactions)
|
64
|
-
const memory = new MemorySaver(); // TODO extract to config
|
65
|
-
|
66
|
-
// Compile the workflow into a runnable app
|
67
|
-
const app = workflow.compile({ checkpointer: memory });
|
68
|
-
|
69
|
-
// Construct the initial the messages including the preamble as a system message
|
70
|
-
const messages: Message[] = [new SystemMessage(preamble), new HumanMessage(diff)];
|
71
|
-
|
72
|
-
indicateProgress();
|
73
|
-
// TODO create proper progress indicator for async tasks.
|
74
|
-
const progress = setInterval(() => indicateProgress(), 1000);
|
75
|
-
const output = await app.invoke({ messages }, context.session);
|
76
|
-
clearInterval(progress);
|
77
|
-
const lastMessage = output.messages[output.messages.length - 1];
|
78
|
-
return typeof lastMessage.content === 'string'
|
79
|
-
? lastMessage.content
|
80
|
-
: JSON.stringify(lastMessage.content);
|
81
|
-
}
|
package/src/prompt.ts
CHANGED
@@ -1,25 +1,43 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
1
|
+
import {
|
2
|
+
readFileFromCurrentDir,
|
3
|
+
readFileFromCurrentOrInstallDir,
|
4
|
+
spawnCommand,
|
5
|
+
} from '#src/utils.js';
|
4
6
|
import { displayError } from '#src/consoleUtils.js';
|
5
|
-
import { exit
|
7
|
+
import { exit } from '#src/systemUtils.js';
|
8
|
+
import { GSLOTH_BACKSTORY } from '#src/config.js';
|
9
|
+
import { getGslothConfigReadPath } from '#src/filePathUtils.js';
|
6
10
|
|
7
|
-
export function
|
8
|
-
|
9
|
-
const filePath = resolve(installDir, GSLOTH_BACKSTORY);
|
10
|
-
return readFileSyncWithMessages(filePath, 'Error reading internal preamble file at:') || '';
|
11
|
+
export function readBackstory(): string {
|
12
|
+
return readFileFromCurrentOrInstallDir(GSLOTH_BACKSTORY, true);
|
11
13
|
}
|
12
14
|
|
13
|
-
export function
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
'Error reading preamble file at:',
|
15
|
+
export function readGuidelines(guidelinesFilename: string): string {
|
16
|
+
try {
|
17
|
+
const filePath = getGslothConfigReadPath(guidelinesFilename);
|
18
|
+
return readFileFromCurrentDir(filePath);
|
19
|
+
} catch (error) {
|
20
|
+
displayError(
|
20
21
|
'Consider running `gsloth init` to set up your project. Check `gsloth init --help` to see options.'
|
21
|
-
)
|
22
|
-
|
22
|
+
);
|
23
|
+
throw error;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
export function readReviewInstructions(reviewInstructions: string): string {
|
28
|
+
return readConfigPromptFile(reviewInstructions);
|
29
|
+
}
|
30
|
+
|
31
|
+
function readConfigPromptFile(guidelinesFilename: string): string {
|
32
|
+
try {
|
33
|
+
const filePath = getGslothConfigReadPath(guidelinesFilename);
|
34
|
+
return readFileFromCurrentOrInstallDir(filePath);
|
35
|
+
} catch (error) {
|
36
|
+
displayError(
|
37
|
+
'Consider running `gsloth init` to set up your project. Check `gsloth init --help` to see options.'
|
38
|
+
);
|
39
|
+
throw error;
|
40
|
+
}
|
23
41
|
}
|
24
42
|
|
25
43
|
/**
|
package/src/systemUtils.ts
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import { dirname, resolve } from 'node:path';
|
2
2
|
import { fileURLToPath } from 'url';
|
3
|
+
import { Command } from 'commander';
|
4
|
+
import { ProgressIndicator } from '#src/utils.js';
|
3
5
|
|
4
6
|
/**
|
5
7
|
* This file contains all system functions and objects that are globally available
|
@@ -12,10 +14,12 @@ import { fileURLToPath } from 'url';
|
|
12
14
|
|
13
15
|
interface InnerState {
|
14
16
|
installDir: string | null | undefined;
|
17
|
+
stringFromStdin: string;
|
15
18
|
}
|
16
19
|
|
17
20
|
const innerState: InnerState = {
|
18
21
|
installDir: undefined,
|
22
|
+
stringFromStdin: '',
|
19
23
|
};
|
20
24
|
|
21
25
|
// Process-related functions and objects
|
@@ -26,6 +30,12 @@ export const getInstallDir = (): string => {
|
|
26
30
|
}
|
27
31
|
throw new Error('Install directory not set');
|
28
32
|
};
|
33
|
+
/**
|
34
|
+
* Cached string from stdin. Should only be called after readStdin completes execution.
|
35
|
+
*/
|
36
|
+
export const getStringFromStdin = (): string => {
|
37
|
+
return innerState.stringFromStdin;
|
38
|
+
};
|
29
39
|
export const exit = (code?: number): never => process.exit(code || 0);
|
30
40
|
export const stdin = process.stdin;
|
31
41
|
export const stdout = process.stdout;
|
@@ -44,6 +54,34 @@ export const setEntryPoint = (indexJs: string): void => {
|
|
44
54
|
innerState.installDir = resolve(dirPath);
|
45
55
|
};
|
46
56
|
|
57
|
+
/**
|
58
|
+
* Asynchronously reads the stdin and stores it as a string,
|
59
|
+
* it can later be retrieved with getStringFromStdin.
|
60
|
+
*/
|
61
|
+
export function readStdin(program: Command): Promise<void> {
|
62
|
+
return new Promise((resolvePromise) => {
|
63
|
+
if (stdin.isTTY) {
|
64
|
+
program.parseAsync().then(() => resolvePromise());
|
65
|
+
} else {
|
66
|
+
// Support piping diff into gsloth
|
67
|
+
const progressIndicator = new ProgressIndicator('reading STDIN', true);
|
68
|
+
|
69
|
+
stdin.on('readable', function (this: NodeJS.ReadStream) {
|
70
|
+
const chunk = this.read();
|
71
|
+
progressIndicator.indicate();
|
72
|
+
if (chunk !== null) {
|
73
|
+
const chunkStr = chunk.toString('utf8');
|
74
|
+
innerState.stringFromStdin = innerState.stringFromStdin + chunkStr;
|
75
|
+
}
|
76
|
+
});
|
77
|
+
|
78
|
+
stdin.on('end', function () {
|
79
|
+
program.parseAsync(argv).then(() => resolvePromise());
|
80
|
+
});
|
81
|
+
}
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
47
85
|
// Console-related functions
|
48
86
|
export const log = (message: string): void => console.log(message);
|
49
87
|
export const error = (message: string): void => console.error(message);
|
package/src/utils.ts
CHANGED
@@ -1,36 +1,84 @@
|
|
1
1
|
import { display, displayError, displaySuccess, displayWarning } from '#src/consoleUtils.js';
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
3
|
-
import { SlothConfig
|
4
|
-
import { resolve } from 'node:path';
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
3
|
+
import { SlothConfig } from '#src/config.js';
|
4
|
+
import { resolve, dirname } from 'node:path';
|
5
5
|
import { spawn } from 'node:child_process';
|
6
|
-
import {
|
6
|
+
import { getCurrentDir, getInstallDir, stdout } from '#src/systemUtils.js';
|
7
7
|
import url from 'node:url';
|
8
|
-
import { Command } from 'commander';
|
9
8
|
|
10
9
|
export function toFileSafeString(string: string): string {
|
11
10
|
return string.replace(/[^A-Za-z0-9]/g, '-');
|
12
11
|
}
|
13
12
|
|
13
|
+
/**
|
14
|
+
* Returns a formatted date string in the format YYYY-MM-DD_HH-MM-SS using local time
|
15
|
+
* @returns A formatted date string
|
16
|
+
*/
|
14
17
|
export function fileSafeLocalDate(): string {
|
15
18
|
const date = new Date();
|
16
|
-
|
17
|
-
|
18
|
-
const
|
19
|
-
const
|
20
|
-
const
|
21
|
-
|
19
|
+
|
20
|
+
// Format: YYYY-MM-DD_HH-MM-SS using local time directly
|
21
|
+
const year = date.getFullYear();
|
22
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
23
|
+
const day = String(date.getDate()).padStart(2, '0');
|
24
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
25
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
26
|
+
const seconds = String(date.getSeconds()).padStart(2, '0');
|
27
|
+
|
28
|
+
return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`;
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Generates a standardized filename with the format: gth_YYYY-MM-DD_HH-MM-SS_COMMAND.md
|
33
|
+
* @param command - The command that created the file (ASK, REVIEW, PR, etc.)
|
34
|
+
* @returns A standardized filename string
|
35
|
+
*/
|
36
|
+
export function generateStandardFileName(command: string): string {
|
37
|
+
const dateTimeStr = fileSafeLocalDate();
|
38
|
+
const commandStr = toFileSafeString(command.toUpperCase());
|
39
|
+
|
40
|
+
return `gth_${dateTimeStr}_${commandStr}.md`;
|
22
41
|
}
|
23
42
|
|
24
43
|
export function readFileFromCurrentDir(fileName: string): string {
|
25
44
|
const currentDir = getCurrentDir();
|
26
45
|
const filePath = resolve(currentDir, fileName);
|
27
|
-
display(`Reading file ${
|
46
|
+
display(`Reading file ${filePath}...`);
|
28
47
|
return readFileSyncWithMessages(filePath);
|
29
48
|
}
|
30
49
|
|
50
|
+
export function readFileFromCurrentOrInstallDir(filePath: string, silentCurrent?: boolean): string {
|
51
|
+
const currentDir = getCurrentDir();
|
52
|
+
const currentFilePath = resolve(currentDir, filePath);
|
53
|
+
if (!silentCurrent) {
|
54
|
+
display(`Reading file ${currentFilePath}...`);
|
55
|
+
}
|
56
|
+
|
57
|
+
try {
|
58
|
+
return readFileSync(currentFilePath, { encoding: 'utf8' });
|
59
|
+
} catch (_error) {
|
60
|
+
if (!silentCurrent) {
|
61
|
+
display(`The ${currentFilePath} not found or can\'t be read, trying install directory...`);
|
62
|
+
}
|
63
|
+
const installDir = getInstallDir();
|
64
|
+
const installFilePath = resolve(installDir, filePath);
|
65
|
+
try {
|
66
|
+
return readFileSync(installFilePath, { encoding: 'utf8' });
|
67
|
+
} catch (readFromInstallDirError) {
|
68
|
+
displayError(`The ${installFilePath} not found or can\'t be read.`);
|
69
|
+
throw readFromInstallDirError;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
31
74
|
export function writeFileIfNotExistsWithMessages(filePath: string, content: string): void {
|
32
75
|
display(`checking ${filePath} existence`);
|
33
76
|
if (!existsSync(filePath)) {
|
77
|
+
// Create parent directories if they don't exist
|
78
|
+
const parentDir = dirname(filePath);
|
79
|
+
if (!existsSync(parentDir)) {
|
80
|
+
mkdirSync(parentDir, { recursive: true });
|
81
|
+
}
|
34
82
|
writeFileSync(filePath, content);
|
35
83
|
displaySuccess(`Created ${filePath}`);
|
36
84
|
} else {
|
@@ -53,36 +101,10 @@ export function readFileSyncWithMessages(
|
|
53
101
|
} else {
|
54
102
|
displayError((error as Error).message);
|
55
103
|
}
|
56
|
-
|
57
|
-
throw error; // This line will never be reached due to exit(1), but satisfies TypeScript
|
104
|
+
throw error;
|
58
105
|
}
|
59
106
|
}
|
60
107
|
|
61
|
-
export function readStdin(program: Command): Promise<void> {
|
62
|
-
return new Promise((resolvePromise) => {
|
63
|
-
if (stdin.isTTY) {
|
64
|
-
program.parseAsync().then(() => resolvePromise());
|
65
|
-
} else {
|
66
|
-
// Support piping diff into gsloth
|
67
|
-
const progressIndicator = new ProgressIndicator('reading STDIN');
|
68
|
-
progressIndicator.indicate();
|
69
|
-
|
70
|
-
stdin.on('readable', function (this: NodeJS.ReadStream) {
|
71
|
-
const chunk = this.read();
|
72
|
-
progressIndicator.indicate();
|
73
|
-
if (chunk !== null) {
|
74
|
-
const chunkStr = chunk.toString('utf8');
|
75
|
-
(slothContext as { stdin: string }).stdin = slothContext.stdin + chunkStr;
|
76
|
-
}
|
77
|
-
});
|
78
|
-
|
79
|
-
stdin.on('end', function () {
|
80
|
-
program.parseAsync(argv).then(() => resolvePromise());
|
81
|
-
});
|
82
|
-
}
|
83
|
-
});
|
84
|
-
}
|
85
|
-
|
86
108
|
interface SpawnOutput {
|
87
109
|
stdout: string;
|
88
110
|
stderr: string;
|
@@ -95,7 +117,7 @@ export async function spawnCommand(
|
|
95
117
|
successMessage: string
|
96
118
|
): Promise<string> {
|
97
119
|
return new Promise((resolve, reject) => {
|
98
|
-
const progressIndicator = new ProgressIndicator(progressMessage);
|
120
|
+
const progressIndicator = new ProgressIndicator(progressMessage, true);
|
99
121
|
const out: SpawnOutput = { stdout: '', stderr: '' };
|
100
122
|
const spawned = spawn(command, args);
|
101
123
|
|
@@ -134,21 +156,31 @@ export function getSlothVersion(): string {
|
|
134
156
|
}
|
135
157
|
|
136
158
|
export class ProgressIndicator {
|
137
|
-
private
|
138
|
-
|
159
|
+
private interval: number | undefined = undefined;
|
160
|
+
|
161
|
+
constructor(initialMessage: string, manual?: boolean) {
|
162
|
+
stdout.write(initialMessage);
|
163
|
+
if (!manual) {
|
164
|
+
this.interval = setInterval(this.indicateInner, 1000) as unknown as number;
|
165
|
+
}
|
166
|
+
}
|
139
167
|
|
140
|
-
|
141
|
-
|
142
|
-
this.initialMessage = initialMessage;
|
168
|
+
private indicateInner(): void {
|
169
|
+
stdout.write('.');
|
143
170
|
}
|
144
171
|
|
145
172
|
indicate(): void {
|
146
|
-
if (this.
|
147
|
-
|
148
|
-
}
|
149
|
-
|
150
|
-
|
173
|
+
if (this.interval) {
|
174
|
+
throw new Error('ProgressIndicator.indicate only to be called in manual mode');
|
175
|
+
}
|
176
|
+
this.indicateInner();
|
177
|
+
}
|
178
|
+
|
179
|
+
stop(): void {
|
180
|
+
if (this.interval) {
|
181
|
+
clearInterval(this.interval);
|
151
182
|
}
|
183
|
+
stdout.write('\n');
|
152
184
|
}
|
153
185
|
}
|
154
186
|
|
@@ -1,125 +0,0 @@
|
|
1
|
-
You are conducting LangChain.js/LangGraph.js Node.JS code review.
|
2
|
-
|
3
|
-
# Code Review Guidelines for LangChain.js/LangGraph.js Projects
|
4
|
-
|
5
|
-
## Core Review Principles
|
6
|
-
|
7
|
-
### Architecture and Flow
|
8
|
-
- Verify proper separation of LangChain components (LLMs, chains, agents, tools)
|
9
|
-
- Check for clear data flow between components
|
10
|
-
- Ensure proper state management in LangGraph workflows
|
11
|
-
- Validate error handling and fallback mechanisms
|
12
|
-
|
13
|
-
### Performance Considerations
|
14
|
-
- Review chunking strategies for large inputs
|
15
|
-
- Check for proper caching implementation
|
16
|
-
- Verify memory management for conversation chains
|
17
|
-
- Assess streaming implementation where applicable
|
18
|
-
|
19
|
-
### Security
|
20
|
-
- Validate API key handling and environment variables
|
21
|
-
- Make sure no personal data is present in code
|
22
|
-
- Check for proper input sanitization
|
23
|
-
- Review rate limiting implementation
|
24
|
-
- Verify output validation and sanitization
|
25
|
-
|
26
|
-
## Technical Checklist
|
27
|
-
|
28
|
-
### LangChain.js Specific
|
29
|
-
- [ ] Proper chain composition and sequencing
|
30
|
-
- [ ] Correct prompt template formatting
|
31
|
-
- [ ] Appropriate memory implementation
|
32
|
-
- [ ] Tool configuration and validation
|
33
|
-
- [ ] Output parser implementation
|
34
|
-
- [ ] Model configuration and defaults
|
35
|
-
|
36
|
-
### LangGraph.js Specific
|
37
|
-
- [ ] State machine definition correctness
|
38
|
-
- [ ] Edge case handling in workflows
|
39
|
-
- [ ] Proper node transitions
|
40
|
-
- [ ] State persistence strategy
|
41
|
-
- [ ] Graph visualization implementation (if applicable)
|
42
|
-
|
43
|
-
### General Code Quality
|
44
|
-
- [ ] TypeScript type definitions
|
45
|
-
- [ ] Async/await implementation
|
46
|
-
- [ ] Error boundary definition
|
47
|
-
- [ ] Logging implementation
|
48
|
-
- [ ] Test coverage
|
49
|
-
- [ ] Documentation quality
|
50
|
-
|
51
|
-
## Best Practices
|
52
|
-
|
53
|
-
### Configuration
|
54
|
-
Make sure that API keys are accidentally not included into diff.
|
55
|
-
|
56
|
-
### Common Pitfalls to Check
|
57
|
-
1. Improper chain composition
|
58
|
-
2. Missing error handlers
|
59
|
-
3. Memory leaks in long-running chains
|
60
|
-
4. Incorrect prompt engineering
|
61
|
-
5. Inadequate rate limiting
|
62
|
-
6. Missing type definitions
|
63
|
-
7. Improper streaming implementation
|
64
|
-
|
65
|
-
### Performance Optimization Points
|
66
|
-
1. Caching strategy
|
67
|
-
2. Batch processing implementation
|
68
|
-
3. Connection pooling
|
69
|
-
4. Resource cleanup
|
70
|
-
5. Memory management
|
71
|
-
|
72
|
-
## Testing Requirements
|
73
|
-
|
74
|
-
### Unit Tests
|
75
|
-
- Individual chain components
|
76
|
-
- Tool implementations
|
77
|
-
- Parser functions
|
78
|
-
- State transitions
|
79
|
-
|
80
|
-
### Integration Tests
|
81
|
-
- End-to-end workflows
|
82
|
-
- External API interactions
|
83
|
-
- Error scenarios
|
84
|
-
- State persistence
|
85
|
-
|
86
|
-
### Load Tests
|
87
|
-
- Concurrent request handling
|
88
|
-
- Memory usage under load
|
89
|
-
- Response time benchmarks
|
90
|
-
|
91
|
-
## Documentation Requirements
|
92
|
-
|
93
|
-
1. Architecture overview
|
94
|
-
2. Component interaction diagrams
|
95
|
-
3. Configuration guide
|
96
|
-
4. API documentation
|
97
|
-
5. Error handling guide
|
98
|
-
6. Performance optimization guide
|
99
|
-
7. Deployment checklist
|
100
|
-
|
101
|
-
## Monitoring and Observability
|
102
|
-
|
103
|
-
### Metrics to Track
|
104
|
-
- Chain execution times
|
105
|
-
- Token usage
|
106
|
-
- Error rates
|
107
|
-
- Memory consumption
|
108
|
-
- API latencies
|
109
|
-
|
110
|
-
### Logging Requirements
|
111
|
-
- Request/response pairs
|
112
|
-
- Error stack traces
|
113
|
-
- Performance metrics
|
114
|
-
- State transitions
|
115
|
-
- Resource usage
|
116
|
-
|
117
|
-
---
|
118
|
-
|
119
|
-
Provide specific feedback on any areas of concern or suggestions for improvement. Please categorize your feedback (e.g., "Bug," "Suggestion," "Nitpick").
|
120
|
-
|
121
|
-
Important! In the end conclude if you would recommend to approve this PR or not. Use ✅⚠️❌ symbols to highlight your feedback appropriately.
|
122
|
-
|
123
|
-
Thank you for your thorough review!
|
124
|
-
|
125
|
-
Important! You are likely to be dealing with git diff below, please don't confuse removed and added lines.
|
package/UX-RESEARCH.md
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
# UX Research
|
2
|
-
|
3
|
-
## Currently available commands:
|
4
|
-
```
|
5
|
-
gsloth --help
|
6
|
-
Usage: gsloth [options] [command]
|
7
|
-
|
8
|
-
Gaunt Sloth Assistant reviewing your PRs
|
9
|
-
|
10
|
-
Options:
|
11
|
-
-V, --version output the version number
|
12
|
-
-h, --help display help for command
|
13
|
-
|
14
|
-
Commands:
|
15
|
-
init <type> Initialize the Gaunt Sloth Assistant in your project.
|
16
|
-
This will write necessary config files.
|
17
|
-
pr [options] <prNumber> Review a PR in current git directory (assuming that
|
18
|
-
GH cli is installed and authenticated for current
|
19
|
-
project
|
20
|
-
review [options] Review provided diff or other content
|
21
|
-
ask [options] <message> Ask a question
|
22
|
-
help [command] display help for command
|
23
|
-
```
|
24
|
-
|
25
|
-
pr (we decided to rename it to r as shortcut for review with pull request provider)
|
26
|
-
```
|
27
|
-
gsloth pr --help
|
28
|
-
Usage: gsloth pr [options] <prNumber>
|
29
|
-
|
30
|
-
Review a PR in current git directory (assuming that GH cli is installed and
|
31
|
-
authenticated for current project
|
32
|
-
|
33
|
-
Arguments:
|
34
|
-
prNumber PR number to review
|
35
|
-
|
36
|
-
Options:
|
37
|
-
-f, --file <file> Input file. Content of this file will be added BEFORE the
|
38
|
-
diff
|
39
|
-
-h, --help display help for command
|
40
|
-
```
|
41
|
-
|
42
|
-
ask
|
43
|
-
```
|
44
|
-
gsloth ask --help
|
45
|
-
Usage: gsloth ask [options] <message>
|
46
|
-
|
47
|
-
Ask a question
|
48
|
-
|
49
|
-
Arguments:
|
50
|
-
message A message
|
51
|
-
|
52
|
-
Options:
|
53
|
-
-f, --file <file> Input file. Context of this file will be added BEFORE the
|
54
|
-
diff
|
55
|
-
-h, --help display help for command
|
56
|
-
```
|
57
|
-
|
58
|
-
review (lacks documentaion, it also accepts pipe with stdin)
|
59
|
-
```
|
60
|
-
gsloth review --help
|
61
|
-
Usage: gsloth review [options]
|
62
|
-
|
63
|
-
Review provided diff or other content
|
64
|
-
|
65
|
-
Options:
|
66
|
-
-f, --file <file> Input file. Context of this file will be added BEFORE the
|
67
|
-
diff
|
68
|
-
-h, --help display help for command
|
69
|
-
```
|
70
|
-
|
71
|
-
## Future functions
|
72
|
-
|
73
|
-
- JIRA. We need to privide a jira number as a criteria, this should somehow go through separate provider and using config from .gsloth.config.
|
74
|
-
- External links (simple public links)
|
75
|
-
- Editing files
|
76
|
-
- Improve experience with specs or criteria (or requirements?)
|
77
|
-
- Should we allow to mention that the data is diff or plain code? Maybe we can somehow deduct it or ask smaller model to guess?
|
78
|
-
- Slot editing local files
|