@valni/cli-darwin-x64 0.1.5 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valni/cli-darwin-x64",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -48,13 +48,11 @@ export async function loadRegistryModels(): Promise<Record<string, RegistryModel
48
48
  const distDirectory = findPiAiDist();
49
49
  const registry: Record<string, RegistryModel> = {};
50
50
  if (distDirectory === undefined) {
51
- const names = AI_PACKAGES.map(([scope, name]) => `${scope}/${name}`).join(" or ");
52
- console.error(
53
- `pi-switchboard: no ${names} beside the host executable, so models list without a context window or display name.`,
54
- );
51
+ // The catalog supplies the context window and the display name, and a
52
+ // genuinely missing context window is reported precisely in
53
+ // buildModelConfigs. The registry is only a source of last resort.
55
54
  return registry;
56
55
  }
57
- const missing: string[] = [];
58
56
  for (const file of REGISTRY_FILES) {
59
57
  let loaded: Record<string, Record<string, RegistryModel>>;
60
58
  try {
@@ -63,10 +61,9 @@ export async function loadRegistryModels(): Promise<Record<string, RegistryModel
63
61
  Record<string, RegistryModel>
64
62
  >;
65
63
  } catch (error) {
66
- if (isModuleNotFound(error)) {
67
- missing.push(file);
68
- continue;
69
- }
64
+ // A registry file that is not there is not a problem: everything a
65
+ // user sees first comes from the catalog.
66
+ if (isModuleNotFound(error)) continue;
70
67
  throw error;
71
68
  }
72
69
  for (const exported of Object.values(loaded)) {
@@ -76,11 +73,6 @@ export async function loadRegistryModels(): Promise<Record<string, RegistryModel
76
73
  }
77
74
  }
78
75
  }
79
- if (missing.length === REGISTRY_FILES.length) {
80
- console.error(
81
- `pi-switchboard: no model registry in ${distDirectory}/providers (${missing.join(", ")}). Models will list without a context window or display name.`,
82
- );
83
- }
84
76
  return registry;
85
77
  }
86
78
 
