pi-harness-runtime 1.1.93 → 1.1.95
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/e2e/api-key-resolver.ts +146 -0
- package/harness/e2e/chatgpt-quota-scraper.ts +28 -4
- package/harness/e2e/glm-quota-scraper.ts +11 -1
- package/package.json +1 -1
- package/packages/a2a-adapter/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/config-capture/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/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/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-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/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/performance-optimizer/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/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/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/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/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/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Key Resolver - Auto-discover API keys from pi.dev config
|
|
3
|
+
*
|
|
4
|
+
* Scans ~/.pi/agent/auth.json to find API keys for:
|
|
5
|
+
* - zai (GLM)
|
|
6
|
+
* - minimax
|
|
7
|
+
* - And other providers
|
|
8
|
+
*
|
|
9
|
+
* Then copies to ~/.pi-harness-runtime/keys/ for easy access.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
13
|
+
import { join, dirname } from "node:path";
|
|
14
|
+
|
|
15
|
+
/** pi.dev auth file location */
|
|
16
|
+
const PI_AUTH_FILE = join(process.env.HOME || "/home/frappe", ".pi", "agent", "auth.json");
|
|
17
|
+
|
|
18
|
+
/** Our keys directory */
|
|
19
|
+
const KEYS_DIR = join(process.env.HOME || "/home/frappe", ".pi-harness-runtime", "keys");
|
|
20
|
+
|
|
21
|
+
/** Key file mappings */
|
|
22
|
+
const KEY_MAPPINGS: Record<string, string> = {
|
|
23
|
+
zai: "zai-api-key.txt",
|
|
24
|
+
minimax: "minimax-api-key.txt",
|
|
25
|
+
openai: "openai-api-key.txt",
|
|
26
|
+
anthropic: "anthropic-api-key.txt",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** pi.dev auth file structure */
|
|
30
|
+
interface PiAuth {
|
|
31
|
+
[provider: string]: {
|
|
32
|
+
type?: string;
|
|
33
|
+
key?: string;
|
|
34
|
+
access?: string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Read API keys from pi.dev auth.json
|
|
40
|
+
*/
|
|
41
|
+
export function readPiAuth(): PiAuth | null {
|
|
42
|
+
try {
|
|
43
|
+
if (!existsSync(PI_AUTH_FILE)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const content = readFileSync(PI_AUTH_FILE, "utf-8");
|
|
47
|
+
return JSON.parse(content) as PiAuth;
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get specific provider's API key from pi.dev auth
|
|
55
|
+
*/
|
|
56
|
+
export function getProviderKey(provider: string): string | null {
|
|
57
|
+
const auth = readPiAuth();
|
|
58
|
+
if (!auth || !auth[provider]) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// For api_key type, use the key directly
|
|
63
|
+
if (auth[provider].type === "api_key" && auth[provider].key) {
|
|
64
|
+
return auth[provider].key ?? null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// For oauth type, could return access token (but usually not needed)
|
|
68
|
+
// if (auth[provider].type === "oauth" && auth[provider].access) {
|
|
69
|
+
// return auth[provider].access ?? null;
|
|
70
|
+
// }
|
|
71
|
+
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Sync API keys from pi.dev to our keys directory
|
|
77
|
+
* This ensures we always have the latest keys without re-configuration
|
|
78
|
+
*/
|
|
79
|
+
export function syncApiKeysToKeysDir(): void {
|
|
80
|
+
const auth = readPiAuth();
|
|
81
|
+
if (!auth) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Ensure keys directory exists
|
|
86
|
+
if (!existsSync(KEYS_DIR)) {
|
|
87
|
+
mkdirSync(KEYS_DIR, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Sync each provider
|
|
91
|
+
for (const [provider, filename] of Object.entries(KEY_MAPPINGS)) {
|
|
92
|
+
if (auth[provider]?.type === "api_key" && auth[provider].key) {
|
|
93
|
+
const filepath = join(KEYS_DIR, filename);
|
|
94
|
+
const currentKey = existsSync(filepath)
|
|
95
|
+
? readFileSync(filepath, "utf-8").trim()
|
|
96
|
+
: null;
|
|
97
|
+
|
|
98
|
+
// Only write if key changed or file doesn't exist
|
|
99
|
+
if (currentKey !== auth[provider].key) {
|
|
100
|
+
writeFileSync(filepath, auth[provider].key!);
|
|
101
|
+
console.log(`[api-key-resolver] Synced ${provider} key to ${filepath}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get API key with auto-sync fallback
|
|
109
|
+
* Priority: 1. Keys file 2. pi.dev auth.json 3. Environment variable
|
|
110
|
+
*/
|
|
111
|
+
export function resolveApiKey(
|
|
112
|
+
provider: "zai" | "minimax" | "openai" | "anthropic",
|
|
113
|
+
envVar?: string
|
|
114
|
+
): string | null {
|
|
115
|
+
// 1. Try environment variable first
|
|
116
|
+
if (envVar && process.env[envVar]) {
|
|
117
|
+
return process.env[envVar] ?? null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 2. Try our keys directory
|
|
121
|
+
const filename = KEY_MAPPINGS[provider];
|
|
122
|
+
if (filename) {
|
|
123
|
+
const filepath = join(KEYS_DIR, filename);
|
|
124
|
+
if (existsSync(filepath)) {
|
|
125
|
+
const key = readFileSync(filepath, "utf-8").trim();
|
|
126
|
+
if (key.length > 10) {
|
|
127
|
+
return key;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 3. Try pi.dev auth.json
|
|
133
|
+
const authKey = getProviderKey(provider);
|
|
134
|
+
if (authKey) {
|
|
135
|
+
// Sync to keys dir for future use
|
|
136
|
+
syncApiKeysToKeysDir();
|
|
137
|
+
return authKey;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Auto-initialize: sync keys on module load
|
|
145
|
+
*/
|
|
146
|
+
syncApiKeysToKeysDir();
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
27
27
|
import { join } from "node:path";
|
|
28
28
|
import { homedir } from "node:os";
|
|
29
|
+
import { resolveApiKey } from "./api-key-resolver.js";
|
|
29
30
|
|
|
30
31
|
export interface ChatGPTQuotaData {
|
|
31
32
|
provider: "openai" | "openai-codex";
|
|
@@ -165,15 +166,38 @@ export class ChatGPTQuotaScraper {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
/**
|
|
168
|
-
* Load tokens from auth file
|
|
169
|
+
* Load tokens from auth file (tries multiple sources)
|
|
169
170
|
*/
|
|
170
171
|
loadTokens(): ChatGPTAuthTokens | null {
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
// Try primary auth file (~/.codex/auth.json)
|
|
173
|
+
let auth = loadAuthFile(this.config.authFile);
|
|
174
|
+
let tokens = auth?.tokens;
|
|
175
|
+
|
|
176
|
+
// Fallback: try pi.dev auth.json (~/.pi/agent/auth.json)
|
|
177
|
+
if (!tokens) {
|
|
178
|
+
try {
|
|
179
|
+
const piAuthPath = join(homedir(), ".pi", "agent", "auth.json");
|
|
180
|
+
if (existsSync(piAuthPath)) {
|
|
181
|
+
const piAuth = JSON.parse(readFileSync(piAuthPath, "utf-8"));
|
|
182
|
+
// Check for openai-codex OAuth tokens
|
|
183
|
+
if (piAuth["openai-codex"]?.type === "oauth") {
|
|
184
|
+
tokens = {
|
|
185
|
+
access_token: piAuth["openai-codex"].access,
|
|
186
|
+
refresh_token: piAuth["openai-codex"].refresh,
|
|
187
|
+
id_token: piAuth["openai-codex"].access, // Use access as id_token
|
|
188
|
+
account_id: piAuth["openai-codex"].accountId,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
} catch {
|
|
193
|
+
// Ignore pi auth read errors
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!tokens) {
|
|
173
198
|
return null;
|
|
174
199
|
}
|
|
175
200
|
|
|
176
|
-
const tokens = auth.tokens;
|
|
177
201
|
const client_id = tokens.id_token ? extractClientId(tokens.id_token) : null;
|
|
178
202
|
|
|
179
203
|
if (!tokens.access_token || !tokens.refresh_token || !client_id) {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
import { existsSync, readFileSync } from "node:fs";
|
|
30
30
|
import { join } from "node:path";
|
|
31
|
+
import { resolveApiKey } from "./api-key-resolver.js";
|
|
31
32
|
import { homedir } from "node:os";
|
|
32
33
|
|
|
33
34
|
export interface GLMQuotaData {
|
|
@@ -103,6 +104,7 @@ const SUBSCRIPTION_ENDPOINT = "/biz/subscription/list";
|
|
|
103
104
|
* Load API key from file, checking multiple locations
|
|
104
105
|
*/
|
|
105
106
|
function loadApiKey(path: string): string | null {
|
|
107
|
+
// First try: use the provided path (legacy behavior)
|
|
106
108
|
if (existsSync(path)) {
|
|
107
109
|
try {
|
|
108
110
|
const key = readFileSync(path, "utf-8").trim();
|
|
@@ -111,7 +113,8 @@ function loadApiKey(path: string): string | null {
|
|
|
111
113
|
// ignore
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
|
-
|
|
116
|
+
|
|
117
|
+
// Second try: fallback to legacy location
|
|
115
118
|
if (existsSync(LEGACY_API_KEY_FILE)) {
|
|
116
119
|
try {
|
|
117
120
|
const key = readFileSync(LEGACY_API_KEY_FILE, "utf-8").trim();
|
|
@@ -120,6 +123,13 @@ function loadApiKey(path: string): string | null {
|
|
|
120
123
|
// ignore
|
|
121
124
|
}
|
|
122
125
|
}
|
|
126
|
+
|
|
127
|
+
// Third try: auto-discover from pi.dev auth.json
|
|
128
|
+
const autoKey = resolveApiKey("zai");
|
|
129
|
+
if (autoKey) {
|
|
130
|
+
return autoKey;
|
|
131
|
+
}
|
|
132
|
+
|
|
123
133
|
return null;
|
|
124
134
|
}
|
|
125
135
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.95",
|
|
4
4
|
"description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/provider-router",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.95",
|
|
4
4
|
"description": "Enhanced Provider Router for pi-harness-runtime — intelligent routing with capabilities, costs, and quotas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/provider-router.js",
|