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/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
- constructor(config: CloudProviderConfig);
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
  /**