pi-ghost-autocomplete 0.8.0 → 0.9.0
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 +2 -1
- package/dist/bench-cli.js +1 -1
- package/dist/bench.js +1 -1
- package/dist/config.d.ts +22 -0
- package/dist/index.js +1 -1
- package/dist/intent.d.ts +14 -0
- package/dist/providers/cloud-provider.d.ts +45 -1
- package/dist/replay-cli.js +1 -1
- package/package.json +17 -14
package/dist/intent.d.ts
CHANGED
|
@@ -145,6 +145,20 @@ export declare function isPathContext(lineBeforeCursor: string, _token: {
|
|
|
145
145
|
token: string;
|
|
146
146
|
insideQuote: boolean;
|
|
147
147
|
}): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Is the draft a finished sentence with the cursor parked right after the
|
|
150
|
+
* terminator? Session 53.
|
|
151
|
+
*
|
|
152
|
+
* When true there is nothing left to *complete*: any continuation has to open
|
|
153
|
+
* a new sentence, and a chat model handed a finished question plus the
|
|
154
|
+
* conversation context does the thing it was trained to do — it answers.
|
|
155
|
+
* That is exactly the failure this predicate suppresses ("… für Android?" →
|
|
156
|
+
* ghost "Um das Vorhandene auf Android zu übertragen, benötigen wir …").
|
|
157
|
+
*
|
|
158
|
+
* A trailing space means the user has deliberately started the next sentence,
|
|
159
|
+
* so completion resumes as soon as they type one.
|
|
160
|
+
*/
|
|
161
|
+
export declare function isSentenceComplete(draft: string): boolean;
|
|
148
162
|
/**
|
|
149
163
|
* Short human-readable description for each intent, suitable for injection
|
|
150
164
|
* into LLM system prompts or FIM comment headers. Single canonical source —
|
|
@@ -2,12 +2,56 @@
|
|
|
2
2
|
* SPDX-License-Identifier: SSPL-1.0
|
|
3
3
|
* SPDX-FileCopyrightText: 2025 Alessandro Pungitore <alessandro@pungitore.ch>
|
|
4
4
|
*/
|
|
5
|
+
import type { Api, Model, Models, ProviderEnv, ProviderHeaders } from "@earendil-works/pi-ai";
|
|
6
|
+
import type { ModelRegistry } from "@earendil-works/pi-coding-agent";
|
|
5
7
|
import type { CloudProviderConfig } from "../config.js";
|
|
6
8
|
import type { GhostProvider, GhostRequest, StreamDelta } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Resolved auth forwarded into a cloud request. All three fields are
|
|
11
|
+
* per-call options on pi-ai's stream/complete (`ProviderRequestOptions`).
|
|
12
|
+
* `baseUrl` is intentionally absent — it is a property of the static
|
|
13
|
+
* `Provider`, not a per-call option, so `builtinModels()` always uses the
|
|
14
|
+
* provider's default endpoint (see {@link resolveAuth}).
|
|
15
|
+
*/
|
|
16
|
+
export interface ResolvedGhostAuth {
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
headers?: ProviderHeaders;
|
|
19
|
+
env?: ProviderEnv;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve auth for a cloud request. Precedence:
|
|
23
|
+
* 1. `config.apiKey` (explicit `PI_GHOST_API_KEY`) — wins whenever set.
|
|
24
|
+
* 2. The session's real registry (`ctx.modelRegistry.getApiKeyAndHeaders`)
|
|
25
|
+
* — reflects the user's models.json config and stored credentials exactly
|
|
26
|
+
* as the main agent sees them, so a provider already configured for the
|
|
27
|
+
* session (e.g. Groq) is reused without a separate ghost key. We forward
|
|
28
|
+
* the resolved `headers` and `env` too (OAuth bearer headers, regional /
|
|
29
|
+
* endpoint env), not just the api-key string. HOWEVER: a custom `baseUrl`
|
|
30
|
+
* cannot be honored here — `builtinModels()` ignores models.json URLs and
|
|
31
|
+
* `baseUrl` is not a per-call option — so when the registry resolved a
|
|
32
|
+
* custom `baseUrl` we skip it entirely and fall back to ambient auth, to
|
|
33
|
+
* avoid sending a custom-endpoint key to the default endpoint.
|
|
34
|
+
* 3. The builtin registry's ambient auth (`Models.getAuth`) — env keys like
|
|
35
|
+
* `GROQ_API_KEY`. Kept for the bench/replay paths that run without a live
|
|
36
|
+
* session registry.
|
|
37
|
+
*
|
|
38
|
+
* Safe by construction: the registry branch only adopts auth when it carries
|
|
39
|
+
* no custom `baseUrl`, so it can never send credentials to the wrong endpoint.
|
|
40
|
+
* Worst case it falls through to the original ambient path.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveAuth(models: Models, config: CloudProviderConfig, model: Model<Api>, registry?: ModelRegistry): Promise<ResolvedGhostAuth>;
|
|
7
43
|
export declare class CloudProvider implements GhostProvider {
|
|
8
44
|
private readonly config;
|
|
45
|
+
private readonly registry?;
|
|
9
46
|
readonly name = "ghost-cloud";
|
|
10
|
-
|
|
47
|
+
/**
|
|
48
|
+
* @param registry The session's real model registry, used to resolve the
|
|
49
|
+
* provider API key from the user's actual configuration (models.json,
|
|
50
|
+
* stored credentials, env) so ghost can reuse the same key the main agent
|
|
51
|
+
* uses — without requiring a separate `PI_GHOST_API_KEY`. Optional for
|
|
52
|
+
* tests and the non-session bench/replay paths.
|
|
53
|
+
*/
|
|
54
|
+
constructor(config: CloudProviderConfig, registry?: ModelRegistry | undefined);
|
|
11
55
|
get debounceMs(): number;
|
|
12
56
|
predict(req: GhostRequest): Promise<string | null>;
|
|
13
57
|
/**
|