@get-bb/plugin-sdk 0.6.9 → 0.6.15
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-app.d.ts +218 -89
- package/bundled-types/bb-plugin-sdk-host.d.ts +4 -2
- package/bundled-types/bb-plugin-sdk-internal-composer-customization-validation.d.ts +1 -1
- package/bundled-types/bb-plugin-sdk-internal-composer-handle.d.ts +17 -10
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +8 -12
- package/bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts +9 -4
- package/bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts +6 -4
- package/bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts +1 -4
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +38 -31
- package/bundled-types/bb-plugin-sdk-testing.d.ts +4 -2
- package/bundled-types/bb-plugin-sdk.d.ts +222 -91
- package/dist/host.js +17 -14
- package/dist/internal/composer-customization-validation.js +20 -6
- package/dist/internal/composer-handle.js +2 -0
- package/dist/internal/host-policy.js +1 -0
- package/dist/internal/plugin-app-collector.js +44 -13
- package/dist/provider-bridge-acp.js +7662 -314
- package/dist/provider-bridge-testing.js +21 -6
- package/dist/provider-bridge-worker-entry.mjs +7 -2
- package/dist/provider-bridge.js +7401 -169
- package/dist/replay-provider-child.mjs +72 -0
- package/dist/testing/app.js +47 -14
- package/dist/testing/index.js +1 -0
- package/package.json +1 -1
|
@@ -354,6 +354,70 @@ function readNewlineDelimitedLines(input, onLine) {
|
|
|
354
354
|
// Player
|
|
355
355
|
// ---------------------------------------------------------------------------
|
|
356
356
|
|
|
357
|
+
function servePiCatalog(entries) {
|
|
358
|
+
const models = new Map();
|
|
359
|
+
let state = {};
|
|
360
|
+
for (const entry of entries) {
|
|
361
|
+
if (entry.dir !== "provider→bridge") continue;
|
|
362
|
+
const message = parseLine(entry.line);
|
|
363
|
+
if (message?.type !== "response" || message.success !== true) continue;
|
|
364
|
+
const candidates = [];
|
|
365
|
+
if (message.command === "get_state" && message.data?.model) {
|
|
366
|
+
candidates.push(message.data.model);
|
|
367
|
+
if (!state.model) state = message.data;
|
|
368
|
+
}
|
|
369
|
+
if (
|
|
370
|
+
message.command === "get_available_models" &&
|
|
371
|
+
Array.isArray(message.data?.models)
|
|
372
|
+
) {
|
|
373
|
+
candidates.push(...message.data.models);
|
|
374
|
+
}
|
|
375
|
+
for (const model of candidates) {
|
|
376
|
+
if (typeof model?.provider === "string" && typeof model.id === "string") {
|
|
377
|
+
models.set(`${model.provider}/${model.id}`, model);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const channelOut = createWriteStream(null, { fd: 3 });
|
|
382
|
+
const channelIn = new Socket({ fd: 4, readable: true, writable: false });
|
|
383
|
+
channelIn.on("error", () => {});
|
|
384
|
+
channelIn.unref();
|
|
385
|
+
readNewlineDelimitedLines(channelIn, (line) => {
|
|
386
|
+
const message = parseLine(line);
|
|
387
|
+
if (message?.kind !== "request" || message.method !== "model-scope") return;
|
|
388
|
+
channelOut.write(
|
|
389
|
+
`${JSON.stringify({
|
|
390
|
+
kind: "reply",
|
|
391
|
+
id: message.id,
|
|
392
|
+
result: {
|
|
393
|
+
scopedModelIds: [...models.keys()],
|
|
394
|
+
...(state.model
|
|
395
|
+
? { defaultModelId: `${state.model.provider}/${state.model.id}` }
|
|
396
|
+
: {}),
|
|
397
|
+
},
|
|
398
|
+
})}\n`,
|
|
399
|
+
);
|
|
400
|
+
});
|
|
401
|
+
readNewlineDelimitedLines(process.stdin, (line) => {
|
|
402
|
+
const message = parseLine(line);
|
|
403
|
+
if (typeof message?.id !== "string") return;
|
|
404
|
+
process.stdout.write(
|
|
405
|
+
`${JSON.stringify({
|
|
406
|
+
id: message.id,
|
|
407
|
+
type: "response",
|
|
408
|
+
command: message.type,
|
|
409
|
+
success: true,
|
|
410
|
+
data:
|
|
411
|
+
message.type === "get_available_models"
|
|
412
|
+
? { models: [...models.values()] }
|
|
413
|
+
: state,
|
|
414
|
+
})}\n`,
|
|
415
|
+
);
|
|
416
|
+
});
|
|
417
|
+
process.stdin.on("end", () => process.exit(0));
|
|
418
|
+
process.on("SIGTERM", () => process.exit(0));
|
|
419
|
+
}
|
|
420
|
+
|
|
357
421
|
function main() {
|
|
358
422
|
// A bridge's install gate may probe `<cli> --version` through the replay
|
|
359
423
|
// command; answer like a CLI instead of claiming a segment and waiting.
|
|
@@ -369,6 +433,14 @@ function main() {
|
|
|
369
433
|
...readLane(args.recording, "provider→bridge"),
|
|
370
434
|
...readLane(args.recording, "bridge→provider"),
|
|
371
435
|
].sort((left, right) => left.run - right.run || left.seq - right.seq);
|
|
436
|
+
if (
|
|
437
|
+
args.dialect === "pi-rpc" &&
|
|
438
|
+
process.argv.includes("--no-session") &&
|
|
439
|
+
!process.argv.includes("--session-dir")
|
|
440
|
+
) {
|
|
441
|
+
servePiCatalog(entries);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
372
444
|
const segments = buildSegments(entries, dialect);
|
|
373
445
|
const segmentIndex = claimSegmentIndex(args.state);
|
|
374
446
|
let script = segments[segmentIndex] ?? [];
|
package/dist/testing/app.js
CHANGED
|
@@ -491,6 +491,8 @@ function createComposerHandleBinding(key, initial) {
|
|
|
491
491
|
removeMention,
|
|
492
492
|
onSubmitted,
|
|
493
493
|
focus: () => target().focus(),
|
|
494
|
+
experimental_openPopup: (id) => target().openPopup?.(controller.pluginId, id) ?? false,
|
|
495
|
+
experimental_closePopup: () => target().closePopup?.(controller.pluginId) ?? false,
|
|
494
496
|
submit,
|
|
495
497
|
setSelection,
|
|
496
498
|
experimental_removeMention: (mention) => {
|
|
@@ -637,13 +639,12 @@ function requireUniqueId(kind, seen, id) {
|
|
|
637
639
|
}
|
|
638
640
|
seen.add(id);
|
|
639
641
|
}
|
|
640
|
-
function parseContributionArray(kind, value, onRejected, parse) {
|
|
642
|
+
function parseContributionArray(kind, value, onRejected, parse, seenIds = /* @__PURE__ */ new Set()) {
|
|
641
643
|
if (value === void 0) return void 0;
|
|
642
644
|
if (!Array.isArray(value)) {
|
|
643
645
|
onRejected(`${kind}: must be an array when set`);
|
|
644
646
|
return void 0;
|
|
645
647
|
}
|
|
646
|
-
const seenIds = /* @__PURE__ */ new Set();
|
|
647
648
|
const parsed = [];
|
|
648
649
|
for (const [index, entry] of value.entries()) {
|
|
649
650
|
const entryKind = `${kind}[${index}]`;
|
|
@@ -681,7 +682,7 @@ function parseMenuItem(entryKind, value) {
|
|
|
681
682
|
run: requireFunction(entryKind, "run", entry?.run)
|
|
682
683
|
};
|
|
683
684
|
}
|
|
684
|
-
function parseRegions(kind, registration, onRejected) {
|
|
685
|
+
function parseRegions(kind, registration, onRejected, seenPopupIds) {
|
|
685
686
|
const actions = parseContributionArray(`${kind}.actions`, registration.actions, onRejected, (entryKind, value) => {
|
|
686
687
|
const entry = value;
|
|
687
688
|
return {
|
|
@@ -716,6 +717,20 @@ function parseRegions(kind, registration, onRejected) {
|
|
|
716
717
|
onRejected,
|
|
717
718
|
parseMenuItem
|
|
718
719
|
);
|
|
720
|
+
const popups = parseContributionArray(
|
|
721
|
+
`${kind}.experimental_popups`,
|
|
722
|
+
registration.experimental_popups,
|
|
723
|
+
onRejected,
|
|
724
|
+
(entryKind, value) => {
|
|
725
|
+
const entry = value;
|
|
726
|
+
return {
|
|
727
|
+
id: requireSlotId(entryKind, entry?.id),
|
|
728
|
+
label: requireNonEmptyString(entryKind, "label", entry?.label),
|
|
729
|
+
component: requireComponent(entryKind, entry?.component)
|
|
730
|
+
};
|
|
731
|
+
},
|
|
732
|
+
seenPopupIds
|
|
733
|
+
);
|
|
719
734
|
let richText;
|
|
720
735
|
if (registration.richText !== void 0) {
|
|
721
736
|
const raw = registration.richText;
|
|
@@ -758,10 +773,11 @@ function parseRegions(kind, registration, onRejected) {
|
|
|
758
773
|
...banners !== void 0 ? { banners } : {},
|
|
759
774
|
...plusMenu !== void 0 ? { plusMenu } : {},
|
|
760
775
|
...sendMenu !== void 0 ? { sendMenu } : {},
|
|
761
|
-
...richText !== void 0 ? { richText } : {}
|
|
776
|
+
...richText !== void 0 ? { richText } : {},
|
|
777
|
+
...popups !== void 0 ? { experimental_popups: popups } : {}
|
|
762
778
|
};
|
|
763
779
|
}
|
|
764
|
-
function collectComposerCustomization(registration, seenIds, onRejected) {
|
|
780
|
+
function collectComposerCustomization(registration, seenIds, onRejected, seenPopupIds = /* @__PURE__ */ new Set()) {
|
|
765
781
|
const kind = "composer.customize";
|
|
766
782
|
try {
|
|
767
783
|
const raw = registration;
|
|
@@ -787,7 +803,7 @@ function collectComposerCustomization(registration, seenIds, onRejected) {
|
|
|
787
803
|
(scope) => scope !== "side-chat"
|
|
788
804
|
)
|
|
789
805
|
} : {},
|
|
790
|
-
...parseRegions(`${kind}(${id})`, raw ?? {}, onRejected)
|
|
806
|
+
...parseRegions(`${kind}(${id})`, raw ?? {}, onRejected, seenPopupIds)
|
|
791
807
|
};
|
|
792
808
|
} catch (error) {
|
|
793
809
|
onRejected(error instanceof Error ? error.message : String(error));
|
|
@@ -1173,6 +1189,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
1173
1189
|
threadPanelAction: /* @__PURE__ */ new Set(),
|
|
1174
1190
|
newThreadPanelAction: /* @__PURE__ */ new Set(),
|
|
1175
1191
|
composerCustomization: /* @__PURE__ */ new Set(),
|
|
1192
|
+
composerPopup: /* @__PURE__ */ new Set(),
|
|
1176
1193
|
pendingInteraction: /* @__PURE__ */ new Set(),
|
|
1177
1194
|
sidebarFooterItem: /* @__PURE__ */ new Set(),
|
|
1178
1195
|
sidebarNavigation: /* @__PURE__ */ new Set(),
|
|
@@ -1192,24 +1209,38 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
1192
1209
|
machineProviderInputs: /* @__PURE__ */ new Set(),
|
|
1193
1210
|
contentScript: /* @__PURE__ */ new Set()
|
|
1194
1211
|
};
|
|
1195
|
-
function
|
|
1196
|
-
const kind = "commands.register";
|
|
1212
|
+
function collectCommand(kind, registration) {
|
|
1197
1213
|
const id = requireSlotId(kind, registration?.id);
|
|
1198
1214
|
requireUniqueId(kind, seenIds.command, id);
|
|
1199
1215
|
if (typeof registration.run !== "function") {
|
|
1200
1216
|
throw new Error(`${kind}: "run" must be a function`);
|
|
1201
1217
|
}
|
|
1218
|
+
return {
|
|
1219
|
+
id,
|
|
1220
|
+
defaultShortcut: registration.defaultShortcut === void 0 ? null : commandShortcutSchema.parse(registration.defaultShortcut),
|
|
1221
|
+
title: requireNonEmptyString(kind, "title", registration.title)
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
function registerCommand(registration) {
|
|
1225
|
+
const kind = "commands.register";
|
|
1226
|
+
const command = collectCommand(kind, registration);
|
|
1202
1227
|
if (registration.isAvailable !== void 0 && typeof registration.isAvailable !== "function") {
|
|
1203
1228
|
throw new Error(`${kind}: "isAvailable" must be a function`);
|
|
1204
1229
|
}
|
|
1205
1230
|
collected.commandPaletteActions.push({
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
title: requireNonEmptyString(kind, "title", registration.title),
|
|
1231
|
+
target: "app",
|
|
1232
|
+
...command,
|
|
1209
1233
|
...registration.isAvailable !== void 0 ? { isAvailable: registration.isAvailable } : {},
|
|
1210
1234
|
run: registration.run
|
|
1211
1235
|
});
|
|
1212
1236
|
}
|
|
1237
|
+
function registerComposerCommand(registration) {
|
|
1238
|
+
collected.commandPaletteActions.push({
|
|
1239
|
+
target: "composer",
|
|
1240
|
+
...collectCommand("composer.experimental_registerCommand", registration),
|
|
1241
|
+
run: registration.run
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1213
1244
|
definition.setup({
|
|
1214
1245
|
commands: { register: registerCommand },
|
|
1215
1246
|
slots: {
|
|
@@ -1567,12 +1598,14 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
1567
1598
|
const customization = collectComposerCustomization(
|
|
1568
1599
|
registration,
|
|
1569
1600
|
seenIds.composerCustomization,
|
|
1570
|
-
onComposerCustomizationRejected
|
|
1601
|
+
onComposerCustomizationRejected,
|
|
1602
|
+
seenIds.composerPopup
|
|
1571
1603
|
);
|
|
1572
1604
|
if (customization !== null) {
|
|
1573
1605
|
collected.composerCustomizations.push(customization);
|
|
1574
1606
|
}
|
|
1575
|
-
}
|
|
1607
|
+
},
|
|
1608
|
+
experimental_registerCommand: registerComposerCommand
|
|
1576
1609
|
},
|
|
1577
1610
|
experimental_icons: {
|
|
1578
1611
|
register(registration) {
|
|
@@ -1970,7 +2003,7 @@ function TestProviderModelPicker({
|
|
|
1970
2003
|
value: draft.serviceTier ?? "",
|
|
1971
2004
|
onChange: (event) => setDraft((current) => {
|
|
1972
2005
|
const serviceTier2 = event.target.value;
|
|
1973
|
-
if (serviceTier2
|
|
2006
|
+
if (serviceTier2 === "") {
|
|
1974
2007
|
const next = { ...current };
|
|
1975
2008
|
delete next.serviceTier;
|
|
1976
2009
|
return next;
|
package/dist/testing/index.js
CHANGED