pi-spark 0.22.0 → 0.22.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-spark",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "description": "Pi package that polishes your daily experience.",
5
5
  "keywords": [
6
6
  "pi-coding-agent",
@@ -18,7 +18,7 @@ export function registerCredits(pi: ExtensionAPI): void {
18
18
 
19
19
  pi.on("session_start", (_event, ctx) => {
20
20
  const config = loadConfig(ctx).credits;
21
- if (ctx.mode !== "tui" || !config) return;
21
+ if (!["tui", "rpc"].includes(ctx.mode) || !config) return;
22
22
 
23
23
  const providers = getEnabledProviders(config);
24
24
  if (providers.length === 0) return;
@@ -5,7 +5,7 @@ import { hyperlink, Text } from "@earendil-works/pi-tui";
5
5
 
6
6
  import { SplitLine } from "../../components/split-line";
7
7
  import { loadConfig } from "../../config";
8
- import { formatContextUsage, formatCost, formatCwd, sanitizeText } from "../../utils/format";
8
+ import { formatContextUsage, formatCwd, sanitizeText } from "../../utils/format";
9
9
  import { getEntryUsage } from "../../utils/usage";
10
10
 
11
11
  import type { ExtensionContext, ExtensionAPI, ReadonlyFooterDataProvider, Theme } from "@earendil-works/pi-coding-agent";
@@ -76,11 +76,9 @@ class FooterComponent implements Component {
76
76
 
77
77
  private getStyledCostText(): string {
78
78
  const totalCost = this.ctx.sessionManager.getEntries().reduce((acc, entry) => acc + (getEntryUsage(entry)?.cost.total ?? 0), 0);
79
+ if (totalCost < 0.0005) return ""; // Hide cost below half a millicent, since it would render as $0.000.
79
80
 
80
- // Hide cost below half a cent, since it would render as $0.00.
81
- if (totalCost < 0.005) return "";
82
-
83
- const costText = formatCost(totalCost);
81
+ const costText = `$${totalCost.toFixed(3)}`;
84
82
 
85
83
  if (totalCost > 20) return this.theme.fg("warning", costText);
86
84
  return this.theme.fg("dim", costText);
@@ -87,6 +87,7 @@ export class RecapManager {
87
87
  const options: SimpleStreamOptions = { maxTokens: MAX_TOKENS, signal };
88
88
  if (auth.apiKey) options.apiKey = auth.apiKey;
89
89
  if (auth.headers) options.headers = auth.headers;
90
+ if (auth.env) options.env = auth.env;
90
91
  if (thinkingLevel !== "off") options.reasoning = thinkingLevel;
91
92
 
92
93
  const response = await completeBackground(model, {
@@ -70,6 +70,7 @@ export class TitleManager {
70
70
  const options: SimpleStreamOptions = { maxTokens: MAX_TOKENS, signal };
71
71
  if (auth.apiKey) options.apiKey = auth.apiKey;
72
72
  if (auth.headers) options.headers = auth.headers;
73
+ if (auth.env) options.env = auth.env;
73
74
  if (thinkingLevel !== "off") options.reasoning = thinkingLevel;
74
75
 
75
76
  const response = await completeBackground(model, {
@@ -26,10 +26,6 @@ export function formatContextUsage(contextUsage: ContextUsage | undefined): stri
26
26
  return `${tokens === null ? "?" : formatTokens(tokens)}/${contextWindow === null ? "?" : formatTokens(contextWindow)} (${percentText})`;
27
27
  }
28
28
 
29
- export function formatCost(cost: number): string {
30
- return `$${cost.toFixed(2)}`;
31
- }
32
-
33
29
  export function formatCwd(cwd: string, home: string): string {
34
30
  const resolvedCwd = resolve(cwd);
35
31
  const resolvedHome = resolve(home);
@@ -59,7 +59,7 @@ export async function resolveModelSettings(ctx: ExtensionContext, config: Option
59
59
  return;
60
60
  }
61
61
 
62
- const { model, warning: modelWarning } = await resolveModelSelection(ctx, config, feature, fallbackModel);
62
+ const { model, warning: modelWarning } = await resolveModel(ctx, config, feature, fallbackModel);
63
63
  const { thinkingLevel, warning: thinkingLevelWarning } = resolveThinkingLevel(model, config.thinkingLevel ?? DEFAULT_THINKING_LEVEL);
64
64
 
65
65
  return {
@@ -69,41 +69,28 @@ export async function resolveModelSettings(ctx: ExtensionContext, config: Option
69
69
  };
70
70
  }
71
71
 
72
- async function resolveModelSelection(ctx: ExtensionContext, config: OptionalModelConfig, feature: string, fallbackModel: Model<Api>): Promise<ModelSelection> {
73
- if (!config.provider && !config.model) {
74
- return {
75
- model: fallbackModel,
76
- warning: undefined,
77
- };
78
- }
79
-
80
- if (!config.provider || !config.model) {
81
- return {
82
- model: fallbackModel,
83
- warning: `Both ${feature}.provider and ${feature}.model are required; using the current model.`,
84
- };
85
- }
86
-
87
- const model = ctx.modelRegistry.find(config.provider, config.model);
88
- if (!model) {
89
- return {
90
- model: fallbackModel,
91
- warning: `Model ${formatModel(config.provider, config.model)} not found; using the current model.`,
92
- };
72
+ async function resolveModel(ctx: ExtensionContext, config: OptionalModelConfig, feature: string, fallbackModel: Model<Api>): Promise<ModelSelection> {
73
+ let model = fallbackModel;
74
+ let warning: string | undefined = undefined;
75
+
76
+ if (config.provider && config.model) {
77
+ const reference = formatModel(config.provider, config.model);
78
+ const configuredModel = ctx.modelRegistry.find(config.provider, config.model);
79
+ if (!configuredModel) {
80
+ warning = `Model ${reference} not found; using the current model.`;
81
+ } else {
82
+ const auth = await ctx.modelRegistry.getApiKeyAndHeaders(configuredModel);
83
+ if (auth.ok) {
84
+ model = configuredModel;
85
+ } else {
86
+ warning = `Model ${reference} unavailable: ${auth.error}; using the current model.`;
87
+ }
88
+ }
89
+ } else if (config.provider || config.model) {
90
+ warning = `Both ${feature}.provider and ${feature}.model are required; using the current model.`;
93
91
  }
94
92
 
95
- const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
96
- if (!auth.ok) {
97
- return {
98
- model: fallbackModel,
99
- warning: `Model ${formatModel(config.provider, config.model)} unavailable: ${auth.error}; using the current model.`,
100
- };
101
- }
102
-
103
- return {
104
- model,
105
- warning: undefined,
106
- };
93
+ return { model, warning };
107
94
  }
108
95
 
109
96
  function resolveThinkingLevel(model: Model<Api>, requested: ModelThinkingLevel): ThinkingLevelSelection {