@yaklabs-ai/plugin-sdk 0.54.0 → 0.54.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.
@@ -1,12 +1,20 @@
1
1
  // packages/herd-transcript/dist/context-messages.js
2
+ var TAB_CONTEXT_CUSTOM_TYPE = "tab_context";
2
3
  var UI_ACTION_CUSTOM_TYPE = "ui_action";
4
+ var COMPOSER_REFERENCES_CUSTOM_TYPE = "composer_references";
3
5
  var USER_PASTED_CONTENT_CUSTOM_TYPE = "user_pasted_content";
4
6
  var ATTACHMENTS_CUSTOM_TYPE = "attachments";
5
7
  var DAEMON_SERVICE_TURN_CUSTOM_TYPE = "daemon_service_turn";
8
+ var COLLABORATION_MESSAGE_CUSTOM_TYPE = "collaboration_message";
9
+ var RUNTIME_NOTICE_CUSTOM_TYPE = "runtime_notice";
10
+ var AVAILABILITY_FACTS_CUSTOM_TYPE = "availability_facts";
6
11
  var MID_TURN_COMPACTION_OUTCOME_CUSTOM_TYPE = "mid_turn_compaction_outcome";
7
12
  var RUN_CONTINUATION_CARRIER_CUSTOM_TYPE = "herd_run_continuation";
8
13
  var DYNAMIC_CONTEXT_CUSTOM_TYPE = "dynamic_context";
14
+ var USER_SHELL_COMMAND_CUSTOM_TYPE = "user_shell_command";
9
15
  var USER_INVOKED_CUSTOM_TYPE = "user_invoked";
16
+ var HEADLESS_OPERATION_CUSTOM_TYPE = "headless_operation";
17
+ var SYSTEM_PROMPT_DELTA_CUSTOM_TYPE = "system_prompt_delta";
10
18
 
11
19
  // packages/herd-transcript/dist/turn-messages.js
12
20
  var SUBAGENT_RESULT_CUSTOM_TYPE = "subagent_result";
@@ -213,8 +221,30 @@ var coverageSchema = z2.strictObject({
213
221
  knownOmittedCount: z2.number().int().nonnegative().optional()
214
222
  }).refine((value) => value.status !== "complete" || !value.knownOmittedCount);
215
223
 
224
+ // packages/herd-transcript/dist/is-object.js
225
+ function isObject(value) {
226
+ return typeof value === "object" && value !== null && !Array.isArray(value);
227
+ }
228
+
229
+ // packages/herd-transcript/dist/subscription-failure.js
230
+ var SUBSCRIPTION_FAILURE_KEYS = [
231
+ "subscription.expired",
232
+ "subscription.access-denied",
233
+ "subscription.client-refused",
234
+ "subscription.scope-refused",
235
+ "subscription.renewal-failed",
236
+ "subscription.unreachable",
237
+ "subscription.incomplete",
238
+ "subscription.temporary",
239
+ // Picked by a screen that knows a renewal failed but holds no record.
240
+ "subscription.no-record",
241
+ "subscription.unclassified"
242
+ ];
243
+
216
244
  // packages/herd-transcript/dist/run-failure.js
217
245
  var RUN_FAILURE_DIAGNOSTIC_TYPE = "herd.run.failure";
