@code-yeongyu/senpi 2026.10.26-1 → 2026.10.27-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/CHANGELOG.md +39 -0
- package/dist/bundle/chunks/{anthropic-messages-M235FJQV.js → anthropic-messages-ODSFJCXR.js} +1 -1
- package/dist/bundle/chunks/{args-FBNJOJSR.js → args-SWKJAYQD.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-YQRTQ7H6.js → azure-openai-responses-REGXS4XO.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/{chunk-DMFAVE5N.js → chunk-4QVORFQ2.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZXHLH4MW.js → chunk-5W3DTM2J.js} +1 -1
- package/dist/bundle/chunks/{chunk-QYFOHFPS.js → chunk-6CJC6JY4.js} +1 -1
- package/dist/bundle/chunks/{chunk-QREKAXKX.js → chunk-6GAMRAVM.js} +5 -5
- package/dist/bundle/chunks/{chunk-MSHRIZGT.js → chunk-7IZH2KQX.js} +3 -3
- package/dist/bundle/chunks/{chunk-PH3JDRB2.js → chunk-ARSENVDY.js} +1 -1
- package/dist/bundle/chunks/{chunk-5KZH6EYQ.js → chunk-CNDPCYNT.js} +1 -1
- package/dist/bundle/chunks/{chunk-DYWIFF2Q.js → chunk-CYOHFREV.js} +1 -1
- package/dist/bundle/chunks/{chunk-3LPWILUZ.js → chunk-DNDZPKIQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZLIVZQDY.js → chunk-EQNUL2WB.js} +1 -1
- package/dist/bundle/chunks/{chunk-LO5MYLGF.js → chunk-FQDARFHT.js} +1 -1
- package/dist/bundle/chunks/{chunk-7KOUQSBX.js → chunk-GPPOPK76.js} +3 -3
- package/dist/bundle/chunks/{chunk-I7QWTWVZ.js → chunk-IHKHCWWG.js} +1 -1
- package/dist/bundle/chunks/{chunk-MY4ZD3EW.js → chunk-IY4G44MN.js} +1 -1
- package/dist/bundle/chunks/{chunk-OQ3WDMB3.js → chunk-JH7MVRNJ.js} +1 -1
- package/dist/bundle/chunks/chunk-KBSFTXAT.js +2 -0
- package/dist/bundle/chunks/{chunk-UW6M3EXY.js → chunk-KRO63T4Q.js} +1 -1
- package/dist/bundle/chunks/{chunk-J5FCH7TI.js → chunk-KTDIIF2F.js} +1 -1
- package/dist/bundle/chunks/{chunk-3WP5RFQR.js → chunk-NDNIMC5W.js} +1 -1
- package/dist/bundle/chunks/chunk-NXQFBAUI.js +2 -0
- package/dist/bundle/chunks/{chunk-CDQPA4FP.js → chunk-ODRGPC5S.js} +1 -1
- package/dist/bundle/chunks/{chunk-5FQMNHXV.js → chunk-P5E4EVQF.js} +1 -1
- package/dist/bundle/chunks/{chunk-3A3XCLNH.js → chunk-PDG4XWO2.js} +1 -1
- package/dist/bundle/chunks/{chunk-5LWUUXMH.js → chunk-PY4ZQHTN.js} +1 -1
- package/dist/bundle/chunks/chunk-Q2A2V6NT.js +5 -0
- package/dist/bundle/chunks/{chunk-SOXQ42VS.js → chunk-RQ5JTXUC.js} +1 -1
- package/dist/bundle/chunks/{chunk-JPGT64RV.js → chunk-TV3UI63P.js} +1 -1
- package/dist/bundle/chunks/{chunk-JFQUWEN7.js → chunk-TWHF52G6.js} +4 -4
- package/dist/bundle/chunks/{chunk-6U3TBFBA.js → chunk-UJPG4ROT.js} +1 -1
- package/dist/bundle/chunks/{chunk-UDM7VO6O.js → chunk-XM36IFP3.js} +1 -1
- package/dist/bundle/chunks/{chunk-XQ45JMGN.js → chunk-Z6BREXV3.js} +1 -1
- package/dist/bundle/chunks/chunk-ZAS4NBVK.js +410 -0
- package/dist/bundle/chunks/{chunk-ADQAPDPV.js → chunk-ZP6JJDYV.js} +1 -1
- package/dist/bundle/chunks/{chunk-EZP6AYW2.js → chunk-ZXIAVLJV.js} +88 -88
- package/dist/bundle/chunks/{cli-main-55EQA5PS.js → cli-main-36FRZ7ZB.js} +1 -1
- package/dist/bundle/chunks/client-CBDPMWZJ.js +2 -0
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-ZJQGIIRC.js → cloudflare-workers-ai-system-one-WDHT7BBV.js} +1 -1
- package/dist/bundle/chunks/cursor-agent.js +1 -1
- package/dist/bundle/chunks/devin-agent.js +1 -1
- package/dist/bundle/chunks/{dispatch-C2IBP5VV.js → dispatch-W5PENPZM.js} +3 -3
- package/dist/bundle/chunks/{google-generative-ai-5G4RIQA6.js → google-generative-ai-FHYFXKLA.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-ALD4P27O.js → google-vertex-5DWE5U5K.js} +1 -1
- package/dist/bundle/chunks/{help-fast-path-PEIKGCKZ.js → help-fast-path-FETLIF3W.js} +1 -1
- package/dist/bundle/chunks/{host-command-657VCQ34.js → host-command-XEB7SHT3.js} +1 -1
- package/dist/bundle/chunks/{host-session-command-OV5XDOJK.js → host-session-command-FFN52LXJ.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-MLXSYK2H.js → interactive-mode-5S7NNV2Z.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-RAE4K2XY.js → mistral-conversations-I2PI7DDF.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-774MACJU.js → multi-session-host-E3OPE6HJ.js} +3 -3
- package/dist/bundle/chunks/{openai-codex-responses-3CW4R7TG.js → openai-codex-responses-WSEX6SH7.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-5UIJXQUF.js → openai-completions-YCBHTBSS.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-2BO44MRW.js → openai-responses-GXNSQF4A.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-MZHVCX2S.js → package-manager-cli-3XO456VE.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-RF6GER4R.js → pi-messages-O6GISIRW.js} +1 -1
- package/dist/bundle/chunks/protocol-GLNWYI5G.js +2 -0
- package/dist/bundle/chunks/{role-ETSFSDTS.js → role-SHIZQKK4.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-ZMQB4GPO.js → rotation-stream-2PCZWNKF.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-UJXOIZCW.js → rpc-mode-GLWKLTMA.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-KA7LFFNK.js → schedule-command-B7RRSANU.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-MFWXUR7Z.js → session-control-endpoint-KLE2X4RR.js} +1 -1
- package/dist/bundle/chunks/{session-picker-BP33NRSL.js → session-picker-DTGBOXDR.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +131 -131
- package/dist/bundle/chunks/{typesafe-system-one-GNNZ5O5U.js → typesafe-system-one-XGYJJVSE.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/core/agent-session.d.ts +11 -1
- package/dist/core/agent-session.js +19 -2
- package/dist/core/extensions/builtin/anthropic-subscription/account-context.d.ts +15 -0
- package/dist/core/extensions/builtin/anthropic-subscription/account-context.js +53 -0
- package/dist/core/extensions/builtin/anthropic-subscription/auth-attempt.d.ts +3 -0
- package/dist/core/extensions/builtin/anthropic-subscription/auth-attempt.js +26 -9
- package/dist/core/extensions/builtin/anthropic-subscription/auth-lane-boundary.d.ts +16 -0
- package/dist/core/extensions/builtin/anthropic-subscription/auth-lane-boundary.js +27 -0
- package/dist/core/extensions/builtin/anthropic-subscription/auth-lane.d.ts +2 -13
- package/dist/core/extensions/builtin/anthropic-subscription/auth-lane.js +3 -26
- package/dist/core/extensions/builtin/anthropic-subscription/errors.js +3 -2
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +6 -1
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +1 -1
- package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +13 -2
- package/dist/core/extensions/builtin/compaction/index.js +7 -1
- package/dist/core/extensions/builtin/herdr/index.js +9 -5
- package/dist/core/extensions/builtin/mcp/auth/oauth-issuer.d.ts +6 -0
- package/dist/core/extensions/builtin/mcp/auth/oauth-issuer.js +25 -0
- package/dist/core/extensions/builtin/mcp/auth/oauth-provider.d.ts +3 -3
- package/dist/core/extensions/builtin/mcp/auth/oauth-provider.js +50 -19
- package/dist/core/extensions/builtin/mcp/auth/oauth-refresh.js +4 -3
- package/dist/core/extensions/builtin/mcp/auth/oauth.js +19 -12
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.js +1 -0
- package/dist/core/extensions/builtin/mcp/modern/dispatch.js +1 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.js +33 -35
- package/dist/core/extensions/builtin/mcp/modern/request.js +6 -2
- package/dist/core/extensions/builtin/mcp/modern/transport.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/modern/transport.js +4 -2
- package/dist/core/extensions/builtin/mcp/sdk.lazy.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/sdk.lazy.js +2 -0
- package/dist/core/extensions/builtin/mcp/transport-sdk.js +12 -1
- package/dist/core/extensions/builtin/terminal/extension-state.js +2 -1
- package/dist/core/extensions/builtin/vertex-model-garden/auth.d.ts +9 -0
- package/dist/core/extensions/builtin/vertex-model-garden/auth.js +17 -1
- package/dist/core/extensions/builtin/websearch/websearch/providers/google.d.ts +6 -0
- package/dist/core/extensions/builtin/websearch/websearch/providers/google.js +6 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/lifecycle-children.d.ts +3 -1
- package/dist/core/lifecycle-children.js +79 -15
- package/dist/core/lifecycle-record.js +1 -24
- package/dist/core/lifecycle-session-binding.js +2 -1
- package/dist/core/lifecycle-wait-items.d.ts +17 -0
- package/dist/core/lifecycle-wait-items.js +72 -0
- package/dist/core/model-runtime.js +6 -1
- package/dist/core/provider-api-key-auth.d.ts +6 -1
- package/dist/core/provider-api-key-auth.js +11 -4
- package/dist/core/provider-composer.d.ts +8 -1
- package/dist/core/provider-composer.js +7 -3
- package/dist/core/sdk.js +4 -1
- package/dist/core/session-activity.js +2 -0
- package/dist/core/session-lifecycle-types.d.ts +20 -4
- package/dist/core/session-lifecycle.js +35 -4
- package/dist/core/structured-session-lane.d.ts +33 -0
- package/dist/core/structured-session-lane.js +62 -0
- package/dist/core/work-custody-record.d.ts +2 -1
- package/dist/core/work-custody-record.js +2 -0
- package/dist/core/work-obligations.d.ts +1 -1
- package/dist/core/work-obligations.js +8 -2
- package/dist/modes/interactive/interactive-mode.d.ts +2 -1
- package/dist/modes/interactive/interactive-mode.js +2 -1
- package/dist/modes/json-event.d.ts +79 -1
- package/dist/modes/json-event.js +79 -1
- package/dist/modes/rpc/compact-commit-dependencies.d.ts +13 -0
- package/dist/modes/rpc/compact-commit-dependencies.js +48 -0
- package/dist/modes/rpc/compact-content-index.d.ts +84 -0
- package/dist/modes/rpc/compact-content-index.js +243 -0
- package/dist/modes/rpc/compact-content-store.d.ts +10 -43
- package/dist/modes/rpc/compact-content-store.js +61 -163
- package/dist/modes/rpc/compact-index-pages.d.ts +12 -0
- package/dist/modes/rpc/compact-index-pages.js +31 -0
- package/dist/modes/rpc/compact-read-lease.d.ts +15 -0
- package/dist/modes/rpc/compact-read-lease.js +40 -0
- package/dist/modes/rpc/compact-session-state.d.ts +14 -63
- package/dist/modes/rpc/compact-session-state.js +69 -51
- package/dist/modes/rpc/compact-spool-dir.d.ts +4 -1
- package/dist/modes/rpc/compact-spool-dir.js +41 -8
- package/dist/modes/rpc/compact-spool-storage.d.ts +58 -0
- package/dist/modes/rpc/compact-spool-storage.js +195 -0
- package/dist/modes/rpc/compact-storage-io.d.ts +2 -1
- package/dist/modes/rpc/compact-storage-io.js +7 -1
- package/dist/modes/rpc/compact-text-roots.d.ts +22 -0
- package/dist/modes/rpc/compact-text-roots.js +138 -0
- package/dist/modes/rpc/compact-text-view.d.ts +22 -0
- package/dist/modes/rpc/compact-text-view.js +16 -0
- package/dist/modes/rpc/compact-transition.d.ts +41 -0
- package/dist/modes/rpc/compact-transition.js +12 -0
- package/dist/modes/rpc/connection-handler.d.ts +2 -0
- package/dist/modes/rpc/connection-handler.js +12 -6
- package/dist/modes/rpc/host-ensure-start.js +5 -3
- package/dist/modes/rpc/security-presentations.js +2 -1
- package/dist/modes/rpc/session-binding.js +10 -0
- package/dist/modes/rpc/session-event-writer.d.ts +2 -0
- package/dist/modes/rpc/session-event-writer.js +2 -0
- package/dist/modes/rpc/session-record-stream.d.ts +3 -3
- package/dist/modes/rpc/session-record-stream.js +3 -3
- package/dist/modes/rpc/session-structured-lanes.d.ts +12 -0
- package/dist/modes/rpc/session-structured-lanes.js +24 -0
- package/dist/modes/rpc/session-worker-client.js +6 -5
- package/dist/modes/rpc/structured-session-records.d.ts +12 -0
- package/dist/modes/rpc/structured-session-records.js +88 -0
- package/docs/extensions.md +7 -1
- package/docs/rpc.md +17 -2
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-GQJYNFMO.js +0 -2
- package/dist/bundle/chunks/chunk-VICDRG3J.js +0 -410
- package/dist/bundle/chunks/chunk-VL7O5PO4.js +0 -5
- package/dist/bundle/chunks/client-LOS6GSEW.js +0 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* reads the same records from either.
|
|
8
8
|
*/
|
|
9
9
|
import type { AgentAbortSource } from "../../core/agent-abort-provenance.ts";
|
|
10
|
-
import type { AgentSession } from "../../core/agent-session.ts";
|
|
11
|
-
/** Subscribes `output` to the session's records; returns the unsubscribe. */
|
|
12
|
-
export declare function subscribeSessionRecords(session: AgentSession, output: (record: object) => void, onAbortSource?: (source: AgentAbortSource) => void): () => void;
|
|
10
|
+
import type { AgentSession, AgentSessionEventListener } from "../../core/agent-session.ts";
|
|
11
|
+
/** Subscribes `output` to the session's records (from `source`, by default `session.subscribe`); returns the unsubscribe. */
|
|
12
|
+
export declare function subscribeSessionRecords(session: AgentSession, output: (record: object) => void, onAbortSource?: (source: AgentAbortSource) => void, source?: (listener: AgentSessionEventListener) => () => void): () => void;
|
|
13
13
|
//# sourceMappingURL=session-record-stream.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { clientFacingIdentity } from "./client-admission-record.js";
|
|
2
2
|
import { ClientAdmissions } from "./client-admissions.js";
|
|
3
3
|
import { ClientMessageEvents } from "./client-message-events.js";
|
|
4
|
-
/** Subscribes `output` to the session's records; returns the unsubscribe. */
|
|
5
|
-
export function subscribeSessionRecords(session, output, onAbortSource = () => { }) {
|
|
4
|
+
/** Subscribes `output` to the session's records (from `source`, by default `session.subscribe`); returns the unsubscribe. */
|
|
5
|
+
export function subscribeSessionRecords(session, output, onAbortSource = () => { }, source = (listener) => session.subscribe(listener)) {
|
|
6
6
|
const correlatedEvents = new ClientMessageEvents(output, () => ClientAdmissions.forSession(session).hasIdentities);
|
|
7
|
-
return
|
|
7
|
+
return source((event) => {
|
|
8
8
|
if (event.type === "session_lifecycle") {
|
|
9
9
|
// The connection adds the routing handle; classic stdio has no envelope.
|
|
10
10
|
const { sessionId: _sessionId, ...record } = event;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type StructuredReceiver = (record: object) => void;
|
|
2
|
+
/**
|
|
3
|
+
* Per-session receivers of the internal structured lane (senpi#4272): the host-side owner of seeded records and
|
|
4
|
+
* block controls (S03/S04) registers here. Legacy sockets, stdout and the replay snapshot never read it.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SessionStructuredLanes {
|
|
7
|
+
private readonly receivers;
|
|
8
|
+
observe(sessionId: string, receiver: StructuredReceiver): () => void;
|
|
9
|
+
accept(sessionId: string, record: object): void;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=session-structured-lanes.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session receivers of the internal structured lane (senpi#4272): the host-side owner of seeded records and
|
|
3
|
+
* block controls (S03/S04) registers here. Legacy sockets, stdout and the replay snapshot never read it.
|
|
4
|
+
*/
|
|
5
|
+
export class SessionStructuredLanes {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.receivers = new Map();
|
|
8
|
+
}
|
|
9
|
+
observe(sessionId, receiver) {
|
|
10
|
+
const receivers = this.receivers.get(sessionId) ?? new Set();
|
|
11
|
+
receivers.add(receiver);
|
|
12
|
+
this.receivers.set(sessionId, receivers);
|
|
13
|
+
return () => {
|
|
14
|
+
receivers.delete(receiver);
|
|
15
|
+
if (receivers.size === 0 && this.receivers.get(sessionId) === receivers)
|
|
16
|
+
this.receivers.delete(sessionId);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
accept(sessionId, record) {
|
|
20
|
+
for (const receiver of [...(this.receivers.get(sessionId) ?? [])])
|
|
21
|
+
receiver(record);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=session-structured-lanes.js.map
|
|
@@ -5,6 +5,7 @@ import { ownProcessStartedAtMs } from "../../core/extensions/builtin/terminal/pr
|
|
|
5
5
|
import { isSecurityNoticeState } from "../../core/security-notices.js";
|
|
6
6
|
import { createWebViewBroker } from "../../core/webview/webview-broker.js";
|
|
7
7
|
import { roleConnection } from "./connection-roles.js";
|
|
8
|
+
import { answeredUiRequestId } from "./extension-ui-response.js";
|
|
8
9
|
import { subscriptionLimits } from "../../core/subscription-limits/limit-store.js";
|
|
9
10
|
import { SessionWorkerRequests } from "./session-worker-requests.js";
|
|
10
11
|
import { acknowledge, acknowledgeGrant } from "./session-worker-signals.js";
|
|
@@ -125,11 +126,11 @@ export class SessionWorkerClient {
|
|
|
125
126
|
if (writer.handleMcpForm(command))
|
|
126
127
|
return;
|
|
127
128
|
const connection = writer.currentConnection();
|
|
128
|
-
|
|
129
|
-
command
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
writer.acceptWorkerGrantResponse(sessionId,
|
|
129
|
+
const grantAnswer = "type" in command && command.type === "extension_ui_response"
|
|
130
|
+
? answeredUiRequestId(command)
|
|
131
|
+
: undefined;
|
|
132
|
+
if (grantAnswer !== undefined &&
|
|
133
|
+
writer.acceptWorkerGrantResponse(sessionId, grantAnswer, connection) === false)
|
|
133
134
|
return;
|
|
134
135
|
await this.request({
|
|
135
136
|
type: "command",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentSession } from "../../core/agent-session.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The engine-socket compact-updates rollout flag (`<brand>_ENGINE_SOCKET_COMPACT_UPDATES`), explicit-true only.
|
|
4
|
+
* Off, no session holds a structured subscription and every destination keeps its existing bytes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function structuredLaneEnabled(): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The session's internal structured lane, correlated like its legacy records: seeded `toJsonEvent` projections of
|
|
9
|
+
* every session event plus the three block controls, in session order. Never a legacy destination.
|
|
10
|
+
*/
|
|
11
|
+
export declare function subscribeStructuredSessionRecords(session: AgentSession, output: (record: object) => void): () => void;
|
|
12
|
+
//# sourceMappingURL=structured-session-records.d.ts.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { getAssistantCapture } from "@earendil-works/pi-ai";
|
|
2
|
+
import { envValue } from "../../core/brand.js";
|
|
3
|
+
import { toJsonEvent } from "../json-event.js";
|
|
4
|
+
import { subscribeSessionRecords } from "./session-record-stream.js";
|
|
5
|
+
/**
|
|
6
|
+
* The engine-socket compact-updates rollout flag (`<brand>_ENGINE_SOCKET_COMPACT_UPDATES`), explicit-true only.
|
|
7
|
+
* Off, no session holds a structured subscription and every destination keeps its existing bytes.
|
|
8
|
+
*/
|
|
9
|
+
export function structuredLaneEnabled() {
|
|
10
|
+
const value = envValue("ENGINE_SOCKET_COMPACT_UPDATES");
|
|
11
|
+
return value === "1" || value === "true";
|
|
12
|
+
}
|
|
13
|
+
const SEEDS = { blockSeeds: 1 };
|
|
14
|
+
/**
|
|
15
|
+
* Admits a block's records only after its own seed or insert reached this subscriber, so a subscriber that attached
|
|
16
|
+
* mid-message gets no seed, delta or control for that message, never a wrong one. A started block whose next record
|
|
17
|
+
* has no capture, or that has no accepted end when the message ends, is invalid: its later records are dropped and
|
|
18
|
+
* the assistant `message_end` names it in `invalidatedBlocks`, so a reader rebuilds it from the terminal message.
|
|
19
|
+
* A terminal that rewrote blocks from `rewrittenFrom` on invalidates every block at or above that index, and a
|
|
20
|
+
* `message_end` with no interpretable terminal capture (cancel, idle timeout) invalidates every block of the message.
|
|
21
|
+
* Blocks are addressed by the capture's own index (`capture.contentIndex ?? event.contentIndex`), never a drifted public one.
|
|
22
|
+
*/
|
|
23
|
+
class SeededBlockGate {
|
|
24
|
+
accept(record) {
|
|
25
|
+
if (record.type === "message_block_state" || record.type === "message_block_metadata")
|
|
26
|
+
return this.control(record, record.type === "message_block_state" ? record.phase : undefined);
|
|
27
|
+
if (record.type === "message_tool_arguments_reset")
|
|
28
|
+
return this.control(record);
|
|
29
|
+
if (record.type === "message_start" && record.message.role === "assistant") {
|
|
30
|
+
const seeded = toJsonEvent(record, SEEDS);
|
|
31
|
+
this.blocks = seeded && new Map();
|
|
32
|
+
return seeded;
|
|
33
|
+
}
|
|
34
|
+
if (record.type === "message_end" && record.message.role === "assistant")
|
|
35
|
+
return this.end(record);
|
|
36
|
+
if (record.type !== "message_update")
|
|
37
|
+
return toJsonEvent(record, SEEDS);
|
|
38
|
+
if (!this.blocks)
|
|
39
|
+
return undefined;
|
|
40
|
+
const seeded = toJsonEvent(record, SEEDS);
|
|
41
|
+
const update = record.assistantMessageEvent;
|
|
42
|
+
if (!("contentIndex" in update))
|
|
43
|
+
return seeded;
|
|
44
|
+
const index = getAssistantCapture(record)?.contentIndex ?? update.contentIndex;
|
|
45
|
+
const starts = update.type === "text_start" || update.type === "thinking_start" || update.type === "toolcall_start";
|
|
46
|
+
if (!starts && this.blocks.get(index) !== "open")
|
|
47
|
+
return undefined;
|
|
48
|
+
const ends = update.type === "text_end" || update.type === "thinking_end" || update.type === "toolcall_end";
|
|
49
|
+
this.blocks.set(index, seeded ? (ends ? "ended" : "open") : "invalid");
|
|
50
|
+
return seeded;
|
|
51
|
+
}
|
|
52
|
+
control(record, phase) {
|
|
53
|
+
const state = this.blocks?.get(record.contentIndex);
|
|
54
|
+
if (!this.blocks || state === "invalid")
|
|
55
|
+
return undefined;
|
|
56
|
+
if (phase === "insert")
|
|
57
|
+
this.blocks.set(record.contentIndex, "open");
|
|
58
|
+
else if (state === undefined || (phase === "end" && state !== "open"))
|
|
59
|
+
return undefined;
|
|
60
|
+
else if (phase === "end")
|
|
61
|
+
this.blocks.set(record.contentIndex, "ended");
|
|
62
|
+
return record;
|
|
63
|
+
}
|
|
64
|
+
end(record) {
|
|
65
|
+
const capture = getAssistantCapture(record);
|
|
66
|
+
const rewrittenFrom = capture?.message === undefined ? 0 : (capture.rewrittenFrom ?? Number.POSITIVE_INFINITY);
|
|
67
|
+
const invalidatedBlocks = [...(this.blocks ?? [])].flatMap(([index, state]) => state === "ended" && index < rewrittenFrom ? [] : [index]);
|
|
68
|
+
this.blocks = undefined;
|
|
69
|
+
const seeded = toJsonEvent(record, SEEDS) ?? record;
|
|
70
|
+
return invalidatedBlocks.length === 0
|
|
71
|
+
? seeded
|
|
72
|
+
: { ...seeded, invalidatedBlocks: invalidatedBlocks.sort((a, b) => a - b) };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The session's internal structured lane, correlated like its legacy records: seeded `toJsonEvent` projections of
|
|
77
|
+
* every session event plus the three block controls, in session order. Never a legacy destination.
|
|
78
|
+
*/
|
|
79
|
+
export function subscribeStructuredSessionRecords(session, output) {
|
|
80
|
+
const gate = new SeededBlockGate();
|
|
81
|
+
return subscribeSessionRecords(session, output, undefined, (listener) => session.subscribeStructured((record) => {
|
|
82
|
+
const accepted = gate.accept(record);
|
|
83
|
+
// Correlation reads only `type`, `role` and outer fields, which seeded records and controls keep.
|
|
84
|
+
if (accepted)
|
|
85
|
+
listener(accepted);
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=structured-session-records.js.map
|
package/docs/extensions.md
CHANGED
|
@@ -2170,7 +2170,13 @@ session-notice identity. Restart redelivers unconsumed queued messages once, but
|
|
|
2170
2170
|
never replays a consumed result or reruns an interrupted tool.
|
|
2171
2171
|
|
|
2172
2172
|
`pi.lifecycle.reportChild({ taskId, childSessionId, runEpoch, generation, state,
|
|
2173
|
-
waitingOn?, terminal? })` persists runner-owned child state.
|
|
2173
|
+
label?, since?, waitingOn?, terminal? })` persists runner-owned child state. `label`
|
|
2174
|
+
is a producer-authored name and `since` is the child's own state-entry time (ISO);
|
|
2175
|
+
an unparseable `since` is dropped. `waitingOn` takes the `SessionLifecycle.waitingOn`
|
|
2176
|
+
shape described in [RPC session lifecycle](rpc.md#session-lifecycle), named lists
|
|
2177
|
+
included; its counts stay authoritative and the child's human waits are not kept.
|
|
2178
|
+
A nonterminal report appears in the parent's `waitingOn.childReports` as
|
|
2179
|
+
`{ taskId, childSessionId, runEpoch, state, label?, since? }`. Stale epoch/generation
|
|
2174
2180
|
pairs are ignored; a higher `runEpoch` clears the old terminal status. Terminal
|
|
2175
2181
|
values are `completed`, `error`, `lost`, `interrupted`, and `cancelled`. Child UI
|
|
2176
2182
|
requests remain automatically answered by their runners, not routed to a person.
|
package/docs/rpc.md
CHANGED
|
@@ -145,8 +145,23 @@ The shared `SessionLifecycle` type is exported by `@code-yeongyu/senpi`:
|
|
|
145
145
|
- `seq`, `epoch`, `epochOrigin` (`human` or `automatic`), `humanInputRevision`,
|
|
146
146
|
`selfSettleEligible`, `restoring`, `persisted`, `runPaused`, and `since` (ISO time).
|
|
147
147
|
- `role` (`root` or `child`), `rootSessionId`, and optional `parentSessionId` and `taskId`.
|
|
148
|
-
- Optional `waitingOn`: `{ children, background, human
|
|
149
|
-
`source
|
|
148
|
+
- Optional `waitingOn`: `{ children, background, human, childSources?, childReports?, childReportsOmitted? }`.
|
|
149
|
+
`children` and each source's `activeCount` are the authoritative counts; every named list below is
|
|
150
|
+
supplemental and may be incomplete, so never derive a count from a list's length. `children` is the
|
|
151
|
+
larger of the nonterminal child reports and the summed `childSources` counts.
|
|
152
|
+
Background entries carry `source`, `activeCount`, optional `items`, optional `omittedItems`, and
|
|
153
|
+
optional `retryAtMs`. `childSources` entries carry `source`, `activeCount`, optional `items`, and
|
|
154
|
+
optional `omittedItems`. Each item is `{ id, label?, startedAt? }` (`startedAt` is ISO time), taken
|
|
155
|
+
from the producer's `wake_source_state` snapshot: its `items`, or the legacy `monitors` list when
|
|
156
|
+
`items` is missing or null. Terminal monitors are named by their stable `mon_` id. Each list is a
|
|
157
|
+
snapshot: entries whose `id` is not a non-blank string are dropped, duplicates collapse to one entry
|
|
158
|
+
per `id`, the list is sorted by `id`, and at most 32 entries are kept. `omittedItems` is the
|
|
159
|
+
producer's own omitted count plus any valid items cut at 32; it is not `activeCount` minus the list
|
|
160
|
+
length. Invalid detail drops only the detail, never the count.
|
|
161
|
+
`childReports` lists nonterminal reports from `reportChild` as
|
|
162
|
+
`{ taskId, childSessionId, runEpoch, state, label?, since? }`, excluding reports about the session
|
|
163
|
+
itself, sorted by `taskId` and capped at 32; `childReportsOmitted` counts the reports cut by that cap.
|
|
164
|
+
Human entries carry `kind`,
|
|
150
165
|
`originSessionId`, `requestId`, `revision`, `since`, and optional child identity/label.
|
|
151
166
|
Human kinds are `question`, `approval`, `goal_blocked`, `goal_paused`, `stalled`,
|
|
152
167
|
and `interrupted_run`; attention remains visible even when a hold wins precedence.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.27-1",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@earendil-works/chord": "0.99.1",
|
|
74
|
-
"@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.10.
|
|
75
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.
|
|
76
|
-
"@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.10.
|
|
74
|
+
"@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.10.27-1",
|
|
75
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.27-1",
|
|
76
|
+
"@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.10.27-1",
|
|
77
77
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
78
78
|
"ajv": "8.20.0",
|
|
79
79
|
"chalk": "6.0.0",
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"yaml": "2.9.1",
|
|
94
94
|
"@anthropic-ai/claude-agent-sdk": "0.3.306",
|
|
95
95
|
"@anthropic-ai/sdk": "0.127.0",
|
|
96
|
-
"@code-yeongyu/senpi-codemode": "2026.10.
|
|
97
|
-
"@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.10.
|
|
96
|
+
"@code-yeongyu/senpi-codemode": "2026.10.27-1",
|
|
97
|
+
"@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.10.27-1",
|
|
98
98
|
"@modelcontextprotocol/sdk": "1.32.1",
|
|
99
99
|
"@mozilla/readability": "0.6.0",
|
|
100
100
|
"linkedom": "0.18.13",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
var captures=new WeakMap,readers=new WeakMap,writers=new WeakMap,states=new WeakMap,demanded=new WeakSet,warned=new WeakSet,NO_CHANGE=Object.freeze({}),subscribers=0,capturedAny=!1;function subscribeAssistantCapture(){subscribers++;let held=!0;return()=>{held&&subscribers--,held=!1}}function setAssistantReader(owner,reader){readers.set(owner,reader)}function setAssistantProgressWriter(owner,writer){writers.set(owner,writer)}function enableAssistantCapture(owner){states.has(owner)||states.set(owner,void 0)}function activeState(owner){let state=states.get(owner);if(state!==void 0||!states.has(owner))return state??void 0;let decided=subscribers>0||demanded.has(owner)?{positions:new Map,metadata:new Map,insertCopies:new Map,failedBlocks:new Set}:null;return capturedAny||=decided!==null,states.set(owner,decided),decided??void 0}function dropCapture(owner,error,state,contentIndex){contentIndex!==void 0&&state?.failedBlocks.add(contentIndex),!warned.has(owner)&&(warned.add(owner),console.warn("[assistant-capture] could not build an internal capture record; that block's records are dropped",error))}function pushAssistantProgress(owner,progress){let writer=writers.get(owner);if(!writer)return;if(Object.isFrozen(progress)){writer(progress);return}let state=activeState(owner);if(!(!state||state.failedBlocks.has(progress.contentIndex)))try{writer(freezeProgress(state,progress))}catch(error){dropCapture(owner,error,state,progress.contentIndex)}}function freezeProgress(state,progress){if(progress.type==="message_tool_arguments_reset"&&state.positions.set(progress.contentIndex,{offset:progress.rawArgumentPrefix.length,parsedThrough:progress.parsedThrough}),progress.type!=="message_block_state")return Object.freeze({...progress});let previous=state.insertCopies.get(progress.contentIndex),current=publicBlock(progress.block),block=previous!==void 0&&sameValue(current,previous)?previous:freezeCapture(current);return progress.phase==="insert"?state.insertCopies.set(progress.contentIndex,block):state.insertCopies.delete(progress.contentIndex),Object.freeze({...progress,block})}function pushAssistantSignature(owner,contentIndex,block,signature){!signature||signature===(block.type==="text"?block.textSignature:block.thinkingSignature)||pushAssistantProgress(owner,{type:"message_block_metadata",contentIndex,...block.type==="text"?{textSignature:signature}:{thinkingSignature:signature}})}function pushAssistantCompleteBlock(owner,contentIndex,block){for(let phase of["insert","end"])pushAssistantProgress(owner,{type:"message_block_state",contentIndex,phase,block})}function assistantRecords(source){demanded.add(source);let read=readers.get(source);return{[Symbol.asyncIterator]:()=>read?.(entry=>({value:"event"in entry?entry.event:entry.progress,done:!1}))??source[Symbol.asyncIterator]()}}function assistantEvents(source,onProgress){let read=readers.get(source);return{[Symbol.asyncIterator]:()=>read?.(entry=>{if("event"in entry)return{value:entry.event,done:!1};onProgress(entry.progress)})??source[Symbol.asyncIterator]()}}function getAssistantCapture(event){return captures.get(event)}function isAssistantProgress(event){return event.type==="message_block_state"||event.type==="message_block_metadata"||event.type==="message_tool_arguments_reset"}function freezeCapture(value){let freeze=part=>{if(!(part===null||typeof part!="object"||Object.isFrozen(part))){for(let child of Object.values(part))freeze(child);Object.freeze(part)}},copy=structuredClone(value);return freeze(copy),copy}function publicBlock(block){return Object.fromEntries({text:["type","text","audience","textSignature"],thinking:["type","thinking","thinkingSignature","redacted","startedAt","endedAt"],toolCall:["type","id","name","arguments","incomplete","errorMessage","thoughtSignature","namespace"],providerNative:["type","subtype","raw"]}[block.type].filter(key=>key in block).map(key=>[key,Reflect.get(block,key)]))}function sameValue(left,right){if(left===right)return!0;if(!isPlainData(left)||!isPlainData(right)||Array.isArray(left)!==Array.isArray(right))return!1;let keys=Object.keys(left);return keys.length===Object.keys(right).length&&keys.every(key=>Object.hasOwn(right,key)&&sameValue(Reflect.get(left,key),Reflect.get(right,key)))}function isPlainData(value){if(typeof value!="object"||value===null)return!1;let prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===Array.prototype||prototype===null}function dropAssistantCapture(event){capturedAny&&captures.delete(event)}function carryAssistantCapture(source,target,terminal){let capture=captures.get(source);if(!capture)return target;try{captures.set(target,terminal?Object.freeze({...capture,message:freezeCapture({...terminal,content:terminal.content.map(publicBlock)})}):capture)}catch(error){dropCapture(source,error)}return target}function captureAssistantEvent(owner,event,hint={}){let state=activeState(owner);if(!state||captures.has(event))return;let contentIndex="contentIndex"in event?hint.contentIndex??event.contentIndex:void 0;if(!(contentIndex!==void 0&&state.failedBlocks.has(contentIndex)))try{captures.set(event,buildCapture(state,event,hint))}catch(error){dropCapture(owner,error,state,contentIndex)}}function buildCapture(state,event,hint){let message=event.type==="done"?event.message:event.type==="error"?event.error:event.partial,usage=usageCopy(state,message.usage);if(!("contentIndex"in event))return Object.freeze({usage,metadata:changedMetadata(state,message),message:freezeCapture({...message,content:message.content.map(publicBlock)})});let index=hint.contentIndex??event.contentIndex,own=index===event.contentIndex?{}:{contentIndex:index};if("delta"in event){let position=state.positions.get(index)??{offset:0,parsedThrough:0},offset=hint.offset??position.offset;return position.offset=offset+event.delta.length,event.type==="toolcall_delta"&&event.delta.length>0&&(position.parsedThrough=hint.parsedThrough??Math.max(position.parsedThrough,position.offset)),state.positions.set(index,position),Object.freeze({usage,offset,...own,...event.type==="toolcall_delta"?{parsedThrough:position.parsedThrough}:{}})}let metadata=changedMetadata(state,message),block=freezeCapture(publicBlock(event.type==="toolcall_end"?event.toolCall:message.content[index]));if(event.type!=="text_start"&&event.type!=="thinking_start"&&event.type!=="toolcall_start")return Object.freeze({usage,metadata,block,...own});let rawArgumentPrefix=hint.rawArgumentPrefix??"",coveredCodeUnits=block.type==="text"?block.text.length:block.type==="thinking"?block.thinking.length:rawArgumentPrefix.length,parsedThrough=hint.parsedThrough??0;return state.positions.set(index,{offset:hint.offset??coveredCodeUnits,parsedThrough}),Object.freeze({usage,metadata,block,coveredCodeUnits,...own,...block.type==="toolCall"?{rawArgumentPrefix,parsedThrough}:{}})}function usageCopy(state,usage){if(state.usage!==void 0&&sameValue(usage,state.usage))return state.usage;let copy=Object.freeze({...usage,cost:Object.freeze({...usage.cost}),...usage.contextUsage?{contextUsage:Object.freeze({...usage.contextUsage})}:{}});return state.usage=copy,copy}function changedMetadata(state,message){let changed={};for(let key of Object.keys(message)){if(key==="content"||key==="usage")continue;let value=Reflect.get(message,key);(!state.metadata.has(key)||state.metadata.get(key)!==value)&&(changed[key]=value)}for(let key of state.metadata.keys())key in message||(changed[key]=null);let frozen=Object.keys(changed).length===0?NO_CHANGE:freezeCapture(changed);for(let key of Object.keys(changed))key in message?state.metadata.set(key,Reflect.get(message,key)):state.metadata.delete(key);return frozen}var FifoQueue=class{constructor(){this.incoming=[],this.outgoing=[]}get length(){return this.incoming.length+this.outgoing.length}enqueue(value){this.incoming.push(value)}prepend(value){this.outgoing.push(value)}dequeue(){if(this.outgoing.length===0)for(;this.incoming.length>0;)this.outgoing.push(this.incoming.pop());return this.outgoing.pop()}},EventStream=class{#queue;#queueHead;#failed;#error;#localWorkDepth;constructor(isComplete,extractResult){this.#queue=[],this.#queueHead=0,this.waiting=new FifoQueue,this.done=!1,this.#failed=!1,this.#localWorkDepth=0,this.isComplete=isComplete,this.extractResult=extractResult,this.finalResultPromise=new Promise((resolve,reject)=>{this.resolveFinalResult=resolve,this.rejectFinalResult=reject}),this.finalResultPromise.catch(()=>{})}get queue(){return this.#queue.slice(this.#queueHead).flatMap(entry=>"event"in entry?[entry.event]:[])}#enqueue(event){this.#queue.push(event)}#dequeue(){let event=this.#queue[this.#queueHead];if(event===void 0)throw new Error("EventStream queue underflow");return this.#queueHead++,this.#queueHead>1024&&this.#queueHead*2>=this.#queue.length&&(this.#queue=this.#queue.slice(this.#queueHead),this.#queueHead=0),event}push(event){this.done||(this.isComplete(event)&&(this.done=!0,this.resolveFinalResult(this.extractResult(event))),this.#deliver({event}))}enqueueProgress(progress){this.done||this.#deliver({progress})}#deliver(entry){let waiter=this.waiting.dequeue();waiter?waiter.resolve({value:entry,done:!1}):this.#enqueue(entry)}end(result){for(this.done=!0,result!==void 0&&this.resolveFinalResult(result);this.waiting.length>0;){let waiter=this.waiting.dequeue();waiter&&waiter.resolve({value:void 0,done:!0})}}fail(error){if(!this.done)for(this.done=!0,this.#failed=!0,this.#error=error,this.rejectFinalResult(error);this.waiting.length>0;){let waiter=this.waiting.dequeue();waiter&&waiter.reject(error)}}[Symbol.asyncIterator](){return this.mapIterator(entry=>"event"in entry?{value:entry.event,done:!1}:void 0)}mapIterator(project){return{next:()=>{for(;this.#queueHead<this.#queue.length;){let result=project(this.#dequeue());if(result)return Promise.resolve(result)}return this.#failed?Promise.reject(this.#error):this.done?Promise.resolve({value:void 0,done:!0}):new Promise((resolve,reject)=>{let waiter={reject,resolve:next=>{let result=next.done?{value:void 0,done:!0}:project(next.value);result?resolve(result):this.waiting.prepend(waiter)}};this.waiting.enqueue(waiter)})}}}result(){return this.finalResultPromise}async trackLocalWork(work){this.#localWorkDepth++;try{return await work}finally{this.#localWorkDepth--}}hasPendingLocalWork(){return this.#localWorkDepth>0}},AssistantMessageEventStream=class _AssistantMessageEventStream extends EventStream{constructor(options={}){super(event=>event.type==="done"||event.type==="error",event=>{if(event.type==="done")return event.message;if(event.type==="error")return event.error;throw new Error("Unexpected event type for final result")}),options.captureBlocks&&enableAssistantCapture(this),setAssistantProgressWriter(this,progress=>this.enqueueProgress(progress)),new.target.prototype[Symbol.asyncIterator]===_AssistantMessageEventStream.prototype[Symbol.asyncIterator]&&setAssistantReader(this,project=>this.mapIterator(project))}push(event,hint){this.done||(captureAssistantEvent(this,event,hint),super.push(event))}[Symbol.asyncIterator](){return this.mapIterator(entry=>{if("event"in entry)return dropAssistantCapture(entry.event),{value:entry.event,done:!1}})}};function createAssistantMessageEventStream(){return new AssistantMessageEventStream}function formatThrownValue(value){return value instanceof Error?value.message||value.name:typeof value=="string"?value:String(value)}function extractDiagnosticError(error){if(!(error instanceof Error))return{name:"ThrownValue",message:formatThrownValue(error)};let code=error.code;return{name:error.name||void 0,message:error.message||error.name,stack:error.stack,code:typeof code=="string"||typeof code=="number"?code:void 0}}function createAssistantMessageDiagnostic(type,error,details){return{type,timestamp:Date.now(),error:extractDiagnosticError(error),details}}function appendAssistantMessageDiagnostic(message,diagnostic){message.diagnostics=[...message.diagnostics??[],diagnostic]}export{subscribeAssistantCapture,setAssistantReader,enableAssistantCapture,pushAssistantProgress,pushAssistantSignature,pushAssistantCompleteBlock,assistantRecords,assistantEvents,getAssistantCapture,isAssistantProgress,carryAssistantCapture,EventStream,AssistantMessageEventStream,createAssistantMessageEventStream,formatThrownValue,extractDiagnosticError,createAssistantMessageDiagnostic,appendAssistantMessageDiagnostic};
|