@stackmemoryai/stackmemory 1.5.2 → 1.5.4
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 +24 -1
- package/dist/src/cli/commands/dashboard.js +47 -1
- package/dist/src/cli/commands/orchestrate.js +82 -5
- package/dist/src/cli/commands/orchestrator.js +428 -61
- package/package.json +2 -2
- package/scripts/gepa/.before-optimize.md +89 -53
- package/scripts/gepa/generations/gen-000/baseline.md +8 -0
- package/scripts/gepa/generations/gen-001/baseline.md +8 -0
- package/scripts/gepa/generations/gen-001/variant-a.md +81 -81
- package/scripts/gepa/generations/gen-001/variant-b.md +78 -64
- package/scripts/gepa/generations/gen-001/variant-c.md +54 -74
- package/scripts/gepa/generations/gen-001/variant-d.md +79 -113
- package/scripts/gepa/results/eval-1-baseline.json +74 -74
- package/scripts/gepa/results/eval-1-variant-a.json +64 -64
- package/scripts/gepa/results/eval-1-variant-b.json +65 -65
- package/scripts/gepa/results/eval-1-variant-c.json +78 -58
- package/scripts/gepa/results/eval-1-variant-d.json +77 -57
- package/scripts/gepa/state.json +14 -14
|
@@ -6,25 +6,25 @@
|
|
|
6
6
|
"taskId": "eval-001",
|
|
7
7
|
"taskName": "simple_function",
|
|
8
8
|
"weight": 1,
|
|
9
|
-
"passed":
|
|
10
|
-
"passRate": 0,
|
|
9
|
+
"passed": true,
|
|
10
|
+
"passRate": 0.6666666666666666,
|
|
11
11
|
"criteria": {
|
|
12
12
|
"has_function": {
|
|
13
|
-
"passed":
|
|
14
|
-
"reason": "
|
|
13
|
+
"passed": true,
|
|
14
|
+
"reason": "A real, working function named isPalindrome is defined with proper TypeScript syntax and implementation"
|
|
15
15
|
},
|
|
16
16
|
"handles_edge_cases": {
|
|
17
|
-
"passed":
|
|
18
|
-
"reason": "
|
|
17
|
+
"passed": true,
|
|
18
|
+
"reason": "The code handles edge cases by converting to lowercase, removing non-alphanumeric characters, and comparing cleaned strings - covers cases like mixed case, spaces, and punctuation"
|
|
19
19
|
},
|
|
20
20
|
"is_tested": {
|
|
21
21
|
"passed": false,
|
|
22
|
-
"reason": "
|
|
22
|
+
"reason": "No test cases or test calls are provided in the output; only the function definition exists without any testing code"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"judgeMode": "llm",
|
|
26
|
-
"duration":
|
|
27
|
-
"output": "
|
|
26
|
+
"duration": 8242,
|
|
27
|
+
"output": "```typescript\nfunction isPalindrome(s: string): boolean {\n const cleaned = s.toLowerCase().replace(/[^a-z0-9]/g, '');\n return cleaned === cleaned.split('').reverse().join('');\n}\n```\n"
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"taskId": "eval-002",
|
|
@@ -35,20 +35,20 @@
|
|
|
35
35
|
"criteria": {
|
|
36
36
|
"uses_async": {
|
|
37
37
|
"passed": false,
|
|
38
|
-
"reason": "No async/await code
|
|
38
|
+
"reason": "No async/await code is present in the output. The AI only asks for clarification instead of providing refactored code."
|
|
39
39
|
},
|
|
40
40
|
"preserves_behavior": {
|
|
41
41
|
"passed": false,
|
|
42
|
-
"reason": "
|
|
42
|
+
"reason": "No refactored code was provided, so behavior cannot be preserved or verified."
|
|
43
43
|
},
|
|
44
44
|
"no_nested_callbacks": {
|
|
45
45
|
"passed": false,
|
|
46
|
-
"reason": "No
|
|
46
|
+
"reason": "No code was refactored at all. The output is a request for input rather than a solution."
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
"judgeMode": "llm",
|
|
50
|
-
"duration":
|
|
51
|
-
"output": "
|
|
50
|
+
"duration": 8332,
|
|
51
|
+
"output": "Which file or code snippet would you like me to refactor?\n"
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"taskId": "eval-003",
|
|
@@ -59,72 +59,72 @@
|
|
|
59
59
|
"criteria": {
|
|
60
60
|
"bug_fixed": {
|
|
61
61
|
"passed": false,
|
|
62
|
-
"reason": "No code was
|
|
62
|
+
"reason": "No code was fixed; the AI requested clarification instead of fixing the bug"
|
|
63
63
|
},
|
|
64
64
|
"no_new_bugs": {
|
|
65
65
|
"passed": false,
|
|
66
|
-
"reason": "
|
|
66
|
+
"reason": "No code was provided to evaluate for new bugs"
|
|
67
67
|
},
|
|
68
68
|
"explains_fix": {
|
|
69
69
|
"passed": false,
|
|
70
|
-
"reason": "No explanation was provided; the
|
|
70
|
+
"reason": "No explanation of any fix was provided; the AI only asked for more information"
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"judgeMode": "llm",
|
|
74
|
-
"duration":
|
|
75
|
-
"output": "
|
|
74
|
+
"duration": 9222,
|
|
75
|
+
"output": "Could you point me to the file and loop you'd like me to fix? Or share the relevant code snippet?\n"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
"taskId": "eval-004",
|
|
79
79
|
"taskName": "add_feature",
|
|
80
80
|
"weight": 1.5,
|
|
81
|
-
"passed":
|
|
82
|
-
"passRate": 0
|
|
81
|
+
"passed": false,
|
|
82
|
+
"passRate": 0,
|
|
83
83
|
"criteria": {
|
|
84
84
|
"has_pagination": {
|
|
85
|
-
"passed":
|
|
86
|
-
"reason": "
|
|
85
|
+
"passed": false,
|
|
86
|
+
"reason": "No pagination code is implemented. The AI only asks for clarification instead of providing a working solution."
|
|
87
87
|
},
|
|
88
88
|
"has_limit": {
|
|
89
|
-
"passed":
|
|
90
|
-
"reason": "
|
|
89
|
+
"passed": false,
|
|
90
|
+
"reason": "No limit parameter is defined or implemented in the output."
|
|
91
91
|
},
|
|
92
92
|
"has_offset": {
|
|
93
93
|
"passed": false,
|
|
94
|
-
"reason": "
|
|
94
|
+
"reason": "No offset parameter is defined or implemented in the output."
|
|
95
95
|
},
|
|
96
96
|
"backwards_compatible": {
|
|
97
|
-
"passed":
|
|
98
|
-
"reason": "
|
|
97
|
+
"passed": false,
|
|
98
|
+
"reason": "No code is provided to evaluate backwards compatibility. The output is a clarification request rather than a solution."
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
101
|
"judgeMode": "llm",
|
|
102
|
-
"duration":
|
|
103
|
-
"output": "
|
|
102
|
+
"duration": 9128,
|
|
103
|
+
"output": "Which API endpoint should I add pagination to? Please share the file path or endpoint name.\n"
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
"taskId": "eval-005",
|
|
107
107
|
"taskName": "code_review",
|
|
108
108
|
"weight": 1.3,
|
|
109
|
-
"passed":
|
|
110
|
-
"passRate": 0
|
|
109
|
+
"passed": false,
|
|
110
|
+
"passRate": 0,
|
|
111
111
|
"criteria": {
|
|
112
112
|
"identifies_security_issue": {
|
|
113
|
-
"passed":
|
|
114
|
-
"reason": "
|
|
113
|
+
"passed": false,
|
|
114
|
+
"reason": "The output does not identify any security issue. Instead, it asks for PR details and provides no analysis."
|
|
115
115
|
},
|
|
116
116
|
"identifies_performance_issue": {
|
|
117
117
|
"passed": false,
|
|
118
|
-
"reason": "
|
|
118
|
+
"reason": "The output does not identify any performance issue. It only requests information rather than providing a review."
|
|
119
119
|
},
|
|
120
120
|
"actionable_feedback": {
|
|
121
|
-
"passed":
|
|
122
|
-
"reason": "
|
|
121
|
+
"passed": false,
|
|
122
|
+
"reason": "The output provides no actionable feedback. It is a request for input, not a code review with concrete suggestions or findings."
|
|
123
123
|
}
|
|
124
124
|
},
|
|
125
125
|
"judgeMode": "llm",
|
|
126
|
-
"duration":
|
|
127
|
-
"output": "
|
|
126
|
+
"duration": 17368,
|
|
127
|
+
"output": "Which PR would you like me to review? Please share the PR URL, PR number, or branch name.\n"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"taskId": "sm-001",
|
|
@@ -135,28 +135,28 @@
|
|
|
135
135
|
"criteria": {
|
|
136
136
|
"has_switch_case": {
|
|
137
137
|
"passed": false,
|
|
138
|
-
"reason": "
|
|
138
|
+
"reason": "Only described in text; no actual switch/case code block is provided in the output"
|
|
139
139
|
},
|
|
140
140
|
"has_zod_schema": {
|
|
141
141
|
"passed": false,
|
|
142
|
-
"reason": "
|
|
142
|
+
"reason": "Schema is mentioned but not actually defined in code; only described as text"
|
|
143
143
|
},
|
|
144
144
|
"validates_input": {
|
|
145
145
|
"passed": false,
|
|
146
|
-
"reason": "
|
|
146
|
+
"reason": "Validation is discussed but no actual validation code is shown in the output"
|
|
147
147
|
},
|
|
148
148
|
"returns_typed_response": {
|
|
149
149
|
"passed": false,
|
|
150
|
-
"reason": "
|
|
150
|
+
"reason": "Return format is described but no actual return statement or typed response object is provided"
|
|
151
151
|
},
|
|
152
152
|
"handles_not_found": {
|
|
153
153
|
"passed": false,
|
|
154
|
-
"reason": "
|
|
154
|
+
"reason": "Error handling is mentioned ('throws if not found') but no actual try/catch or error handling code is shown"
|
|
155
155
|
}
|
|
156
156
|
},
|
|
157
157
|
"judgeMode": "llm",
|
|
158
|
-
"duration":
|
|
159
|
-
"output": "\n"
|
|
158
|
+
"duration": 28686,
|
|
159
|
+
"output": "Please approve the file write permission and I'll apply the change. The edit adds a `get_frame_summary` case between `close_frame` and `default` that:\n\n1. Validates `frameId` with `z.object({ frameId: z.string().min(1) })`\n2. Looks up the frame, throws if not found\n3. Returns `{ frameId, name, status, eventCount: frame.events.length }`\n"
|
|
160
160
|
},
|
|
161
161
|
{
|
|
162
162
|
"taskId": "sm-002",
|
|
@@ -167,52 +167,52 @@
|
|
|
167
167
|
"criteria": {
|
|
168
168
|
"has_delete_trigger": {
|
|
169
169
|
"passed": false,
|
|
170
|
-
"reason": "
|
|
170
|
+
"reason": "No DELETE trigger is provided in the output, only a request for permission"
|
|
171
171
|
},
|
|
172
172
|
"uses_fts_delete_syntax": {
|
|
173
173
|
"passed": false,
|
|
174
|
-
"reason": "No FTS5 DELETE syntax is present
|
|
174
|
+
"reason": "No FTS5 DELETE syntax is present in the output"
|
|
175
175
|
},
|
|
176
176
|
"references_old_row": {
|
|
177
177
|
"passed": false,
|
|
178
|
-
"reason": "
|
|
178
|
+
"reason": "No reference to OLD row values in any trigger code"
|
|
179
179
|
},
|
|
180
180
|
"matches_column_list": {
|
|
181
181
|
"passed": false,
|
|
182
|
-
"reason": "
|
|
182
|
+
"reason": "No column list or trigger definition is included in the output"
|
|
183
183
|
}
|
|
184
184
|
},
|
|
185
185
|
"judgeMode": "llm",
|
|
186
|
-
"duration":
|
|
187
|
-
"output": "
|
|
186
|
+
"duration": 37943,
|
|
187
|
+
"output": "Please approve the write permission so I can apply the fix.\n"
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
190
|
"taskId": "sm-003",
|
|
191
191
|
"taskName": "daemon_service_lifecycle",
|
|
192
192
|
"weight": 1.5,
|
|
193
|
-
"passed":
|
|
194
|
-
"passRate":
|
|
193
|
+
"passed": true,
|
|
194
|
+
"passRate": 1,
|
|
195
195
|
"criteria": {
|
|
196
196
|
"clears_old_interval": {
|
|
197
|
-
"passed":
|
|
198
|
-
"reason": "
|
|
197
|
+
"passed": true,
|
|
198
|
+
"reason": "The fix adds `if (this.isRunning) this.stop();` at the top of `start()`, which ensures any existing interval is cleared via `stop()` before a new one is created. This directly addresses the timer leak."
|
|
199
199
|
},
|
|
200
200
|
"prevents_double_start": {
|
|
201
|
-
"passed":
|
|
202
|
-
"reason": "
|
|
201
|
+
"passed": true,
|
|
202
|
+
"reason": "The guard `if (this.isRunning) this.stop();` prevents double-start by checking the running state and stopping the old interval before proceeding, making `start()` idempotent."
|
|
203
203
|
},
|
|
204
204
|
"has_getstate_method": {
|
|
205
|
-
"passed":
|
|
206
|
-
"reason": "
|
|
205
|
+
"passed": true,
|
|
206
|
+
"reason": "A complete `getState()` method is defined in the output that returns an object with the required properties. The method is shown as actual code, not just a TODO or mention."
|
|
207
207
|
},
|
|
208
208
|
"returns_correct_state_shape": {
|
|
209
|
-
"passed":
|
|
210
|
-
"reason": "
|
|
209
|
+
"passed": true,
|
|
210
|
+
"reason": "The `getState()` method returns an object with all four required properties: `isRunning`, `intervalMs`, `lastRunTime`, and `errorCount`. The intervalMs calculation matches the service's interval conversion logic."
|
|
211
211
|
}
|
|
212
212
|
},
|
|
213
213
|
"judgeMode": "llm",
|
|
214
|
-
"duration":
|
|
215
|
-
"output": "\n"
|
|
214
|
+
"duration": 39514,
|
|
215
|
+
"output": "It seems write permission isn't granted. Here are both changes needed — apply them manually or grant write access:\n\n**Fix 1 — `start()`: guard against double-start (lines 25–31)**\n\n```ts\n// Before\n// BUG: No guard against double-start — calling start() twice\n// creates two intervals but only stores the second one.\n// The first interval leaks and keeps running forever.\nstart(): void {\n this.isRunning = true;\n const intervalMs = this.config.interval * 60 * 1000;\n\n// After\nstart(): void {\n if (this.isRunning) this.stop();\n this.isRunning = true;\n const intervalMs = this.config.interval * 60 * 1000;\n```\n\n**Fix 2 — remove stale `updateConfig` comment and add `getState()` (lines 47–57)**\n\n```ts\n// Before\n// BUG: Calls stop() then start() but start() doesn't check\n// if already running, so if stop() fails to clear the interval\n// (e.g., intervalId is undefined), we leak.\nupdateConfig(config: Partial<ServiceConfig>): void {\n const wasRunning = this.isRunning;\n if (wasRunning) this.stop();\n this.config = { ...this.config, ...config };\n if (wasRunning && this.config.enabled) this.start();\n}\n\n// TODO: Add getState() method returning ServiceState\n\n// After\nupdateConfig(config: Partial<ServiceConfig>): void {\n const wasRunning = this.isRunning;\n if (wasRunning) this.stop();\n this.config = { ...this.config, ...config };\n if (wasRunning && this.config.enabled) this.start();\n}\n\ngetState(): ServiceState {\n return {\n isRunning: this.isRunning,\n intervalMs: this.config.interval * 60 * 1000,\n lastRunTime: this.lastRunTime,\n errorCount: this.errorCount,\n };\n}\n```\n\n---\n\n**Root cause:** `start()` unconditionally called `setInterval` without checking `isRunning`. Any call path that triggers `start()` while the service is already running (direct double-call, or `updateConfig` if `stop()` somehow left `isRunning = true`) would orphan the old interval — `intervalId` gets overwritten so `clearInterval` can never reach it.\n\n**The fix:** `if (this.isRunning) this.stop("
|
|
216
216
|
}
|
|
217
217
|
]
|
|
218
218
|
}
|
|
@@ -6,25 +6,25 @@
|
|
|
6
6
|
"taskId": "eval-001",
|
|
7
7
|
"taskName": "simple_function",
|
|
8
8
|
"weight": 1,
|
|
9
|
-
"passed":
|
|
10
|
-
"passRate": 0,
|
|
9
|
+
"passed": true,
|
|
10
|
+
"passRate": 0.6666666666666666,
|
|
11
11
|
"criteria": {
|
|
12
12
|
"has_function": {
|
|
13
|
-
"passed":
|
|
14
|
-
"reason": "
|
|
13
|
+
"passed": true,
|
|
14
|
+
"reason": "A complete, working function named is_palindrome is defined with proper syntax and type hints"
|
|
15
15
|
},
|
|
16
16
|
"handles_edge_cases": {
|
|
17
17
|
"passed": false,
|
|
18
|
-
"reason": "
|
|
18
|
+
"reason": "The function only handles spaces and case sensitivity, but doesn't handle punctuation, special characters, or empty strings - common edge cases for palindrome checking"
|
|
19
19
|
},
|
|
20
20
|
"is_tested": {
|
|
21
|
-
"passed":
|
|
22
|
-
"reason": "
|
|
21
|
+
"passed": true,
|
|
22
|
+
"reason": "Usage examples are provided showing the function being called with different inputs"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"judgeMode": "llm",
|
|
26
|
-
"duration":
|
|
27
|
-
"output": "
|
|
26
|
+
"duration": 10826,
|
|
27
|
+
"output": "```python\ndef is_palindrome(s: str) -> bool:\n s = s.lower().replace(\" \", \"\")\n return s == s[::-1]\n```\n\n**Usage:**\n```python\nis_palindrome(\"racecar\") # True\nis_palindrome(\"A man a plan a canal Panama\") # True\nis_palindrome(\"hello\") # False\n```\n"
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"taskId": "eval-002",
|
|
@@ -35,72 +35,72 @@
|
|
|
35
35
|
"criteria": {
|
|
36
36
|
"uses_async": {
|
|
37
37
|
"passed": false,
|
|
38
|
-
"reason": "No async/await code is
|
|
38
|
+
"reason": "No async/await code is present. The AI output is a request for input rather than a refactored code example."
|
|
39
39
|
},
|
|
40
40
|
"preserves_behavior": {
|
|
41
41
|
"passed": false,
|
|
42
|
-
"reason": "
|
|
42
|
+
"reason": "No refactored code is provided, so behavior cannot be preserved or verified."
|
|
43
43
|
},
|
|
44
44
|
"no_nested_callbacks": {
|
|
45
45
|
"passed": false,
|
|
46
|
-
"reason": "No code refactoring was performed
|
|
46
|
+
"reason": "No code refactoring was performed. The output does not demonstrate elimination of nested callbacks."
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
"judgeMode": "llm",
|
|
50
|
-
"duration":
|
|
51
|
-
"output": "
|
|
50
|
+
"duration": 13085,
|
|
51
|
+
"output": "Please share the code you'd like me to refactor.\n"
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"taskId": "eval-003",
|
|
55
55
|
"taskName": "fix_bug",
|
|
56
56
|
"weight": 1.2,
|
|
57
57
|
"passed": false,
|
|
58
|
-
"passRate": 0
|
|
58
|
+
"passRate": 0,
|
|
59
59
|
"criteria": {
|
|
60
60
|
"bug_fixed": {
|
|
61
61
|
"passed": false,
|
|
62
|
-
"reason": "No code was provided by the user, so
|
|
62
|
+
"reason": "No code was provided by the user, so no bug could be fixed. The AI correctly asked for the code but did not fix anything."
|
|
63
63
|
},
|
|
64
64
|
"no_new_bugs": {
|
|
65
|
-
"passed":
|
|
66
|
-
"reason": "
|
|
65
|
+
"passed": false,
|
|
66
|
+
"reason": "Cannot evaluate this criterion when no code was analyzed or modified."
|
|
67
67
|
},
|
|
68
68
|
"explains_fix": {
|
|
69
69
|
"passed": false,
|
|
70
|
-
"reason": "No explanation of
|
|
70
|
+
"reason": "No explanation of a fix was provided because no code was available to analyze or correct."
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"judgeMode": "llm",
|
|
74
|
-
"duration":
|
|
75
|
-
"output": "I
|
|
74
|
+
"duration": 9146,
|
|
75
|
+
"output": "I don't see any code in your message. Please share the code with the loop you'd like me to fix.\n"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
"taskId": "eval-004",
|
|
79
79
|
"taskName": "add_feature",
|
|
80
80
|
"weight": 1.5,
|
|
81
|
-
"passed":
|
|
82
|
-
"passRate": 0
|
|
81
|
+
"passed": false,
|
|
82
|
+
"passRate": 0,
|
|
83
83
|
"criteria": {
|
|
84
84
|
"has_pagination": {
|
|
85
|
-
"passed":
|
|
86
|
-
"reason": "
|
|
85
|
+
"passed": false,
|
|
86
|
+
"reason": "No pagination implementation provided; AI only asks clarifying questions instead of delivering code"
|
|
87
87
|
},
|
|
88
88
|
"has_limit": {
|
|
89
|
-
"passed":
|
|
90
|
-
"reason": "
|
|
89
|
+
"passed": false,
|
|
90
|
+
"reason": "No limit parameter implemented in any code"
|
|
91
91
|
},
|
|
92
92
|
"has_offset": {
|
|
93
93
|
"passed": false,
|
|
94
|
-
"reason": "
|
|
94
|
+
"reason": "No offset parameter implemented in any code"
|
|
95
95
|
},
|
|
96
96
|
"backwards_compatible": {
|
|
97
|
-
"passed":
|
|
98
|
-
"reason": "
|
|
97
|
+
"passed": false,
|
|
98
|
+
"reason": "No implementation provided to evaluate backwards compatibility"
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
101
|
"judgeMode": "llm",
|
|
102
|
-
"duration":
|
|
103
|
-
"output": "
|
|
102
|
+
"duration": 14908,
|
|
103
|
+
"output": "Which API endpoint would you like to add pagination to? Can you point me to the specific file or endpoint?\n"
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
"taskId": "eval-005",
|
|
@@ -111,52 +111,52 @@
|
|
|
111
111
|
"criteria": {
|
|
112
112
|
"identifies_security_issue": {
|
|
113
113
|
"passed": false,
|
|
114
|
-
"reason": "The output does not identify any security
|
|
114
|
+
"reason": "The output does not identify any security issue. It only requests the PR to be reviewed without analyzing any code."
|
|
115
115
|
},
|
|
116
116
|
"identifies_performance_issue": {
|
|
117
117
|
"passed": false,
|
|
118
|
-
"reason": "The output does not identify any performance
|
|
118
|
+
"reason": "The output does not identify any performance issue. It only requests input without providing any analysis."
|
|
119
119
|
},
|
|
120
120
|
"actionable_feedback": {
|
|
121
121
|
"passed": false,
|
|
122
|
-
"reason": "The output provides no
|
|
122
|
+
"reason": "The output provides no feedback at all, only a request for the PR details. No actionable suggestions or recommendations are given."
|
|
123
123
|
}
|
|
124
124
|
},
|
|
125
125
|
"judgeMode": "llm",
|
|
126
|
-
"duration":
|
|
127
|
-
"output": "
|
|
126
|
+
"duration": 16301,
|
|
127
|
+
"output": "Which PR would you like me to review? Please share the PR URL, PR number + repo, or paste the diff/description.\n"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"taskId": "sm-001",
|
|
131
131
|
"taskName": "add_mcp_tool_handler",
|
|
132
132
|
"weight": 1.5,
|
|
133
|
-
"passed":
|
|
134
|
-
"passRate":
|
|
133
|
+
"passed": true,
|
|
134
|
+
"passRate": 1,
|
|
135
135
|
"criteria": {
|
|
136
136
|
"has_switch_case": {
|
|
137
|
-
"passed":
|
|
138
|
-
"reason": "
|
|
137
|
+
"passed": true,
|
|
138
|
+
"reason": "The output shows a valid case clause 'get_frame_summary': with proper switch/case syntax"
|
|
139
139
|
},
|
|
140
140
|
"has_zod_schema": {
|
|
141
|
-
"passed":
|
|
142
|
-
"reason": "
|
|
141
|
+
"passed": true,
|
|
142
|
+
"reason": "Zod schema is defined with z.object({ frameId: z.string().min(1) })"
|
|
143
143
|
},
|
|
144
144
|
"validates_input": {
|
|
145
|
-
"passed":
|
|
146
|
-
"reason": "
|
|
145
|
+
"passed": true,
|
|
146
|
+
"reason": "Input validation occurs via .parse(args) which will throw if frameId is missing or invalid"
|
|
147
147
|
},
|
|
148
148
|
"returns_typed_response": {
|
|
149
|
-
"passed":
|
|
150
|
-
"reason": "
|
|
149
|
+
"passed": true,
|
|
150
|
+
"reason": "Returns an object with the exact required fields: { frameId, name, status, eventCount }"
|
|
151
151
|
},
|
|
152
152
|
"handles_not_found": {
|
|
153
|
-
"passed":
|
|
154
|
-
"reason": "
|
|
153
|
+
"passed": true,
|
|
154
|
+
"reason": "Explicitly checks if frame exists and throws an Error with descriptive message if not found"
|
|
155
155
|
}
|
|
156
156
|
},
|
|
157
157
|
"judgeMode": "llm",
|
|
158
|
-
"duration":
|
|
159
|
-
"output": "
|
|
158
|
+
"duration": 59274,
|
|
159
|
+
"output": "The edit was denied. Please grant write permission to `/private/tmp/gepa-eval-r2ZUp5/mcp-dispatch-stub.ts` and I'll apply the change.\n\nHere's what I'm adding at line 32 (replacing the TODO comment):\n\n```ts\ncase 'get_frame_summary': {\n const input = z.object({ frameId: z.string().min(1) }).parse(args);\n const frame = frames.get(input.frameId);\n if (!frame) throw new Error(`Frame not found: ${input.frameId}`);\n return { frameId: frame.id, name: frame.name, status: frame.status, eventCount: frame.events.length };\n}\n```\n\n- Zod validates `frameId` as a required non-empty string\n- Throws if the frame doesn't exist (consistent with `close_frame`)\n- Returns `{ frameId, name, status, eventCount }` derived from `frame.events.length`\n"
|
|
160
160
|
},
|
|
161
161
|
{
|
|
162
162
|
"taskId": "sm-002",
|
|
@@ -167,52 +167,52 @@
|
|
|
167
167
|
"criteria": {
|
|
168
168
|
"has_delete_trigger": {
|
|
169
169
|
"passed": true,
|
|
170
|
-
"reason": "A DELETE trigger named 'frames_ad' is
|
|
170
|
+
"reason": "A DELETE trigger named 'frames_ad' is defined with AFTER DELETE ON frames clause"
|
|
171
171
|
},
|
|
172
172
|
"uses_fts_delete_syntax": {
|
|
173
173
|
"passed": true,
|
|
174
|
-
"reason": "The trigger uses FTS5
|
|
174
|
+
"reason": "The trigger uses FTS5 delete syntax: INSERT INTO frames_fts(frames_fts, ...) VALUES ('delete', ...)"
|
|
175
175
|
},
|
|
176
176
|
"references_old_row": {
|
|
177
177
|
"passed": true,
|
|
178
|
-
"reason": "The trigger correctly references
|
|
178
|
+
"reason": "The trigger correctly references old.rowid, old.name, old.digest_text, old.inputs, old.outputs"
|
|
179
179
|
},
|
|
180
180
|
"matches_column_list": {
|
|
181
181
|
"passed": true,
|
|
182
|
-
"reason": "The column list (
|
|
182
|
+
"reason": "The column list (rowid, name, digest_text, inputs, outputs) matches the existing INSERT and UPDATE triggers"
|
|
183
183
|
}
|
|
184
184
|
},
|
|
185
185
|
"judgeMode": "llm",
|
|
186
|
-
"duration":
|
|
187
|
-
"output": "
|
|
186
|
+
"duration": 27339,
|
|
187
|
+
"output": "Waiting for your approval to write the file. The change replaces the bug comment with:\n\n```sql\n-- Sync trigger: DELETE\nCREATE TRIGGER IF NOT EXISTS frames_ad AFTER DELETE ON frames BEGIN\n INSERT INTO frames_fts(frames_fts, rowid, name, digest_text, inputs, outputs)\n VALUES ('delete', old.rowid, old.name, old.digest_text, old.inputs, old.outputs);\nEND;\n```\n\nThis follows the same pattern as the first half of the UPDATE trigger — using the FTS5 `'delete'` command with `old.*` values to remove the stale entry from the index.\n"
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
190
|
"taskId": "sm-003",
|
|
191
191
|
"taskName": "daemon_service_lifecycle",
|
|
192
192
|
"weight": 1.5,
|
|
193
193
|
"passed": true,
|
|
194
|
-
"passRate":
|
|
194
|
+
"passRate": 1,
|
|
195
195
|
"criteria": {
|
|
196
196
|
"clears_old_interval": {
|
|
197
|
-
"passed":
|
|
198
|
-
"reason": "The
|
|
197
|
+
"passed": true,
|
|
198
|
+
"reason": "The fix adds a guard `if (this.isRunning) return` to `start()`, which prevents calling `setInterval` twice. Combined with `stop()` calling `clearInterval`, old intervals are properly cleared before new ones are created."
|
|
199
199
|
},
|
|
200
200
|
"prevents_double_start": {
|
|
201
201
|
"passed": true,
|
|
202
|
-
"reason": "The guard
|
|
202
|
+
"reason": "The guard `if (this.isRunning) return` at the top of `start()` directly prevents double-calls to `start()` by returning early if already running."
|
|
203
203
|
},
|
|
204
204
|
"has_getstate_method": {
|
|
205
205
|
"passed": true,
|
|
206
|
-
"reason": "A `getState()` method is defined that returns an object with the required properties."
|
|
206
|
+
"reason": "A `getState()` method is defined with working implementation that returns an object with the required properties."
|
|
207
207
|
},
|
|
208
208
|
"returns_correct_state_shape": {
|
|
209
209
|
"passed": true,
|
|
210
|
-
"reason": "The
|
|
210
|
+
"reason": "The `getState()` method returns an object with all four required fields: `isRunning`, `intervalMs`, `lastRunTime`, and `errorCount` with appropriate values."
|
|
211
211
|
}
|
|
212
212
|
},
|
|
213
213
|
"judgeMode": "llm",
|
|
214
|
-
"duration":
|
|
215
|
-
"output": "
|
|
214
|
+
"duration": 37880,
|
|
215
|
+
"output": "It seems write permissions aren't granted for that file. Here are the two changes needed:\n\n**Fix 1 — guard `start()` against double-call** (`leaky-service.ts:28`):\n\n```typescript\nstart(): void {\n if (this.isRunning) return; // ADD THIS — prevents interval leak on double-start\n this.isRunning = true;\n const intervalMs = this.config.interval * 60 * 1000;\n // ...\n}\n```\n\n**Fix 2 — remove the BUG comment on `updateConfig`** (it's actually correct — it calls `stop()` first which clears the interval, then `start()` which now has the guard). The `updateConfig` bug comment was describing a secondary issue that's resolved by the `start()` guard.\n\n**Add `getState()`** (`leaky-service.ts:57`):\n\n```typescript\ngetState(): ServiceState {\n return {\n isRunning: this.isRunning,\n intervalMs: this.config.interval * 60 * 1000,\n lastRunTime: this.lastRunTime,\n errorCount: this.errorCount,\n };\n}\n```\n\n---\n\n**Root cause summary:**\n\n- `start()` set `this.isRunning = true` and called `setInterval` unconditionally, so calling it twice created two timers but only saved the second handle — the first leaked forever\n- `updateConfig` called `stop()` → `start()`, which was fine structurally, but since `start()` had no idempotency guard, any external call to `start()` before `updateConfig` finished would cause the same leak\n- The fix is a single `if (this.isRunning) return` at the top of `start()` — `stop()` already handles teardown correctly (`clearInterval` + `isRunning = false`)\n\nCan you grant write access to the file so I can apply the edits directly?\n"
|
|
216
216
|
}
|
|
217
217
|
]
|
|
218
218
|
}
|