@skydiveai/pi-server 0.1.0-beta.2978 → 0.1.0-beta.3016

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.
Files changed (2) hide show
  1. package/dist/index.mjs +17 -2
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1803,6 +1803,20 @@ function messageTimestampMs(m) {
1803
1803
  const ts = m?.timestamp;
1804
1804
  return typeof ts === "number" && Number.isFinite(ts) ? ts : null;
1805
1805
  }
1806
+ /**
1807
+ * Drop assistant messages recorded as failed model calls (stopReason 'error')
1808
+ * from the session-trailer slice. pi keeps an aborted attempt in the session
1809
+ * when auto-retry re-runs the model call in place, so a recovered turn carries
1810
+ * both the errored attempt and the successful retry. The trailer is only built
1811
+ * on the clean path -- a turn that exhausts its retries fails and never emits
1812
+ * one -- so any stopReason 'error' assistant message in the slice is an
1813
+ * aborted attempt the retry replaced, not a message downstream should join.
1814
+ * A user abort ('aborted') is a cancel, not a retried provider failure, and is
1815
+ * kept, matching the terminal-error capture above.
1816
+ */
1817
+ function dropAbortedModelAttempts(messages) {
1818
+ return messages.filter((m) => !(m?.role === "assistant" && m.stopReason === "error" && m.errorMessage !== "aborted"));
1819
+ }
1806
1820
  function piMessagesToOpenAI(messages) {
1807
1821
  const out = [];
1808
1822
  for (const m of messages) {
@@ -2248,7 +2262,8 @@ function runStream$1({ session, sm, prompt, images, sessionId, created, reqStart
2248
2262
  });
2249
2263
  }
2250
2264
  function emitSessionMessagesTrailer({ writer, sm, baselineMessageCount, sessionId, created, usage }) {
2251
- const sessionMessages = piMessagesToOpenAI(sm.buildSessionContext().messages.slice(baselineMessageCount));
2265
+ const all = sm.buildSessionContext().messages;
2266
+ const sessionMessages = piMessagesToOpenAI(dropAbortedModelAttempts(all.slice(baselineMessageCount)));
2252
2267
  if (sessionMessages.length === 0 && !usage) return;
2253
2268
  const chunk = {
2254
2269
  id: sessionId,
@@ -2371,7 +2386,7 @@ async function runBlocking$1({ session, sm, prompt, images, sessionId, created,
2371
2386
  };
2372
2387
  if (toolCalls.length) message.tool_calls = toolCalls;
2373
2388
  const all = sm.buildSessionContext().messages;
2374
- const sessionMessages = piMessagesToOpenAI(all.slice(baselineMessageCount));
2389
+ const sessionMessages = piMessagesToOpenAI(dropAbortedModelAttempts(all.slice(baselineMessageCount)));
2375
2390
  const response = {
2376
2391
  id: sessionId,
2377
2392
  object: "chat.completion",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skydiveai/pi-server",
3
- "version": "0.1.0-beta.2978",
3
+ "version": "0.1.0-beta.3016",
4
4
  "homepage": "https://skydive.com",
5
5
  "license": "MIT",
6
6
  "author": "Create, Inc.",