pi-harness-runtime 1.1.408 → 1.1.410
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/harness/key-file-audit.ts +2 -2
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/durable-review/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-sink/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/permission-mode/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/dist/adapters.d.ts +1 -1
- package/packages/providers/dist/adapters.d.ts.map +1 -1
- package/packages/providers/dist/deepagents-adapter.d.ts +22 -1
- package/packages/providers/dist/deepagents-adapter.d.ts.map +1 -1
- package/packages/providers/dist/deepagents-adapter.js +3 -8
- package/packages/providers/dist/deepagents-adapter.js.map +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/providers/src/adapters.ts +1 -1
- package/packages/providers/src/deepagents-adapter.ts +28 -31
- package/packages/qdrant-skills/dist/embedder.d.ts +5 -1
- package/packages/qdrant-skills/dist/embedder.d.ts.map +1 -1
- package/packages/qdrant-skills/dist/embedder.js +52 -37
- package/packages/qdrant-skills/dist/embedder.js.map +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/qdrant-skills/src/embedder.ts +56 -40
- package/packages/qdrant-skills/test/embedder.test.ts +97 -0
- package/packages/quota-manager/dist/quota-manager.d.ts +1 -1
- package/packages/quota-manager/dist/quota-manager.d.ts.map +1 -1
- package/packages/quota-manager/dist/quota-manager.js +10 -8
- package/packages/quota-manager/dist/quota-manager.js.map +1 -1
- package/packages/quota-manager/dist/tui-usage-monitor.d.ts +5 -3
- package/packages/quota-manager/dist/tui-usage-monitor.d.ts.map +1 -1
- package/packages/quota-manager/dist/tui-usage-monitor.js +30 -10
- package/packages/quota-manager/dist/tui-usage-monitor.js.map +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/quota-manager/src/quota-manager.ts +10 -9
- package/packages/quota-manager/src/tui-usage-monitor.ts +40 -17
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/dist/loader.d.ts.map +1 -1
- package/packages/skills/dist/loader.js +9 -6
- package/packages/skills/dist/loader.js.map +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/skills/src/loader.ts +13 -6
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/tooling-preference/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/two-phase-review/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/dist/worktree.d.ts +1 -1
- package/packages/worktree/dist/worktree.d.ts.map +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/worktree/src/worktree.ts +1 -1
- package/packages/write-review/package.json +1 -1
- package/scripts/typecheck-packages.mjs +3 -3
- package/packages/providers/adapters.ts +0 -362
- package/packages/providers/deepagents-adapter.ts +0 -458
- package/packages/providers/glm-usage.ts +0 -248
- package/packages/providers/index.ts +0 -85
- package/packages/providers/openai-usage.ts +0 -263
- package/packages/trajectory/dist/test/store.test.d.ts +0 -2
- package/packages/trajectory/dist/test/store.test.d.ts.map +0 -1
- package/packages/trajectory/dist/test/store.test.js +0 -228
- package/packages/trajectory/dist/test/store.test.js.map +0 -1
- package/packages/types/src/agent-worker-types.d.ts +0 -206
- package/packages/types/src/agent-worker-types.js +0 -41
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Providers Package
|
|
3
|
-
*
|
|
4
|
-
* Provider adapters, agent workers, and usage fetchers.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Provider Adapters (RFC-0002)
|
|
8
|
-
export {
|
|
9
|
-
AdapterRegistry,
|
|
10
|
-
MiniMaxAdapter,
|
|
11
|
-
OpenAIAdapter,
|
|
12
|
-
ClaudeAdapter,
|
|
13
|
-
} from "./adapters.js";
|
|
14
|
-
export type {
|
|
15
|
-
AdapterConfig,
|
|
16
|
-
AdapterResult,
|
|
17
|
-
ProviderAdapter,
|
|
18
|
-
QuotaSignal,
|
|
19
|
-
} from "./adapters.js";
|
|
20
|
-
|
|
21
|
-
// Agent Workers (RFC-0029, RFC-0030)
|
|
22
|
-
import {
|
|
23
|
-
DeepAgentsAdapter,
|
|
24
|
-
createDeepAgentsAdapter,
|
|
25
|
-
} from "./deepagents-adapter.js";
|
|
26
|
-
import {
|
|
27
|
-
AgentWorkerRegistry,
|
|
28
|
-
type AgentWorker,
|
|
29
|
-
type AgentWorkerConfig,
|
|
30
|
-
type AgentStatus,
|
|
31
|
-
type TaskRequest,
|
|
32
|
-
type TaskResult,
|
|
33
|
-
type TaskResultStatus,
|
|
34
|
-
type HealthStatus,
|
|
35
|
-
type AgentWorkerEvents,
|
|
36
|
-
type TaskProgress,
|
|
37
|
-
type DeepAgentsConfig,
|
|
38
|
-
type DeepAgentsTaskRequest,
|
|
39
|
-
type DeepAgentsResult,
|
|
40
|
-
type AgentWorkerFactory,
|
|
41
|
-
} from "../../packages/types/src/agent-worker-types.js";
|
|
42
|
-
|
|
43
|
-
// Re-export for consumers
|
|
44
|
-
export { DeepAgentsAdapter, createDeepAgentsAdapter, AgentWorkerRegistry };
|
|
45
|
-
export type {
|
|
46
|
-
AgentWorker,
|
|
47
|
-
AgentWorkerConfig,
|
|
48
|
-
AgentStatus,
|
|
49
|
-
TaskRequest,
|
|
50
|
-
TaskResult,
|
|
51
|
-
TaskResultStatus,
|
|
52
|
-
HealthStatus,
|
|
53
|
-
AgentWorkerEvents,
|
|
54
|
-
TaskProgress,
|
|
55
|
-
DeepAgentsConfig,
|
|
56
|
-
DeepAgentsTaskRequest,
|
|
57
|
-
DeepAgentsResult,
|
|
58
|
-
AgentWorkerFactory,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// OpenAI Usage (TUI Message Parsing)
|
|
62
|
-
export { OpenAIUsageProvider } from "./openai-usage.js";
|
|
63
|
-
export type {
|
|
64
|
-
OpenAIUsageData,
|
|
65
|
-
OpenAIUsageConfig,
|
|
66
|
-
} from "./openai-usage.js";
|
|
67
|
-
|
|
68
|
-
// GLM Usage (TUI Message Parsing)
|
|
69
|
-
export { GLMUsageProvider } from "./glm-usage.js";
|
|
70
|
-
export type {
|
|
71
|
-
GLMUsageData,
|
|
72
|
-
GLMUsageConfig,
|
|
73
|
-
} from "./glm-usage.js";
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Create a default agent worker registry with all built-in workers
|
|
77
|
-
*/
|
|
78
|
-
export function createDefaultAgentWorkerRegistry(): AgentWorkerRegistry {
|
|
79
|
-
const registry = new AgentWorkerRegistry();
|
|
80
|
-
|
|
81
|
-
// Register DeepAgents adapter
|
|
82
|
-
registry.register("deepagents", createDeepAgentsAdapter);
|
|
83
|
-
|
|
84
|
-
return registry;
|
|
85
|
-
}
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAI Usage Parser — TUI Message Parsing
|
|
3
|
-
*
|
|
4
|
-
* OpenAI (GPT) reports quota exhaustion via TUI in pi.dev.
|
|
5
|
-
* When tokens run out or context window is full, pi shows:
|
|
6
|
-
* - Exact reset time
|
|
7
|
-
* - Which limit was hit
|
|
8
|
-
*
|
|
9
|
-
* This module hooks into TUI messages to capture quota signals.
|
|
10
|
-
* No API key needed - uses the same method as GLM.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { EventEmitter } from "node:events";
|
|
14
|
-
|
|
15
|
-
export interface OpenAIUsageData {
|
|
16
|
-
provider: "openai";
|
|
17
|
-
timestamp: string;
|
|
18
|
-
/** Usage percentage (0-100), if available */
|
|
19
|
-
usedPct?: number;
|
|
20
|
-
/** Remaining percentage (0-100) */
|
|
21
|
-
remainingPct: number;
|
|
22
|
-
/** If exhausted */
|
|
23
|
-
exhausted: boolean;
|
|
24
|
-
/** Reset time */
|
|
25
|
-
resetsAt: string;
|
|
26
|
-
/** Which limit was hit */
|
|
27
|
-
limitType: "tokens" | "context_window" | "rate_limit" | "unknown";
|
|
28
|
-
/** Original message from TUI */
|
|
29
|
-
originalMessage: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface OpenAIUsageConfig {
|
|
33
|
-
/** Called when OpenAI quota signal is detected from TUI */
|
|
34
|
-
onQuotaSignal?: (data: OpenAIUsageData) => void;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* OpenAI quota message patterns from TUI
|
|
39
|
-
* These patterns match the messages pi displays when OpenAI hits limits
|
|
40
|
-
*/
|
|
41
|
-
const OPENAI_QUOTA_PATTERNS = [
|
|
42
|
-
// Context window full
|
|
43
|
-
{
|
|
44
|
-
pattern: /OpenAI|GPT|context.*(?:window|length).*(?:full|exceeded|limit)/i,
|
|
45
|
-
limitType: "context_window" as const,
|
|
46
|
-
},
|
|
47
|
-
// Tokens exhausted
|
|
48
|
-
{
|
|
49
|
-
pattern: /openai.*(?:quota|limit|exhausted|tokens?.*(?:ran out|exceeded))/i,
|
|
50
|
-
limitType: "tokens" as const,
|
|
51
|
-
},
|
|
52
|
-
// Rate limit
|
|
53
|
-
{
|
|
54
|
-
pattern: /openai.*rate.?limit|429/i,
|
|
55
|
-
limitType: "rate_limit" as const,
|
|
56
|
-
},
|
|
57
|
-
// Reset time patterns
|
|
58
|
-
{
|
|
59
|
-
pattern: /openai.*reset.*(?:at|in).*(\d{1,2}):(\d{2})/i,
|
|
60
|
-
limitType: "unknown" as const,
|
|
61
|
-
},
|
|
62
|
-
// Error codes
|
|
63
|
-
{
|
|
64
|
-
pattern: /insufficient_quota|context_length_exceeded/i,
|
|
65
|
-
limitType: "tokens" as const,
|
|
66
|
-
},
|
|
67
|
-
];
|
|
68
|
-
|
|
69
|
-
const RESET_TIME_PATTERNS = [
|
|
70
|
-
/reset(?:s)?\s+(?:at|in)\s+(\d{1,2}):(\d{2})/i,
|
|
71
|
-
/(?:at|in)\s+(\d{1,2}):(\d{2})/i,
|
|
72
|
-
/retry\s+after\s+(\d{1,2}):(\d{2})/i,
|
|
73
|
-
/(\d{1,2}):(\d{2})\s*(?:am|pm)/i,
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
export class OpenAIUsageProvider extends EventEmitter {
|
|
77
|
-
private lastUsageData: OpenAIUsageData | null = null;
|
|
78
|
-
private onQuotaSignal?: (data: OpenAIUsageData) => void;
|
|
79
|
-
|
|
80
|
-
constructor(config: OpenAIUsageConfig = {}) {
|
|
81
|
-
super();
|
|
82
|
-
this.onQuotaSignal = config.onQuotaSignal;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Check if auto-fetch is possible via TUI
|
|
87
|
-
* OpenAI reports quota via TUI, so this is always true when hooked
|
|
88
|
-
*/
|
|
89
|
-
supportsAutoFetch(): boolean {
|
|
90
|
-
return true; // TUI integration is always available
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Process a TUI message and extract OpenAI quota data
|
|
95
|
-
* Call this when receiving error/status messages from pi
|
|
96
|
-
*/
|
|
97
|
-
processTUIMessage(message: string): OpenAIUsageData | null {
|
|
98
|
-
// Check if this is an OpenAI quota message
|
|
99
|
-
for (const { pattern, limitType } of OPENAI_QUOTA_PATTERNS) {
|
|
100
|
-
if (pattern.test(message)) {
|
|
101
|
-
const usageData = this.parseOpenAIQuotaMessage(message, limitType);
|
|
102
|
-
|
|
103
|
-
if (usageData) {
|
|
104
|
-
this.lastUsageData = usageData;
|
|
105
|
-
|
|
106
|
-
// Emit event
|
|
107
|
-
this.emit("quota", usageData);
|
|
108
|
-
|
|
109
|
-
// Call callback if set
|
|
110
|
-
this.onQuotaSignal?.(usageData);
|
|
111
|
-
|
|
112
|
-
return usageData;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Parse reset time from message
|
|
122
|
-
*/
|
|
123
|
-
private parseResetTime(message: string): string | undefined {
|
|
124
|
-
for (const pattern of RESET_TIME_PATTERNS) {
|
|
125
|
-
const match = message.match(pattern);
|
|
126
|
-
if (match) {
|
|
127
|
-
let hour = parseInt(match[1], 10);
|
|
128
|
-
const minute = parseInt(match[2], 10);
|
|
129
|
-
|
|
130
|
-
// Handle AM/PM
|
|
131
|
-
const isPM = /pm/i.test(
|
|
132
|
-
message.slice(match.index ?? 0, (match.index ?? 0) + 10),
|
|
133
|
-
);
|
|
134
|
-
const isAM = /am/i.test(
|
|
135
|
-
message.slice(match.index ?? 0, (match.index ?? 0) + 10),
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
if (isPM && hour < 12) hour += 12;
|
|
139
|
-
if (isAM && hour === 12) hour = 0;
|
|
140
|
-
|
|
141
|
-
// Convert to ISO string for today or tomorrow
|
|
142
|
-
const now = new Date();
|
|
143
|
-
const resetTime = new Date(now);
|
|
144
|
-
resetTime.setHours(hour, minute, 0, 0);
|
|
145
|
-
|
|
146
|
-
// If time has passed today, assume tomorrow
|
|
147
|
-
if (resetTime <= now) {
|
|
148
|
-
resetTime.setDate(resetTime.getDate() + 1);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return resetTime.toISOString();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return undefined;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Parse the OpenAI quota message
|
|
160
|
-
*/
|
|
161
|
-
private parseOpenAIQuotaMessage(
|
|
162
|
-
message: string,
|
|
163
|
-
limitType: OpenAIUsageData["limitType"],
|
|
164
|
-
): OpenAIUsageData {
|
|
165
|
-
const resetsAt =
|
|
166
|
-
this.parseResetTime(message) ??
|
|
167
|
-
new Date(Date.now() + 60 * 60 * 1000).toISOString();
|
|
168
|
-
|
|
169
|
-
// Try to extract percentage if present
|
|
170
|
-
let usedPct: number | undefined;
|
|
171
|
-
const pctMatch = message.match(/(\d+)%/);
|
|
172
|
-
if (pctMatch) {
|
|
173
|
-
usedPct = parseInt(pctMatch[1], 10);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
provider: "openai",
|
|
178
|
-
timestamp: new Date().toISOString(),
|
|
179
|
-
usedPct,
|
|
180
|
-
remainingPct: usedPct !== undefined ? 100 - usedPct : 0,
|
|
181
|
-
exhausted: true,
|
|
182
|
-
resetsAt,
|
|
183
|
-
limitType,
|
|
184
|
-
originalMessage: message,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Get the last captured usage data
|
|
190
|
-
*/
|
|
191
|
-
getLastUsage(): OpenAIUsageData | null {
|
|
192
|
-
return this.lastUsageData;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Clear stored usage data
|
|
197
|
-
*/
|
|
198
|
-
clear(): void {
|
|
199
|
-
this.lastUsageData = null;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* For QuotaManager integration
|
|
204
|
-
* Returns current state (from last TUI message)
|
|
205
|
-
*/
|
|
206
|
-
async getUsage(): Promise<OpenAIUsageData> {
|
|
207
|
-
if (!this.lastUsageData) {
|
|
208
|
-
return {
|
|
209
|
-
provider: "openai",
|
|
210
|
-
timestamp: new Date().toISOString(),
|
|
211
|
-
remainingPct: 100,
|
|
212
|
-
exhausted: false,
|
|
213
|
-
resetsAt: "",
|
|
214
|
-
limitType: "unknown",
|
|
215
|
-
originalMessage: "",
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
return this.lastUsageData;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Get usage as percentage
|
|
223
|
-
*/
|
|
224
|
-
async getUsagePercent(): Promise<number> {
|
|
225
|
-
const usage = await this.getUsage();
|
|
226
|
-
return usage.usedPct ?? 100 - usage.remainingPct;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Check if quota is exhausted
|
|
231
|
-
*/
|
|
232
|
-
async isExhausted(): Promise<boolean> {
|
|
233
|
-
const usage = await this.getUsage();
|
|
234
|
-
return usage.exhausted;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Integration helper: Hook OpenAI usage provider into pi extension
|
|
240
|
-
*
|
|
241
|
-
* Usage:
|
|
242
|
-
* ```typescript
|
|
243
|
-
* const openaiUsage = new OpenAIUsageProvider({
|
|
244
|
-
* onQuotaSignal: (data) => {
|
|
245
|
-
* quotaManager.recordSignal({
|
|
246
|
-
* provider: "openai",
|
|
247
|
-
* source: "tui_message",
|
|
248
|
-
* windowType: data.limitType === "context_window" ? "daily" : "5h",
|
|
249
|
-
* exhausted: data.exhausted,
|
|
250
|
-
* resetsAt: data.resetsAt,
|
|
251
|
-
* });
|
|
252
|
-
* }
|
|
253
|
-
* });
|
|
254
|
-
*
|
|
255
|
-
* pi.on("error", (event) => {
|
|
256
|
-
* openaiUsage.processTUIMessage(event.message);
|
|
257
|
-
* });
|
|
258
|
-
*
|
|
259
|
-
* pi.on("message", (event) => {
|
|
260
|
-
* openaiUsage.processTUIMessage(event.message);
|
|
261
|
-
* });
|
|
262
|
-
* ```
|
|
263
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../test/store.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeEach } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import { rmSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { homedir } from "node:os";
|
|
6
|
-
import { TrajectoryStore, resetTrajectoryStore } from "../src/store.js";
|
|
7
|
-
const TEST_DIR = join(homedir(), ".pi-harness-test-trajectories");
|
|
8
|
-
function freshStore() {
|
|
9
|
-
rmSync(TEST_DIR, { force: true, recursive: true });
|
|
10
|
-
mkdirSync(TEST_DIR, { recursive: true });
|
|
11
|
-
return new TrajectoryStore(TEST_DIR);
|
|
12
|
-
}
|
|
13
|
-
describe("TrajectoryStore", () => {
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
rmSync(TEST_DIR, { force: true, recursive: true });
|
|
16
|
-
mkdirSync(TEST_DIR, { recursive: true });
|
|
17
|
-
resetTrajectoryStore();
|
|
18
|
-
});
|
|
19
|
-
it("start() returns a UUID", () => {
|
|
20
|
-
const store = freshStore();
|
|
21
|
-
const id = store.start("test task");
|
|
22
|
-
assert.match(id, /^[0-9a-f-]{36}$/);
|
|
23
|
-
});
|
|
24
|
-
it("append() writes NDJSON to the correct daily file", () => {
|
|
25
|
-
const store = freshStore();
|
|
26
|
-
const id = "test-id-123";
|
|
27
|
-
const now = new Date();
|
|
28
|
-
store.append({
|
|
29
|
-
id,
|
|
30
|
-
taskRequest: "fix the login bug",
|
|
31
|
-
createdAt: now.toISOString(),
|
|
32
|
-
durationMs: 5000,
|
|
33
|
-
iterations: 2,
|
|
34
|
-
verdict: "approved",
|
|
35
|
-
reason: "reviewer approved",
|
|
36
|
-
plan: "# Plan\n1. Fix it",
|
|
37
|
-
code: "// fixed",
|
|
38
|
-
files: ["auth.ts"],
|
|
39
|
-
comments: [{ file: "auth.ts", comment: "looks good", severity: "minor" }],
|
|
40
|
-
summary: "looks good",
|
|
41
|
-
classified: false,
|
|
42
|
-
});
|
|
43
|
-
// Should have created a daily file
|
|
44
|
-
const files = readdirSync(TEST_DIR);
|
|
45
|
-
assert.ok(files.length > 0, "should create at least one directory");
|
|
46
|
-
// Navigate to the daily file
|
|
47
|
-
const monthDir = files[0];
|
|
48
|
-
const monthFiles = readdirSync(join(TEST_DIR, monthDir));
|
|
49
|
-
assert.ok(monthFiles.length > 0, "should create daily ndjson file");
|
|
50
|
-
const content = readFileSync(join(TEST_DIR, monthDir, monthFiles[0]), "utf8");
|
|
51
|
-
const record = JSON.parse(content.split("\n").find((l) => l.trim()));
|
|
52
|
-
assert.strictEqual(record.id, id);
|
|
53
|
-
assert.strictEqual(record.verdict, "approved");
|
|
54
|
-
assert.strictEqual(record.iterations, 2);
|
|
55
|
-
});
|
|
56
|
-
it("list() returns records newest-first", () => {
|
|
57
|
-
const store = freshStore();
|
|
58
|
-
const id1 = store.start("task 1");
|
|
59
|
-
store.append({
|
|
60
|
-
id: id1,
|
|
61
|
-
taskRequest: "task 1",
|
|
62
|
-
createdAt: "2025-07-01T10:00:00.000Z",
|
|
63
|
-
durationMs: 1000,
|
|
64
|
-
iterations: 1,
|
|
65
|
-
verdict: "approved",
|
|
66
|
-
reason: "ok",
|
|
67
|
-
plan: "p1",
|
|
68
|
-
code: "c1",
|
|
69
|
-
files: [],
|
|
70
|
-
comments: [],
|
|
71
|
-
summary: "s1",
|
|
72
|
-
classified: false,
|
|
73
|
-
});
|
|
74
|
-
const id2 = store.start("task 2");
|
|
75
|
-
store.append({
|
|
76
|
-
id: id2,
|
|
77
|
-
taskRequest: "task 2",
|
|
78
|
-
createdAt: "2025-07-02T10:00:00.000Z",
|
|
79
|
-
durationMs: 2000,
|
|
80
|
-
iterations: 2,
|
|
81
|
-
verdict: "changes_requested",
|
|
82
|
-
reason: "converged: only minor comments",
|
|
83
|
-
plan: "p2",
|
|
84
|
-
code: "c2",
|
|
85
|
-
files: [],
|
|
86
|
-
comments: [],
|
|
87
|
-
summary: "s2",
|
|
88
|
-
classified: false,
|
|
89
|
-
});
|
|
90
|
-
const all = store.list();
|
|
91
|
-
assert.strictEqual(all.length, 2);
|
|
92
|
-
assert.strictEqual(all[0].id, id2, "newest first");
|
|
93
|
-
assert.strictEqual(all[1].id, id1);
|
|
94
|
-
});
|
|
95
|
-
it("stats() aggregates correctly", () => {
|
|
96
|
-
const store = freshStore();
|
|
97
|
-
store.append({
|
|
98
|
-
id: "s1",
|
|
99
|
-
taskRequest: "t1",
|
|
100
|
-
createdAt: "2025-07-01T10:00:00.000Z",
|
|
101
|
-
durationMs: 1000,
|
|
102
|
-
iterations: 1,
|
|
103
|
-
verdict: "approved",
|
|
104
|
-
reason: "reviewer approved",
|
|
105
|
-
plan: "p",
|
|
106
|
-
code: "c",
|
|
107
|
-
files: ["a.ts"],
|
|
108
|
-
comments: [],
|
|
109
|
-
summary: "s",
|
|
110
|
-
classified: false,
|
|
111
|
-
});
|
|
112
|
-
store.append({
|
|
113
|
-
id: "s2",
|
|
114
|
-
taskRequest: "t2",
|
|
115
|
-
createdAt: "2025-07-01T11:00:00.000Z",
|
|
116
|
-
durationMs: 3000,
|
|
117
|
-
iterations: 3,
|
|
118
|
-
verdict: "changes_requested",
|
|
119
|
-
reason: "max iterations (3) reached with changes still requested",
|
|
120
|
-
plan: "p",
|
|
121
|
-
code: "c",
|
|
122
|
-
files: ["a.ts", "b.ts"],
|
|
123
|
-
comments: [],
|
|
124
|
-
summary: "s",
|
|
125
|
-
classified: false,
|
|
126
|
-
});
|
|
127
|
-
const stats = store.stats();
|
|
128
|
-
assert.strictEqual(stats.total, 2);
|
|
129
|
-
assert.strictEqual(stats.byVerdict.approved, 1);
|
|
130
|
-
assert.strictEqual(stats.byVerdict.changes_requested, 1);
|
|
131
|
-
assert.strictEqual(stats.avgIterations, 2);
|
|
132
|
-
assert.strictEqual(stats.avgDurationMs, 2000);
|
|
133
|
-
assert.strictEqual(stats.byFile["a.ts"], 2);
|
|
134
|
-
assert.strictEqual(stats.byFile["b.ts"], 1);
|
|
135
|
-
assert.strictEqual(stats.byLabel["max-iterations"], 1);
|
|
136
|
-
assert.strictEqual(stats.byLabel["converged"], 1);
|
|
137
|
-
});
|
|
138
|
-
it("classify() returns correct label for converged", () => {
|
|
139
|
-
const store = freshStore();
|
|
140
|
-
const cls = store.classify({
|
|
141
|
-
id: "x",
|
|
142
|
-
taskRequest: "x",
|
|
143
|
-
createdAt: new Date().toISOString(),
|
|
144
|
-
durationMs: 1000,
|
|
145
|
-
iterations: 1,
|
|
146
|
-
verdict: "approved",
|
|
147
|
-
reason: "reviewer approved",
|
|
148
|
-
plan: "",
|
|
149
|
-
code: "",
|
|
150
|
-
files: [],
|
|
151
|
-
comments: [],
|
|
152
|
-
summary: "",
|
|
153
|
-
classified: false,
|
|
154
|
-
});
|
|
155
|
-
assert.strictEqual(cls.label, "converged");
|
|
156
|
-
assert.strictEqual(cls.trajectoryId, "x");
|
|
157
|
-
});
|
|
158
|
-
it("classify() returns stuck for same-file reason", () => {
|
|
159
|
-
const store = freshStore();
|
|
160
|
-
const cls = store.classify({
|
|
161
|
-
id: "y",
|
|
162
|
-
taskRequest: "y",
|
|
163
|
-
createdAt: new Date().toISOString(),
|
|
164
|
-
durationMs: 1000,
|
|
165
|
-
iterations: 2,
|
|
166
|
-
verdict: "changes_requested",
|
|
167
|
-
reason: "stuck: same file (auth.ts) flagged for 3 comment(s)",
|
|
168
|
-
plan: "",
|
|
169
|
-
code: "",
|
|
170
|
-
files: ["auth.ts"],
|
|
171
|
-
comments: [],
|
|
172
|
-
summary: "",
|
|
173
|
-
classified: false,
|
|
174
|
-
});
|
|
175
|
-
assert.strictEqual(cls.label, "stuck");
|
|
176
|
-
assert.strictEqual(cls.pattern, "same-file-repeated");
|
|
177
|
-
assert.ok(cls.confidence < 1.0);
|
|
178
|
-
});
|
|
179
|
-
it("byVerdict() filters correctly", () => {
|
|
180
|
-
const store = freshStore();
|
|
181
|
-
store.append({
|
|
182
|
-
id: "v1",
|
|
183
|
-
taskRequest: "v1",
|
|
184
|
-
createdAt: "2025-07-01T10:00:00.000Z",
|
|
185
|
-
durationMs: 1000,
|
|
186
|
-
iterations: 1,
|
|
187
|
-
verdict: "approved",
|
|
188
|
-
reason: "ok",
|
|
189
|
-
plan: "",
|
|
190
|
-
code: "",
|
|
191
|
-
files: [],
|
|
192
|
-
comments: [],
|
|
193
|
-
summary: "",
|
|
194
|
-
classified: false,
|
|
195
|
-
});
|
|
196
|
-
store.append({
|
|
197
|
-
id: "v2",
|
|
198
|
-
taskRequest: "v2",
|
|
199
|
-
createdAt: "2025-07-02T10:00:00.000Z",
|
|
200
|
-
durationMs: 1000,
|
|
201
|
-
iterations: 1,
|
|
202
|
-
verdict: "blocked",
|
|
203
|
-
reason: "blocked",
|
|
204
|
-
plan: "",
|
|
205
|
-
code: "",
|
|
206
|
-
files: [],
|
|
207
|
-
comments: [],
|
|
208
|
-
summary: "",
|
|
209
|
-
classified: false,
|
|
210
|
-
});
|
|
211
|
-
const approved = store.byVerdict("approved");
|
|
212
|
-
assert.strictEqual(approved.length, 1);
|
|
213
|
-
assert.strictEqual(approved[0].id, "v1");
|
|
214
|
-
const blocked = store.byVerdict("blocked");
|
|
215
|
-
assert.strictEqual(blocked.length, 1);
|
|
216
|
-
assert.strictEqual(blocked[0].id, "v2");
|
|
217
|
-
});
|
|
218
|
-
it("stats() handles empty store gracefully", () => {
|
|
219
|
-
rmSync(TEST_DIR, { force: true, recursive: true });
|
|
220
|
-
mkdirSync(TEST_DIR, { recursive: true });
|
|
221
|
-
// Remove the month dir so the store sees an empty directory
|
|
222
|
-
const store = freshStore();
|
|
223
|
-
const stats = store.stats();
|
|
224
|
-
assert.strictEqual(stats.total, 0);
|
|
225
|
-
assert.strictEqual(stats.avgIterations, 0);
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
//# sourceMappingURL=store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../test/store.test.ts"],"names":[],"mappings":"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"}
|