@code-yeongyu/senpi-agent-core 2026.10.26-2 → 2026.10.27-2

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.
@@ -535,6 +535,7 @@ async function streamAssistantResponse(context, config, signal, emit, streamFunc
535
535
  await emit(carryAssistantCapture(event, {
536
536
  type: "message_start",
537
537
  message: { ...partialMessage },
538
+ streaming: true,
538
539
  }));
539
540
  break;
540
541
  case "text_start":
package/dist/agent.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readProviderDiagnostic, sanitizeProviderDiagnostic, } from "@earendil-works/pi-ai";
1
+ import { readProviderDiagnostic, sanitizeProviderDiagnostic, sanitizeProviderErrorMessage, } from "@earendil-works/pi-ai";
2
2
  import { buildProviderContext as buildProviderContextFromAgentContext, runAgentLoop, runAgentLoopContinue, } from "./agent-loop.js";
3
3
  import { ProviderRetryWatchdogAbortError } from "./assistant-terminal-state.js";
4
4
  import { dispatchInternalAgent, internalLoopSink, } from "./internal-events.js";
@@ -600,6 +600,8 @@ export class Agent {
600
600
  ...(!aborted && isLocalFailure(error) ? { failureSource: "local" } : {}),
601
601
  timestamp: Date.now(),
602
602
  };
603
+ // A thrown provider error never passed the stream boundary: classify and redact it the same way (senpi#4282).
604
+ sanitizeProviderErrorMessage(failureMessage);
603
605
  await this.processEvents({ type: "message_start", message: failureMessage });
604
606
  await this.processEvents({ type: "message_end", message: failureMessage });
605
607
  await this.processEvents({ type: "turn_end", message: failureMessage, toolResults: [] });
@@ -1,4 +1,4 @@
1
- import { isClassifierRefusal, isCursorExecResolved, readProviderDiagnostic, } from "@earendil-works/pi-ai";
1
+ import { isClassifierRefusal, isCursorExecResolved, readProviderDiagnostic, sanitizeProviderErrorMessage, } from "@earendil-works/pi-ai";
2
2
  import { isOAuthRefreshUnavailableError } from "@earendil-works/pi-ai/utils/oauth-refresh-error";
3
3
  import { OAUTH_REFRESH_UNAVAILABLE_DIAGNOSTIC } from "@earendil-works/pi-ai/utils/retry";
4
4
  const EMPTY_USAGE = {
@@ -69,7 +69,7 @@ export function shouldFinalizeIdleAsStop(partialMessage, providerToolResults) {
69
69
  export function createTerminalFailureAssistantMessage(model, reason, error, partialMessage) {
70
70
  const errorMessage = error instanceof Error ? error.message : String(error);
71
71
  const providerDiagnostic = reason === "error" ? readProviderDiagnostic(error) : undefined;
72
- return {
72
+ const message = {
73
73
  role: "assistant",
74
74
  content: partialMessage?.content ?? [{ type: "text", text: "" }],
75
75
  api: partialMessage?.api ?? model.api,
@@ -94,6 +94,9 @@ export function createTerminalFailureAssistantMessage(model, reason, error, part
94
94
  ...(error instanceof ProviderRetryWatchdogAbortError ? { abortSource: "provider" } : {}),
95
95
  timestamp: partialMessage?.timestamp ?? Date.now(),
96
96
  };
97
+ // A thrown provider error never passed the stream boundary: classify and redact it the same way (senpi#4282).
98
+ sanitizeProviderErrorMessage(message);
99
+ return message;
97
100
  }
98
101
  export function normalizeTerminalAssistantMessage(message, event) {
99
102
  if (event.type === "done")
@@ -1,4 +1,4 @@
1
- import { AssistantMessageFrameEncoder, isRetryableAssistantError } from "@earendil-works/pi-ai";
1
+ import { AssistantMessageFrameEncoder, isRetryableAssistantError, sanitizeProviderErrorMessage, } from "@earendil-works/pi-ai";
2
2
  import { estimateContextTokens } from "@earendil-works/pi-ai/utils/estimate";
3
3
  import { planManagedEntry, prepareDraft, sameSnapshot, takeSnapshot } from "../system.js";
4
4
  import { toStored, } from "../types.js";
@@ -291,6 +291,8 @@ async function stream(cp, model, messages, rt, ctx) {
291
291
  errorMessage: String(error),
292
292
  timestamp: rt.now(),
293
293
  };
294
+ // A thrown provider error never passed the stream boundary: classify and redact it the same way (senpi#4282).
295
+ sanitizeProviderErrorMessage(terminal);
294
296
  }
295
297
  if (pending.length > 0)
296
298
  await flush();
@@ -1,3 +1,4 @@
1
+ /** Internal to senpi packages; not a public API; may change without notice. */
1
2
  import { type AssistantProgress } from "@earendil-works/pi-ai";
2
3
  import type { AgentEvent, AgentLoopConfig } from "./types.ts";
3
4
  export declare const internalProgressSink: unique symbol;
@@ -1,3 +1,4 @@
1
+ /** Internal to senpi packages; not a public API; may change without notice. */
1
2
  import { subscribeAssistantCapture } from "@earendil-works/pi-ai";
2
3
  export const internalProgressSink = Symbol("internalProgressSink");
3
4
  const channels = new WeakMap();
package/dist/types.d.ts CHANGED
@@ -546,6 +546,7 @@ export type AgentEvent = {
546
546
  } | {
547
547
  type: "message_start";
548
548
  message: AgentMessage;
549
+ streaming?: true;
549
550
  } | {
550
551
  type: "message_update";
551
552
  message: AgentMessage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-agent-core",
3
- "version": "2026.10.26-2",
3
+ "version": "2026.10.27-2",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -62,8 +62,8 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@earendil-works/chord": "0.99.1",
65
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.26-2",
66
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.26-2",
65
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.27-2",
66
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.27-2",
67
67
  "diff": "9.0.0",
68
68
  "ignore": "7.0.9",
69
69
  "typebox": "1.3.34",