pi-harness-runtime 0.10.23 → 0.10.25
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/CHANGELOG.md +39 -0
- package/package.json +1 -1
- package/packages/file-copy-helper/src/extension.js +98 -0
- package/packages/file-copy-helper/src/extension.ts +60 -12
- package/packages/todo-bd-sync/dist/src/detector.js +108 -0
- package/packages/todo-bd-sync/src/detector.ts +1 -1
- package/packages/auth/src/minimax-browser-auth.js +0 -889
- package/packages/capability-registry/src/types.js +0 -10
- package/packages/checkpoint/src/checkpoint-manager.js +0 -29
- package/packages/clipboard/src/copy-sync.js +0 -169
- package/packages/clipboard/src/gist-relay.js +0 -185
- package/packages/clipboard/src/github-login.js +0 -68
- package/packages/config-capture/src/index.js +0 -268
- package/packages/cookie-sanitizer/src/atomic-write.js +0 -66
- package/packages/cookie-sanitizer/src/detect-format.js +0 -87
- package/packages/cookie-sanitizer/src/index.js +0 -38
- package/packages/cookie-sanitizer/src/infer-provider.js +0 -95
- package/packages/cookie-sanitizer/src/normalize.js +0 -74
- package/packages/cookie-sanitizer/src/parse-json.js +0 -107
- package/packages/cookie-sanitizer/src/parse-netscape.js +0 -98
- package/packages/cookie-sanitizer/src/sync.js +0 -268
- package/packages/cookie-sanitizer/src/types.js +0 -12
- package/packages/cookie-sanitizer/src/watcher.js +0 -147
- package/packages/evaluation-engine/src/engine.js +0 -343
- package/packages/evaluation-engine/src/index.js +0 -7
- package/packages/evaluation-engine/src/types.js +0 -14
- package/packages/event-store/src/types.js +0 -5
- package/packages/experience-replay/src/index.js +0 -6
- package/packages/experience-replay/src/replay.js +0 -228
- package/packages/experience-replay/src/types.js +0 -6
- package/packages/learning-engine/src/engine.js +0 -294
- package/packages/learning-engine/src/index.js +0 -7
- package/packages/learning-engine/src/types.js +0 -63
- package/packages/memory-engine/src/engine.js +0 -507
- package/packages/memory-engine/src/index.js +0 -7
- package/packages/memory-engine/src/types.js +0 -39
- package/packages/model-registry/src/types.js +0 -5
- package/packages/performance-optimizer/src/index.js +0 -6
- package/packages/performance-optimizer/src/optimizer.js +0 -304
- package/packages/performance-optimizer/src/types.js +0 -6
- package/packages/projection-engine/src/types.js +0 -5
- package/packages/providers/src/provider-id.js +0 -112
- package/packages/quota-manager/src/quota-manager.js +0 -259
- package/packages/quota-manager/src/tui-usage-monitor.js +0 -267
- package/packages/todo-bd-sync/src/detector.js +0 -131
- package/packages/todo-bd-sync/src/extension.js +0 -104
- package/packages/todo-bd-sync/src/sync.js +0 -289
- package/packages/todo-bd-sync/src/task-analyzer.js +0 -239
- package/packages/todo-bd-sync/src/types.js +0 -66
- package/packages/token-estimation/src/index.js +0 -114
- package/packages/workflow-events/src/types.js +0 -5
- package/packages/write-review/src/blackboard.js +0 -228
- package/packages/write-review/src/gate.js +0 -137
- package/packages/write-review/src/index.js +0 -17
- package/packages/write-review/src/injection.js +0 -141
- package/packages/write-review/src/review.js +0 -153
- package/packages/write-review/src/trigger.js +0 -106
- package/packages/write-review/src/types.js +0 -25
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Learning Engine (RFC-0058)
|
|
3
|
-
*
|
|
4
|
-
* Extracts reusable lessons from completed and failed jobs.
|
|
5
|
-
*/
|
|
6
|
-
import { randomUUID } from "node:crypto";
|
|
7
|
-
import { containsSecret, calculateConfidence, } from "./types.js";
|
|
8
|
-
// --- Pattern Extraction --------------------------------------------------------
|
|
9
|
-
function extractProviderSuccessPatterns(metrics) {
|
|
10
|
-
const patterns = [];
|
|
11
|
-
// Group by task type
|
|
12
|
-
const byTaskType = new Map();
|
|
13
|
-
for (const metric of metrics) {
|
|
14
|
-
const existing = byTaskType.get(metric.taskType) || [];
|
|
15
|
-
existing.push(metric);
|
|
16
|
-
byTaskType.set(metric.taskType, existing);
|
|
17
|
-
}
|
|
18
|
-
// Find best provider per task type
|
|
19
|
-
for (const [taskType, taskMetrics] of byTaskType) {
|
|
20
|
-
if (taskMetrics.length < 2)
|
|
21
|
-
continue;
|
|
22
|
-
let bestProvider = taskMetrics[0];
|
|
23
|
-
let bestSuccessRate = 0;
|
|
24
|
-
for (const metric of taskMetrics) {
|
|
25
|
-
const total = metric.successCount + metric.failureCount;
|
|
26
|
-
if (total > 0) {
|
|
27
|
-
const successRate = metric.successCount / total;
|
|
28
|
-
if (successRate > bestSuccessRate) {
|
|
29
|
-
bestSuccessRate = successRate;
|
|
30
|
-
bestProvider = metric;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (bestSuccessRate > 0.7) {
|
|
35
|
-
patterns.push({
|
|
36
|
-
type: "provider_success",
|
|
37
|
-
description: `Provider '${bestProvider.providerId}' performs best for '${taskType}' tasks (${(bestSuccessRate * 100).toFixed(0)}% success rate)`,
|
|
38
|
-
occurrenceCount: bestProvider.successCount + bestProvider.failureCount,
|
|
39
|
-
successIndicators: [
|
|
40
|
-
`${bestSuccessRate > 0.8 ? "high" : "good"} success rate`,
|
|
41
|
-
],
|
|
42
|
-
failureIndicators: [],
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return patterns;
|
|
47
|
-
}
|
|
48
|
-
function extractRepairPatterns(repairs) {
|
|
49
|
-
const patterns = [];
|
|
50
|
-
// Group by repair type
|
|
51
|
-
const byType = new Map();
|
|
52
|
-
for (const repair of repairs) {
|
|
53
|
-
const existing = byType.get(repair.repairType) || [];
|
|
54
|
-
existing.push(repair);
|
|
55
|
-
byType.set(repair.repairType, existing);
|
|
56
|
-
}
|
|
57
|
-
for (const [repairType, typeRepairs] of byType) {
|
|
58
|
-
const successCount = typeRepairs.filter((r) => r.success).length;
|
|
59
|
-
const total = typeRepairs.length;
|
|
60
|
-
const successRate = total > 0 ? successCount / total : 0;
|
|
61
|
-
patterns.push({
|
|
62
|
-
type: "repair_strategy",
|
|
63
|
-
description: `Repair strategy '${repairType}' has ${(successRate * 100).toFixed(0)}% success rate`,
|
|
64
|
-
occurrenceCount: total,
|
|
65
|
-
successIndicators: successRate > 0.5 ? [`effective for ${successCount} tasks`] : [],
|
|
66
|
-
failureIndicators: successRate <= 0.5
|
|
67
|
-
? [`ineffective for ${total - successCount} tasks`]
|
|
68
|
-
: [],
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
return patterns;
|
|
72
|
-
}
|
|
73
|
-
function extractFailurePatterns(events) {
|
|
74
|
-
const patterns = [];
|
|
75
|
-
const failureTypes = new Map();
|
|
76
|
-
// Count failure types
|
|
77
|
-
for (const event of events) {
|
|
78
|
-
if (event.type.includes("error") || event.type.includes("failure")) {
|
|
79
|
-
const existing = failureTypes.get(event.message) || 0;
|
|
80
|
-
failureTypes.set(event.message, existing + 1);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Create patterns for common failures
|
|
84
|
-
for (const [message, count] of failureTypes) {
|
|
85
|
-
if (count >= 2) {
|
|
86
|
-
patterns.push({
|
|
87
|
-
type: "failure_cause",
|
|
88
|
-
description: message,
|
|
89
|
-
occurrenceCount: count,
|
|
90
|
-
successIndicators: [],
|
|
91
|
-
failureIndicators: [`occurred ${count} times`],
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return patterns;
|
|
96
|
-
}
|
|
97
|
-
// --- Experience Creation ------------------------------------------------------
|
|
98
|
-
function createExperience(pattern, scope, humanFeedback) {
|
|
99
|
-
// Calculate confidence
|
|
100
|
-
const factors = {
|
|
101
|
-
occurrenceCount: pattern.occurrenceCount,
|
|
102
|
-
consistentPositiveOutcomes: pattern.successIndicators.length * pattern.occurrenceCount,
|
|
103
|
-
humanApprovalCount: humanFeedback?.filter((f) => f.approved).length || 0,
|
|
104
|
-
frameworkCorroboration: 0,
|
|
105
|
-
contradictoryOutcomes: pattern.failureIndicators.length,
|
|
106
|
-
singleEventEvidence: pattern.occurrenceCount === 1,
|
|
107
|
-
staleRepository: false,
|
|
108
|
-
changedProjectRules: false,
|
|
109
|
-
};
|
|
110
|
-
const confidence = calculateConfidence(factors);
|
|
111
|
-
// Determine status
|
|
112
|
-
let status = "proposed";
|
|
113
|
-
if (humanFeedback?.some((f) => f.approved)) {
|
|
114
|
-
status = "approved";
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
id: randomUUID(),
|
|
118
|
-
scope,
|
|
119
|
-
pattern: pattern.description,
|
|
120
|
-
recommendation: generateRecommendation(pattern),
|
|
121
|
-
confidence,
|
|
122
|
-
evidenceRefs: [],
|
|
123
|
-
status,
|
|
124
|
-
createdAt: new Date().toISOString(),
|
|
125
|
-
updatedAt: new Date().toISOString(),
|
|
126
|
-
tags: [pattern.type],
|
|
127
|
-
taskType: scope === "task_type" ? undefined : undefined,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
function generateRecommendation(pattern) {
|
|
131
|
-
switch (pattern.type) {
|
|
132
|
-
case "provider_success":
|
|
133
|
-
return `Use the recommended provider for this task type to improve success rate.`;
|
|
134
|
-
case "repair_strategy":
|
|
135
|
-
return `Consider using this repair strategy for similar failures.`;
|
|
136
|
-
case "failure_cause":
|
|
137
|
-
return `Avoid or handle this failure condition proactively.`;
|
|
138
|
-
case "prompt_structure":
|
|
139
|
-
return `Use this prompt structure for better outcomes.`;
|
|
140
|
-
case "framework_command":
|
|
141
|
-
return `Use this command pattern for framework-specific tasks.`;
|
|
142
|
-
case "test_scenario":
|
|
143
|
-
return `Add this test scenario to catch regressions.`;
|
|
144
|
-
case "context_source":
|
|
145
|
-
return `Prioritize this context source for similar tasks.`;
|
|
146
|
-
default:
|
|
147
|
-
return pattern.description;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
// --- Secret Filtering ---------------------------------------------------------
|
|
151
|
-
function filterSecrets(data) {
|
|
152
|
-
const filtered = {};
|
|
153
|
-
for (const [key, value] of Object.entries(data)) {
|
|
154
|
-
// Skip secret-like keys
|
|
155
|
-
if (containsSecret(key)) {
|
|
156
|
-
filtered[key] = "[REDACTED]";
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
// Recursively filter nested objects
|
|
160
|
-
if (typeof value === "object" && value !== null) {
|
|
161
|
-
filtered[key] = filterSecrets(value);
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
filtered[key] = value;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return filtered;
|
|
168
|
-
}
|
|
169
|
-
// --- Main Engine -------------------------------------------------------------
|
|
170
|
-
export class LearningEngine {
|
|
171
|
-
framework;
|
|
172
|
-
repository;
|
|
173
|
-
constructor(options) {
|
|
174
|
-
this.framework = options?.framework;
|
|
175
|
-
this.repository = options?.repository;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Extract learned experiences from completed job
|
|
179
|
-
*/
|
|
180
|
-
learn(request) {
|
|
181
|
-
const experiences = [];
|
|
182
|
-
// 1. Extract provider success patterns
|
|
183
|
-
const providerPatterns = extractProviderSuccessPatterns(request.providerMetrics);
|
|
184
|
-
for (const pattern of providerPatterns) {
|
|
185
|
-
const experience = createExperience(pattern, "task_type", request.humanFeedback);
|
|
186
|
-
experiences.push(experience);
|
|
187
|
-
}
|
|
188
|
-
// 2. Extract repair patterns
|
|
189
|
-
const repairPatterns = extractRepairPatterns(request.repairHistory);
|
|
190
|
-
for (const pattern of repairPatterns) {
|
|
191
|
-
const experience = createExperience(pattern, "task_type", request.humanFeedback);
|
|
192
|
-
experiences.push(experience);
|
|
193
|
-
}
|
|
194
|
-
// 3. Extract failure patterns
|
|
195
|
-
const filteredEvents = request.events
|
|
196
|
-
.map((e) => {
|
|
197
|
-
if (e.data) {
|
|
198
|
-
return { ...e, data: filterSecrets(e.data) };
|
|
199
|
-
}
|
|
200
|
-
return e;
|
|
201
|
-
})
|
|
202
|
-
.map((e) => ({
|
|
203
|
-
type: e.type,
|
|
204
|
-
message: e.message,
|
|
205
|
-
data: e.data,
|
|
206
|
-
}));
|
|
207
|
-
const failurePatterns = extractFailurePatterns(filteredEvents);
|
|
208
|
-
for (const pattern of failurePatterns) {
|
|
209
|
-
const experience = createExperience(pattern, "global", request.humanFeedback);
|
|
210
|
-
experiences.push(experience);
|
|
211
|
-
}
|
|
212
|
-
// 4. Process human feedback
|
|
213
|
-
if (request.humanFeedback) {
|
|
214
|
-
for (const feedback of request.humanFeedback) {
|
|
215
|
-
if (feedback.approved) {
|
|
216
|
-
// Find matching experience or create new one
|
|
217
|
-
const existing = experiences.find((e) => e.pattern.toLowerCase().includes(feedback.taskId.toLowerCase()));
|
|
218
|
-
if (existing) {
|
|
219
|
-
existing.status = "approved";
|
|
220
|
-
existing.confidence = Math.min(100, existing.confidence + 20);
|
|
221
|
-
existing.updatedAt = new Date().toISOString();
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
// 5. Calculate summary
|
|
227
|
-
const summary = {
|
|
228
|
-
totalExtracted: experiences.length,
|
|
229
|
-
approved: experiences.filter((e) => e.status === "approved").length,
|
|
230
|
-
proposed: experiences.filter((e) => e.status === "proposed").length,
|
|
231
|
-
rejected: experiences.filter((e) => e.status === "rejected").length,
|
|
232
|
-
};
|
|
233
|
-
return {
|
|
234
|
-
jobId: request.jobId,
|
|
235
|
-
experiences,
|
|
236
|
-
summary,
|
|
237
|
-
extractedAt: new Date().toISOString(),
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Approve a learned experience
|
|
242
|
-
*/
|
|
243
|
-
approve(experience) {
|
|
244
|
-
return {
|
|
245
|
-
...experience,
|
|
246
|
-
status: "approved",
|
|
247
|
-
confidence: Math.min(100, experience.confidence + 10),
|
|
248
|
-
updatedAt: new Date().toISOString(),
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Reject a learned experience
|
|
253
|
-
*/
|
|
254
|
-
reject(experience) {
|
|
255
|
-
return {
|
|
256
|
-
...experience,
|
|
257
|
-
status: "rejected",
|
|
258
|
-
updatedAt: new Date().toISOString(),
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Export experience to OKF format
|
|
263
|
-
*/
|
|
264
|
-
toOkfFormat(experience) {
|
|
265
|
-
const timestamp = new Date().toISOString();
|
|
266
|
-
const tags = experience.tags.join(", ");
|
|
267
|
-
return `---
|
|
268
|
-
type: Engineering Lesson
|
|
269
|
-
title: ${experience.pattern.substring(0, 60)}
|
|
270
|
-
tags: [${tags}]
|
|
271
|
-
timestamp: ${timestamp}
|
|
272
|
-
authority: ${experience.status}
|
|
273
|
-
scope: ${experience.scope}
|
|
274
|
-
confidence: ${experience.confidence}
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
${experience.recommendation}
|
|
278
|
-
|
|
279
|
-
## Evidence
|
|
280
|
-
|
|
281
|
-
${experience.evidenceRefs.length > 0
|
|
282
|
-
? experience.evidenceRefs.map((ref) => `- ${ref}`).join("\n")
|
|
283
|
-
: "No evidence references available."}
|
|
284
|
-
|
|
285
|
-
## Pattern
|
|
286
|
-
|
|
287
|
-
${experience.pattern}
|
|
288
|
-
`;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// --- Factory -----------------------------------------------------------------
|
|
292
|
-
export function createLearningEngine(options) {
|
|
293
|
-
return new LearningEngine(options);
|
|
294
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Learning Engine Types (RFC-0058)
|
|
3
|
-
*
|
|
4
|
-
* Interfaces for learning from runtime execution.
|
|
5
|
-
*/
|
|
6
|
-
// --- Secret Detection ---------------------------------------------------------
|
|
7
|
-
export const SECRET_PATTERNS = [
|
|
8
|
-
/api[_-]?key/i,
|
|
9
|
-
/password/i,
|
|
10
|
-
/secret/i,
|
|
11
|
-
/token/i,
|
|
12
|
-
/bearer/i,
|
|
13
|
-
/auth/i,
|
|
14
|
-
/credential/i,
|
|
15
|
-
/private[_-]?key/i,
|
|
16
|
-
/access[_-]?token/i,
|
|
17
|
-
/refresh[_-]?token/i,
|
|
18
|
-
];
|
|
19
|
-
export function containsSecret(value) {
|
|
20
|
-
return SECRET_PATTERNS.some((pattern) => pattern.test(value));
|
|
21
|
-
}
|
|
22
|
-
export function redactSecrets(data) {
|
|
23
|
-
const redacted = { ...data };
|
|
24
|
-
for (const [key, value] of Object.entries(redacted)) {
|
|
25
|
-
if (typeof value === "string" && containsSecret(key)) {
|
|
26
|
-
redacted[key] = "[REDACTED]";
|
|
27
|
-
}
|
|
28
|
-
else if (typeof value === "object" && value !== null) {
|
|
29
|
-
redacted[key] = redactSecrets(value);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return redacted;
|
|
33
|
-
}
|
|
34
|
-
export function calculateConfidence(factors) {
|
|
35
|
-
let confidence = 0;
|
|
36
|
-
// Occurrence boost (up to +30)
|
|
37
|
-
confidence += Math.min(30, factors.occurrenceCount * 5);
|
|
38
|
-
// Consistent positive outcomes (up to +25)
|
|
39
|
-
if (factors.occurrenceCount > 0) {
|
|
40
|
-
const consistencyRatio = factors.consistentPositiveOutcomes / factors.occurrenceCount;
|
|
41
|
-
confidence += consistencyRatio * 25;
|
|
42
|
-
}
|
|
43
|
-
// Human approval (up to +20)
|
|
44
|
-
confidence += Math.min(20, factors.humanApprovalCount * 10);
|
|
45
|
-
// Framework corroboration (up to +10)
|
|
46
|
-
confidence += Math.min(10, factors.frameworkCorroboration * 5);
|
|
47
|
-
// Penalties
|
|
48
|
-
// Contradictory outcomes (-15 per)
|
|
49
|
-
confidence -= Math.min(40, factors.contradictoryOutcomes * 15);
|
|
50
|
-
// Single event evidence (-10)
|
|
51
|
-
if (factors.singleEventEvidence) {
|
|
52
|
-
confidence -= 10;
|
|
53
|
-
}
|
|
54
|
-
// Stale repository (-5)
|
|
55
|
-
if (factors.staleRepository) {
|
|
56
|
-
confidence -= 5;
|
|
57
|
-
}
|
|
58
|
-
// Changed project rules (-20)
|
|
59
|
-
if (factors.changedProjectRules) {
|
|
60
|
-
confidence -= 20;
|
|
61
|
-
}
|
|
62
|
-
return Math.max(0, Math.min(100, Math.round(confidence)));
|
|
63
|
-
}
|