246
+ var RUN_FAILURE_CUSTOM_TYPE = "run_failure";
247
+ var RUN_RECOVERY_CUSTOM_TYPE = "run_recovery";
218
248
  var runFailureCauseSchema = z3.strictObject({
219
249
  reason: z3.enum(RUN_FAILURE_REASONS),
220
250
  source: z3.enum(["assistant_message", "exception", "runtime"]),
@@ -233,8 +263,27 @@ var runFailureCauseSchema = z3.strictObject({
233
263
  authSource: z3.enum(["oauth", "api-key"]).optional(),
234
264
  credentialRef: z3.string().optional()
235
265
  });
266
+ var RUN_FAILURE_DOMAINS = ["model", "runtime"];
267
+ var RUN_FAILURE_ORGANIZATION_CODES = [
268
+ "model.organization_unavailable.changed",
269
+ "model.organization_unavailable.unreachable",
270
+ "model.organization_unavailable.connecting",
271
+ "model.organization_unavailable.not_ready"
272
+ ];
273
+ var RUN_FAILURE_SIGN_IN_REASONS = [
274
+ "auth",
275
+ "network",
276
+ "server_error"
277
+ ];
278
+ var RUN_FAILURE_CODES = [
279
+ ...RUN_FAILURE_REASONS.map((reason) => `model.${reason}`),
280
+ "runtime.interrupted",
281
+ "runtime.final_output_missing",
282
+ ...RUN_FAILURE_ORGANIZATION_CODES,
283
+ ...RUN_FAILURE_SIGN_IN_REASONS.flatMap((reason) => SUBSCRIPTION_FAILURE_KEYS.map((key) => `model.${reason}.${key}`))
284
+ ];
236
285
  var runFailureSchema = failureSchema(runFailureCauseSchema).extend({
237
- domain: z3.enum(["model", "runtime"])
286
+ domain: z3.enum(RUN_FAILURE_DOMAINS)
238
287
  });
239
288
  var runFailureRecordSchema = z3.strictObject({
240
289
  failure: runFailureSchema.refine((failure) => readFailure(runFailureSchema, failure).status === "valid", "invalid or oversized model failure occurrence"),
@@ -621,13 +670,6 @@ function parsePresentationAnchor(value) {
621
670
 
622
671
  // packages/herd-transcript/dist/tool-call-failure.js
623
672
  import { z as z5 } from "zod";
624
-
625
- // packages/herd-transcript/dist/is-object.js
626
- function isObject(value) {
627
- return typeof value === "object" && value !== null && !Array.isArray(value);
628
- }
629
-
630
- // packages/herd-transcript/dist/tool-call-failure.js
631
673
  var TOOL_CALL_FAILURE_DETAILS_KEY = "toolCallFailure";
632
674
  var TOOL_CALL_FAILURE_DOMAIN = "tool-call";
633
675
  var TOOL_CALL_FAILURE_CATEGORIES = [
@@ -1414,7 +1456,7 @@ function reduceToolResultMessage(state, event, replay) {
1414
1456
  const body = getPath(asRecord2(event) ?? {}, ["message"]) ?? getPath(asRecord2(event) ?? {}, ["entry"]) ?? event;
1415
1457
  return reduceToolCompletion(state, normalizeToolResultMessageCompletion(body, getTimestamp(event), getEntryId(event)), replay);
1416
1458
  }
1417
- function normalizeToolResultMessageCompletion(body, completedAt, entryId) {
1459
+ function normalizeToolResultMessageCompletion(body, completedAt, entryId2) {
1418
1460
  const record = asRecord2(body);
1419
1461
  const toolCallId = getToolCallId(body);
1420
1462
  if (record === void 0 || toolCallId === void 0)
@@ -1423,7 +1465,7 @@ function normalizeToolResultMessageCompletion(body, completedAt, entryId) {
1423
1465
  const resultText = getResultText(record);
1424
1466
  return {
1425
1467
  toolCallId,
1426
- ...stringField("entryId", entryId),
1468
+ ...stringField("entryId", entryId2),
1427
1469
  ...stringField("name", getToolName(record)),
1428
1470
  ...stringField("resultText", resultText),
1429
1471
  ...unknownField("resultDetails", record["details"]),
@@ -3932,10 +3974,564 @@ function contentText(content) {
3932
3974
  function asRecord3(value) {
3933
3975
  return typeof value === "object" && value !== null ? value : void 0;
3934
3976
  }
3977
+
3978
+ // packages/plugin-protocol/dist/phase-shift.js
3979
+ import { z as z7 } from "zod";
3980
+
3981
+ // packages/plugin-protocol/dist/transcript.js
3982
+ import { z as z6 } from "zod";
3983
+ var WorkBlockCoverageSchema = z6.strictObject({
3984
+ firstToolResultEntryId: z6.string().min(1),
3985
+ lastToolResultEntryId: z6.string().min(1),
3986
+ toolResultEntryIds: z6.array(z6.string().min(1)).min(1).max(4096)
3987
+ }).refine((value) => value.firstToolResultEntryId === value.toolResultEntryIds[0] && value.lastToolResultEntryId === value.toolResultEntryIds.at(-1) && new Set(value.toolResultEntryIds).size === value.toolResultEntryIds.length);
3988
+ var RUN_STARTED_CUSTOM_TYPE = "session_run_started";
3989
+ var RUN_TERMINAL_CUSTOM_TYPE2 = "session_run_state";
3990
+
3991
+ // packages/plugin-protocol/dist/phase-shift.js
3992
+ var PHASE_SHIFT_EXTENSION_ID = "kay.phase-shift";
3993
+ var PHASE_SHIFT_ENTRY_NAME = "observation";
3994
+ var PHASE_SHIFT_CUSTOM_TYPE = `ext:${PHASE_SHIFT_EXTENSION_ID}:${PHASE_SHIFT_ENTRY_NAME}`;
3995
+ var PHASE_SHIFT_TIMELINE_CUSTOM_TYPE = `ext:${PHASE_SHIFT_EXTENSION_ID}:timeline`;
3996
+ var PHASE_SHIFT_DETECTOR_VERSION = "activity-memory-v1";
3997
+ var entryId = z7.string().min(1).max(256);
3998
+ var purpose = z7.string().trim().min(1).max(320);
3999
+ var sourceTime = z7.iso.datetime();
4000
+ var phaseShiftMemorySchema = z7.object({
4001
+ startEntryId: entryId,
4002
+ purpose,
4003
+ anchors: z7.array(z7.object({ entryId, excerpt: z7.string().max(250) })).min(1).max(3)
4004
+ });
4005
+ var phaseShiftCostSchema = z7.object({
4006
+ amountUsd: z7.number().nonnegative(),
4007
+ amountBasis: z7.enum(["measured", "list-estimate", "unknown"]),
4008
+ inputTokens: z7.number().int().nonnegative(),
4009
+ outputTokens: z7.number().int().nonnegative(),
4010
+ /**
4011
+ * The highest provider-attempt ordinal this check accounted for; recovery
4012
+ * after a failure makes it more than one. An attempt that threw before
4013
+ * reporting usage is invisible to accounting, so this is a lower bound on
4014
+ * what the provider was actually asked to do.
4015
+ */
4016
+ attempts: z7.number().int().positive()
4017
+ });
4018
+ var observationFields = {
4019
+ detectorVersion: z7.literal(PHASE_SHIFT_DETECTOR_VERSION),
4020
+ modelReference: z7.string().min(1).max(256),
4021
+ observedAt: z7.iso.datetime(),
4022
+ throughEntryId: entryId,
4023
+ windowEntryIds: z7.array(entryId).min(1).max(40),
4024
+ memory: phaseShiftMemorySchema
4025
+ };
4026
+ var changeFields = {
4027
+ startEntryId: entryId,
4028
+ relation: z7.enum(["outcome", "phase"]),
4029
+ reason: z7.string().trim().min(1).max(2e3),
4030
+ purposeAfter: purpose
4031
+ };
4032
+ var phaseShiftObservationV1Schema = z7.object({
4033
+ version: z7.literal(1),
4034
+ ...observationFields,
4035
+ changes: z7.array(z7.object(changeFields)).max(39)
4036
+ });
4037
+ var phaseShiftObservationV2Schema = z7.object({
4038
+ version: z7.literal(2),
4039
+ ...observationFields,
4040
+ /** Timestamp of the `windowEntryIds[0]` entry: where this check's coverage starts. */
4041
+ windowStartAt: sourceTime,
4042
+ /** Timestamp of the `throughEntryId` entry: where this check's coverage ends. */
4043
+ throughAt: sourceTime,
4044
+ /** What this check cost to run; absent on a record written before it was accounted. */
4045
+ cost: phaseShiftCostSchema.optional(),
4046
+ changes: z7.array(z7.object({
4047
+ ...changeFields,
4048
+ /** Timestamp of the `startEntryId` entry: when the new work began. */
4049
+ startedAt: sourceTime
4050
+ })).max(39)
4051
+ });
4052
+ var phaseShiftObservationSchema = z7.discriminatedUnion("version", [
4053
+ phaseShiftObservationV1Schema,
4054
+ phaseShiftObservationV2Schema
4055
+ ]);
4056
+
4057
+ // packages/time/dist/temporal.js
4058
+ import { Temporal as Polyfill } from "@js-temporal/polyfill";
4059
+ var engineTemporal = Reflect.get(globalThis, "Temporal");
4060
+
4061
+ // packages/plugin-protocol/dist/transcript-review.js
4062
+ var RUN_INPUT_CUSTOM_TYPE = "session_run_input";
4063
+ var ANSI_RE = new RegExp([
4064
+ "\\u001b\\[[0-?]*[ -/]*[@-~]",
4065
+ "\\u001b\\][^\\u0007\\u001b]*(?:\\u0007|\\u001b\\\\)",
4066
+ "\\u001b[@-Z\\\\-_]",
4067
+ "\\[[0-9;]*m"
4068
+ ].join("|"), "g");
4069
+
4070
+ // packages/agent-runtime-protocol/dist/model-change-reason.js
4071
+ var MODEL_CHANGE_REASON_CUSTOM_TYPE = "model_change_reason";
4072
+
4073
+ // packages/agent-runtime-protocol/dist/run-offline-stop.js
4074
+ import { z as z8 } from "zod";
4075
+ var RUN_OFFLINE_STOP_CUSTOM_TYPE = "run_offline_stop";
4076
+ var runOfflineStopSchema = z8.strictObject({
4077
+ failureRef: failureRefSchema
4078
+ });
4079
+
4080
+ // packages/agent-runtime-protocol/dist/routed-send.js
4081
+ function standsInForHumanSend(details) {
4082
+ return typeof details === "object" && details !== null && details.standsInForHumanSend === true;
4083
+ }
4084
+
4085
+ // packages/agent-runtime-protocol/dist/transcript-type-table.js
4086
+ function recordOf(value) {
4087
+ return typeof value === "object" && value !== null ? value : void 0;
4088
+ }
4089
+ function stringField2(details, key) {
4090
+ const value = recordOf(details)?.[key];
4091
+ return typeof value === "string" ? value : void 0;
4092
+ }
4093
+ var DAEMON_SERVICE_AUDIENCE = {
4094
+ wake: "model",
4095
+ subagent_brief: "person",
4096
+ subagent_wake: "model",
4097
+ automation: "model",
4098
+ followup_lane: "model",
4099
+ continuation: "person"
4100
+ };
4101
+ function daemonServiceOf(details) {
4102
+ const service = stringField2(details, "service");
4103
+ return service !== void 0 && Object.hasOwn(DAEMON_SERVICE_AUDIENCE, service) ? service : void 0;
4104
+ }
4105
+ function unansweredPermissionKind(details) {
4106
+ if (stringField2(details, "noticeKind") !== "permission_ask_unanswered")
4107
+ return void 0;
4108
+ const kind = stringField2(details, "kind");
4109
+ return kind === "expired" || kind === "undisplayed" ? kind : void 0;
4110
+ }
4111
+ function answersToolCall(details) {
4112
+ const toolCallId = stringField2(details, "toolCallId");
4113
+ return toolCallId === void 0 ? void 0 : { toolCallId };
4114
+ }
4115
+ function answersDraftCard(details) {
4116
+ const toolCallId = stringField2(details, "reviewToolCallId");
4117
+ if (toolCallId === void 0)
4118
+ return void 0;
4119
+ const elementId = stringField2(details, "elementId");
4120
+ return elementId === void 0 ? { toolCallId } : { toolCallId, elementId };
4121
+ }
4122
+ function herdPlacement(typeKey) {
4123
+ const row = DEFAULT_CUSTOM_MESSAGE_PLACEMENTS.get(typeKey);
4124
+ if (row === void 0)
4125
+ throw new Error(`@herd/transcript has no placement for ${typeKey}`);
4126
+ return row.placement;
4127
+ }
4128
+ var MESSAGE_DRAFT_SENT_TYPE = "message_draft_sent";
4129
+ var INTERRUPTED_RUN_RESUME_NOTE_CUSTOM_TYPE = "interrupted_run_resume_note";
4130
+ var ROWS = [
4131
+ // The six companions of a person's send, delivered in the same batch as its text: context and
4132
+ // attachments before it, dynamic context after. The bubble draws the three the person made
4133
+ // (attachments as its footer, an invoked command as its pill, a paste inline where it was
4134
+ // typed); the other three are context computed for the model. A card answer is not one (a
4135
+ // parts-only send is the input itself), nor is a shell command the person ran (a record of
4136
+ // its own, never tied to a text send).
4137
+ {
4138
+ typeKey: ATTACHMENTS_CUSTOM_TYPE,
4139
+ kinds: ["context"],
4140
+ placement: herdPlacement(ATTACHMENTS_CUSTOM_TYPE),
4141
+ audience: "person"
4142
+ },
4143
+ {
4144
+ typeKey: USER_INVOKED_CUSTOM_TYPE,
4145
+ kinds: ["context"],
4146
+ placement: herdPlacement(USER_INVOKED_CUSTOM_TYPE),
4147
+ audience: "person"
4148
+ },
4149
+ {
4150
+ typeKey: USER_PASTED_CONTENT_CUSTOM_TYPE,
4151
+ kinds: ["context"],
4152
+ placement: herdPlacement(USER_PASTED_CONTENT_CUSTOM_TYPE),
4153
+ audience: "person"
4154
+ },
4155
+ // The shell's ambient pane projection (north-star §5).
4156
+ {
4157
+ typeKey: TAB_CONTEXT_CUSTOM_TYPE,
4158
+ kinds: ["context"],
4159
+ placement: "companion-of-send",
4160
+ audience: "model"
4161
+ },
4162
+ // The pills the person picked, serialized for the agent's resolution; the bubble already shows
4163
+ // them as the marker text they typed.
4164
+ {
4165
+ typeKey: COMPOSER_REFERENCES_CUSTOM_TYPE,
4166
+ kinds: ["context"],
4167
+ placement: "companion-of-send",
4168
+ audience: "model"
4169
+ },
4170
+ // Retrieved memory and skill context, not work done on the person's behalf.
4171
+ {
4172
+ typeKey: DYNAMIC_CONTEXT_CUSTOM_TYPE,
4173
+ kinds: ["context"],
4174
+ placement: herdPlacement(DYNAMIC_CONTEXT_CUSTOM_TYPE),
4175
+ audience: "model"
4176
+ },
4177
+ // A card answer is the person's, and the card shows it: a spent MessageDraft reads Approved,
4178
+ // an answered Card collapses to the pressed label (ruling 2026-09-03). A row of its own repeated
4179
+ // it as the raw wire payload. Known gap: only MessageDraft rehydrates what was submitted, so a
4180
+ // typed Field value or an answer to a Button outside a Card survives a reload only in raw mode.
4181
+ {
4182
+ typeKey: UI_ACTION_CUSTOM_TYPE,
4183
+ kinds: ["said"],
4184
+ placement: herdPlacement(UI_ACTION_CUSTOM_TYPE),
4185
+ audience: "person",
4186
+ answers: answersToolCall
4187
+ },
4188
+ {
4189
+ typeKey: MESSAGE_DRAFT_SENT_TYPE,
4190
+ kinds: ["context"],
4191
+ placement: "standalone",
4192
+ audience: "model",
4193
+ answers: answersDraftCard
4194
+ },
4195
+ {
4196
+ typeKey: "plugin_card_submitted",
4197
+ kinds: ["context"],
4198
+ placement: "standalone",
4199
+ audience: "model"
4200
+ },
4201
+ // Tells the agent a send's outcome is unknown so it does not send again. Its text is an
4202
+ // instruction to the model. Known gap (#13684): the card states the outcome to the person only
4203
+ // in the renderer that pressed Send. It does not read this record, so after a reload or a daemon
4204
+ // restart it shows idle until a second press, which the daemon refuses as unconfirmed.
4205
+ {
4206
+ typeKey: "message_draft_send_unknown",
4207
+ kinds: ["context"],
4208
+ placement: "standalone",
4209
+ audience: "model",
4210
+ answers: answersDraftCard
4211
+ },
4212
+ // The daemon's agent-only note of a person's decision on an expired approval.
4213
+ {
4214
+ typeKey: "approval_decision",
4215
+ kinds: ["context"],
4216
+ placement: "standalone",
4217
+ audience: "model"
4218
+ },
4219
+ {
4220
+ typeKey: USER_SHELL_COMMAND_CUSTOM_TYPE,
4221
+ kinds: ["work"],
4222
+ placement: "standalone",
4223
+ audience: "person"
4224
+ },
4225
+ {
4226
+ typeKey: COLLABORATION_MESSAGE_CUSTOM_TYPE,
4227
+ kinds: ["said"],
4228
+ placement: "standalone",
4229
+ audience: "person"
4230
+ },
4231
+ // A settled result joins the agent turn that awaits it; one that does not read as settled
4232
+ // detached work stands where it landed. A spawn can keep its result out of the person's
4233
+ // transcript; that one is outside it.
4234
+ {
4235
+ typeKey: SUBAGENT_RESULT_CUSTOM_TYPE,
4236
+ kinds: ["said"],
4237
+ placement: herdPlacement(SUBAGENT_RESULT_CUSTOM_TYPE),
4238
+ audience: "person"
4239
+ },
4240
+ {
4241
+ typeKey: BACKGROUND_TASK_RESULT_CUSTOM_TYPE,
4242
+ kinds: ["work"],
4243
+ placement: herdPlacement(BACKGROUND_TASK_RESULT_CUSTOM_TYPE),
4244
+ audience: "person"
4245
+ },
4246
+ // Maintenance the run already performed, not an input the agent resumes on: post-run
4247
+ // compaction routinely lands after the final answer while the run is still open, and
4248
+ // counting it kept that answered turn reading as still working.
4249
+ {
4250
+ typeKey: COMPACTION_MARKER_CUSTOM_TYPE,
4251
+ kinds: ["context"],
4252
+ placement: herdPlacement(COMPACTION_MARKER_CUSTOM_TYPE),
4253
+ audience: "person"
4254
+ },
4255
+ // Fails closed: a service this release cannot read is the daemon's plumbing.
4256
+ {
4257
+ typeKey: DAEMON_SERVICE_TURN_CUSTOM_TYPE,
4258
+ kinds: ["said", "context"],
4259
+ // A wake delivery joins the agent turn it wakes; every other service stands where it landed.
4260
+ placement: herdPlacement(DAEMON_SERVICE_TURN_CUSTOM_TYPE),
4261
+ audience: (details) => {
4262
+ const service = daemonServiceOf(details);
4263
+ return service === void 0 ? void 0 : DAEMON_SERVICE_AUDIENCE[service];
4264
+ },
4265
+ onUndecodable: "hide"
4266
+ },
4267
+ // A notice whose kind is new to this release still reads as a generic notice. A missed-approval
4268
+ // notice of a kind this release does not know cannot say what was missed, so it hides.
4269
+ {
4270
+ typeKey: RUNTIME_NOTICE_CUSTOM_TYPE,
4271
+ kinds: ["notice"],
4272
+ placement: "standalone",
4273
+ audience: (details) => stringField2(details, "noticeKind") === "permission_ask_unanswered" && unansweredPermissionKind(details) === void 0 ? void 0 : "person",
4274
+ onUndecodable: "hide"
4275
+ },
4276
+ // Model-facing statements. Each was once visible for no decided reason, because this
4277
+ // classification allows by default.
4278
+ //
4279
+ // Who the person is connected as and what waits on a connect; Plugins and Connections show it
4280
+ // better, and the body instructs the agent.
4281
+ {
4282
+ typeKey: AVAILABILITY_FACTS_CUSTOM_TYPE,
4283
+ kinds: ["context"],
4284
+ placement: "standalone",
4285
+ audience: "model"
4286
+ },
4287
+ // The kernel telling the model a section of its own frozen instructions moved (#2996).
4288
+ {
4289
+ typeKey: SYSTEM_PROMPT_DELTA_CUSTOM_TYPE,
4290
+ kinds: ["context"],
4291
+ placement: "standalone",
4292
+ audience: "model"
4293
+ },
4294
+ // The statement into a forked headless session that no person is present.
4295
+ {
4296
+ typeKey: HEADLESS_OPERATION_CUSTOM_TYPE,
4297
+ kinds: ["context"],
4298
+ placement: "standalone",
4299
+ audience: "model"
4300
+ },
4301
+ // The note sent with a resumed run's first request: check before repeating an action.
4302
+ {
4303
+ typeKey: INTERRUPTED_RUN_RESUME_NOTE_CUSTOM_TYPE,
4304
+ kinds: ["context"],
4305
+ placement: "standalone",
4306
+ audience: "model"
4307
+ },
4308
+ // A compaction reminder riding the last result of a fan-out.
4309
+ {
4310
+ typeKey: "phase_shift_nudge",
4311
+ kinds: ["context"],
4312
+ placement: "standalone",
4313
+ audience: "model"
4314
+ },
4315
+ // Retired 2026-10-19 (the primer now rides the first call's result); older transcripts hold it.
4316
+ {
4317
+ typeKey: "auto_primer",
4318
+ kinds: ["context"],
4319
+ placement: "standalone",
4320
+ audience: "model"
4321
+ },
4322
+ // The kernel's notes to the model. The repair joins the agent turn it asks to finish; the other
4323
+ // two stay out of the transcript.
4324
+ {
4325
+ typeKey: MID_TURN_COMPACTION_OUTCOME_CUSTOM_TYPE,
4326
+ kinds: ["context"],
4327
+ placement: herdPlacement(MID_TURN_COMPACTION_OUTCOME_CUSTOM_TYPE),
4328
+ audience: "model"
4329
+ },
4330
+ {
4331
+ typeKey: FINAL_OUTPUT_REPAIR_CUSTOM_TYPE,
4332
+ kinds: ["context"],
4333
+ placement: herdPlacement(FINAL_OUTPUT_REPAIR_CUSTOM_TYPE),
4334
+ audience: "model"
4335
+ },
4336
+ {
4337
+ typeKey: RUN_CONTINUATION_CARRIER_CUSTOM_TYPE,
4338
+ kinds: ["context"],
4339
+ placement: herdPlacement(RUN_CONTINUATION_CARRIER_CUSTOM_TYPE),
4340
+ audience: "model"
4341
+ },
4342
+ // What the person sees when the policy changes their model, and a send a helper answered in the
4343
+ // session model's place (both drawn by the smart-model-selection plugin).
4344
+ {
4345
+ typeKey: "model_selection_change",
4346
+ kinds: ["notice"],
4347
+ placement: "standalone",
4348
+ audience: "person"
4349
+ },
4350
+ {
4351
+ typeKey: "model_selection_handoff",
4352
+ kinds: ["said"],
4353
+ placement: "opens-turn",
4354
+ audience: "person"
4355
+ },
4356
+ // Synthesized while reading, never written: a failed reply the renderer redraws as a
4357
+ // provider-switch notice, and activity the reducer could not classify.
4358
+ {
4359
+ typeKey: "kay.provider_fallback",
4360
+ kinds: ["notice"],
4361
+ placement: "standalone",
4362
+ audience: "person"
4363
+ },
4364
+ {
4365
+ typeKey: "herd.unknown_activity",
4366
+ kinds: ["unrecognized"],
4367
+ placement: "standalone",
4368
+ audience: "person"
4369
+ }
4370
+ ];
4371
+ function keyedRows(rows) {
4372
+ const table = /* @__PURE__ */ new Map();
4373
+ for (const row of rows) {
4374
+ if (table.has(row.typeKey))
4375
+ throw new Error(`two type rows for ${row.typeKey}`);
4376
+ table.set(row.typeKey, row);
4377
+ }
4378
+ return table;
4379
+ }
4380
+ var UNLISTED_TRANSCRIPT_TYPE_ROW = {
4381
+ typeKey: OTHER_CUSTOM_TYPES,
4382
+ kinds: ["unrecognized"],
4383
+ placement: (details, display) => standsInForHumanSend(details) ? "opens-turn" : customMessagePlacement(void 0, details, display),
4384
+ audience: "person"
4385
+ };
4386
+ var TRANSCRIPT_TYPE_TABLE = keyedRows(ROWS);
4387
+ var TRANSCRIPT_PLACEMENTS = new Map([
4388
+ ...TRANSCRIPT_TYPE_TABLE,
4389
+ [OTHER_CUSTOM_TYPES, UNLISTED_TRANSCRIPT_TYPE_ROW]
4390
+ ]);
4391
+ var ENTRY_ROWS = [
4392
+ // The daemon's bookkeeping. These were 20.3% of every attach snapshot and 26% of every tail
4393
+ // preview on 60 real transcripts (2026-09-01, apps/kay/bench/daemon-memory/projection-size.mjs);
4394
+ // a single resolved prompt is ~160 KB and a session writes one per daemon restart. Most are
4395
+ // spelled here because their constants live in @bonsai/agent-runtime, which this package cannot
4396
+ // import; the daemon's census test pins each constant to its row.
4397
+ ...[
4398
+ RUN_FAILURE_CUSTOM_TYPE,
4399
+ PHASE_SHIFT_CUSTOM_TYPE,
4400
+ RUN_TERMINAL_CUSTOM_TYPE2,
4401
+ RUN_STARTED_CUSTOM_TYPE,
4402
+ RUN_INPUT_CUSTOM_TYPE,
4403
+ "cwd_transition",
4404
+ "project_transition",
4405
+ "user_title",
4406
+ "agent_identity",
4407
+ "session_provenance",
4408
+ "processing_speed",
4409
+ "definition_permission_authority",
4410
+ "registered_definition_pointer",
4411
+ "inherited_definition_rules_pointer",
4412
+ "final_output_contract",
4413
+ "headless_session",
4414
+ "session_cleared",
4415
+ "composition_snapshot",
4416
+ "resolved_prompt",
4417
+ "model_selection",
4418
+ "owed_reply",
4419
+ // Replaced by owed_reply entries (session index migration 3); older logs still hold it.
4420
+ "subagent_task_lifecycle_event",
4421
+ // Retired 2026-09-10 with the daemon workspace roster; no install wrote one, but a log that did
4422
+ // must still keep it off the surface.
4423
+ "workspace_ref",
4424
+ // Converted pi 0.99.1 config records: data migration 4 keeps a format-3 transcript's session
4425
+ // name, model, thinking level and tool records as entries; their values live in the session's
4426
+ // own documents.
4427
+ "session_info",
4428
+ "model_change",
4429
+ "thinking_level_change",
4430
+ "active_tools_change"
4431
+ ].map((typeKey) => ({ typeKey, audience: "host-only" })),
4432
+ // Daemon-written, surface-read: the steward's recap trailer, the provider-switch notice
4433
+ // (provider-fallback-transcript.ts, #6370) and the recovered-run notice.
4434
+ { typeKey: "session_steward", audience: "person" },
4435
+ { typeKey: MODEL_CHANGE_REASON_CUSTOM_TYPE, audience: "person" },
4436
+ { typeKey: RUN_RECOVERY_CUSTOM_TYPE, audience: "person" },
4437
+ { typeKey: RUN_OFFLINE_STOP_CUSTOM_TYPE, audience: "person" }
4438
+ ];
4439
+ var CUSTOM_ENTRY_TYPE_TABLE = keyedRows(ENTRY_ROWS);
4440
+
4441
+ // packages/agent-runtime-protocol/dist/failure-echo.js
4442
+ function stripErrorLabel(text) {
4443
+ return text.replace(/^\s*(?:\S+\s+)?error:\s*/i, "").trim();
4444
+ }
4445
+ function echoesFailure(text, failure) {
4446
+ const candidate = stripErrorLabel(text);
4447
+ if (candidate === "")
4448
+ return false;
4449
+ if (candidate === failure)
4450
+ return true;
4451
+ if (looksLikeHtml(candidate) && readableFailureText(candidate) === failure) {
4452
+ return true;
4453
+ }
4454
+ return failure.endsWith("\u2026") && candidate.startsWith(failure.slice(0, -1));
4455
+ }
4456
+ function withoutFailureEcho(item) {
4457
+ const failure = stripErrorLabel(item.failureText ?? "");
4458
+ if (failure === "")
4459
+ return item;
4460
+ const parts = item.parts.filter((part) => part.type !== "text" || !echoesFailure(part.text, failure));
4461
+ return parts.length === item.parts.length ? item : { ...item, parts };
4462
+ }
4463
+ function visibleTextWithoutFailureEcho(item) {
4464
+ if (item.parts.length === 0) {
4465
+ const text = item.text ?? "";
4466
+ const failure = stripErrorLabel(item.failureText ?? "");
4467
+ return failure !== "" && echoesFailure(text, failure) ? "" : text;
4468
+ }
4469
+ const texts = [];
4470
+ for (const part of withoutFailureEcho(item).parts) {
4471
+ if (part.type === "text")
4472
+ texts.push(part.text);
4473
+ }
4474
+ return texts.join("\n");
4475
+ }
4476
+
4477
+ // packages/agent-runtime-protocol/dist/answer-stretch.js
4478
+ function isReply2(block) {
4479
+ return block.kind === "final_answer" || block.kind === "provisional_response";
4480
+ }
4481
+ function isBackgroundInput(block) {
4482
+ if (block.kind !== "custom_message")
4483
+ return false;
4484
+ const { message } = block;
4485
+ if (isEmbeddedAgentResultMessage(message) || isDaemonWakeMessage(message))
4486
+ return true;
4487
+ if (message.customType !== DAEMON_SERVICE_TURN_CUSTOM_TYPE)
4488
+ return false;
4489
+ const service = daemonServiceOf(message.details);
4490
+ return service === "automation" || service === "followup_lane";
4491
+ }
4492
+ function isBareFailureReply(block) {
4493
+ return block.status === "failed" && visibleTextWithoutFailureEcho(block.source).trim() === "";
4494
+ }
4495
+ function isStretchAnswer(block) {
4496
+ return isReply2(block) && !isBareFailureReply(block) && block.text.trim() !== "";
4497
+ }
4498
+ function answerStretchStarts(blocks) {
4499
+ const starts = /* @__PURE__ */ new Set();
4500
+ let answered = false;
4501
+ let pendingInput;
4502
+ for (const block of blocks) {
4503
+ if (block.kind === "steer_message") {
4504
+ starts.add(block.id);
4505
+ answered = false;
4506
+ pendingInput = void 0;
4507
+ } else if (answered && pendingInput === void 0 && isBackgroundInput(block)) {
4508
+ pendingInput = block.id;
4509
+ } else if (isStretchAnswer(block)) {
4510
+ if (pendingInput !== void 0)
4511
+ starts.add(pendingInput);
4512
+ pendingInput = void 0;
4513
+ answered = true;
4514
+ }
4515
+ }
4516
+ return starts;
4517
+ }
4518
+ function stretchOpeningResults(blocks, start) {
4519
+ const results = [];
4520
+ for (const block of blocks.slice(start)) {
4521
+ if (block.kind !== "custom_message")
4522
+ break;
4523
+ if (isEmbeddedAgentResultMessage(block.message))
4524
+ results.push(block);
4525
+ }
4526
+ return results;
4527
+ }
3935
4528
  export {
4529
+ TRANSCRIPT_TYPE_TABLE,
4530
+ answerStretchStarts,
3936
4531
  customMessagePlacement,
3937
4532
  eventsForEntry,
3938
4533
  projectCanonicalTranscript,
3939
4534
  reconstructInteractiveState,
3940
- runBoundaryReplayEvent
4535
+ runBoundaryReplayEvent,
4536
+ stretchOpeningResults
3941
4537
  };