@get-bb/plugin-sdk 0.4.24 → 0.4.28
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/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +0 -25
- package/bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts +0 -200
- package/bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts +1 -440
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +0 -665
- package/bundled-types/bb-plugin-sdk-testing.d.ts +0 -16
- package/bundled-types/bb-plugin-sdk.d.ts +37 -295
- package/dist/ai-services.js +5 -1
- package/dist/internal/host-policy.js +95 -108
- package/dist/provider-bridge-acp.js +74 -616
- package/dist/provider-bridge-testing.js +177 -580
- package/dist/provider-bridge-worker-entry.mjs +15 -9
- package/dist/provider-bridge.js +64 -558
- package/dist/testing/index.js +133 -114
- package/package.json +1 -1
|
@@ -111,16 +111,7 @@ var canonicalPromptMentionResourceSchema = z2.discriminatedUnion("kind", [
|
|
|
111
111
|
z2.object({
|
|
112
112
|
kind: z2.literal("plugin"),
|
|
113
113
|
pluginId: z2.string(),
|
|
114
|
-
/**
|
|
115
|
-
* Named shared-UI icon hint supplied by the plugin mention item. Omitted
|
|
116
|
-
* by mentions persisted before icon hints were stored.
|
|
117
|
-
*/
|
|
118
114
|
icon: z2.string().nullable().optional(),
|
|
119
|
-
/**
|
|
120
|
-
* Opaque item reference minted by the server's mention search
|
|
121
|
-
* (`<providerId>:<provider item id>`); resolved back through the same
|
|
122
|
-
* plugin's mention provider at send time (plugin design §4.9).
|
|
123
|
-
*/
|
|
124
115
|
itemId: z2.string(),
|
|
125
116
|
label: z2.string()
|
|
126
117
|
})
|
|
@@ -159,21 +150,11 @@ var promptInputSchema = z2.discriminatedUnion("type", [
|
|
|
159
150
|
}),
|
|
160
151
|
z2.object({
|
|
161
152
|
type: z2.literal("localImage"),
|
|
162
|
-
/**
|
|
163
|
-
* Absolute paths and URI-like values are passed through to the runtime.
|
|
164
|
-
* Relative paths are server-managed attachment references, not workspace
|
|
165
|
-
* relative files.
|
|
166
|
-
*/
|
|
167
153
|
path: z2.string(),
|
|
168
154
|
...promptInputVisibilityFields
|
|
169
155
|
}),
|
|
170
156
|
z2.object({
|
|
171
157
|
type: z2.literal("localFile"),
|
|
172
|
-
/**
|
|
173
|
-
* Absolute paths and URI-like values are passed through to the runtime.
|
|
174
|
-
* Relative paths are server-managed attachment references, not workspace
|
|
175
|
-
* relative files.
|
|
176
|
-
*/
|
|
177
158
|
path: z2.string(),
|
|
178
159
|
name: z2.string().optional(),
|
|
179
160
|
sizeBytes: z2.number().int().nonnegative().optional(),
|
|
@@ -241,13 +222,7 @@ var runtimeThreadExecutionBaseOptionsSchema = z2.object({
|
|
|
241
222
|
model: z2.string().min(1),
|
|
242
223
|
serviceTier: serviceTierSchema,
|
|
243
224
|
reasoningLevel: reasoningLevelSchema,
|
|
244
|
-
/** Present only when the prompt entered a BB prompt mode. */
|
|
245
225
|
promptMode: promptModeSchema.optional(),
|
|
246
|
-
/**
|
|
247
|
-
* Plugin-derived, provider-scoped options. Always present — an empty
|
|
248
|
-
* object when the provider derives none — so the daemon never has to
|
|
249
|
-
* guess whether the server ran the hook.
|
|
250
|
-
*/
|
|
251
226
|
providerOptions: jsonObjectSchema
|
|
252
227
|
});
|
|
253
228
|
var runtimeThreadExecutionOptionsSchema = runtimeThreadExecutionBaseOptionsSchema.and(runtimePermissionPolicySchema);
|
|
@@ -280,7 +255,6 @@ var workflowAgentStateValues = [
|
|
|
280
255
|
];
|
|
281
256
|
var workflowAgentStateSchema = z3.enum(workflowAgentStateValues);
|
|
282
257
|
var workflowAgentSnapshotSchema = z3.object({
|
|
283
|
-
/** 1-based agent counter; the stable identity for fold/replace semantics. */
|
|
284
258
|
index: z3.number().int().positive(),
|
|
285
259
|
label: z3.string(),
|
|
286
260
|
state: workflowAgentStateSchema,
|
|
@@ -304,10 +278,8 @@ var workflowAgentSnapshotSchema = z3.object({
|
|
|
304
278
|
durationMs: z3.number().optional()
|
|
305
279
|
});
|
|
306
280
|
var workflowPhaseSnapshotSchema = z3.object({
|
|
307
|
-
/** 1-based phase counter; meta.phases are seeded before any agent runs. */
|
|
308
281
|
index: z3.number().int().positive(),
|
|
309
282
|
title: z3.string(),
|
|
310
|
-
/** "child" marks a nested workflow() sub-run group. */
|
|
311
283
|
kind: z3.string().optional()
|
|
312
284
|
});
|
|
313
285
|
var workflowProgressSnapshotSchema = z3.object({
|
|
@@ -340,9 +312,7 @@ function jsonByteLength(value) {
|
|
|
340
312
|
import { z as z4 } from "zod";
|
|
341
313
|
var THREAD_EVENT_ITEM_PRESENTATION_DETAIL_MAX_LENGTH = 280;
|
|
342
314
|
var threadEventItemPresentationLabelSchema = z4.object({
|
|
343
|
-
/** Present-tense row title while the item is in flight ("Reading file"). */
|
|
344
315
|
pending: z4.string().min(1),
|
|
345
|
-
/** Past-tense row title once the item settled ("Read file"). */
|
|
346
316
|
completed: z4.string().min(1)
|
|
347
317
|
});
|
|
348
318
|
var threadEventItemPresentationIconSchema = z4.object({
|
|
@@ -355,16 +325,9 @@ var threadEventItemPresentationTintSchema = z4.object({
|
|
|
355
325
|
var threadEventItemPresentationSchema = z4.object({
|
|
356
326
|
label: threadEventItemPresentationLabelSchema,
|
|
357
327
|
icon: threadEventItemPresentationIconSchema,
|
|
358
|
-
/** Row headline beside the label (a path, a query, a child thread title). */
|
|
359
328
|
title: z4.string().optional(),
|
|
360
|
-
/**
|
|
361
|
-
* Short Markdown summary shown in the row body. Length-capped here so a
|
|
362
|
-
* bridge cannot turn the persisted row into a transcript.
|
|
363
|
-
*/
|
|
364
329
|
detail: z4.string().max(THREAD_EVENT_ITEM_PRESENTATION_DETAIL_MAX_LENGTH).optional(),
|
|
365
|
-
/** Low-value rows (TodoWrite, ToolSearch) clients collapse by default. */
|
|
366
330
|
suppress: z4.boolean().optional(),
|
|
367
|
-
/** Accent colour per theme; omitted rows use the neutral row tint. */
|
|
368
331
|
tint: threadEventItemPresentationTintSchema.optional()
|
|
369
332
|
});
|
|
370
333
|
|
|
@@ -484,9 +447,7 @@ var pendingInteractionPermissionGrantApprovalSubjectSchema = z6.object({
|
|
|
484
447
|
var pendingInteractionPlanApprovalSubjectSchema = z6.object({
|
|
485
448
|
kind: z6.literal("plan"),
|
|
486
449
|
itemId: z6.string().min(1),
|
|
487
|
-
/** The plan body, as Markdown. */
|
|
488
450
|
plan: z6.string().min(1),
|
|
489
|
-
/** Where the provider saved the plan, or null when it kept it in memory. */
|
|
490
451
|
planFilePath: z6.string().min(1).nullable()
|
|
491
452
|
});
|
|
492
453
|
var pendingInteractionToolUseApprovalSubjectSchema = z6.object({
|
|
@@ -788,21 +749,13 @@ var systemEventTypeValues = [
|
|
|
788
749
|
"client/turn/rejected",
|
|
789
750
|
"client/turn/start",
|
|
790
751
|
"system/error",
|
|
791
|
-
// Legacy persisted user-visible system event from a removed runtime path.
|
|
792
|
-
// Retained for read/decode/render compatibility only.
|
|
793
752
|
"system/manager/user_message",
|
|
794
753
|
"system/thread/interrupted",
|
|
795
754
|
"system/operation",
|
|
796
755
|
"system/interaction/lifecycle",
|
|
797
|
-
// Legacy persisted per-shape interaction events; every status change now
|
|
798
|
-
// appends one `system/interaction/lifecycle`. Retained for read/decode
|
|
799
|
-
// only: `convertLegacyStoredThreadEvent` projects a stored row into the
|
|
800
|
-
// lifecycle event, so no consumer sees these types.
|
|
801
756
|
"system/permissionGrant/lifecycle",
|
|
802
757
|
"system/userQuestion/lifecycle",
|
|
803
758
|
"system/thread-provisioning",
|
|
804
|
-
// Legacy persisted watchdog diagnostic; retained for read/decode/render
|
|
805
|
-
// only, with no current producer.
|
|
806
759
|
"system/provider-turn-watchdog"
|
|
807
760
|
];
|
|
808
761
|
var threadTurnInitiatorValues = ["user", "agent", "system"];
|
|
@@ -854,18 +807,10 @@ var clientTurnLifecycleEventDataSchema = z8.object({
|
|
|
854
807
|
var turnRequestEventDataSchema = z8.object({
|
|
855
808
|
direction: z8.literal("outbound"),
|
|
856
809
|
requestId: clientTurnRequestIdSchema,
|
|
857
|
-
/** Failed request resumed by a guarded system continuation, when present. */
|
|
858
810
|
continuationOfRequestId: clientTurnRequestIdSchema.optional(),
|
|
859
811
|
source: z8.enum(["spawn", "tell"]),
|
|
860
812
|
initiator: threadTurnInitiatorSchema,
|
|
861
|
-
// Non-null only when initiator === "agent". The invariant is enforced by
|
|
862
|
-
// writer typings rather than a schema refine so legacy persisted events
|
|
863
|
-
// (initiator: "agent", senderThreadId: null from before the field
|
|
864
|
-
// existed) still parse — the stored variant defaults both fields.
|
|
865
813
|
senderThreadId: z8.string().nullable(),
|
|
866
|
-
// Family-B system-message taxonomy fields. Optional at the persisted-event
|
|
867
|
-
// level: legacy events (pre-taxonomy) lack them and must still parse. The
|
|
868
|
-
// projection defaults absent values to `unlabeled` / `null`.
|
|
869
814
|
systemMessageKind: systemMessageKindSchema.optional(),
|
|
870
815
|
systemMessageSubject: systemMessageSubjectSchema.nullable().optional(),
|
|
871
816
|
input: z8.array(promptInputSchema),
|
|
@@ -951,15 +896,14 @@ var systemUserQuestionLifecycleEventDataSchema = z8.object({
|
|
|
951
896
|
var systemThreadInterruptedReasonValues = [
|
|
952
897
|
"manual-stop",
|
|
953
898
|
"host-daemon-restarted",
|
|
954
|
-
// Legacy persisted watchdog interruption; retained for read/replay only,
|
|
955
|
-
// with no current producer.
|
|
956
899
|
"provider-turn-idle"
|
|
957
900
|
];
|
|
958
901
|
var systemThreadInterruptedReasonSchema = z8.enum(
|
|
959
902
|
systemThreadInterruptedReasonValues
|
|
960
903
|
);
|
|
961
904
|
var systemThreadInterruptedEventDataSchema = z8.object({
|
|
962
|
-
reason: systemThreadInterruptedReasonSchema
|
|
905
|
+
reason: systemThreadInterruptedReasonSchema,
|
|
906
|
+
cause: z8.literal("host-connection-lost").optional()
|
|
963
907
|
});
|
|
964
908
|
var provisioningTranscriptEntrySchema = z8.object({
|
|
965
909
|
type: z8.enum(["step", "output"]),
|
|
@@ -996,11 +940,6 @@ var systemProviderTurnWatchdogEventDataSchema = z8.object({
|
|
|
996
940
|
activeTurnId: z8.string().min(1),
|
|
997
941
|
activeTurnStartedAt: z8.number().int().nonnegative(),
|
|
998
942
|
lastActivityEventSequence: z8.number().int().positive(),
|
|
999
|
-
/**
|
|
1000
|
-
* Diagnostic label only (the UI interpolates it verbatim). A plain string —
|
|
1001
|
-
* not the activity enum — so editing event classifications never makes
|
|
1002
|
-
* previously persisted watchdog events unparseable.
|
|
1003
|
-
*/
|
|
1004
943
|
lastActivityEventType: z8.string().min(1),
|
|
1005
944
|
lastActivityEventAt: z8.number().int().nonnegative(),
|
|
1006
945
|
providerId: z8.string().min(1),
|
|
@@ -1272,7 +1211,6 @@ var providerRateLimitStatusSchema = z11.enum([
|
|
|
1272
1211
|
"unknown"
|
|
1273
1212
|
]);
|
|
1274
1213
|
var providerRateLimitWindowSchema = z11.object({
|
|
1275
|
-
/** Opaque provider-issued key. New provider windows must not break parsing. */
|
|
1276
1214
|
providerKey: z11.string().min(1).nullable(),
|
|
1277
1215
|
label: z11.string().min(1).nullable(),
|
|
1278
1216
|
status: providerRateLimitStatusSchema,
|
|
@@ -1357,11 +1295,9 @@ var threadEventDelegationItemSchema = z11.object({
|
|
|
1357
1295
|
type: z11.literal("delegation"),
|
|
1358
1296
|
id: z11.string(),
|
|
1359
1297
|
childRef: z11.string().min(1),
|
|
1360
|
-
/** Human label for the delegated work (the child's description). */
|
|
1361
1298
|
label: z11.string(),
|
|
1362
1299
|
status: threadEventItemStatusSchema,
|
|
1363
1300
|
background: z11.boolean(),
|
|
1364
|
-
/** Terminal summary from the child; absent while it runs. */
|
|
1365
1301
|
summary: z11.string().optional(),
|
|
1366
1302
|
...itemPresentationField,
|
|
1367
1303
|
parentToolCallId: z11.string().optional()
|
|
@@ -1422,10 +1358,6 @@ var threadEventWarningCategorySchema = z11.enum([
|
|
|
1422
1358
|
"deprecation",
|
|
1423
1359
|
"config",
|
|
1424
1360
|
"general",
|
|
1425
|
-
/**
|
|
1426
|
-
* The provider declined a compaction that bb asked for because there was
|
|
1427
|
-
* nothing to compact. The warning settles the pending compaction row.
|
|
1428
|
-
*/
|
|
1429
1361
|
"compaction-skipped"
|
|
1430
1362
|
]);
|
|
1431
1363
|
var providerRawEventSchema = z11.object({
|
|
@@ -1454,28 +1386,15 @@ var toolCallProgressEventSchema = z11.object({
|
|
|
1454
1386
|
var threadEventBackgroundTaskItemSchema = z11.object({
|
|
1455
1387
|
type: z11.literal("backgroundTask"),
|
|
1456
1388
|
id: z11.string(),
|
|
1457
|
-
/**
|
|
1458
|
-
* The provider's stable task id, shared by every generation (restart) of
|
|
1459
|
-
* the same task; consumers use it to correlate a restarted task with its
|
|
1460
|
-
* earlier generations. Absent only on events persisted before the field
|
|
1461
|
-
* existed — those encoded the family in the item id's legacy `#N`
|
|
1462
|
-
* generation suffix instead.
|
|
1463
|
-
*/
|
|
1464
1389
|
familyId: z11.string().optional(),
|
|
1465
|
-
/** Raw SDK task discriminant (e.g. "local_workflow"); "unknown" when the provider omitted it. */
|
|
1466
1390
|
taskType: z11.string(),
|
|
1467
1391
|
description: z11.string(),
|
|
1468
1392
|
status: threadEventItemStatusSchema,
|
|
1469
1393
|
taskStatus: backgroundTaskStatusSchema,
|
|
1470
|
-
/** Ambient/housekeeping task; consumers hide it from the inline transcript. */
|
|
1471
1394
|
skipTranscript: z11.boolean(),
|
|
1472
|
-
/** meta.name of the workflow script; only present for workflow tasks. */
|
|
1473
1395
|
workflowName: z11.string().optional(),
|
|
1474
|
-
/** Merged workflow tree; absent until the provider reports progress records. */
|
|
1475
1396
|
workflow: workflowProgressSnapshotSchema.optional(),
|
|
1476
|
-
/** Absent until the provider reports usage. */
|
|
1477
1397
|
usage: backgroundTaskUsageSchema.optional(),
|
|
1478
|
-
/** Terminal summary from the provider; absent while the task runs. */
|
|
1479
1398
|
summary: z11.string().optional(),
|
|
1480
1399
|
error: z11.string().optional(),
|
|
1481
1400
|
outputFile: z11.string().optional(),
|
|
@@ -1483,7 +1402,6 @@ var threadEventBackgroundTaskItemSchema = z11.object({
|
|
|
1483
1402
|
parentToolCallId: z11.string().optional()
|
|
1484
1403
|
});
|
|
1485
1404
|
var threadEventItemSchema = z11.discriminatedUnion("type", [
|
|
1486
|
-
// bb authors user messages itself, so they carry no bridge presentation.
|
|
1487
1405
|
z11.object({
|
|
1488
1406
|
type: z11.literal("userMessage"),
|
|
1489
1407
|
id: z11.string(),
|
|
@@ -1505,10 +1423,6 @@ var threadEventItemSchema = z11.discriminatedUnion("type", [
|
|
|
1505
1423
|
cwd: z11.string(),
|
|
1506
1424
|
status: threadEventItemStatusSchema,
|
|
1507
1425
|
approvalStatus: threadEventItemApprovalStatusSchema,
|
|
1508
|
-
/**
|
|
1509
|
-
* Omitted when the process produced no stdout/stderr. Adapters should omit
|
|
1510
|
-
* this field instead of emitting an empty string placeholder.
|
|
1511
|
-
*/
|
|
1512
1426
|
aggregatedOutput: z11.string().optional(),
|
|
1513
1427
|
exitCode: z11.number().optional(),
|
|
1514
1428
|
durationMs: z11.number().optional(),
|
|
@@ -1541,10 +1455,6 @@ var threadEventItemSchema = z11.discriminatedUnion("type", [
|
|
|
1541
1455
|
error: z11.string().optional(),
|
|
1542
1456
|
durationMs: z11.number().optional(),
|
|
1543
1457
|
truncation: threadEventItemTruncationSchema.optional(),
|
|
1544
|
-
/**
|
|
1545
|
-
* The escape hatch for tools with no core kind: the bridge says how the
|
|
1546
|
-
* row reads (label, glyph, headline, suppression).
|
|
1547
|
-
*/
|
|
1548
1458
|
...itemPresentationField,
|
|
1549
1459
|
parentToolCallId: z11.string().optional()
|
|
1550
1460
|
}),
|
|
@@ -1593,12 +1503,9 @@ var unscopedProviderEventSchema = z11.discriminatedUnion("type", [
|
|
|
1593
1503
|
z11.object({
|
|
1594
1504
|
type: z11.literal("turn/completed"),
|
|
1595
1505
|
threadId: z11.string(),
|
|
1596
|
-
// Server reconciliation can synthesize interrupted completions when the
|
|
1597
|
-
// original provider thread id was never persisted.
|
|
1598
1506
|
providerThreadId: z11.string().nullable(),
|
|
1599
1507
|
status: threadEventTurnStatusSchema,
|
|
1600
1508
|
error: z11.object({ message: z11.string() }).optional(),
|
|
1601
|
-
/** Provider-native point through which a replacement branch should retain history. */
|
|
1602
1509
|
providerCheckpointId: z11.string().min(1).optional()
|
|
1603
1510
|
}),
|
|
1604
1511
|
z11.object({
|
|
@@ -1665,10 +1572,6 @@ var unscopedProviderEventSchema = z11.discriminatedUnion("type", [
|
|
|
1665
1572
|
providerThreadId: z11.string(),
|
|
1666
1573
|
itemId: z11.string(),
|
|
1667
1574
|
delta: z11.string(),
|
|
1668
|
-
/**
|
|
1669
|
-
* When true, this delta replaces previously accumulated command output
|
|
1670
|
-
* instead of appending to it. Omission means the delta appends.
|
|
1671
|
-
*/
|
|
1672
1575
|
reset: z11.boolean().optional(),
|
|
1673
1576
|
parentToolCallId: z11.string().optional()
|
|
1674
1577
|
}),
|
|
@@ -1713,49 +1616,24 @@ var unscopedProviderEventSchema = z11.discriminatedUnion("type", [
|
|
|
1713
1616
|
parentToolCallId: z11.string().optional()
|
|
1714
1617
|
}),
|
|
1715
1618
|
toolCallProgressEventSchema,
|
|
1716
|
-
/**
|
|
1717
|
-
* Superseding state snapshot for an in-flight background task. Thread-scoped
|
|
1718
|
-
* (not turn-scoped) because tasks outlive their spawning turn: late events
|
|
1719
|
-
* must not interleave into later turns' sequence-contiguous windows. Each
|
|
1720
|
-
* progress event carries the full current item state; consumers replace, not
|
|
1721
|
-
* merge. The item is placed in the timeline by its turn-scoped item/started.
|
|
1722
|
-
*/
|
|
1723
1619
|
z11.object({
|
|
1724
1620
|
type: z11.literal("item/backgroundTask/progress"),
|
|
1725
1621
|
threadId: z11.string(),
|
|
1726
1622
|
providerThreadId: z11.string(),
|
|
1727
1623
|
item: threadEventBackgroundTaskItemSchema
|
|
1728
1624
|
}),
|
|
1729
|
-
/**
|
|
1730
|
-
* Terminal state for a background task, carrying the full final item
|
|
1731
|
-
* payload. Dedicated event (instead of the generic turn-scoped
|
|
1732
|
-
* item/completed) because it may arrive turns after the item/started.
|
|
1733
|
-
*/
|
|
1734
1625
|
z11.object({
|
|
1735
1626
|
type: z11.literal("item/backgroundTask/completed"),
|
|
1736
1627
|
threadId: z11.string(),
|
|
1737
1628
|
providerThreadId: z11.string(),
|
|
1738
1629
|
item: threadEventBackgroundTaskItemSchema
|
|
1739
1630
|
}),
|
|
1740
|
-
/**
|
|
1741
|
-
* Superseding snapshot for an in-flight background delegation (`background:
|
|
1742
|
-
* true`). Thread-scoped for the same reason as `item/backgroundTask/
|
|
1743
|
-
* progress`: a background child outlives its spawning turn, and late events
|
|
1744
|
-
* must not interleave into later turns' sequence-contiguous windows. The
|
|
1745
|
-
* item is placed in the timeline by its turn-scoped `item/started`.
|
|
1746
|
-
*/
|
|
1747
1631
|
z11.object({
|
|
1748
1632
|
type: z11.literal("item/delegation/progress"),
|
|
1749
1633
|
threadId: z11.string(),
|
|
1750
1634
|
providerThreadId: z11.string(),
|
|
1751
1635
|
item: threadEventDelegationItemSchema
|
|
1752
1636
|
}),
|
|
1753
|
-
/**
|
|
1754
|
-
* Terminal state for a background delegation, carrying the full final item.
|
|
1755
|
-
* Dedicated event (instead of the turn-scoped `item/completed`) because it
|
|
1756
|
-
* may arrive turns after the `item/started`. Foreground delegations settle
|
|
1757
|
-
* through `item/completed`.
|
|
1758
|
-
*/
|
|
1759
1637
|
z11.object({
|
|
1760
1638
|
type: z11.literal("item/delegation/completed"),
|
|
1761
1639
|
threadId: z11.string(),
|
|
@@ -1802,16 +1680,6 @@ var unscopedProviderEventSchema = z11.discriminatedUnion("type", [
|
|
|
1802
1680
|
providerThreadId: z11.string(),
|
|
1803
1681
|
rateLimits: providerRateLimitStateSchema
|
|
1804
1682
|
}),
|
|
1805
|
-
/**
|
|
1806
|
-
* Plugin-declared thread state (grammar v3): a `"<pluginId>/<name>"` kind
|
|
1807
|
-
* beside the core thread-state family (usage, context window, rate limits,
|
|
1808
|
-
* model fallback, context cleared). Latest snapshot wins per `kind`: a
|
|
1809
|
-
* bridge re-sends the whole state, never a diff, and a consumer keeps one
|
|
1810
|
-
* value per kind. The server validated `payload` against the owning
|
|
1811
|
-
* plugin's declared `state` schema at ingest; a payload that failed that
|
|
1812
|
-
* check was persisted as `provider/unhandled` instead, so every stored row
|
|
1813
|
-
* of this type carries a payload its plugin vouched for.
|
|
1814
|
-
*/
|
|
1815
1683
|
z11.object({
|
|
1816
1684
|
type: z11.literal("thread/extensionState/updated"),
|
|
1817
1685
|
threadId: z11.string(),
|
|
@@ -1997,8 +1865,6 @@ var availableModelSchema = z13.object({
|
|
|
1997
1865
|
id: z13.string(),
|
|
1998
1866
|
model: z13.string(),
|
|
1999
1867
|
displayName: z13.string(),
|
|
2000
|
-
/** Provider route used to run this model when it is distinct from the
|
|
2001
|
-
* selected agent provider (for example, a model provider nested under Pi). */
|
|
2002
1868
|
routeProviderId: z13.string().min(1).optional(),
|
|
2003
1869
|
description: z13.string(),
|
|
2004
1870
|
supportedReasoningEfforts: z13.array(modelReasoningEffortSchema),
|
|
@@ -2012,20 +1878,8 @@ var providerCapabilitiesSchema = z13.object({
|
|
|
2012
1878
|
supportsServiceTier: z13.boolean(),
|
|
2013
1879
|
supportsNativeUserQuestion: z13.boolean(),
|
|
2014
1880
|
supportsFork: z13.boolean(),
|
|
2015
|
-
/**
|
|
2016
|
-
* The provider can recreate a session at an earlier point, which is what
|
|
2017
|
-
* edit-past-message rewind needs. Separate from `supportsFork`: ACP clones
|
|
2018
|
-
* whole sessions (tip-only) and cannot stop at a checkpoint.
|
|
2019
|
-
*/
|
|
2020
1881
|
supportsSessionRewind: z13.boolean(),
|
|
2021
1882
|
permissionModes: z13.array(permissionModeSchema).min(1),
|
|
2022
|
-
/**
|
|
2023
|
-
* How far one `model/list` answer travels: `"host"` when the bridge answers
|
|
2024
|
-
* from account or agent state and ignores the workspace path, so bb probes
|
|
2025
|
-
* once per machine; `"workspace"` when project configuration can change the
|
|
2026
|
-
* answer. Declared by the provider's plugin — core never infers it from an
|
|
2027
|
-
* id.
|
|
2028
|
-
*/
|
|
2029
1883
|
modelCatalogScope: providerModelCatalogScopeSchema
|
|
2030
1884
|
});
|
|
2031
1885
|
var providerComposerCommandSchema = z13.object({
|
|
@@ -2048,17 +1902,11 @@ var providerComposerActionSchema = z13.discriminatedUnion("kind", [
|
|
|
2048
1902
|
})
|
|
2049
1903
|
]);
|
|
2050
1904
|
var providerStringsSchema = z13.object({
|
|
2051
|
-
/** How to sign in on the host ("Run `claude` on the machine to sign in."). */
|
|
2052
1905
|
signInHint: z13.string().min(1),
|
|
2053
|
-
/** Shown when a session's credentials expired. */
|
|
2054
1906
|
expiredHint: z13.string().min(1),
|
|
2055
|
-
/** Where to install the agent. */
|
|
2056
1907
|
installUrl: z13.string().min(1),
|
|
2057
|
-
/** Brand prefix stripped from model display names ("Claude "). */
|
|
2058
1908
|
brandPrefix: z13.string().min(1).optional(),
|
|
2059
|
-
/** Plan-mode banner copy for providers that declare the `plan` action. */
|
|
2060
1909
|
planModeCopy: z13.string().min(1).optional(),
|
|
2061
|
-
/** Per-theme tint for the provider icon. */
|
|
2062
1910
|
iconTint: z13.object({ light: z13.string().min(1), dark: z13.string().min(1) }).optional()
|
|
2063
1911
|
});
|
|
2064
1912
|
var providerOptionDescriptorSchema = z13.object({
|
|
@@ -2076,31 +1924,11 @@ var providerExtensionKindsSchema = z13.record(
|
|
|
2076
1924
|
);
|
|
2077
1925
|
var providerInfoSchema = z13.object({
|
|
2078
1926
|
id: z13.string(),
|
|
2079
|
-
/**
|
|
2080
|
-
* The plugin that registered the provider (`bb.providers.register`). The
|
|
2081
|
-
* owner of the provider's extension-kind namespace, and the bundle the
|
|
2082
|
-
* app loads on the first thread of this provider.
|
|
2083
|
-
*/
|
|
2084
1927
|
pluginId: z13.string().min(1),
|
|
2085
1928
|
displayName: z13.string(),
|
|
2086
|
-
/**
|
|
2087
|
-
* Declared grouping key shared by related providers (the ACP agents).
|
|
2088
|
-
* Absent when the provider declared none. Grouping only.
|
|
2089
|
-
*/
|
|
2090
1929
|
family: z13.string().min(1).optional(),
|
|
2091
|
-
/**
|
|
2092
|
-
* The declared icon, projected by form. A plugin-relative asset path
|
|
2093
|
-
* (`icon: "./icons/agent.svg"`) is served by the provider-logo route and
|
|
2094
|
-
* arrives here as `logoUrl`; a named host glyph (`icon: "Zap"`) has no
|
|
2095
|
-
* bytes to serve and arrives as `icon.glyph`, the same vocabulary an
|
|
2096
|
-
* item presentation's `icon` uses. A declaration names at most one form,
|
|
2097
|
-
* so at most one of the two is set; `icon` is absent when the declaration
|
|
2098
|
-
* named a path or nothing. Clients draw a vendored brand mark first, then
|
|
2099
|
-
* `logoUrl`, then `icon.glyph`, then the display name's initial.
|
|
2100
|
-
*/
|
|
2101
1930
|
icon: z13.object({ glyph: z13.string().min(1) }).optional(),
|
|
2102
1931
|
logoUrl: z13.string().min(1).nullable(),
|
|
2103
|
-
/** Sessionless maintenance requests the provider's bridge implements. */
|
|
2104
1932
|
maintenance: z13.object({
|
|
2105
1933
|
health: z13.boolean(),
|
|
2106
1934
|
usage: z13.boolean(),
|
|
@@ -2109,13 +1937,6 @@ var providerInfoSchema = z13.object({
|
|
|
2109
1937
|
capabilities: providerCapabilitiesSchema,
|
|
2110
1938
|
composerActions: z13.array(providerComposerActionSchema),
|
|
2111
1939
|
available: z13.boolean(),
|
|
2112
|
-
// -------------------------------------------------------------------------
|
|
2113
|
-
// Target-state projection (docs/provider-plugin-api.md §1). Optional and
|
|
2114
|
-
// unfilled until WS2a projects them from the plugin declaration; absence
|
|
2115
|
-
// means "the provider declared none", never a default. The
|
|
2116
|
-
// `capabilities.supports*` fields above stay until WS2a stabilizes the
|
|
2117
|
-
// surface as one unit.
|
|
2118
|
-
// -------------------------------------------------------------------------
|
|
2119
1940
|
strings: providerStringsSchema.optional(),
|
|
2120
1941
|
serviceTiers: z13.array(providerOptionDescriptorSchema).optional(),
|
|
2121
1942
|
reasoningLevels: z13.array(providerOptionDescriptorSchema).optional(),
|
|
@@ -2175,24 +1996,14 @@ var deltaItemKeySchema = z14.object({
|
|
|
2175
1996
|
var providerTurnIdSchema = deltaKeyPartSchema;
|
|
2176
1997
|
var deltaFileChangeSchema = z14.object({
|
|
2177
1998
|
path: z14.string(),
|
|
2178
|
-
/** The bridge states the change kind; the assembler never derives it. */
|
|
2179
1999
|
kind: z14.enum(["add", "update", "delete"]),
|
|
2180
2000
|
movePath: z14.string().optional(),
|
|
2181
|
-
/** Provider-supplied unified diff; preferred over old/new text building. */
|
|
2182
2001
|
diff: z14.string().optional(),
|
|
2183
2002
|
oldText: z14.string().optional(),
|
|
2184
|
-
/** When present the assembler builds the unified diff from old/new text. */
|
|
2185
2003
|
newText: z14.string().optional()
|
|
2186
2004
|
});
|
|
2187
2005
|
var deltaBackgroundTaskShapeSchema = z14.object({
|
|
2188
2006
|
type: z14.literal("backgroundTask"),
|
|
2189
|
-
/**
|
|
2190
|
-
* The provider's stable task id, shared by every generation (restart) of
|
|
2191
|
-
* the same task. Rides through to the canonical item so consumers can
|
|
2192
|
-
* correlate a restarted task with its earlier generations — the assembler
|
|
2193
|
-
* mints fresh item ids per generation, so identity must travel as data,
|
|
2194
|
-
* never as id text.
|
|
2195
|
-
*/
|
|
2196
2007
|
familyId: z14.string().min(1),
|
|
2197
2008
|
taskType: z14.string(),
|
|
2198
2009
|
description: z14.string(),
|
|
@@ -2246,20 +2057,8 @@ var deltaItemShapeSchema = z14.discriminatedUnion("type", [
|
|
|
2246
2057
|
}),
|
|
2247
2058
|
z14.object({
|
|
2248
2059
|
type: z14.literal("fileChange"),
|
|
2249
|
-
/** Empty while a path is not yet known, including bare close fallbacks. */
|
|
2250
2060
|
changes: z14.array(deltaFileChangeSchema)
|
|
2251
2061
|
}),
|
|
2252
|
-
/**
|
|
2253
|
-
* The generic tool call: the escape hatch for tools with no core kind. In
|
|
2254
|
-
* grammar v3 the bridge says how the row reads through the delta's
|
|
2255
|
-
* `presentation` (label, icon, suppression) instead of core keeping a
|
|
2256
|
-
* tool-name table. A `tool` item without presentation is read as legacy
|
|
2257
|
-
* data: `@bb/domain`'s `upgradeLegacyToolItem` reshapes read/grep/glob/
|
|
2258
|
-
* find/ls by name and suppresses the Task- and Todo-family bookkeeping
|
|
2259
|
-
* calls when the stored row is parsed, and any other name renders with
|
|
2260
|
-
* the generic tool row — until the backfill migration, after which
|
|
2261
|
-
* `presentation` is required.
|
|
2262
|
-
*/
|
|
2263
2062
|
z14.object({
|
|
2264
2063
|
type: z14.literal("tool"),
|
|
2265
2064
|
tool: z14.string(),
|
|
@@ -2289,7 +2088,6 @@ var deltaItemShapeSchema = z14.discriminatedUnion("type", [
|
|
|
2289
2088
|
}),
|
|
2290
2089
|
z14.object({ type: z14.literal("imageView"), path: z14.string() }),
|
|
2291
2090
|
deltaBackgroundTaskShapeSchema,
|
|
2292
|
-
// Grammar v3 shapes. Every existing shape above is kept unchanged.
|
|
2293
2091
|
deltaFileReadShapeSchema,
|
|
2294
2092
|
deltaSearchShapeSchema,
|
|
2295
2093
|
deltaDelegationShapeSchema,
|
|
@@ -2323,51 +2121,21 @@ function requireExtensionPresentation(delta, ctx) {
|
|
|
2323
2121
|
}
|
|
2324
2122
|
}
|
|
2325
2123
|
var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
2326
|
-
/**
|
|
2327
|
-
* The provider consumed an input (immediate or steered). The assembler owns
|
|
2328
|
-
* the queue-until-turn-opens behavior and the terminal-turn invariant.
|
|
2329
|
-
* With `providerTurnId` the acceptance is emitted against that vouched turn
|
|
2330
|
-
* directly (codex correlates acceptance to a named native turn).
|
|
2331
|
-
*/
|
|
2332
2124
|
z14.object({
|
|
2333
2125
|
kind: z14.literal("input.accepted"),
|
|
2334
2126
|
clientRequestId: clientTurnRequestIdSchema,
|
|
2335
2127
|
providerTurnId: providerTurnIdSchema.optional()
|
|
2336
2128
|
}),
|
|
2337
|
-
/**
|
|
2338
|
-
* Input the provider itself injected into the conversation, with no bb
|
|
2339
|
-
* client request behind it (a pi extension's `sendMessage` custom message
|
|
2340
|
-
* that triggered or steered a turn). The assembler records it as a
|
|
2341
|
-
* `userMessage` item in the open turn so the transcript shows what the
|
|
2342
|
-
* model was answering. Dropped silently when no turn is open: the provider
|
|
2343
|
-
* appended it to its own context without running the agent, so there is no
|
|
2344
|
-
* bb turn to attach it to.
|
|
2345
|
-
*/
|
|
2346
2129
|
z14.object({
|
|
2347
2130
|
kind: z14.literal("input.provider"),
|
|
2348
2131
|
text: z14.string().min(1),
|
|
2349
2132
|
parentRef: deltaKeyPartSchema.optional()
|
|
2350
2133
|
}),
|
|
2351
|
-
/**
|
|
2352
|
-
* An explicit provider signal opened work (pi `agent_start`, codex
|
|
2353
|
-
* `turn/started`). With `providerTurnId` the turn lives in the keyed
|
|
2354
|
-
* provider-turn space: several may be open at once (codex multiplexes
|
|
2355
|
-
* subagent child turns onto one thread) and none of the current-turn
|
|
2356
|
-
* machinery is touched.
|
|
2357
|
-
*/
|
|
2358
2134
|
z14.object({
|
|
2359
2135
|
kind: z14.literal("turn.open"),
|
|
2360
2136
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2361
|
-
/** Provider-native parent tool-call id for delegated child turns. */
|
|
2362
2137
|
parentRef: deltaKeyPartSchema.optional()
|
|
2363
2138
|
}),
|
|
2364
|
-
/**
|
|
2365
|
-
* The bridge's conclusion that the turn settled. `claimIfIdle: true` marks
|
|
2366
|
-
* fallback closers that own a turn only if accepted input is pending
|
|
2367
|
-
* (the old bridge-kit terminal-turn rule, applied centrally); an open turn is
|
|
2368
|
-
* always settled. A keyed boundary (`providerTurnId`) always emits — the
|
|
2369
|
-
* provider named the turn — and settles only that turn.
|
|
2370
|
-
*/
|
|
2371
2139
|
z14.object({
|
|
2372
2140
|
kind: z14.literal("turn.boundary"),
|
|
2373
2141
|
status: threadEventTurnStatusSchema,
|
|
@@ -2376,40 +2144,15 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2376
2144
|
claimIfIdle: z14.boolean().optional(),
|
|
2377
2145
|
providerTurnId: providerTurnIdSchema.optional()
|
|
2378
2146
|
}),
|
|
2379
|
-
/**
|
|
2380
|
-
* A parsed item opened. `attach: "currentOrLast"` pins the item to the turn
|
|
2381
|
-
* that is open or just closed without opening a new one (pi threshold
|
|
2382
|
-
* compaction); the default attaches to the open turn only. A known
|
|
2383
|
-
* `providerItemId` reuses its minted bb id (an explicit open reopens the
|
|
2384
|
-
* same item, codex's settle/reopen rule).
|
|
2385
|
-
*/
|
|
2386
2147
|
z14.object({
|
|
2387
2148
|
kind: z14.literal("item.open"),
|
|
2388
2149
|
key: deltaItemKeySchema,
|
|
2389
2150
|
item: deltaItemShapeSchema,
|
|
2390
|
-
/**
|
|
2391
|
-
* Grammar v3: how the row reads, persisted with the opened item. The
|
|
2392
|
-
* one place presentation travels. Optional for core shapes while v2
|
|
2393
|
-
* deltas are accepted; REQUIRED for `extension` shapes.
|
|
2394
|
-
*/
|
|
2395
2151
|
presentation: deltaPresentationSchema.optional(),
|
|
2396
2152
|
attach: deltaAttachSchema.optional(),
|
|
2397
2153
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2398
2154
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2399
2155
|
}).superRefine(requireExtensionPresentation),
|
|
2400
|
-
/**
|
|
2401
|
-
* The item settled. `item` is REQUIRED and always carries the full terminal
|
|
2402
|
-
* item shape (Michael's uniform close rule, 2026-08-18): the assembler
|
|
2403
|
-
* builds the completed item from it. With a same-shaped item open under the
|
|
2404
|
-
* key, the terminal shape wins and the opened item contributes only its
|
|
2405
|
-
* minted id; with a different-shaped item open, the assembler closes the
|
|
2406
|
-
* opened shape and then emits the terminal shape (ACP's dual-complete);
|
|
2407
|
-
* with nothing open it builds the bare completed item.
|
|
2408
|
-
*
|
|
2409
|
-
* Provider-identified closes (`key.providerItemId`) dedup: a repeated close
|
|
2410
|
-
* for a settled id is dropped and an explicit `item.open` reopens the id
|
|
2411
|
-
* (codex retries the terminal notification after approvals).
|
|
2412
|
-
*/
|
|
2413
2156
|
z14.object({
|
|
2414
2157
|
kind: z14.literal("item.close"),
|
|
2415
2158
|
key: deltaItemKeySchema,
|
|
@@ -2417,32 +2160,12 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2417
2160
|
resultText: z14.string().optional(),
|
|
2418
2161
|
exitCode: z14.number().optional(),
|
|
2419
2162
|
aggregatedOutput: z14.string().optional(),
|
|
2420
|
-
/** Terminal approval verdict (codex declined → denied). Default null. */
|
|
2421
2163
|
approvalStatus: z14.literal("denied").optional(),
|
|
2422
2164
|
item: deltaItemShapeSchema,
|
|
2423
|
-
/**
|
|
2424
|
-
* Grammar v3: the terminal presentation. Like `item`, the close carries
|
|
2425
|
-
* the full terminal form; when absent the opened item's presentation
|
|
2426
|
-
* survives onto the completed item (close-echo). REQUIRED for an
|
|
2427
|
-
* `extension` shape, which has nothing to echo without it.
|
|
2428
|
-
*/
|
|
2429
2165
|
presentation: deltaPresentationSchema.optional(),
|
|
2430
2166
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2431
2167
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2432
2168
|
}).superRefine(requireExtensionPresentation),
|
|
2433
|
-
/**
|
|
2434
|
-
* Free-form progress on an open item (non-command tool updates), or — with
|
|
2435
|
-
* `snapshot` — a re-embedded snapshot of work that outlives its turn: a
|
|
2436
|
-
* background task (`item/backgroundTask/progress`) or, in grammar v3, a
|
|
2437
|
-
* background delegation (`item/delegation/progress`); both thread-scoped,
|
|
2438
|
-
* no turn required.
|
|
2439
|
-
*
|
|
2440
|
-
* Progress is throttled centrally by the assembler (one emission per item
|
|
2441
|
-
* key per policy interval, 500ms default; the newest suppressed snapshot is
|
|
2442
|
-
* flushed trailing-edge on the thread's next traffic once the window
|
|
2443
|
-
* elapses, and an `item.close` supersedes it). `flush: true` bypasses the
|
|
2444
|
-
* throttle and resets the window — status transitions must land immediately.
|
|
2445
|
-
*/
|
|
2446
2169
|
z14.object({
|
|
2447
2170
|
kind: z14.literal("item.progress"),
|
|
2448
2171
|
key: deltaItemKeySchema,
|
|
@@ -2452,17 +2175,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2452
2175
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2453
2176
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2454
2177
|
}),
|
|
2455
|
-
/**
|
|
2456
|
-
* Streamed text — the one streaming dialect. Every text stream is keyed
|
|
2457
|
-
* like every other item: by the provider's own item id when the provider
|
|
2458
|
-
* names its message items (codex), or by a bridge-chosen `key.channel`
|
|
2459
|
-
* (`"assistant"`, `"thinking-2"`) plus `key.parentRef` for providers whose
|
|
2460
|
-
* streams are anonymous (claude, pi, acp). The first delta for an unknown
|
|
2461
|
-
* key synthesizes the channel's `item/started`; later deltas (and deltas
|
|
2462
|
-
* for a provider id already opened or settled) reuse the mapped id. The
|
|
2463
|
-
* assembler accumulates the stream text per open item so `item.textClose`
|
|
2464
|
-
* can settle without a provider-final text.
|
|
2465
|
-
*/
|
|
2466
2178
|
z14.object({
|
|
2467
2179
|
kind: z14.literal("item.textDelta"),
|
|
2468
2180
|
key: deltaItemKeySchema,
|
|
@@ -2471,18 +2183,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2471
2183
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2472
2184
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2473
2185
|
}),
|
|
2474
|
-
/**
|
|
2475
|
-
* Settle a text stream. `text` present: the provider's final text, preferred
|
|
2476
|
-
* over the accumulated stream (and enough on its own — a close for a key
|
|
2477
|
-
* nothing streamed under completes a fresh item). `text` absent: settle
|
|
2478
|
-
* with the accumulated stream text, completing nothing when the stream only
|
|
2479
|
-
* ever received whitespace. Either way the key is released, so later text
|
|
2480
|
-
* mints a fresh item. `channel` says which item to mint for a bare close
|
|
2481
|
-
* and where a provider-final `text` lands on a reasoning item. Providers
|
|
2482
|
-
* that name their message items may instead settle through `item.close`
|
|
2483
|
-
* with the full terminal shape (the uniform close rule) — that is the same
|
|
2484
|
-
* item lifecycle, not a second streaming dialect.
|
|
2485
|
-
*/
|
|
2486
2186
|
z14.object({
|
|
2487
2187
|
kind: z14.literal("item.textClose"),
|
|
2488
2188
|
key: deltaItemKeySchema,
|
|
@@ -2491,10 +2191,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2491
2191
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2492
2192
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2493
2193
|
}),
|
|
2494
|
-
/**
|
|
2495
|
-
* Item-keyed exact output append (codex command/fileChange output deltas).
|
|
2496
|
-
* Never synthesizes an open and never diffs — the text is already a delta.
|
|
2497
|
-
*/
|
|
2498
2194
|
z14.object({
|
|
2499
2195
|
kind: z14.literal("item.outputDelta"),
|
|
2500
2196
|
key: deltaItemKeySchema,
|
|
@@ -2503,26 +2199,12 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2503
2199
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2504
2200
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2505
2201
|
}),
|
|
2506
|
-
/**
|
|
2507
|
-
* Cumulative command output snapshot (pi bash). The assembler diffs
|
|
2508
|
-
* consecutive snapshots into `outputDelta`/`reset` events.
|
|
2509
|
-
*/
|
|
2510
2202
|
z14.object({
|
|
2511
2203
|
kind: z14.literal("command.outputSnapshot"),
|
|
2512
2204
|
key: deltaItemKeySchema,
|
|
2513
2205
|
text: z14.string(),
|
|
2514
2206
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2515
2207
|
}),
|
|
2516
|
-
/**
|
|
2517
|
-
* Provider-reported usage — the one usage dialect. `total` is the running
|
|
2518
|
-
* session total and `last` the most recent turn's usage; a provider that
|
|
2519
|
-
* reports exact cumulative totals (codex) forwards both verbatim, and a
|
|
2520
|
-
* provider that reports per-turn usage (claude, pi) sums `last` into
|
|
2521
|
-
* `total` itself (`addTokenUsage` in the bridge kit), resetting at every
|
|
2522
|
-
* session construction alongside `session.reset`. Emits
|
|
2523
|
-
* `thread/tokenUsage/updated` only: a provider whose usage also measures
|
|
2524
|
-
* the context window sends the `contextWindow` delta beside it.
|
|
2525
|
-
*/
|
|
2526
2208
|
z14.object({
|
|
2527
2209
|
kind: z14.literal("usage"),
|
|
2528
2210
|
total: threadEventTokenUsageBreakdownSchema,
|
|
@@ -2530,13 +2212,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2530
2212
|
modelContextWindow: z14.number().nullable(),
|
|
2531
2213
|
providerTurnId: providerTurnIdSchema.optional()
|
|
2532
2214
|
}),
|
|
2533
|
-
/**
|
|
2534
|
-
* Context-window meter. `attach: "currentOrLast"` legalizes post-turn
|
|
2535
|
-
* attachment (pi reports after `agent_end` for the turn that just closed);
|
|
2536
|
-
* a `providerTurnId` scopes the reading to that vouched turn instead
|
|
2537
|
-
* (codex measures the window per native turn) and `attach` is then
|
|
2538
|
-
* irrelevant.
|
|
2539
|
-
*/
|
|
2540
2215
|
z14.object({
|
|
2541
2216
|
kind: z14.literal("contextWindow"),
|
|
2542
2217
|
used: z14.number().nullable(),
|
|
@@ -2551,54 +2226,26 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2551
2226
|
noTurnFallback: deltaNoTurnFallbackSchema.optional()
|
|
2552
2227
|
}),
|
|
2553
2228
|
z14.object({ kind: z14.literal("context.cleared") }),
|
|
2554
|
-
/** The aggregate working-tree diff for a turn (codex turn/diff/updated). */
|
|
2555
2229
|
z14.object({
|
|
2556
2230
|
kind: z14.literal("turn.diff"),
|
|
2557
2231
|
diff: z14.string(),
|
|
2558
2232
|
providerTurnId: providerTurnIdSchema.optional()
|
|
2559
2233
|
}),
|
|
2560
|
-
// Thread metadata (codex thread lifecycle notifications).
|
|
2561
2234
|
z14.object({ kind: z14.literal("thread.started") }),
|
|
2562
2235
|
z14.object({
|
|
2563
2236
|
kind: z14.literal("thread.identity"),
|
|
2564
2237
|
providerThreadId: z14.string().min(1)
|
|
2565
2238
|
}),
|
|
2566
2239
|
z14.object({ kind: z14.literal("thread.name"), name: z14.string().min(1) }),
|
|
2567
|
-
/**
|
|
2568
|
-
* Plugin-declared thread state (grammar v3): `"<pluginId>/<name>"` kinds
|
|
2569
|
-
* beside the core thread-state family (usage, context window, rate limits,
|
|
2570
|
-
* model fallback, context cleared). Latest snapshot wins per kind — the
|
|
2571
|
-
* assembler and the timeline keep one value per `kind`, so a bridge re-sends
|
|
2572
|
-
* the whole state, never a diff. Codex goals ride this way (the codex
|
|
2573
|
-
* plugin's `provider-codex/goal`, a null payload once cleared). The payload
|
|
2574
|
-
* is opaque here; the server validates it against the plugin's declared
|
|
2575
|
-
* `state` schema at ingest (the same site as extension items).
|
|
2576
|
-
* The namespaced kind travels as `extensionKind` only because `kind` is
|
|
2577
|
-
* this union's discriminator; the item shape and the persisted item call
|
|
2578
|
-
* the same value `kind`.
|
|
2579
|
-
*/
|
|
2580
2240
|
z14.object({
|
|
2581
2241
|
kind: z14.literal("extension.state"),
|
|
2582
2242
|
extensionKind: extensionKindSchema,
|
|
2583
2243
|
payload: jsonValueSchema
|
|
2584
2244
|
}),
|
|
2585
|
-
/**
|
|
2586
|
-
* Normalized rate-limit snapshot. The provider-dialect merge (codex's
|
|
2587
|
-
* sticky rateLimitReachedType over sparse rolling updates) stays
|
|
2588
|
-
* bridge-side — it is seeded from a per-child post-initialize read the
|
|
2589
|
-
* assembler never sees.
|
|
2590
|
-
*/
|
|
2591
2245
|
z14.object({
|
|
2592
2246
|
kind: z14.literal("provider.rateLimits"),
|
|
2593
2247
|
rateLimits: providerRateLimitStateSchema
|
|
2594
2248
|
}),
|
|
2595
|
-
/**
|
|
2596
|
-
* Provider-reported error. `settlesTurn: true` also closes the turn that
|
|
2597
|
-
* owns the error as failed (an open turn, or one claimed through pending
|
|
2598
|
-
* accepted input). A `providerTurnId` scopes the error to that vouched
|
|
2599
|
-
* turn; `threadScoped: true` pins thread scope (codex errors without a
|
|
2600
|
-
* native turn id never attach to whatever turn happens to be open).
|
|
2601
|
-
*/
|
|
2602
2249
|
z14.object({
|
|
2603
2250
|
kind: z14.literal("provider.error"),
|
|
2604
2251
|
message: z14.string(),
|
|
@@ -2610,13 +2257,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2610
2257
|
providerTurnId: providerTurnIdSchema.optional(),
|
|
2611
2258
|
threadScoped: z14.boolean().optional()
|
|
2612
2259
|
}),
|
|
2613
|
-
/**
|
|
2614
|
-
* The provider switched models mid-flight (claude model fallback). Scoped to
|
|
2615
|
-
* the open-or-just-closed turn when one exists, thread scope otherwise (the
|
|
2616
|
-
* claude translator's currentOrLast rule). Cross-message dedup of the early
|
|
2617
|
-
* assistant fallback block against the later system duplicate stays
|
|
2618
|
-
* bridge-side — it is keyed by the bridge's own segment tracking.
|
|
2619
|
-
*/
|
|
2620
2260
|
z14.object({
|
|
2621
2261
|
kind: z14.literal("provider.modelFallback"),
|
|
2622
2262
|
originalModel: z14.string().min(1),
|
|
@@ -2624,10 +2264,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2624
2264
|
reason: z14.enum(["refusal", "provider"]),
|
|
2625
2265
|
message: z14.string()
|
|
2626
2266
|
}),
|
|
2627
|
-
/**
|
|
2628
|
-
* `vouchedTurn: true` scopes the warning to the open turn when one exists
|
|
2629
|
-
* (ACP warnings are turn-scoped mid-turn); default is thread scope.
|
|
2630
|
-
*/
|
|
2631
2267
|
z14.object({
|
|
2632
2268
|
kind: z14.literal("provider.warning"),
|
|
2633
2269
|
summary: z14.string().optional(),
|
|
@@ -2635,15 +2271,6 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2635
2271
|
category: threadEventWarningCategorySchema.optional(),
|
|
2636
2272
|
vouchedTurn: z14.boolean().optional()
|
|
2637
2273
|
}),
|
|
2638
|
-
/**
|
|
2639
|
-
* The bridge's visibility classification decided this raw event is unknown.
|
|
2640
|
-
* `vouchedTurn: true` scopes it to the open turn if one exists — the
|
|
2641
|
-
* only-caller-vouched-turn-ids rule — and `providerTurnId` scopes it to
|
|
2642
|
-
* that vouched provider turn. `onlyIfNoTurn: true` inverts the guard: the
|
|
2643
|
-
* event surfaces only when NO turn is open (the old translators'
|
|
2644
|
-
* "known event, no active turn" visibility fallback for events that
|
|
2645
|
-
* otherwise translate to silence) and is dropped entirely mid-turn.
|
|
2646
|
-
*/
|
|
2647
2274
|
z14.object({
|
|
2648
2275
|
kind: z14.literal("unhandled"),
|
|
2649
2276
|
raw: providerRawEventSchema,
|
|
@@ -2653,18 +2280,7 @@ var threadDeltaSchema = z14.discriminatedUnion("kind", [
|
|
|
2653
2280
|
parentRef: deltaKeyPartSchema.optional(),
|
|
2654
2281
|
providerTurnId: providerTurnIdSchema.optional()
|
|
2655
2282
|
}),
|
|
2656
|
-
/**
|
|
2657
|
-
* Lifecycle settlement: the session was interrupted. The assembler closes
|
|
2658
|
-
* the open turn and open items as interrupted.
|
|
2659
|
-
*/
|
|
2660
2283
|
z14.object({ kind: z14.literal("session.ended") }),
|
|
2661
|
-
/**
|
|
2662
|
-
* Provider-native id-space boundary: a new provider session was constructed
|
|
2663
|
-
* for this thread (start/resume/fork/rebuild), so its native turn/item ids
|
|
2664
|
-
* may repeat. Drops ALL assembly state for the thread — id maps, settled
|
|
2665
|
-
* sets, open items and streams; the bridge settles any open work first
|
|
2666
|
-
* (nothing is in flight at any construction site).
|
|
2667
|
-
*/
|
|
2668
2284
|
z14.object({ kind: z14.literal("session.reset") })
|
|
2669
2285
|
]);
|
|
2670
2286
|
var threadDeltaNotificationParamsSchema = z14.object({
|
|
@@ -4526,7 +4142,6 @@ var ConformanceClient = class {
|
|
|
4526
4142
|
collector;
|
|
4527
4143
|
nextId = 1;
|
|
4528
4144
|
log = [];
|
|
4529
|
-
/** Every assembled event, in wire order. */
|
|
4530
4145
|
events = [];
|
|
4531
4146
|
drainIntoLog() {
|
|
4532
4147
|
for (const raw of this.transport.takeMessages()) {
|
|
@@ -4570,7 +4185,6 @@ var ConformanceClient = class {
|
|
|
4570
4185
|
);
|
|
4571
4186
|
return id;
|
|
4572
4187
|
}
|
|
4573
|
-
/** Poll until `resolve` yields a value or the deadline passes (→ null). */
|
|
4574
4188
|
async waitFor(resolve3) {
|
|
4575
4189
|
const deadline = Date.now() + this.timeoutMs;
|
|
4576
4190
|
for (; ; ) {
|
|
@@ -4592,7 +4206,6 @@ var ConformanceClient = class {
|
|
|
4592
4206
|
)
|
|
4593
4207
|
);
|
|
4594
4208
|
}
|
|
4595
|
-
/** A settle window: drain for the given quiet period without expectations. */
|
|
4596
4209
|
async settle(quietMs) {
|
|
4597
4210
|
const deadline = Date.now() + quietMs;
|
|
4598
4211
|
while (Date.now() < deadline) {
|
|
@@ -4640,88 +4253,22 @@ function negotiateGrammarVersion(runtime, bridge) {
|
|
|
4640
4253
|
}
|
|
4641
4254
|
var bridgeSteerModeSchema = z18.enum(["inject", "queue"]);
|
|
4642
4255
|
var bridgeCapabilitiesSchema = z18.object({
|
|
4643
|
-
/**
|
|
4644
|
-
* A released session can be re-attached later from its persisted
|
|
4645
|
-
* providerThreadId. The per-session `sessionRestorable` flag on
|
|
4646
|
-
* thread-identity results refines this (an agent update can drop restore
|
|
4647
|
-
* support mid-flight); this handshake value is the default for sessions
|
|
4648
|
-
* that do not say.
|
|
4649
|
-
*/
|
|
4650
4256
|
sessionRestore: z18.boolean().default(false),
|
|
4651
|
-
/**
|
|
4652
|
-
* The bridge mirrors bb archive state into the provider's own session
|
|
4653
|
-
* list. When false the runtime never sends thread/archive or
|
|
4654
|
-
* thread/unarchive.
|
|
4655
|
-
*/
|
|
4656
4257
|
threadArchive: z18.boolean().default(false),
|
|
4657
|
-
/**
|
|
4658
|
-
* The bridge pushes bb thread titles to the provider. When false the
|
|
4659
|
-
* runtime never sends thread/name/set.
|
|
4660
|
-
*/
|
|
4661
4258
|
threadRename: z18.boolean().default(false),
|
|
4662
|
-
/** The bridge supports thread/goal/clear. */
|
|
4663
4259
|
threadGoalClear: z18.boolean().default(false),
|
|
4664
|
-
/**
|
|
4665
|
-
* Session cloning support ({@link providerForkSchema} — the same
|
|
4666
|
-
* vocabulary the provider declaration uses). The declaration is a ceiling
|
|
4667
|
-
* for UI affordances; this is the operative truth, and it may only narrow
|
|
4668
|
-
* the declaration, never widen it.
|
|
4669
|
-
*/
|
|
4670
4260
|
fork: providerForkSchema.default("none"),
|
|
4671
|
-
/**
|
|
4672
|
-
* Where the thread's approval policy is enforced. "runtime" bridges
|
|
4673
|
-
* forward every approval request and the runtime applies the thread
|
|
4674
|
-
* policy (including auto-deny). "provider" bridges enforce policy before
|
|
4675
|
-
* forwarding, so every forwarded request is already known to need user
|
|
4676
|
-
* input and the runtime must not reclassify it against mutable thread
|
|
4677
|
-
* settings.
|
|
4678
|
-
*/
|
|
4679
4261
|
approvalEnforcedBy: z18.enum(["runtime", "provider"]).default("runtime"),
|
|
4680
|
-
/**
|
|
4681
|
-
* The `thread/delta` grammar range this bridge speaks. A bridge that says
|
|
4682
|
-
* nothing is read as speaking exactly the protocol version it negotiated,
|
|
4683
|
-
* so the default is `[2, 2]` — never a wider range it never claimed.
|
|
4684
|
-
* Every bridge in this repo emits v3 and reports `[3, 3]`, and the
|
|
4685
|
-
* runtime's assembler speaks `[3, 3]` only (`ASSEMBLER_GRAMMAR_VERSIONS`),
|
|
4686
|
-
* so a bridge that takes the default is refused at startup: the two
|
|
4687
|
-
* ranges must intersect ({@link negotiateGrammarVersion}) and both sides
|
|
4688
|
-
* emit the highest common version.
|
|
4689
|
-
*/
|
|
4690
4262
|
grammarVersions: bridgeGrammarVersionsSchema.default([
|
|
4691
4263
|
PROVIDER_BRIDGE_PROTOCOL_VERSION,
|
|
4692
4264
|
PROVIDER_BRIDGE_PROTOCOL_VERSION
|
|
4693
4265
|
]),
|
|
4694
|
-
/**
|
|
4695
|
-
* Mid-turn steer delivery ({@link bridgeSteerModeSchema}). Defaults to
|
|
4696
|
-
* `queue`, the conservative reading: absence is the definite "no" the
|
|
4697
|
-
* rest of this handshake uses, and `inject` is the stronger promise (the
|
|
4698
|
-
* steer reaches the model before the turn ends) a bridge must make
|
|
4699
|
-
* explicitly. Nothing in the runtime, server, or clients reads it today:
|
|
4700
|
-
* `turn/steer` is sent either way, and a steer whose turn is gone is
|
|
4701
|
-
* dropped on the bridge's `staleTurn` recovery hint or `NO_ACTIVE_TURN`
|
|
4702
|
-
* error (`steerTurn` in @bb/agent-runtime), whatever the mode. claude,
|
|
4703
|
-
* codex, and pi declare `inject`; ACP and the echo example declare
|
|
4704
|
-
* `queue`.
|
|
4705
|
-
*/
|
|
4706
4266
|
steerMode: bridgeSteerModeSchema.default("queue"),
|
|
4707
|
-
/**
|
|
4708
|
-
* Which optional requests the bridge handles. `skills.configure`: the
|
|
4709
|
-
* bridge accepts `skills/configure` (bb's injected skill roots). When
|
|
4710
|
-
* false the runtime never sends it, so a bridge that answers unknown
|
|
4711
|
-
* methods with METHOD_NOT_FOUND — as the protocol instructs — still
|
|
4712
|
-
* starts threads; it simply runs without injected skills. A bridge that
|
|
4713
|
-
* handles the request declares it; the runtime never probes.
|
|
4714
|
-
*/
|
|
4715
4267
|
skills: z18.object({ configure: z18.boolean().default(false) }).default({ configure: false })
|
|
4716
4268
|
}).passthrough();
|
|
4717
4269
|
var initializeParamsSchema = z18.object({
|
|
4718
4270
|
protocolVersion: z18.number().int().positive(),
|
|
4719
4271
|
client: z18.object({ name: z18.string().min(1), version: z18.string().min(1) }),
|
|
4720
|
-
/**
|
|
4721
|
-
* The `thread/delta` grammar range the runtime's assembler accepts (see
|
|
4722
|
-
* {@link negotiateGrammarVersion}). A runtime that predates the field
|
|
4723
|
-
* reads as speaking exactly its protocol version.
|
|
4724
|
-
*/
|
|
4725
4272
|
grammarVersions: bridgeGrammarVersionsSchema.default([
|
|
4726
4273
|
PROVIDER_BRIDGE_PROTOCOL_VERSION,
|
|
4727
4274
|
PROVIDER_BRIDGE_PROTOCOL_VERSION
|
|
@@ -4729,8 +4276,6 @@ var initializeParamsSchema = z18.object({
|
|
|
4729
4276
|
}).passthrough();
|
|
4730
4277
|
var initializeResultSchema = z18.object({
|
|
4731
4278
|
protocolVersion: z18.number().int().positive(),
|
|
4732
|
-
// An absent capabilities block reads as "no capabilities" via the inner
|
|
4733
|
-
// per-field defaults, so older bridges parse to explicit values.
|
|
4734
4279
|
capabilities: z18.preprocess(
|
|
4735
4280
|
(value) => value ?? {},
|
|
4736
4281
|
bridgeCapabilitiesSchema
|
|
@@ -4743,16 +4288,9 @@ var bridgeExecutionOptionsSchema = z19.object({
|
|
|
4743
4288
|
model: z19.string().min(1).optional(),
|
|
4744
4289
|
serviceTier: serviceTierSchema.optional(),
|
|
4745
4290
|
reasoningLevel: reasoningLevelSchema.optional(),
|
|
4746
|
-
/**
|
|
4747
|
-
* BB prompt mode (`"plan"`), present only when the prompt entered one
|
|
4748
|
-
* through the provider's declared composer action. Each bridge maps it
|
|
4749
|
-
* onto the agent's native equivalent.
|
|
4750
|
-
*/
|
|
4751
4291
|
promptMode: promptModeSchema.optional(),
|
|
4752
|
-
/** Frozen for the life of a provider session; applied at construction. */
|
|
4753
4292
|
instructions: z19.string().optional(),
|
|
4754
4293
|
envVars: z19.record(z19.string(), z19.string()).optional(),
|
|
4755
|
-
/** Provider-scoped session options. Opaque outside the owning bridge. */
|
|
4756
4294
|
providerOptions: z19.record(z19.string(), z19.unknown()).optional()
|
|
4757
4295
|
}).and(runtimePermissionPolicySchema);
|
|
4758
4296
|
|
|
@@ -4763,9 +4301,7 @@ var providerMaintenanceParamsSchema = z20.object({
|
|
|
4763
4301
|
cwd: z20.string().min(1).optional(),
|
|
4764
4302
|
providerOptions: z20.record(z20.string(), z20.unknown()).optional()
|
|
4765
4303
|
}).passthrough();
|
|
4766
|
-
var providerInstallationRequirementSchema = z20.enum([
|
|
4767
|
-
"thread_rewind"
|
|
4768
|
-
]);
|
|
4304
|
+
var providerInstallationRequirementSchema = z20.enum(["thread_rewind"]);
|
|
4769
4305
|
var providerInstallationStatusParamsSchema = providerMaintenanceParamsSchema.extend({
|
|
4770
4306
|
requirement: providerInstallationRequirementSchema.optional()
|
|
4771
4307
|
});
|
|
@@ -4813,26 +4349,20 @@ var providerUsageSchema = z20.discriminatedUnion("status", [
|
|
|
4813
4349
|
accountEmail: z20.string().nullable().default(null)
|
|
4814
4350
|
}).passthrough()
|
|
4815
4351
|
]);
|
|
4816
|
-
var providerHealthResultSchema = z20.discriminatedUnion(
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
z20.object({
|
|
4831
|
-
supported: z20.literal(true),
|
|
4832
|
-
usage: providerUsageSchema
|
|
4833
|
-
}).passthrough()
|
|
4834
|
-
]
|
|
4835
|
-
);
|
|
4352
|
+
var providerHealthResultSchema = z20.discriminatedUnion("supported", [
|
|
4353
|
+
z20.object({ supported: z20.literal(false) }).passthrough(),
|
|
4354
|
+
z20.object({
|
|
4355
|
+
supported: z20.literal(true),
|
|
4356
|
+
health: providerHealthSchema
|
|
4357
|
+
}).passthrough()
|
|
4358
|
+
]);
|
|
4359
|
+
var providerUsageResultSchema = z20.discriminatedUnion("supported", [
|
|
4360
|
+
z20.object({ supported: z20.literal(false) }).passthrough(),
|
|
4361
|
+
z20.object({
|
|
4362
|
+
supported: z20.literal(true),
|
|
4363
|
+
usage: providerUsageSchema
|
|
4364
|
+
}).passthrough()
|
|
4365
|
+
]);
|
|
4836
4366
|
var providerInstallationActionKindSchema = z20.enum([
|
|
4837
4367
|
"install",
|
|
4838
4368
|
"update"
|
|
@@ -4869,28 +4399,34 @@ var providerInstallationCommandSchema = z20.object({
|
|
|
4869
4399
|
args: z20.array(z20.string()).max(64),
|
|
4870
4400
|
displayCommand: z20.string().min(1)
|
|
4871
4401
|
}).passthrough();
|
|
4872
|
-
var providerInstallationVerificationSchema = z20.discriminatedUnion(
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
kind: z20.literal("
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4402
|
+
var providerInstallationVerificationSchema = z20.discriminatedUnion(
|
|
4403
|
+
"kind",
|
|
4404
|
+
[
|
|
4405
|
+
z20.object({ kind: z20.literal("installed") }).passthrough(),
|
|
4406
|
+
z20.object({
|
|
4407
|
+
kind: z20.literal("version_changed"),
|
|
4408
|
+
previousVersion: z20.string().min(1)
|
|
4409
|
+
}).passthrough(),
|
|
4410
|
+
z20.object({
|
|
4411
|
+
kind: z20.literal("version_at_least"),
|
|
4412
|
+
version: z20.string().min(1)
|
|
4413
|
+
}).passthrough()
|
|
4414
|
+
]
|
|
4415
|
+
);
|
|
4416
|
+
var providerInstallationRunResultSchema = z20.discriminatedUnion(
|
|
4417
|
+
"available",
|
|
4418
|
+
[
|
|
4419
|
+
z20.object({
|
|
4420
|
+
available: z20.literal(false),
|
|
4421
|
+
message: z20.string().min(1)
|
|
4422
|
+
}).passthrough(),
|
|
4423
|
+
z20.object({
|
|
4424
|
+
available: z20.literal(true),
|
|
4425
|
+
command: providerInstallationCommandSchema,
|
|
4426
|
+
verification: providerInstallationVerificationSchema
|
|
4427
|
+
}).passthrough()
|
|
4428
|
+
]
|
|
4429
|
+
);
|
|
4894
4430
|
|
|
4895
4431
|
// ../provider-bridge-protocol/src/requests.ts
|
|
4896
4432
|
import { z as z21 } from "zod";
|
|
@@ -4934,24 +4470,12 @@ var threadResumeParamsSchema = z21.object({
|
|
|
4934
4470
|
var threadForkParamsSchema = z21.object({
|
|
4935
4471
|
...sessionConstructionFields,
|
|
4936
4472
|
sourceProviderThreadId: z21.string().min(1),
|
|
4937
|
-
/**
|
|
4938
|
-
* Absent means fork at the tip. Bridges whose handshake advertises
|
|
4939
|
-
* `fork: "tip"` reject a request carrying a checkpoint instead of
|
|
4940
|
-
* silently cloning more history than the bb timeline shows.
|
|
4941
|
-
*/
|
|
4942
4473
|
sourceProviderCheckpointId: z21.string().min(1).optional()
|
|
4943
4474
|
}).passthrough();
|
|
4944
4475
|
var threadStopParamsSchema = z21.object({
|
|
4945
4476
|
threadId: z21.string().min(1),
|
|
4946
4477
|
providerThreadId: z21.string().min(1),
|
|
4947
|
-
/**
|
|
4948
|
-
* "interrupt" stops an active turn and settles it as interrupted.
|
|
4949
|
-
* "release" detaches an idle session so its resources can be reclaimed;
|
|
4950
|
-
* it must never fabricate an interruption. One verb serving both intents
|
|
4951
|
-
* is the #1584 incident — the field is required.
|
|
4952
|
-
*/
|
|
4953
4478
|
intent: z21.enum(["interrupt", "release"]),
|
|
4954
|
-
/** Non-null when the stop interrupts an active provider turn. */
|
|
4955
4479
|
activeTurnId: z21.string().min(1).nullable()
|
|
4956
4480
|
}).passthrough();
|
|
4957
4481
|
var threadRefParams = z21.object({
|
|
@@ -4990,7 +4514,6 @@ var skillsConfigureParamsSchema = z21.object({
|
|
|
4990
4514
|
}).passthrough();
|
|
4991
4515
|
var threadIdentityResultSchema = z21.object({
|
|
4992
4516
|
providerThreadId: z21.string().min(1),
|
|
4993
|
-
/** Refines the handshake's `sessionRestore` for this session. */
|
|
4994
4517
|
sessionRestorable: z21.boolean().optional()
|
|
4995
4518
|
}).passthrough();
|
|
4996
4519
|
var modelListResultSchema = z21.object({
|
|
@@ -5004,17 +4527,11 @@ import { z as z23 } from "zod";
|
|
|
5004
4527
|
// ../provider-bridge-protocol/src/errors.ts
|
|
5005
4528
|
import { z as z22 } from "zod";
|
|
5006
4529
|
var BRIDGE_JSON_RPC_ERRORS = {
|
|
5007
|
-
/** Standard JSON-RPC: params failed schema validation. */
|
|
5008
4530
|
INVALID_PARAMS: -32602,
|
|
5009
|
-
/** Standard JSON-RPC: method not implemented by this bridge. */
|
|
5010
4531
|
METHOD_NOT_FOUND: -32601,
|
|
5011
|
-
/** Generic bridge failure. */
|
|
5012
4532
|
BRIDGE_ERROR: -32e3,
|
|
5013
|
-
/** A turn/steer arrived but the session has no active turn. */
|
|
5014
4533
|
NO_ACTIVE_TURN: -32001,
|
|
5015
|
-
/** thread/resume for a session the provider can no longer restore. */
|
|
5016
4534
|
SESSION_NOT_RESTORABLE: -32002,
|
|
5017
|
-
/** thread/fork with a checkpoint on a bridge that only forks at the tip. */
|
|
5018
4535
|
FORK_CHECKPOINT_UNSUPPORTED: -32003
|
|
5019
4536
|
};
|
|
5020
4537
|
var providerRecoveryHintSchema = z22.object({
|
|
@@ -5028,16 +4545,12 @@ var bridgeErrorDataSchema = z22.object({ recovery: providerRecoveryHintSchema.op
|
|
|
5028
4545
|
var threadIdentityNotificationSchema = z23.object({
|
|
5029
4546
|
threadId: z23.string().min(1),
|
|
5030
4547
|
providerThreadId: z23.string().min(1),
|
|
5031
|
-
/** Refines the handshake's `sessionRestore` for this session. */
|
|
5032
4548
|
sessionRestorable: z23.boolean().optional()
|
|
5033
4549
|
}).passthrough();
|
|
5034
4550
|
var sessionReplacedNotificationSchema = z23.object({
|
|
5035
4551
|
threadId: z23.string().min(1),
|
|
5036
|
-
/** Identity of the replacement session (may equal the old identity). */
|
|
5037
4552
|
providerThreadId: z23.string().min(1).nullable(),
|
|
5038
|
-
/** Human-readable cause, shown in the timeline. */
|
|
5039
4553
|
reason: z23.string().min(1),
|
|
5040
|
-
/** True when provider-side context did not survive the replacement. */
|
|
5041
4554
|
contextLost: z23.boolean().default(false)
|
|
5042
4555
|
}).passthrough();
|
|
5043
4556
|
var providerRawNotificationSchema = z23.object({
|
|
@@ -5081,14 +4594,6 @@ var interactionRequestParamsSchema = z24.object({
|
|
|
5081
4594
|
threadId: z24.string().min(1).optional(),
|
|
5082
4595
|
turnId: z24.union([z24.string().min(1), z24.null()]),
|
|
5083
4596
|
payload: pendingInteractionPayloadSchema,
|
|
5084
|
-
/**
|
|
5085
|
-
* The request's turn id and approval-subject item ids are in the
|
|
5086
|
-
* provider's native id space (a `thread/delta` bridge holds no bb ids):
|
|
5087
|
-
* the runtime adapter translates them through the delta assembler's maps
|
|
5088
|
-
* before the interaction reaches the app. Omission means the ids are
|
|
5089
|
-
* already app-visible (bridges whose approval subjects never referenced
|
|
5090
|
-
* timeline ids — ACP's approval ids never matched timeline ids).
|
|
5091
|
-
*/
|
|
5092
4597
|
providerNativeIds: z24.boolean().optional()
|
|
5093
4598
|
}).passthrough();
|
|
5094
4599
|
|
|
@@ -5332,7 +4837,10 @@ function checkPresentationIconsDeclared(events, icons) {
|
|
|
5332
4837
|
"no item carried a presentation to inspect"
|
|
5333
4838
|
);
|
|
5334
4839
|
}
|
|
5335
|
-
return pass(
|
|
4840
|
+
return pass(
|
|
4841
|
+
PRESENTATION_ICONS_DECLARED_ID,
|
|
4842
|
+
PRESENTATION_ICONS_DECLARED_TITLE
|
|
4843
|
+
);
|
|
5336
4844
|
}
|
|
5337
4845
|
async function runRpcHygieneScenarios(client) {
|
|
5338
4846
|
const results = [];
|
|
@@ -5452,7 +4960,9 @@ async function runHandshakeScenario(client) {
|
|
|
5452
4960
|
const parsed = initializeResultSchema.safeParse(response.result);
|
|
5453
4961
|
if (!parsed.success) {
|
|
5454
4962
|
return failed(
|
|
5455
|
-
`result did not parse: ${parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(
|
|
4963
|
+
`result did not parse: ${parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(
|
|
4964
|
+
"; "
|
|
4965
|
+
)} (got ${JSON.stringify(response.result ?? response.error)})`
|
|
5456
4966
|
);
|
|
5457
4967
|
}
|
|
5458
4968
|
if (parsed.data.protocolVersion !== PROVIDER_BRIDGE_PROTOCOL_VERSION) {
|
|
@@ -5824,7 +5334,11 @@ async function runForkIdentityScenario(context, threadId) {
|
|
|
5824
5334
|
const response = await client.waitForResponse(forkId);
|
|
5825
5335
|
if (response === null) {
|
|
5826
5336
|
return [
|
|
5827
|
-
fail(
|
|
5337
|
+
fail(
|
|
5338
|
+
FORK_IDENTITY_ID,
|
|
5339
|
+
FORK_IDENTITY_TITLE,
|
|
5340
|
+
"thread/fork was not answered"
|
|
5341
|
+
)
|
|
5828
5342
|
];
|
|
5829
5343
|
}
|
|
5830
5344
|
if (response.error !== void 0) {
|
|
@@ -6018,7 +5532,11 @@ async function runInterruptStopScenario(context, threadId) {
|
|
|
6018
5532
|
const stopResponse = await client.waitForResponse(stopId);
|
|
6019
5533
|
if (stopResponse === null) {
|
|
6020
5534
|
return [
|
|
6021
|
-
fail(
|
|
5535
|
+
fail(
|
|
5536
|
+
INTERRUPT_SETTLES_ID,
|
|
5537
|
+
INTERRUPT_SETTLES_TITLE,
|
|
5538
|
+
"thread/stop was not answered"
|
|
5539
|
+
)
|
|
6022
5540
|
];
|
|
6023
5541
|
}
|
|
6024
5542
|
if (stopResponse.error !== void 0) {
|
|
@@ -6334,11 +5852,7 @@ async function runBridgeConformance(options) {
|
|
|
6334
5852
|
...await runSessionLifecycleScenarios({
|
|
6335
5853
|
client,
|
|
6336
5854
|
fixture: options.session,
|
|
6337
|
-
// The same reverse mapping the runtime applies when it names a turn
|
|
6338
|
-
// to the bridge: the assembler's provider↔bb turn-id map.
|
|
6339
5855
|
resolveProviderTurnId: (threadId, bbTurnId) => collector.assembler.getProviderTurnId(threadId, bbTurnId),
|
|
6340
|
-
// A failed handshake reads as the definite absences the schema
|
|
6341
|
-
// defaults to: no fork, so the fork rule is not attempted.
|
|
6342
5856
|
fork: handshake.capabilities?.fork ?? "none"
|
|
6343
5857
|
})
|
|
6344
5858
|
);
|
|
@@ -6556,7 +6070,13 @@ function describeCalibrationEvents(events) {
|
|
|
6556
6070
|
|
|
6557
6071
|
// ../provider-bridge-protocol/src/testing/parity.ts
|
|
6558
6072
|
import { spawn } from "node:child_process";
|
|
6559
|
-
import {
|
|
6073
|
+
import {
|
|
6074
|
+
existsSync as existsSync2,
|
|
6075
|
+
mkdtempSync,
|
|
6076
|
+
realpathSync,
|
|
6077
|
+
rmSync,
|
|
6078
|
+
writeFileSync
|
|
6079
|
+
} from "node:fs";
|
|
6560
6080
|
import { tmpdir } from "node:os";
|
|
6561
6081
|
import { isAbsolute, join as join2, resolve as resolve2 } from "node:path";
|
|
6562
6082
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -6632,7 +6152,10 @@ function bridgeRecordingFileName(direction) {
|
|
|
6632
6152
|
var COMMITTED_RECORDINGS_ROOT = fileURLToPath(
|
|
6633
6153
|
new URL("../../recordings", import.meta.url)
|
|
6634
6154
|
);
|
|
6635
|
-
var RECORDINGS_CHECKOUT_ROOT = resolve(
|
|
6155
|
+
var RECORDINGS_CHECKOUT_ROOT = resolve(
|
|
6156
|
+
COMMITTED_RECORDINGS_ROOT,
|
|
6157
|
+
"../../.."
|
|
6158
|
+
);
|
|
6636
6159
|
function compareRecordingEntries(left, right) {
|
|
6637
6160
|
return left.run - right.run || left.seq - right.seq;
|
|
6638
6161
|
}
|
|
@@ -6662,7 +6185,9 @@ function readBridgeRecordingLane(dir, direction) {
|
|
|
6662
6185
|
if (raw.length === 0) continue;
|
|
6663
6186
|
const entry = parseEntry(raw, file, index + 1);
|
|
6664
6187
|
if (entry.dir !== direction) {
|
|
6665
|
-
throw new Error(
|
|
6188
|
+
throw new Error(
|
|
6189
|
+
`${file}:${index + 1}: entry direction ${entry.dir} in the ${direction} lane`
|
|
6190
|
+
);
|
|
6666
6191
|
}
|
|
6667
6192
|
entries.push(entry);
|
|
6668
6193
|
}
|
|
@@ -6680,7 +6205,9 @@ function readCurrentBridgeLane(dir) {
|
|
|
6680
6205
|
if (raw.length === 0) continue;
|
|
6681
6206
|
const entry = parseEntry(raw, file, index + 1);
|
|
6682
6207
|
if (entry.dir !== "bridge\u2192runtime") {
|
|
6683
|
-
throw new Error(
|
|
6208
|
+
throw new Error(
|
|
6209
|
+
`${file}:${index + 1}: entry direction ${entry.dir} in the current bridge lane`
|
|
6210
|
+
);
|
|
6684
6211
|
}
|
|
6685
6212
|
entries.push(entry);
|
|
6686
6213
|
}
|
|
@@ -6700,7 +6227,9 @@ function withCurrentBridgeLane(recording) {
|
|
|
6700
6227
|
}
|
|
6701
6228
|
function readBridgeRecording(dir) {
|
|
6702
6229
|
const manifestPath = join(dir, "manifest.json");
|
|
6703
|
-
const manifest = existsSync(manifestPath) ? JSON.parse(
|
|
6230
|
+
const manifest = existsSync(manifestPath) ? JSON.parse(
|
|
6231
|
+
readFileSync(manifestPath, "utf8")
|
|
6232
|
+
) : null;
|
|
6704
6233
|
const entries = [];
|
|
6705
6234
|
for (const direction of BRIDGE_RECORDING_DIRECTIONS) {
|
|
6706
6235
|
entries.push(...readBridgeRecordingLane(dir, direction));
|
|
@@ -6731,8 +6260,12 @@ function listRecordedCells(root) {
|
|
|
6731
6260
|
}
|
|
6732
6261
|
|
|
6733
6262
|
// ../provider-bridge-protocol/src/testing/parity.ts
|
|
6734
|
-
var SOURCE_BOOTSTRAP = fileURLToPath2(
|
|
6735
|
-
|
|
6263
|
+
var SOURCE_BOOTSTRAP = fileURLToPath2(
|
|
6264
|
+
new URL("../bridge-worker-entry.ts", import.meta.url)
|
|
6265
|
+
);
|
|
6266
|
+
var BUNDLED_BOOTSTRAP = fileURLToPath2(
|
|
6267
|
+
new URL("./provider-bridge-worker-entry.mjs", import.meta.url)
|
|
6268
|
+
);
|
|
6736
6269
|
function resolveProviderBridgeBootstrapPath() {
|
|
6737
6270
|
if (existsSync2(SOURCE_BOOTSTRAP)) return SOURCE_BOOTSTRAP;
|
|
6738
6271
|
if (existsSync2(BUNDLED_BOOTSTRAP)) return BUNDLED_BOOTSTRAP;
|
|
@@ -6754,7 +6287,9 @@ function defaultNodeArgs(bootstrapPath, modulePath) {
|
|
|
6754
6287
|
}
|
|
6755
6288
|
function resolveProviderBridgeLaunch(options) {
|
|
6756
6289
|
if (!isAbsolute(options.modulePath)) {
|
|
6757
|
-
throw new Error(
|
|
6290
|
+
throw new Error(
|
|
6291
|
+
`bridge module path must be absolute: ${options.modulePath}`
|
|
6292
|
+
);
|
|
6758
6293
|
}
|
|
6759
6294
|
const bootstrapPath = options.bootstrapPath ?? resolveProviderBridgeBootstrapPath();
|
|
6760
6295
|
const dataDir = options.dataDir ?? mkdtempSync(join2(tmpdir(), "bb-parity-data-"));
|
|
@@ -6869,7 +6404,9 @@ function methodOfRecordedBridgeRequest(recording, response, id) {
|
|
|
6869
6404
|
}
|
|
6870
6405
|
return void 0;
|
|
6871
6406
|
}
|
|
6872
|
-
var REPLAY_CHILD_PATH = fileURLToPath2(
|
|
6407
|
+
var REPLAY_CHILD_PATH = fileURLToPath2(
|
|
6408
|
+
new URL("./replay-provider-child.mjs", import.meta.url)
|
|
6409
|
+
);
|
|
6873
6410
|
var PARITY_INITIALIZE_ID = "parity-initialize";
|
|
6874
6411
|
function sleep(ms) {
|
|
6875
6412
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
@@ -6883,7 +6420,9 @@ async function replayRecording(options) {
|
|
|
6883
6420
|
const profile = options.profile ?? DEFAULT_REPLAY_PROFILE;
|
|
6884
6421
|
const recording = readBridgeRecording(options.recordingDir);
|
|
6885
6422
|
const stateDir = mkdtempSync(join2(tmpdir(), "bb-parity-replay-"));
|
|
6886
|
-
const workspaceDir = realpathSync(
|
|
6423
|
+
const workspaceDir = realpathSync(
|
|
6424
|
+
mkdtempSync(join2(tmpdir(), "bb-parity-ws-"))
|
|
6425
|
+
);
|
|
6887
6426
|
const replayCommand = [
|
|
6888
6427
|
process.execPath,
|
|
6889
6428
|
REPLAY_CHILD_PATH,
|
|
@@ -6951,7 +6490,11 @@ async function replayRecording(options) {
|
|
|
6951
6490
|
const recordedAnswers = /* @__PURE__ */ new Map();
|
|
6952
6491
|
for (const step of steps) {
|
|
6953
6492
|
if (step.message !== null && isResponse(step.message)) {
|
|
6954
|
-
const method = methodOfRecordedBridgeRequest(
|
|
6493
|
+
const method = methodOfRecordedBridgeRequest(
|
|
6494
|
+
recording,
|
|
6495
|
+
step.entry,
|
|
6496
|
+
step.message.id
|
|
6497
|
+
) ?? "?";
|
|
6955
6498
|
const queue = recordedAnswers.get(method) ?? [];
|
|
6956
6499
|
queue.push(step.message);
|
|
6957
6500
|
recordedAnswers.set(method, queue);
|
|
@@ -6976,7 +6519,9 @@ async function replayRecording(options) {
|
|
|
6976
6519
|
const queue = recordedAnswers.get(method);
|
|
6977
6520
|
const recorded = queue?.shift();
|
|
6978
6521
|
if (recorded === void 0) {
|
|
6979
|
-
stalls.push(
|
|
6522
|
+
stalls.push(
|
|
6523
|
+
`no recorded answer for bridge request ${method} (${String(message.id)})`
|
|
6524
|
+
);
|
|
6980
6525
|
write(
|
|
6981
6526
|
JSON.stringify({
|
|
6982
6527
|
jsonrpc: "2.0",
|
|
@@ -7003,7 +6548,10 @@ async function replayRecording(options) {
|
|
|
7003
6548
|
return;
|
|
7004
6549
|
}
|
|
7005
6550
|
if (isRequest(message)) {
|
|
7006
|
-
pendingBridgeRequests.push({
|
|
6551
|
+
pendingBridgeRequests.push({
|
|
6552
|
+
id: message.id,
|
|
6553
|
+
method: message.method
|
|
6554
|
+
});
|
|
7007
6555
|
answerBridgeRequest(message);
|
|
7008
6556
|
return;
|
|
7009
6557
|
}
|
|
@@ -7012,13 +6560,19 @@ async function replayRecording(options) {
|
|
|
7012
6560
|
try {
|
|
7013
6561
|
assembled = liveAssembler.assembleMessage(message);
|
|
7014
6562
|
} catch (error) {
|
|
7015
|
-
stalls.push(
|
|
6563
|
+
stalls.push(
|
|
6564
|
+
`invalid thread/delta: ${error instanceof Error ? error.message : String(error)}`
|
|
6565
|
+
);
|
|
7016
6566
|
return;
|
|
7017
6567
|
}
|
|
7018
6568
|
for (const event of assembled) {
|
|
7019
6569
|
const result2 = grammar.observe(event);
|
|
7020
6570
|
if (result2.kind === "violation") {
|
|
7021
|
-
grammarViolations.push({
|
|
6571
|
+
grammarViolations.push({
|
|
6572
|
+
rule: result2.rule,
|
|
6573
|
+
reason: result2.reason,
|
|
6574
|
+
eventType: event.type
|
|
6575
|
+
});
|
|
7022
6576
|
continue;
|
|
7023
6577
|
}
|
|
7024
6578
|
events.push(event);
|
|
@@ -7043,8 +6597,12 @@ async function replayRecording(options) {
|
|
|
7043
6597
|
await sleep(10);
|
|
7044
6598
|
}
|
|
7045
6599
|
}
|
|
7046
|
-
const firstStep = steps.find(
|
|
7047
|
-
|
|
6600
|
+
const firstStep = steps.find(
|
|
6601
|
+
(step) => step.message !== null && isRequest(step.message)
|
|
6602
|
+
);
|
|
6603
|
+
setCursor(
|
|
6604
|
+
firstStep === void 0 ? "end" : { run: firstStep.entry.run, seq: firstStep.entry.seq }
|
|
6605
|
+
);
|
|
7048
6606
|
write(
|
|
7049
6607
|
JSON.stringify({
|
|
7050
6608
|
jsonrpc: "2.0",
|
|
@@ -7061,7 +6619,11 @@ async function replayRecording(options) {
|
|
|
7061
6619
|
for (const step of steps) {
|
|
7062
6620
|
if (step.message === null || !isRequest(step.message)) {
|
|
7063
6621
|
if (step.message !== null && !isResponse(step.message)) {
|
|
7064
|
-
lastSentRuntimeEntry = {
|
|
6622
|
+
lastSentRuntimeEntry = {
|
|
6623
|
+
run: step.entry.run,
|
|
6624
|
+
seq: step.entry.seq,
|
|
6625
|
+
ts: step.entry.ts
|
|
6626
|
+
};
|
|
7065
6627
|
write(step.entry.line);
|
|
7066
6628
|
}
|
|
7067
6629
|
continue;
|
|
@@ -7096,23 +6658,40 @@ async function replayRecording(options) {
|
|
|
7096
6658
|
const threadId = request.params.threadId;
|
|
7097
6659
|
if (typeof threadId === "string") grammar.clearThread(threadId);
|
|
7098
6660
|
}
|
|
7099
|
-
const rewritten = rewriteRecordedMachineFacts(
|
|
6661
|
+
const rewritten = rewriteRecordedMachineFacts(
|
|
6662
|
+
step.entry.line,
|
|
6663
|
+
workspaceDir
|
|
6664
|
+
);
|
|
7100
6665
|
const line = profile.rewriteRuntimeLine === void 0 ? rewritten : profile.rewriteRuntimeLine(rewritten, { replayCommand });
|
|
7101
|
-
lastSentRuntimeEntry = {
|
|
6666
|
+
lastSentRuntimeEntry = {
|
|
6667
|
+
run: step.entry.run,
|
|
6668
|
+
seq: step.entry.seq,
|
|
6669
|
+
ts: step.entry.ts
|
|
6670
|
+
};
|
|
7102
6671
|
write(line);
|
|
7103
6672
|
sentRequestIds.push(String(request.id));
|
|
7104
|
-
const nextStep = steps.slice(steps.indexOf(step) + 1).find(
|
|
7105
|
-
|
|
6673
|
+
const nextStep = steps.slice(steps.indexOf(step) + 1).find(
|
|
6674
|
+
(candidate) => candidate.message !== null && isRequest(candidate.message)
|
|
6675
|
+
);
|
|
6676
|
+
setCursor(
|
|
6677
|
+
nextStep === void 0 ? "end" : { run: nextStep.entry.run, seq: nextStep.entry.seq }
|
|
6678
|
+
);
|
|
7106
6679
|
}
|
|
7107
6680
|
setCursor("end");
|
|
7108
|
-
await waitFor(
|
|
6681
|
+
await waitFor(
|
|
6682
|
+
"the last responses",
|
|
6683
|
+
() => sentRequestIds.every((id) => answeredIds.has(id))
|
|
6684
|
+
);
|
|
7109
6685
|
if (plannedEventCount !== null) {
|
|
7110
6686
|
await waitFor(
|
|
7111
6687
|
`all ${plannedEventCount} planned events before closing the bridge`,
|
|
7112
6688
|
() => events.length >= plannedEventCount
|
|
7113
6689
|
);
|
|
7114
6690
|
}
|
|
7115
|
-
await waitFor(
|
|
6691
|
+
await waitFor(
|
|
6692
|
+
"the stream to settle",
|
|
6693
|
+
() => Date.now() - lastOutputAt >= settleMs
|
|
6694
|
+
);
|
|
7116
6695
|
child.stdin?.end();
|
|
7117
6696
|
const exitCode = await Promise.race([
|
|
7118
6697
|
exited,
|
|
@@ -7154,18 +6733,25 @@ function assembleRecordedEvents(recording, createAssembler, providerId) {
|
|
|
7154
6733
|
}
|
|
7155
6734
|
if (entry.dir !== "bridge\u2192runtime") continue;
|
|
7156
6735
|
const message = parseWire(entry.line);
|
|
7157
|
-
if (message === null || message.method !== THREAD_DELTA_NOTIFICATION_METHOD)
|
|
6736
|
+
if (message === null || message.method !== THREAD_DELTA_NOTIFICATION_METHOD)
|
|
6737
|
+
continue;
|
|
7158
6738
|
let assembled;
|
|
7159
6739
|
try {
|
|
7160
6740
|
assembled = assembler.assembleMessage(message);
|
|
7161
6741
|
} catch (error) {
|
|
7162
|
-
invalidDeltas.push(
|
|
6742
|
+
invalidDeltas.push(
|
|
6743
|
+
error instanceof Error ? error.message : String(error)
|
|
6744
|
+
);
|
|
7163
6745
|
continue;
|
|
7164
6746
|
}
|
|
7165
6747
|
for (const event of assembled) {
|
|
7166
6748
|
const result2 = grammar.observe(event);
|
|
7167
6749
|
if (result2.kind === "violation") {
|
|
7168
|
-
grammarViolations.push({
|
|
6750
|
+
grammarViolations.push({
|
|
6751
|
+
rule: result2.rule,
|
|
6752
|
+
reason: result2.reason,
|
|
6753
|
+
eventType: event.type
|
|
6754
|
+
});
|
|
7169
6755
|
continue;
|
|
7170
6756
|
}
|
|
7171
6757
|
events.push(event);
|
|
@@ -7272,7 +6858,10 @@ function entryApplies(entry, provider, cell) {
|
|
|
7272
6858
|
}
|
|
7273
6859
|
function compareParity(oldRun, newRun, allowlist, scope) {
|
|
7274
6860
|
const layers = {
|
|
7275
|
-
events: [
|
|
6861
|
+
events: [
|
|
6862
|
+
normalizeParityEvents(oldRun.events),
|
|
6863
|
+
normalizeParityEvents(newRun.events)
|
|
6864
|
+
],
|
|
7276
6865
|
rows: [normalizeParityRows(oldRun.rows), normalizeParityRows(newRun.rows)]
|
|
7277
6866
|
};
|
|
7278
6867
|
const staleAllowlist = [];
|
|
@@ -7287,8 +6876,12 @@ function compareParity(oldRun, newRun, allowlist, scope) {
|
|
|
7287
6876
|
const events = diffLayer(layers.events[0], layers.events[1]);
|
|
7288
6877
|
const rows = diffLayer(layers.rows[0], layers.rows[1]);
|
|
7289
6878
|
const grammar = diffLayer(
|
|
7290
|
-
(oldRun.grammarViolations ?? []).map(
|
|
7291
|
-
|
|
6879
|
+
(oldRun.grammarViolations ?? []).map(
|
|
6880
|
+
(violation2) => `${violation2.rule}:${violation2.eventType}`
|
|
6881
|
+
),
|
|
6882
|
+
(newRun.grammarViolations ?? []).map(
|
|
6883
|
+
(violation2) => `${violation2.rule}:${violation2.eventType}`
|
|
6884
|
+
)
|
|
7292
6885
|
);
|
|
7293
6886
|
const clean = (diff) => diff.onlyInOld.length === 0 && diff.onlyInNew.length === 0;
|
|
7294
6887
|
return {
|
|
@@ -7322,7 +6915,12 @@ async function rerecordCurrentBridgeLane(options) {
|
|
|
7322
6915
|
const recording = readBridgeRecording(options.recordingDir);
|
|
7323
6916
|
const run = await replayRecording({ ...options, planFromCurrentLane: false });
|
|
7324
6917
|
if (run.stalls.length > 0) {
|
|
7325
|
-
return {
|
|
6918
|
+
return {
|
|
6919
|
+
file: null,
|
|
6920
|
+
lines: 0,
|
|
6921
|
+
events: run.events.length,
|
|
6922
|
+
stalls: run.stalls
|
|
6923
|
+
};
|
|
7326
6924
|
}
|
|
7327
6925
|
const firstRuntime = recording.entries.find(
|
|
7328
6926
|
(entry) => entry.dir === "runtime\u2192bridge"
|
|
@@ -7361,7 +6959,6 @@ async function rerecordCurrentBridgeLane(options) {
|
|
|
7361
6959
|
entries.push({
|
|
7362
6960
|
ts: anchor.ts + ordinal,
|
|
7363
6961
|
run: anchor.run,
|
|
7364
|
-
// Fractional: after the anchoring runtime entry, before the next one.
|
|
7365
6962
|
seq: anchor.seq + ordinal / (run.lines.length + 1),
|
|
7366
6963
|
dir: BRIDGE_TO_RUNTIME,
|
|
7367
6964
|
line
|