@skydiveai/pi-server 0.1.0-beta.6 → 0.1.0-beta.766

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/index.d.mts CHANGED
@@ -244,17 +244,17 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
244
244
  high: z.ZodOptional<z.ZodNullable<z.ZodString>>;
245
245
  xhigh: z.ZodOptional<z.ZodNullable<z.ZodString>>;
246
246
  }, "strip", z.ZodTypeAny, {
247
- medium?: string | null | undefined;
248
247
  off?: string | null | undefined;
249
248
  minimal?: string | null | undefined;
250
249
  low?: string | null | undefined;
250
+ medium?: string | null | undefined;
251
251
  high?: string | null | undefined;
252
252
  xhigh?: string | null | undefined;
253
253
  }, {
254
- medium?: string | null | undefined;
255
254
  off?: string | null | undefined;
256
255
  minimal?: string | null | undefined;
257
256
  low?: string | null | undefined;
257
+ medium?: string | null | undefined;
258
258
  high?: string | null | undefined;
259
259
  xhigh?: string | null | undefined;
260
260
  }>>;
@@ -272,7 +272,7 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
272
272
  api: "openai-completions";
273
273
  id: string;
274
274
  name: string;
275
- provider: "anthropic" | "amazon-bedrock" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
275
+ provider: "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
276
276
  baseUrl: string;
277
277
  reasoning: boolean;
278
278
  input: ["text" | "image", ...("text" | "image")[]];
@@ -287,10 +287,10 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
287
287
  cacheControlFormat?: "anthropic" | undefined;
288
288
  } | undefined;
289
289
  thinkingLevelMap?: {
290
- medium?: string | null | undefined;
291
290
  off?: string | null | undefined;
292
291
  minimal?: string | null | undefined;
293
292
  low?: string | null | undefined;
293
+ medium?: string | null | undefined;
294
294
  high?: string | null | undefined;
295
295
  xhigh?: string | null | undefined;
296
296
  } | undefined;
@@ -299,7 +299,7 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
299
299
  api: "openai-completions";
300
300
  id: string;
301
301
  name: string;
302
- provider: "anthropic" | "amazon-bedrock" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
302
+ provider: "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
303
303
  baseUrl: string;
304
304
  reasoning: boolean;
305
305
  input: ["text" | "image", ...("text" | "image")[]];
@@ -314,10 +314,10 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
314
314
  cacheControlFormat?: "anthropic" | undefined;
315
315
  } | undefined;
316
316
  thinkingLevelMap?: {
317
- medium?: string | null | undefined;
318
317
  off?: string | null | undefined;
319
318
  minimal?: string | null | undefined;
320
319
  low?: string | null | undefined;
320
+ medium?: string | null | undefined;
321
321
  high?: string | null | undefined;
322
322
  xhigh?: string | null | undefined;
323
323
  } | undefined;
@@ -347,17 +347,17 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
347
347
  high: z.ZodOptional<z.ZodNullable<z.ZodString>>;
348
348
  xhigh: z.ZodOptional<z.ZodNullable<z.ZodString>>;
349
349
  }, "strip", z.ZodTypeAny, {
350
- medium?: string | null | undefined;
351
350
  off?: string | null | undefined;
352
351
  minimal?: string | null | undefined;
353
352
  low?: string | null | undefined;
353
+ medium?: string | null | undefined;
354
354
  high?: string | null | undefined;
355
355
  xhigh?: string | null | undefined;
356
356
  }, {
357
- medium?: string | null | undefined;
358
357
  off?: string | null | undefined;
359
358
  minimal?: string | null | undefined;
360
359
  low?: string | null | undefined;
360
+ medium?: string | null | undefined;
361
361
  high?: string | null | undefined;
362
362
  xhigh?: string | null | undefined;
363
363
  }>>;
@@ -375,7 +375,7 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
375
375
  api: "anthropic-messages";
376
376
  id: string;
377
377
  name: string;