@@ -109,10 +101,11 @@ function toModelConfig(
109
101
  price: ModelRecordPrice | undefined,
110
102
  registryModel: RegistryModel | undefined,
111
103
  catalogContextWindow: number | undefined,
104
+ catalogDisplayName: string | undefined,
112
105
  ) {
113
106
  return {
114
107
  id: record.id,
115
- name: registryModel?.name ?? record.id,
108
+ name: catalogDisplayName ?? registryModel?.name ?? record.id,
116
109
  api: KIND_TO_API[kindTag],
117
110
  baseUrl: `${resolveBaseUrl()}${SENTINEL_SEGMENT}${kindTag}`,
118
111
  reasoning: supportsReasoning(kindTag, profile) ?? registryModel?.reasoning ?? false,
@@ -127,12 +120,13 @@ function toModelConfig(
127
120
  };
128
121
  }
129
122
 
130
- export async function discoverCatalog(baseUrl: string, bearer: string): Promise<ModelsPage> {
123
+ export async function discoverCatalog(baseUrl: string, bearer: string, signal?: AbortSignal): Promise<ModelsPage> {
124
+ const timeout = AbortSignal.timeout(CATALOG_FETCH_TIMEOUT_MS);
131
125
  let response: Response;
132
126
  try {
133
127
  response = await fetch(`${baseUrl}${MODELS_PATH}`, {
134
128
  headers: { Authorization: `Bearer ${bearer}` },
135
- signal: AbortSignal.timeout(CATALOG_FETCH_TIMEOUT_MS),
129
+ signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
136
130
  });
137
131
  } catch (error) {
138
132
  if (isAbortError(error)) throw error;
@@ -168,7 +162,15 @@ export function buildModelConfigs(catalog: ModelsPage, registry: Record<string,
168
162
  const catalogContextWindow = catalog.context_windows?.[record.id];
169
163
  if (catalogContextWindow === undefined && registry[record.id]?.contextWindow === undefined) assumed++;
170
164
  modelConfigs.push(
171
- toModelConfig(record, kindTag, record.kind[kindTag], catalog.prices[record.id], registry[record.id], catalogContextWindow),
165
+ toModelConfig(
166
+ record,
167
+ kindTag,
168
+ record.kind[kindTag],
169
+ catalog.prices[record.id],
170
+ registry[record.id],
171
+ catalogContextWindow,
172
+ catalog.display_names?.[record.id],
173
+ ),
172
174
  );
173
175
  }
174
176
  if (skipped.length > 0) {
@@ -99,22 +99,27 @@ export default async function (pi: ExtensionAPI) {
99
99
  refreshModels: async (context: RefreshModelsContext) => {
100
100
  const bearer = credentialBearer(context.credential);
101
101
  if (!bearer) {
102
- await context.store.delete();
102
+ await context.publish({ persist: null });
103
103
  return [];
104
104
  }
105
- const stored = await context.store.read();
106
105
  if (!context.allowNetwork) {
107
- return stored ? ([...stored.models] as ReturnType<typeof buildModelConfigs>) : startupModels;
106
+ return context.stored
107
+ ? ([...context.stored.models] as ReturnType<typeof buildModelConfigs>)
108
+ : startupModels;
108
109
  }
109
- const catalog = await discoverCatalog(baseUrl, bearer);
110
+ const catalog = await discoverCatalog(baseUrl, bearer, context.signal);
110
111
  const configs = buildModelConfigs(catalog, registry);
111
- await context.store.write({
112
- models: configs as unknown as ModelsStoreEntry["models"],
113
- checkedAt: Math.floor(Date.now() / MILLISECONDS_PER_SECOND),
112
+ const published = await context.publish({
113
+ persist: {
114
+ models: configs as unknown as ModelsStoreEntry["models"],
115
+ checkedAt: Math.floor(Date.now() / MILLISECONDS_PER_SECOND),
116
+ },
114
117
  });
118
+ if (!published) return configs;
115
119
  if (context.credential?.type === "oauth") {
116
120
  try {
117
- registerServerTools(pi, await discoverTools(baseUrl, bearer));
121
+ const tools = await discoverTools(baseUrl, bearer, context.signal);
122
+ if (!context.signal.aborted) registerServerTools(pi, tools);
118
123
  } catch (error) {
119
124
  console.error("pi-switchboard: server tool discovery failed", error);
120
125
  }
@@ -28,14 +28,15 @@ export interface AdvertisedTool {
28
28
  version?: string;
29
29
  }
30
30
 
31
- export async function discoverTools(baseUrl: string, bearer: string): Promise<AdvertisedTool[]> {
31
+ export async function discoverTools(baseUrl: string, bearer: string, signal?: AbortSignal): Promise<AdvertisedTool[]> {
32
+ const timeout = AbortSignal.timeout(DISCOVER_TIMEOUT_MS);
32
33
  let response: Response;
33
34
  try {
34
35
  response = await fetch(`${baseUrl}${MCP_PATH}`, {
35
36
  method: "POST",
36
37
  headers: { "Content-Type": "application/json", Accept: "application/json", Authorization: `Bearer ${bearer}` },
37
38
  body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/list", params: {} }),
38
- signal: AbortSignal.timeout(DISCOVER_TIMEOUT_MS),
39
+ signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
39
40
  });
40
41
  } catch {
41
42
  return [];
@@ -1,4 +1,6 @@
1
- import { Type } from "@earendil-works/pi-ai";
1
+ // typebox directly, not through a harness package: this extension runs in
2
+ // more than one host and must not name any of them at runtime.
3
+ import { Type } from "typebox";
2
4
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
5
  import { type AdvertisedTool, makeProxyExecute } from "./toolProxy.ts";
4
6
 
@@ -31,7 +31,10 @@ export interface ModelRecordPrice {
31
31
  export interface ModelsPage {
32
32
  models: ModelRecord[];
33
33
  prices: Record<string, ModelRecordPrice>;
34
+ /** Real context window per model id, from the catalog. */
34
35
  context_windows?: Record<string, number>;
36
+ /** Human-readable name per model id, from the catalog. */
37
+ display_names?: Record<string, string>;
35
38
  }
36
39
 
37
40
  export type RegistryModel = Model<(typeof KIND_TO_API)[SwitchboardKind]>;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-switchboard",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "type": "module",
5
5
  "description": "Route the pi coding agent through Switchboard: one prepaid balance, spend controls, and a ledger for every model in the catalog",
6
6
  "keywords": [
@@ -23,8 +23,8 @@
23
23
  ]
24
24
  },
25
25
  "devDependencies": {
26
- "@earendil-works/pi-ai": "0.82.1",
27
- "@earendil-works/pi-coding-agent": "0.82.1",
26
+ "@earendil-works/pi-ai": ">=1.0.0",
27
+ "@earendil-works/pi-coding-agent": ">=1.0.0",
28
28
  "typescript": "5.9.3"
29
29
  }
30
30
  }
@@ -0,0 +1,88 @@
1
+ import type { AssistantMessage, AssistantMessageEvent } from "@earendil-works/pi-ai";
2
+
3
+ // Generic event stream class for async iteration
4
+ export class EventStream<T, R = T> implements AsyncIterable<T> {
5
+ private queue: T[] = [];
6
+ private waiting: ((value: IteratorResult<T>) => void)[] = [];
7
+ private done = false;
8
+ private finalResultPromise: Promise<R>;
9
+ private resolveFinalResult!: (result: R) => void;
10
+ private isComplete: (event: T) => boolean;
11
+ private extractResult: (event: T) => R;
12
+
13
+ constructor(isComplete: (event: T) => boolean, extractResult: (event: T) => R) {
14
+ this.isComplete = isComplete;
15
+ this.extractResult = extractResult;
16
+ this.finalResultPromise = new Promise((resolve) => {
17
+ this.resolveFinalResult = resolve;
18
+ });
19
+ }
20
+
21
+ push(event: T): void {
22
+ if (this.done) return;
23
+
24
+ if (this.isComplete(event)) {
25
+ this.done = true;
26
+ this.resolveFinalResult(this.extractResult(event));
27
+ }
28
+
29
+ // Deliver to waiting consumer or queue it
30
+ const waiter = this.waiting.shift();
31
+ if (waiter) {
32
+ waiter({ value: event, done: false });
33
+ } else {
34
+ this.queue.push(event);
35
+ }
36
+ }
37
+
38
+ end(result?: R): void {
39
+ this.done = true;
40
+ if (result !== undefined) {
41
+ this.resolveFinalResult(result);
42
+ }
43
+ // Notify all waiting consumers that we're done
44
+ while (this.waiting.length > 0) {
45
+ const waiter = this.waiting.shift()!;
46
+ waiter({ value: undefined as any, done: true });
47
+ }
48
+ }
49
+
50
+ async *[Symbol.asyncIterator](): AsyncIterator<T> {
51
+ while (true) {
52
+ if (this.queue.length > 0) {
53
+ yield this.queue.shift()!;
54
+ } else if (this.done) {
55
+ return;
56
+ } else {
57
+ const result = await new Promise<IteratorResult<T>>((resolve) => this.waiting.push(resolve));
58
+ if (result.done) return;
59
+ yield result.value;
60
+ }
61
+ }
62
+ }
63
+
64
+ result(): Promise<R> {
65
+ return this.finalResultPromise;
66
+ }
67
+ }
68
+
69
+ export class AssistantMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> {
70
+ constructor() {
71
+ super(
72
+ (event) => event.type === "done" || event.type === "error",
73
+ (event) => {
74
+ if (event.type === "done") {
75
+ return event.message;
76
+ } else if (event.type === "error") {
77
+ return event.error;
78
+ }
79
+ throw new Error("Unexpected event type for final result");
80
+ },
81
+ );
82
+ }
83
+ }
84
+
85
+ /** Factory function for AssistantMessageEventStream (for use in extensions) */
86
+ export function createAssistantMessageEventStream(): AssistantMessageEventStream {
87
+ return new AssistantMessageEventStream();
88
+ }
@@ -0,0 +1,49 @@
1
+ import type { TextContent, Tool, TranscriptContext } from "@earendil-works/pi-ai";
2
+
3
+ /**
4
+ * Read the system prompt and the tools out of a transcript.
5
+ *
6
+ * Both hosts hand a provider the same shape now: system messages replayed in
7
+ * order, where later content appends to the prompt and tools are added and
8
+ * removed by name. Doing the replay here rather than calling a host helper is
9
+ * what keeps a host package out of the runtime imports.
10
+ */
11
+
12
+ interface SystemMessage {
13
+ role: string;
14
+ content: string | TextContent[];
15
+ toolsAdded?: Tool[];
16
+ toolsRemoved?: { name: string }[];
17
+ }
18
+
19
+ function isSystemMessage(message: unknown): message is SystemMessage {
20
+ return message !== null && typeof message === "object" && (message as { role?: unknown }).role === "system";
21
+ }
22
+
23
+ function contentText(content: string | TextContent[]): string {
24
+ if (typeof content === "string") return content;
25
+ return content
26
+ .filter((part) => part.type === "text")
27
+ .map((part) => part.text)
28
+ .join("");
29
+ }
30
+
31
+ export function hostSystemPrompt(context: TranscriptContext): string | undefined {
32
+ const parts: string[] = [];
33
+ for (const message of context.messages) {
34
+ if (!isSystemMessage(message)) continue;
35
+ const text = contentText(message.content);
36
+ if (text.length > 0) parts.push(text);
37
+ }
38
+ return parts.length > 0 ? parts.join("\n\n") : undefined;
39
+ }
40
+
41
+ export function hostTools(context: TranscriptContext): Tool[] {
42
+ const tools = new Map<string, Tool>();
43
+ for (const message of context.messages) {
44
+ if (!isSystemMessage(message)) continue;
45
+ for (const tool of message.toolsRemoved ?? []) tools.delete(tool.name);
46
+ for (const tool of message.toolsAdded ?? []) tools.set(tool.name, tool);
47
+ }
48
+ return [...tools.values()];
49
+ }
@@ -0,0 +1,124 @@
1
+ import { parse as partialParse } from "partial-json";
2
+
3
+ const VALID_JSON_ESCAPES = new Set(['"', "\\", "/", "b", "f", "n", "r", "t", "u"]);
4
+
5
+ function isControlCharacter(char: string): boolean {
6
+ const codePoint = char.codePointAt(0);
7
+ return codePoint !== undefined && codePoint >= 0x00 && codePoint <= 0x1f;
8
+ }
9
+
10
+ function escapeControlCharacter(char: string): string {
11
+ switch (char) {
12
+ case "\b":
13
+ return "\\b";
14
+ case "\f":
15
+ return "\\f";
16
+ case "\n":
17
+ return "\\n";
18
+ case "\r":
19
+ return "\\r";
20
+ case "\t":
21
+ return "\\t";
22
+ default:
23
+ return `\\u${char.codePointAt(0)?.toString(16).padStart(4, "0") ?? "0000"}`;
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Repairs malformed JSON string literals by:
29
+ * - escaping raw control characters inside strings
30
+ * - doubling backslashes before invalid escape characters
31
+ */
32
+ export function repairJson(json: string): string {
33
+ let repaired = "";
34
+ let inString = false;
35
+
36
+ for (let index = 0; index < json.length; index++) {
37
+ const char = json[index];
38
+
39
+ if (!inString) {
40
+ repaired += char;
41
+ if (char === '"') {
42
+ inString = true;
43
+ }
44
+ continue;
45
+ }
46
+
47
+ if (char === '"') {
48
+ repaired += char;
49
+ inString = false;
50
+ continue;
51
+ }
52
+
53
+ if (char === "\\") {
54
+ const nextChar = json[index + 1];
55
+ if (nextChar === undefined) {
56
+ repaired += "\\\\";
57
+ continue;
58
+ }
59
+
60
+ if (nextChar === "u") {
61
+ const unicodeDigits = json.slice(index + 2, index + 6);
62
+ if (/^[0-9a-fA-F]{4}$/.test(unicodeDigits)) {
63
+ repaired += `\\u${unicodeDigits}`;
64
+ index += 5;
65
+ continue;
66
+ }
67
+ }
68
+
69
+ if (VALID_JSON_ESCAPES.has(nextChar)) {
70
+ repaired += `\\${nextChar}`;
71
+ index += 1;
72
+ continue;
73
+ }
74
+
75
+ repaired += "\\\\";
76
+ continue;
77
+ }
78
+
79
+ repaired += isControlCharacter(char) ? escapeControlCharacter(char) : char;
80
+ }
81
+
82
+ return repaired;
83
+ }
84
+
85
+ export function parseJsonWithRepair<T>(json: string): T {
86
+ try {
87
+ return JSON.parse(json) as T;
88
+ } catch (error) {
89
+ const repairedJson = repairJson(json);
90
+ if (repairedJson !== json) {
91
+ return JSON.parse(repairedJson) as T;
92
+ }
93
+ throw error;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Attempts to parse potentially incomplete JSON during streaming.
99
+ * Always returns a valid object, even if the JSON is incomplete.
100
+ *
101
+ * @param partialJson The partial JSON string from streaming
102
+ * @returns Parsed object or empty object if parsing fails
103
+ */
104
+ export function parseStreamingJson<T = Record<string, unknown>>(partialJson: string | undefined): T {
105
+ if (!partialJson || partialJson.trim() === "") {
106
+ return {} as T;
107
+ }
108
+
109
+ try {
110
+ return parseJsonWithRepair<T>(partialJson);
111
+ } catch {
112
+ try {
113
+ const result = partialParse(partialJson);
114
+ return (result ?? {}) as T;
115
+ } catch {
116
+ try {
117
+ const result = partialParse(repairJson(partialJson));
118
+ return (result ?? {}) as T;
119
+ } catch {
120
+ return {} as T;
121
+ }
122
+ }
123
+ }
124
+ }
@@ -1,13 +1,10 @@
1
1
  import {
2
2
  type Api,
3
+ type AssistantMessageEventStream as HostAssistantMessageEventStream,
3
4
  type AssistantMessage,
4
- type AssistantMessageEventStream,
5
- createAssistantMessageEventStream,
6
- type Context,
7
5
  type ImageContent,
8
6
  type Message,
9
7
  type Model,
10
- parseStreamingJson,
11
8
  type SimpleStreamOptions,
12
9
  type StopReason,
13
10
  type TextContent,
@@ -15,7 +12,11 @@ import {
15
12
  type Tool,
16
13
  type ToolCall,
17
14
  type ToolResultMessage,
15
+ type TranscriptContext,
18
16
  } from "@earendil-works/pi-ai";
17
+ import { type AssistantMessageEventStream, createAssistantMessageEventStream } from "./eventStream.ts";
18
+ import { hostSystemPrompt, hostTools } from "./hostContext.ts";
19
+ import { parseStreamingJson } from "./jsonParse.ts";
19
20
  import { messages as sdkMessages, native } from "@valni/switchboard";
20
21
 
21
22
  const SSE_DATA_PREFIX = "data:";
@@ -111,6 +112,7 @@ export function normalizeContextMessages(model: Model<KnownApi>, contextMessages
111
112
 
112
113
  const transformed: Message[] = [];
113
114
  for (const message of imageAware) {
115
+ if (message.role === "system") continue;
114
116
  if (message.role === "user") {
115
117
  transformed.push(message);
116
118
  continue;
@@ -246,14 +248,16 @@ function chatUserParts(content: (TextContent | ImageContent)[]): sdkMessages.Par
246
248
 
247
249
  function buildOpenAIChatRequest(
248
250
  model: Model<KnownApi>,
249
- context: Context,
251
+ context: TranscriptContext,
250
252
  options: SimpleStreamOptions | undefined,
251
253
  ): native.OpenAIChatRequest {
252
254
  const normalized = normalizeContextMessages(model, context.messages);
253
255
  const requestMessages: sdkMessages.Message[] = [];
256
+ const systemPrompt = hostSystemPrompt(context);
257
+ const tools = hostTools(context);
254
258
 
255
- if (context.systemPrompt) {
256
- requestMessages.push(sdkMessages.Message.system(sanitizeText(context.systemPrompt)));
259
+ if (systemPrompt) {
260
+ requestMessages.push(sdkMessages.Message.system(sanitizeText(systemPrompt)));
257
261
  }
258
262
 
259
263
  for (let index = 0; index < normalized.length; index++) {
@@ -320,7 +324,7 @@ function buildOpenAIChatRequest(
320
324
  messages: requestMessages,
321
325
  max_tokens: resolveMaxTokens(model, options),
322
326
  temperature: options?.temperature ?? null,
323
- tools: context.tools && context.tools.length > 0 ? context.tools.map((tool) => new JsonSchemaTool(tool)) : null,
327
+ tools: tools.length > 0 ? tools.map((tool) => new JsonSchemaTool(tool)) : null,
324
328
  reasoning_effort: reasoningLevel ?? null,
325
329
  });
326
330
  }
@@ -520,9 +524,9 @@ function completionsUrl(baseUrl: string): string {
520
524
 
521
525
  export function streamLocalModel(
522
526
  model: Model<Api>,
523
- context: Context,
527
+ context: TranscriptContext,
524
528
  options?: SimpleStreamOptions,
525
- ): AssistantMessageEventStream {
529
+ ): HostAssistantMessageEventStream {
526
530
  const stream = createAssistantMessageEventStream();
527
531
 
528
532
  (async () => {
@@ -579,7 +583,7 @@ export function streamLocalModel(
579
583
  }
580
584
 
581
585
  if (options?.signal?.aborted) throw new Error("Request was aborted");
582
- if (output.stopReason === "aborted" || output.stopReason === "error") {
586
+ if (output.stopReason === "aborted" || output.stopReason === "error" || output.stopReason === "pending") {
583
587
  throw new Error(output.errorMessage || "An unknown error occurred");
584
588
  }
585
589
  if (!state.sawTerminalEvent) throw new Error("The stream ended before a terminal event");
@@ -598,5 +602,9 @@ export function streamLocalModel(
598
602
  }
599
603
  })();
600
604
 
601
- return stream;
605
+ // The host's stream type has private members, so only its own class satisfies
606
+ // it nominally. The object here is the same shape and the host only iterates
607
+ // it, so the cast sits at this one boundary rather than importing the host's
608
+ // constructor and naming its package at runtime.
609
+ return stream as unknown as HostAssistantMessageEventStream;
602
610
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard-local",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "Local models in the pi model picker, managed end to end",
6
6
  "keywords": [
@@ -24,11 +24,12 @@
24
24
  ]
25
25
  },
26
26
  "dependencies": {
27
- "@valni/switchboard": "git+https://github.com/Valni-Labs/switchboard-ts.git#d132540a1fd86491ffabb9327ec38bb903f709a3"
27
+ "@valni/switchboard": "git+https://github.com/Valni-Labs/switchboard-ts.git#d132540a1fd86491ffabb9327ec38bb903f709a3",
28
+ "partial-json": "0.1.7"
28
29
  },
29
30
  "devDependencies": {
30
- "@earendil-works/pi-ai": "0.82.1",
31
- "@earendil-works/pi-coding-agent": "0.82.1",
31
+ "@earendil-works/pi-ai": ">=1.0.0",
32
+ "@earendil-works/pi-coding-agent": ">=1.0.0",
32
33
  "typescript": "5.9.3"
33
34
  }
34
35
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@valni/cli",
3
3
  "private": true,
4
- "version": "0.1.5",
4
+ "version": "0.1.6",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "type": "module",
7
7
  "valniConfig": {
@@ -38,11 +38,11 @@
38
38
  "prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
39
39
  },
40
40
  "dependencies": {
41
- "@valni/agent-core": "^0.1.5",
42
- "@valni/ai": "^0.1.5",
43
- "@valni/tui": "^0.1.5",
44
- "pi-switchboard": "git+https://github.com/Valni-Labs/pi-switchboard.git#b35310164e79b3f99bfd697622527a8458e1719d",
45
- "switchboard-local": "git+https://github.com/Valni-Labs/switchboard-local.git#bda14d2d85735da4519f4545b598b4c5e97e7d3b",
41
+ "@valni/agent-core": "^0.1.6",
42
+ "@valni/ai": "^0.1.6",
43
+ "@valni/tui": "^0.1.6",
44
+ "pi-switchboard": "git+https://github.com/Valni-Labs/pi-switchboard.git#774f1a7985a755fcd483313b729864aa8a9418c3",
45
+ "switchboard-local": "git+https://github.com/Valni-Labs/switchboard-local.git#4ec07263591a4f329fd12eab04d62d6c455be666",
46
46
  "@silvia-odwyer/photon-node": "0.3.4",
47
47
  "chalk": "5.6.2",
48
48
  "cross-spawn": "7.0.6",
package/runtime/valni CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/runtime/valni
3
3
  size: 76058832 bytes
4
- sha256: 9b45d462f5ec1584ac199c4d4056aae97d26bccca546f0040de9724ea86984b1
4
+ sha256: e2d416ce62acfeec49e80bdf551316c4807ffbb0a37d09d90a096919a4284b54