pi-para 0.6.5 → 0.6.6
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 +14 -0
- package/CONFIGURATION.md +1 -1
- package/README.md +1 -1
- package/SETUP.md +2 -2
- package/STRUCTURE.md +1 -1
- package/dist/cli.d.ts +23 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +71 -83
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +2 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +12 -5
- package/dist/commands.js.map +1 -1
- package/dist/credentials.d.ts +2 -2
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +6 -14
- package/dist/credentials.js.map +1 -1
- package/dist/doctor.js +19 -18
- package/dist/doctor.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -10
- package/dist/index.js.map +1 -1
- package/dist/model-resolver.d.ts +13 -6
- package/dist/model-resolver.d.ts.map +1 -1
- package/dist/model-resolver.js +35 -19
- package/dist/model-resolver.js.map +1 -1
- package/package.json +9 -9
- package/src/cli.ts +69 -81
- package/src/commands.ts +15 -6
- package/src/credentials.ts +7 -14
- package/src/doctor.ts +18 -16
- package/src/index.ts +11 -10
- package/src/model-resolver.ts +45 -20
package/src/model-resolver.ts
CHANGED
|
@@ -3,15 +3,22 @@ import type { ProviderCredentialRef, ParaUserConfig } from "./config.js";
|
|
|
3
3
|
import { resolveCredentialRef } from "./credentials.js";
|
|
4
4
|
|
|
5
5
|
export interface ModelRegistryLike {
|
|
6
|
+
getAll(): Model<any>[];
|
|
6
7
|
getAvailable(): Model<any>[];
|
|
7
8
|
find(provider: string, modelId: string): Model<any> | undefined;
|
|
8
9
|
getApiKeyForProvider(provider: string): Promise<string | undefined>;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export interface
|
|
12
|
+
export interface PiCredentialReader {
|
|
13
|
+
hasStoredCredential(provider: string): boolean;
|
|
12
14
|
getApiKey(provider: string): Promise<string | undefined>;
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
export interface PiModelServices {
|
|
18
|
+
modelRegistry: ModelRegistryLike;
|
|
19
|
+
credentials: PiCredentialReader;
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
export type ModelSelection = ProviderCredentialRef | "auto";
|
|
16
23
|
|
|
17
24
|
export function parseProviderModelSpec(spec: string): { provider: string; modelId: string } | null {
|
|
@@ -20,6 +27,10 @@ export function parseProviderModelSpec(spec: string): { provider: string; modelI
|
|
|
20
27
|
return { provider: spec.slice(0, idx), modelId: spec.slice(idx + 1) };
|
|
21
28
|
}
|
|
22
29
|
|
|
30
|
+
function isRemoteModel(model: Model<any>): boolean {
|
|
31
|
+
return model.provider !== "node-llama-cpp" && model.provider !== "local" && !model.provider.includes("llama");
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
export function resolveSelectedModel(
|
|
24
35
|
selection: ModelSelection,
|
|
25
36
|
registry: ModelRegistryLike,
|
|
@@ -27,47 +38,50 @@ export function resolveSelectedModel(
|
|
|
27
38
|
): Model<any> | null {
|
|
28
39
|
if (selection !== "auto") {
|
|
29
40
|
if (selection.model) return registry.find(selection.provider, selection.model) ?? null;
|
|
30
|
-
return registry.getAvailable().find((model) => model.provider === selection.provider) ?? null;
|
|
41
|
+
return registry.getAvailable().find((model) => model.provider === selection.provider && isRemoteModel(model)) ?? null;
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
const legacy = opts.legacyModelSpec ? parseProviderModelSpec(opts.legacyModelSpec) : null;
|
|
34
45
|
if (legacy) {
|
|
35
46
|
const model = registry.find(legacy.provider, legacy.modelId);
|
|
36
|
-
if (model) return model;
|
|
47
|
+
if (model && isRemoteModel(model)) return model;
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
const preferred = opts.preferredModelSpec ? parseProviderModelSpec(opts.preferredModelSpec) : null;
|
|
40
51
|
if (preferred) {
|
|
41
52
|
const model = registry.find(preferred.provider, preferred.modelId);
|
|
42
|
-
if (model) return model;
|
|
53
|
+
if (model && isRemoteModel(model)) return model;
|
|
43
54
|
}
|
|
44
55
|
|
|
45
|
-
return pickBestAvailableModel(registry.getAvailable());
|
|
56
|
+
return pickBestAvailableModel(registry.getAvailable().filter(isRemoteModel));
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
export function pickBestAvailableModel(models: Model<any>[]): Model<any> | null {
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
const remote = models.filter(isRemoteModel);
|
|
61
|
+
if (remote.length === 0) return null;
|
|
62
|
+
const sonnet = remote.find((model) => model.provider === "anthropic" && /sonnet/i.test(model.id));
|
|
51
63
|
if (sonnet) return sonnet;
|
|
52
|
-
return [...
|
|
64
|
+
return [...remote].sort((a, b) => (b.contextWindow ?? 0) - (a.contextWindow ?? 0))[0] ?? null;
|
|
53
65
|
}
|
|
54
66
|
|
|
55
67
|
export function createModelApiKeyResolver(
|
|
56
68
|
selection: ModelSelection,
|
|
57
69
|
registry: ModelRegistryLike,
|
|
58
|
-
opts: {
|
|
70
|
+
opts: { credentials?: PiCredentialReader; secretsPath?: string } = {},
|
|
59
71
|
): (provider: string) => Promise<string | undefined> {
|
|
60
72
|
return async (provider: string) => {
|
|
61
|
-
if (selection === "auto")
|
|
73
|
+
if (selection === "auto") {
|
|
74
|
+
return opts.credentials ? opts.credentials.getApiKey(provider) : registry.getApiKeyForProvider(provider);
|
|
75
|
+
}
|
|
76
|
+
if (selection.provider !== provider) return undefined;
|
|
62
77
|
|
|
63
78
|
if (selection.credentialRef.startsWith("pi-auth:")) {
|
|
64
79
|
const configuredProvider = selection.credentialRef.slice("pi-auth:".length);
|
|
65
|
-
if (configuredProvider !== provider
|
|
66
|
-
return
|
|
80
|
+
if (configuredProvider !== provider) return undefined;
|
|
81
|
+
return opts.credentials ? opts.credentials.getApiKey(provider) : registry.getApiKeyForProvider(provider);
|
|
67
82
|
}
|
|
68
83
|
|
|
69
84
|
if (selection.credentialRef.startsWith("secret:")) {
|
|
70
|
-
if (selection.provider !== provider) return undefined;
|
|
71
85
|
const resolved = await resolveCredentialRef(selection.credentialRef, { secretsPath: opts.secretsPath });
|
|
72
86
|
return resolved.ok ? resolved.value : undefined;
|
|
73
87
|
}
|
|
@@ -80,17 +94,28 @@ export function getCaptureSelection(config: ParaUserConfig): ModelSelection {
|
|
|
80
94
|
return config.models.capture;
|
|
81
95
|
}
|
|
82
96
|
|
|
83
|
-
export async function
|
|
97
|
+
export async function createPiModelServices(
|
|
98
|
+
options: { authPath?: string } = {},
|
|
99
|
+
): Promise<PiModelServices | null> {
|
|
84
100
|
try {
|
|
85
101
|
const mod = await import("@earendil-works/pi-coding-agent");
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
102
|
+
const runtime = await mod.ModelRuntime.create({ authPath: options.authPath, allowModelNetwork: false });
|
|
103
|
+
const modelRegistry = new mod.ModelRegistry(runtime);
|
|
104
|
+
await modelRegistry.refresh();
|
|
105
|
+
return {
|
|
106
|
+
modelRegistry,
|
|
107
|
+
credentials: {
|
|
108
|
+
hasStoredCredential: (provider) => Boolean(mod.readStoredCredential(provider, options.authPath)),
|
|
109
|
+
getApiKey: async (provider) => {
|
|
110
|
+
if (!mod.readStoredCredential(provider, options.authPath)) return undefined;
|
|
111
|
+
return (await runtime.getAuth(provider))?.auth.apiKey;
|
|
112
|
+
},
|
|
113
|
+
},
|
|
89
114
|
};
|
|
90
|
-
if (!typed.AuthStorage || !typed.ModelRegistry) return null;
|
|
91
|
-
const authStorage = typed.AuthStorage.create();
|
|
92
|
-
return { authStorage, modelRegistry: typed.ModelRegistry.create(authStorage) };
|
|
93
115
|
} catch {
|
|
94
116
|
return null;
|
|
95
117
|
}
|
|
96
118
|
}
|
|
119
|
+
|
|
120
|
+
/** @deprecated Use createPiModelServices. */
|
|
121
|
+
export const createPiModelRegistry = createPiModelServices;
|