378
- provider: "anthropic" | "amazon-bedrock" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
378
+ provider: "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
379
379
  baseUrl: string;
380
380
  reasoning: boolean;
381
381
  input: ["text" | "image", ...("text" | "image")[]];
@@ -386,10 +386,10 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
386
386
  supportsLongCacheRetention?: boolean | undefined;
387
387
  } | undefined;
388
388
  thinkingLevelMap?: {
389
- medium?: string | null | undefined;
390
389
  off?: string | null | undefined;
391
390
  minimal?: string | null | undefined;
392
391
  low?: string | null | undefined;
392
+ medium?: string | null | undefined;
393
393
  high?: string | null | undefined;
394
394
  xhigh?: string | null | undefined;
395
395
  } | undefined;
@@ -398,7 +398,7 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
398
398
  api: "anthropic-messages";
399
399
  id: string;
400
400
  name: string;
401
- provider: "anthropic" | "amazon-bedrock" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
401
+ provider: "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
402
402
  baseUrl: string;
403
403
  reasoning: boolean;
404
404
  input: ["text" | "image", ...("text" | "image")[]];
@@ -409,10 +409,10 @@ declare const modelSpecSchema: z.ZodDiscriminatedUnion<"api", [z.ZodObject<{
409
409
  supportsLongCacheRetention?: boolean | undefined;
410
410
  } | undefined;
411
411
  thinkingLevelMap?: {
412
- medium?: string | null | undefined;
413
412
  off?: string | null | undefined;
414
413
  minimal?: string | null | undefined;
415
414
  low?: string | null | undefined;
415
+ medium?: string | null | undefined;
416
416
  high?: string | null | undefined;
417
417
  xhigh?: string | null | undefined;
418
418
  } | undefined;
@@ -445,16 +445,16 @@ declare function buildModelFromSpec(spec: ModelSpec): {
445
445
  contextWindow: number;
446
446
  maxTokens: number;
447
447
  thinkingLevelMap?: {
448
- medium?: string | null | undefined;
449
448
  off?: string | null | undefined;
450
449
  minimal?: string | null | undefined;
451
450
  low?: string | null | undefined;
451
+ medium?: string | null | undefined;
452
452
  high?: string | null | undefined;
453
453
  xhigh?: string | null | undefined;
454
454
  } | undefined;
455
455
  id: string;
456
456
  name: string;
457
- provider: "anthropic" | "amazon-bedrock" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
457
+ provider: "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
458
458
  baseUrl: string;
459
459
  reasoning: boolean;
460
460
  } | {
@@ -473,16 +473,16 @@ declare function buildModelFromSpec(spec: ModelSpec): {
473
473
  contextWindow: number;
474
474
  maxTokens: number;
475
475
  thinkingLevelMap?: {
476
- medium?: string | null | undefined;
477
476
  off?: string | null | undefined;
478
477
  minimal?: string | null | undefined;
479
478
  low?: string | null | undefined;
479
+ medium?: string | null | undefined;
480
480
  high?: string | null | undefined;
481
481
  xhigh?: string | null | undefined;
482
482
  } | undefined;
483
483
  id: string;
484
484
  name: string;
485
- provider: "anthropic" | "amazon-bedrock" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
485
+ provider: "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "opencode" | "opencode-go" | "kimi-coding" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
486
486
  baseUrl: string;
487
487
  reasoning: boolean;
488
488
  };
@@ -542,4 +542,27 @@ declare function getCurrentTraceparent(): string | null;
542
542
  /** Extract the trace id (second segment) from a `traceparent` value. */
543
543
  declare function parseTraceId(traceparent: string | null): string | null;
544
544
  //#endregion
545
- export { type A2AOptions, type AnthropicMessagesOptions, type ChatCompletionsOptions, type CreateSessionArgs, DEFAULT_MODEL, DEFAULT_PROVIDER, DEFAULT_THINKING_LEVEL, KNOWN_PI_PROVIDERS, type Middleware, type ModelSpec, PI_AGENT_DIR, type PostPromptCallback, type ProtocolHandler, type ProtocolsOptions, type ResponsesOptions, type SessionFactory, type SessionSetupCallback, type TraceContext, VALID_THINKING_LEVELS, type WebHandler, buildAgentCard, buildModelFromSpec, chainMiddleware, composeHandlers, createAgentExecutor, createMapSessionRegistry, createPrewarm, createProtocolHandlers, createProtocols, deriveTraceContext, getCurrentTraceparent, logger, modelSpecSchema, mountAt, newTraceContext, parseModelSpec, parseTraceId, requestHeaders, requestLogger, requestUrl, resolveRequestModel, runInTraceContext, setCurrentTraceparent, webHandlerToMiddleware, withSpecApiKey };
545
+ //#region src/billing-blocked-provider-signal.d.ts
546
+ /**
547
+ * Duplicated from the billing gate's `BlockReason` (apps/anyone/billing
548
+ * gate/block-reason.ts): pi-server runs inside the sandbox and must not
549
+ * depend on platform packages. A reason the proxy sends that predates this
550
+ * build fails the enum and degrades to the untyped `billing_blocked`
551
+ * handling — never a crash. Exported so agent-lifecycle's chat.test.ts can
552
+ * pin this copy against its own (which billing's block-reason.test.ts in
553
+ * turn pins against the gate), keeping every copy drift-checked.
554
+ */
555
+ declare const BILLING_BLOCK_REASONS: readonly ["insufficient_balance", "payment_failed", "hard_spend_limit_reached"];
556
+ declare const payloadSchema: z.ZodObject<{
557
+ blockReason: z.ZodEnum<["insufficient_balance", "payment_failed", "hard_spend_limit_reached"]>;
558
+ message: z.ZodString;
559
+ }, "strict", z.ZodTypeAny, {
560
+ blockReason: "insufficient_balance" | "payment_failed" | "hard_spend_limit_reached";
561
+ message: string;
562
+ }, {
563
+ blockReason: "insufficient_balance" | "payment_failed" | "hard_spend_limit_reached";
564
+ message: string;
565
+ }>;
566
+ type BillingBlockedProviderSignal = z.infer<typeof payloadSchema>;
567
+ //#endregion
568
+ export { type A2AOptions, type AnthropicMessagesOptions, BILLING_BLOCK_REASONS, type BillingBlockedProviderSignal, type ChatCompletionsOptions, type CreateSessionArgs, DEFAULT_MODEL, DEFAULT_PROVIDER, DEFAULT_THINKING_LEVEL, KNOWN_PI_PROVIDERS, type Middleware, type ModelSpec, PI_AGENT_DIR, type PostPromptCallback, type ProtocolHandler, type ProtocolsOptions, type ResponsesOptions, type SessionFactory, type SessionSetupCallback, type TraceContext, VALID_THINKING_LEVELS, type WebHandler, buildAgentCard, buildModelFromSpec, chainMiddleware, composeHandlers, createAgentExecutor, createMapSessionRegistry, createPrewarm, createProtocolHandlers, createProtocols, deriveTraceContext, getCurrentTraceparent, logger, modelSpecSchema, mountAt, newTraceContext, parseModelSpec, parseTraceId, requestHeaders, requestLogger, requestUrl, resolveRequestModel, runInTraceContext, setCurrentTraceparent, webHandlerToMiddleware, withSpecApiKey };
package/dist/index.mjs CHANGED
@@ -877,6 +877,7 @@ function classifyCode(status, message, code) {
877
877
  if (status === 429 || code === "rate_limit_exceeded" || /rate[_ ]limit|too many requests|resource[_ ]exhausted/i.test(message)) return "rate_limited";
878
878
  if (status === 529 || code === "provider_overloaded" || /overloaded/i.test(message)) return "provider_overloaded";
879
879
  if (status === 503 || status === 504 || code === "provider_unavailable" || /no healthy upstream|upstream request timeout|stream timeout|service unavailable|unavailable|gateway/i.test(message)) return "provider_unavailable";
880
+ if (code === "content_filter" || /finish_reason:\s*content_filter|content[_ ]filter|content[_ ]management[_ ]policy/i.test(message)) return "content_filter";
880
881
  return "provider_error";
881
882
  }
882
883
  /**
@@ -891,7 +892,7 @@ function isModelProviderError(err) {
891
892
  if (numericStatus(e) !== null) return true;
892
893
  if (e.error && typeof e.error === "object") return true;
893
894
  const msg = messageText(err);
894
- return /prompt is too long|context[_ ]length[_ ]exceeded|exceeds maximum token limit|input token count|rate[_ ]limit|overloaded|no healthy upstream|upstream request timeout|insufficient credits|requires more credits|credit balance is too low|payment required|purchase more credits/i.test(msg);
895
+ return /prompt is too long|context[_ ]length[_ ]exceeded|exceeds maximum token limit|input token count|rate[_ ]limit|overloaded|no healthy upstream|upstream request timeout|insufficient credits|requires more credits|credit balance is too low|payment required|purchase more credits|finish_reason:\s*content_filter|content[_ ]filter|content[_ ]management[_ ]policy/i.test(msg);
895
896
  }
896
897
  /** Build the structured, forwardable error from a thrown model-provider error. */
897
898
  function toModelProviderError(err) {
@@ -1379,6 +1380,65 @@ function create$2(options) {
1379
1380
  };
1380
1381
  }
1381
1382
  //#endregion
1383
+ //#region src/billing-blocked-provider-signal.ts
1384
+ const BILLING_BLOCKED_PROVIDER_SIGNAL_PREFIX = "ANYONE_BILLING_BLOCKED_V1:";
1385
+ /**
1386
+ * Duplicated from the billing gate's `BlockReason` (apps/anyone/billing
1387
+ * gate/block-reason.ts): pi-server runs inside the sandbox and must not
1388
+ * depend on platform packages. A reason the proxy sends that predates this
1389
+ * build fails the enum and degrades to the untyped `billing_blocked`
1390
+ * handling — never a crash. Exported so agent-lifecycle's chat.test.ts can
1391
+ * pin this copy against its own (which billing's block-reason.test.ts in
1392
+ * turn pins against the gate), keeping every copy drift-checked.
1393
+ */
1394
+ const BILLING_BLOCK_REASONS = [
1395
+ "insufficient_balance",
1396
+ "payment_failed",
1397
+ "hard_spend_limit_reached"
1398
+ ];
1399
+ const payloadSchema = z.object({
1400
+ blockReason: z.enum(BILLING_BLOCK_REASONS),
1401
+ message: z.string()
1402
+ }).strict();
1403
+ const nestedProxyEnvelopeSchema = z.object({
1404
+ error: z.object({
1405
+ type: z.literal("billing_blocked"),
1406
+ code: z.literal("billing_blocked"),
1407
+ message: z.string()
1408
+ }).strict(),
1409
+ blockReason: z.enum(BILLING_BLOCK_REASONS),
1410
+ message: z.string()
1411
+ }).strict();
1412
+ function parsePrefixedSignal(message) {
1413
+ const normalized = message.startsWith("402 ") ? message.slice(4) : message;
1414
+ if (!normalized.startsWith(BILLING_BLOCKED_PROVIDER_SIGNAL_PREFIX)) return null;
1415
+ try {
1416
+ const parsed = payloadSchema.safeParse(JSON.parse(normalized.slice(26)));
1417
+ return parsed.success ? parsed.data : null;
1418
+ } catch {
1419
+ return null;
1420
+ }
1421
+ }
1422
+ /**
1423
+ * Decode only the versioned platform envelope. Anthropic and OpenAI prefix the
1424
+ * nested error message with HTTP 402. Google's SDK instead preserves the full
1425
+ * proxy response as JSON, so that outer shape is validated separately.
1426
+ */
1427
+ function parseBillingBlockedProviderSignal(message) {
1428
+ const direct = parsePrefixedSignal(message);
1429
+ if (direct) return direct;
1430
+ try {
1431
+ const envelope = nestedProxyEnvelopeSchema.safeParse(JSON.parse(message));
1432
+ if (!envelope.success) return null;
1433
+ const nested = parsePrefixedSignal(envelope.data.error.message);
1434
+ const topLevel = parsePrefixedSignal(envelope.data.message);
1435
+ if (!nested || nested.blockReason !== envelope.data.blockReason || envelope.data.message !== nested.message && (!topLevel || topLevel.blockReason !== nested.blockReason || topLevel.message !== nested.message)) return null;
1436
+ return nested;
1437
+ } catch {
1438
+ return null;
1439
+ }
1440
+ }
1441
+ //#endregion
1382
1442
  //#region src/protocols/chat-completions.ts
1383
1443
  /**
1384
1444
  * OpenAI Chat Completions–compatible protocol handler.
@@ -1605,6 +1665,10 @@ async function loadHistoryIntoSession({ sm, messages, upToIdxExclusive, modelNam
1605
1665
  }
1606
1666
  }
1607
1667
  }
1668
+ function messageTimestampMs(m) {
1669
+ const ts = m?.timestamp;
1670
+ return typeof ts === "number" && Number.isFinite(ts) ? ts : null;
1671
+ }
1608
1672
  function piMessagesToOpenAI(messages) {
1609
1673
  const out = [];
1610
1674
  for (const m of messages) {
@@ -1633,6 +1697,8 @@ function piMessagesToOpenAI(messages) {
1633
1697
  };
1634
1698
  if (toolCalls.length) msg.tool_calls = toolCalls;
1635
1699
  if (thinking.length) msg.x_thinking = thinking;
1700
+ const createdAtMs = messageTimestampMs(m);
1701
+ if (createdAtMs !== null) msg.x_created_at = createdAtMs;
1636
1702
  out.push(msg);
1637
1703
  continue;
1638
1704
  }
@@ -1644,6 +1710,8 @@ function piMessagesToOpenAI(messages) {
1644
1710
  content: text
1645
1711
  };
1646
1712
  if (m.isError) tm.x_is_error = true;
1713
+ const createdAtMs = messageTimestampMs(m);
1714
+ if (createdAtMs !== null) tm.x_created_at = createdAtMs;
1647
1715
  out.push(tm);
1648
1716
  continue;
1649
1717
  }
@@ -1922,6 +1990,22 @@ function runStream$1({ session, sm, prompt, images, sessionId, created, reqStart
1922
1990
  postPrompt
1923
1991
  });
1924
1992
  if (capturedModelError !== null) {
1993
+ const billingBlocked = parseBillingBlockedProviderSignal(capturedModelError);
1994
+ if (billingBlocked) {
1995
+ log.warn({
1996
+ event: "billing_blocked",
1997
+ chatcmpl_id: sessionId,
1998
+ source: "stop_reason_error"
1999
+ }, "forwarding platform billing block to client");
2000
+ emitBillingBlocked({
2001
+ writer,
2002
+ sessionId,
2003
+ created,
2004
+ billingBlocked
2005
+ });
2006
+ writer.write("data: [DONE]\n\n");
2007
+ return;
2008
+ }
1925
2009
  const providerError = toModelProviderError(new Error(capturedModelError));
1926
2010
  log.warn({
1927
2011
  event: "model_provider_error",
@@ -1957,6 +2041,17 @@ function runStream$1({ session, sm, prompt, images, sessionId, created, reqStart
1957
2041
  err
1958
2042
  }, "chat error");
1959
2043
  if (isModelProviderError(err)) {
2044
+ const billingBlocked = parseBillingBlockedProviderSignal(err instanceof Error ? err.message : String(err));
2045
+ if (billingBlocked) {
2046
+ emitBillingBlocked({
2047
+ writer,
2048
+ sessionId,
2049
+ created,
2050
+ billingBlocked
2051
+ });
2052
+ writer.write("data: [DONE]\n\n");
2053
+ return;
2054
+ }
1960
2055
  const providerError = toModelProviderError(err);
1961
2056
  log.warn({
1962
2057
  event: "model_provider_error",
@@ -2030,6 +2125,23 @@ function emitModelProviderError({ writer, sessionId, created, providerError }) {
2030
2125
  };
2031
2126
  writer.write(`data: ${JSON.stringify(chunk)}\n\n`);
2032
2127
  }
2128
+ function emitBillingBlocked({ writer, sessionId, created, billingBlocked }) {
2129
+ const chunk = {
2130
+ id: sessionId,
2131
+ object: "chat.completion.chunk",
2132
+ created,
2133
+ choices: [{
2134
+ index: 0,
2135
+ delta: {},
2136
+ finish_reason: "stop"
2137
+ }],
2138
+ x_billing_blocked: {
2139
+ block_reason: billingBlocked.blockReason,
2140
+ message: billingBlocked.message
2141
+ }
2142
+ };
2143
+ writer.write(`data: ${JSON.stringify(chunk)}\n\n`);
2144
+ }
2033
2145
  async function runBlocking$1({ session, sm, prompt, images, sessionId, created, reqStart, upstreamStartMs, log, postPrompt, registry, pendingSteerIds }) {
2034
2146
  const baselineMessageCount = sm.buildSessionContext().messages.length;
2035
2147
  let content = "";
@@ -2851,4 +2963,4 @@ function chainMiddleware(middlewares) {
2851
2963
  };
2852
2964
  }
2853
2965
  //#endregion
2854
- export { DEFAULT_MODEL, DEFAULT_PROVIDER, DEFAULT_THINKING_LEVEL, KNOWN_PI_PROVIDERS, PI_AGENT_DIR, VALID_THINKING_LEVELS, buildAgentCard, buildModelFromSpec, chainMiddleware, composeHandlers, createAgentExecutor, createMapSessionRegistry, createPrewarm, createProtocolHandlers, createProtocols, deriveTraceContext, getCurrentTraceparent, logger, modelSpecSchema, mountAt, newTraceContext, parseModelSpec, parseTraceId, requestHeaders, requestLogger, requestUrl, resolveRequestModel, runInTraceContext, setCurrentTraceparent, webHandlerToMiddleware, withSpecApiKey };
2966
+ export { BILLING_BLOCK_REASONS, DEFAULT_MODEL, DEFAULT_PROVIDER, DEFAULT_THINKING_LEVEL, KNOWN_PI_PROVIDERS, PI_AGENT_DIR, VALID_THINKING_LEVELS, buildAgentCard, buildModelFromSpec, chainMiddleware, composeHandlers, createAgentExecutor, createMapSessionRegistry, createPrewarm, createProtocolHandlers, createProtocols, deriveTraceContext, getCurrentTraceparent, logger, modelSpecSchema, mountAt, newTraceContext, parseModelSpec, parseTraceId, requestHeaders, requestLogger, requestUrl, resolveRequestModel, runInTraceContext, setCurrentTraceparent, webHandlerToMiddleware, withSpecApiKey };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skydiveai/pi-server",
3
- "version": "0.1.0-beta.6",
3
+ "version": "0.1.0-beta.766",
4
4
  "homepage": "https://skydive.com",
5
5
  "license": "MIT",
6
6
  "author": "Create, Inc.",
@@ -16,13 +16,13 @@
16
16
  }
17
17
  },
18
18
  "publishConfig": {
19
- "access": "public",
20
19
  "exports": {
21
20
  ".": {
22
21
  "types": "./dist/index.d.mts",
23
22
  "default": "./dist/index.mjs"
24
23
  }
25
24
  },
25
+ "access": "public",
26
26
  "registry": "https://registry.npmjs.org"
27
27
  },
28
28
  "scripts": {