mindoodb-app-sdk 0.0.70 → 0.0.72
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/README.md +106 -1
- package/dist/{chunk-P7SOHCEQ.js → chunk-UFP7O4OJ.js} +746 -36
- package/dist/index.d.ts +3 -55
- package/dist/index.js +61 -1
- package/dist/testing/index.d.ts +136 -2
- package/dist/testing/index.js +422 -18
- package/dist/{types-7oOzrSr5.d.ts → types-DN-E0X34.d.ts} +542 -5
- package/package.json +1 -1
package/dist/testing/index.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MINDOODB_APP_VALUE_TAG,
|
|
3
|
+
MindooDBAppEmbedValidationError,
|
|
3
4
|
assertValidMindooDBCreateIds,
|
|
4
5
|
mindooDBAppComponentFieldsMatch,
|
|
6
|
+
mindooDBAppComponentSupports,
|
|
7
|
+
normalizeMindooDBAppInspectAnchor,
|
|
8
|
+
normalizeMindooDBAppInspectRequest,
|
|
9
|
+
normalizeMindooDBAppInspection,
|
|
10
|
+
normalizeMindooDBAppIssues,
|
|
5
11
|
pageUsers,
|
|
6
|
-
|
|
7
|
-
|
|
12
|
+
performMindooDBAppEmbeddingSave,
|
|
13
|
+
releaseMindooDBAppBridgeSessions,
|
|
14
|
+
resolveMindooDBAppEmbedValidation,
|
|
15
|
+
validateMindooDBAppDefinition
|
|
16
|
+
} from "../chunk-UFP7O4OJ.js";
|
|
8
17
|
|
|
9
18
|
// src/testing/index.ts
|
|
10
19
|
import * as Automerge from "@automerge/automerge";
|
|
@@ -469,6 +478,13 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
469
478
|
let nextSaveError = null;
|
|
470
479
|
let embeddingDirty;
|
|
471
480
|
let saveRequestHandler = null;
|
|
481
|
+
let inspectionProvider = null;
|
|
482
|
+
let showIssuesHandler = null;
|
|
483
|
+
let revealHandler = null;
|
|
484
|
+
const embeddingValidations = [];
|
|
485
|
+
let embeddingSaveCount = 0;
|
|
486
|
+
const beforeSaveHandlers = /* @__PURE__ */ new Map();
|
|
487
|
+
const savedListeners = /* @__PURE__ */ new Set();
|
|
472
488
|
let embedCounter = 0;
|
|
473
489
|
let embeddingFinish = null;
|
|
474
490
|
const accessRequests = [];
|
|
@@ -529,7 +545,10 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
529
545
|
rect: mockRect(input),
|
|
530
546
|
visible: input.visible !== false,
|
|
531
547
|
active: false,
|
|
532
|
-
agentTools: null
|
|
548
|
+
agentTools: null,
|
|
549
|
+
supports: [...component.supports ?? []],
|
|
550
|
+
beforeSave: null,
|
|
551
|
+
requests: []
|
|
533
552
|
});
|
|
534
553
|
setActive(embedId);
|
|
535
554
|
return embedId;
|
|
@@ -582,6 +601,7 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
582
601
|
handles.get(embedId)?.settle(event);
|
|
583
602
|
handles.delete(embedId);
|
|
584
603
|
toolNames.delete(embedId);
|
|
604
|
+
beforeSaveHandlers.delete(embedId);
|
|
585
605
|
closedListeners.forEach((listener) => listener(event));
|
|
586
606
|
notifyChange();
|
|
587
607
|
}
|
|
@@ -604,6 +624,40 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
604
624
|
closed;
|
|
605
625
|
dirty = void 0;
|
|
606
626
|
dirtyListeners = /* @__PURE__ */ new Set();
|
|
627
|
+
savedListeners = /* @__PURE__ */ new Set();
|
|
628
|
+
get supports() {
|
|
629
|
+
return embeds.get(this.embedId)?.supports ?? [];
|
|
630
|
+
}
|
|
631
|
+
async inspect(request) {
|
|
632
|
+
return await inspectEmbed(this.embedId, request);
|
|
633
|
+
}
|
|
634
|
+
onBeforeSave(handler, options2) {
|
|
635
|
+
setBeforeSave(this.embedId, handler, options2?.inspect);
|
|
636
|
+
return () => {
|
|
637
|
+
if (beforeSaveHandlers.get(this.embedId) === handler) {
|
|
638
|
+
setBeforeSave(this.embedId, null);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
onAfterSave(listener) {
|
|
643
|
+
this.savedListeners.add(listener);
|
|
644
|
+
return () => {
|
|
645
|
+
this.savedListeners.delete(listener);
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
notifySaved() {
|
|
649
|
+
const event = { embedId: this.embedId };
|
|
650
|
+
this.savedListeners.forEach((listener) => listener(event));
|
|
651
|
+
}
|
|
652
|
+
async showIssues(issues) {
|
|
653
|
+
await showEmbedIssues(this.embedId, issues);
|
|
654
|
+
}
|
|
655
|
+
async reveal(anchor) {
|
|
656
|
+
await revealInEmbed(this.embedId, anchor);
|
|
657
|
+
}
|
|
658
|
+
async callTool(name, input) {
|
|
659
|
+
return await callEmbedTool(this.embedId, name, input ?? {});
|
|
660
|
+
}
|
|
607
661
|
onDirtyChange(listener) {
|
|
608
662
|
this.dirtyListeners.add(listener);
|
|
609
663
|
return () => {
|
|
@@ -703,7 +757,8 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
703
757
|
notifyChange();
|
|
704
758
|
}
|
|
705
759
|
async function saveEmbed(embedId) {
|
|
706
|
-
|
|
760
|
+
const entry = embeds.get(embedId);
|
|
761
|
+
if (!entry) {
|
|
707
762
|
throw new Error("Unknown embed.");
|
|
708
763
|
}
|
|
709
764
|
const error = nextSaveError;
|
|
@@ -711,7 +766,117 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
711
766
|
if (error) {
|
|
712
767
|
throw new Error(error);
|
|
713
768
|
}
|
|
769
|
+
if (mindooDBAppComponentSupports(entry.supports, "validate")) {
|
|
770
|
+
const validation = await validateEmbed(embedId);
|
|
771
|
+
if (!validation.ok) {
|
|
772
|
+
throw new MindooDBAppEmbedValidationError(validation.issues);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
714
775
|
setEmbedDirty(embedId, false);
|
|
776
|
+
notifyEmbedSaved(embedId);
|
|
777
|
+
}
|
|
778
|
+
function entryOf(embedId) {
|
|
779
|
+
const entry = embeds.get(embedId);
|
|
780
|
+
if (!entry) {
|
|
781
|
+
throw new Error("Unknown embed.");
|
|
782
|
+
}
|
|
783
|
+
return entry;
|
|
784
|
+
}
|
|
785
|
+
function unsupported(message) {
|
|
786
|
+
return Object.assign(new Error(message), { name: "unsupported" });
|
|
787
|
+
}
|
|
788
|
+
async function inspectEmbed(embedId, request) {
|
|
789
|
+
const entry = entryOf(embedId);
|
|
790
|
+
const inspect = normalizeMindooDBAppInspectRequest(request);
|
|
791
|
+
entry.requests.push({ request: "inspect", inspect });
|
|
792
|
+
if (!options.embedInspection || !mindooDBAppComponentSupports(entry.supports, "inspect")) {
|
|
793
|
+
throw unsupported("The component cannot describe its document.");
|
|
794
|
+
}
|
|
795
|
+
return normalizeMindooDBAppInspection(await options.embedInspection(structuredClone(entry), inspect));
|
|
796
|
+
}
|
|
797
|
+
function setBeforeSave(embedId, handler, inspect) {
|
|
798
|
+
const entry = entryOf(embedId);
|
|
799
|
+
if (handler) {
|
|
800
|
+
beforeSaveHandlers.set(embedId, handler);
|
|
801
|
+
entry.beforeSave = { inspect: normalizeMindooDBAppInspectRequest(inspect) };
|
|
802
|
+
} else {
|
|
803
|
+
beforeSaveHandlers.delete(embedId);
|
|
804
|
+
entry.beforeSave = null;
|
|
805
|
+
}
|
|
806
|
+
notifyChange();
|
|
807
|
+
}
|
|
808
|
+
async function validateEmbed(embedId, validateOptions = {}) {
|
|
809
|
+
const entry = entryOf(embedId);
|
|
810
|
+
const handler = beforeSaveHandlers.get(embedId);
|
|
811
|
+
if (!handler) {
|
|
812
|
+
return { ok: true, issues: [] };
|
|
813
|
+
}
|
|
814
|
+
let inspection = null;
|
|
815
|
+
if (options.embedInspection && mindooDBAppComponentSupports(entry.supports, "inspect")) {
|
|
816
|
+
inspection = normalizeMindooDBAppInspection(
|
|
817
|
+
await options.embedInspection(structuredClone(entry), entry.beforeSave?.inspect ?? {})
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
const root = await getDatabase(entry.databaseId).documents.get(entry.docId);
|
|
821
|
+
const answer = await handler({
|
|
822
|
+
embedId,
|
|
823
|
+
inspection,
|
|
824
|
+
root: root ? JSON.parse(JSON.stringify(root.data)) : null
|
|
825
|
+
});
|
|
826
|
+
return await resolveMindooDBAppEmbedValidation(
|
|
827
|
+
normalizeMindooDBAppIssues(answer?.issues),
|
|
828
|
+
validateOptions.interactive !== false,
|
|
829
|
+
options.confirmSaveWarnings ?? (() => true)
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
function notifyEmbedSaved(embedId) {
|
|
833
|
+
if (!embeds.has(embedId)) {
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
handles.get(embedId)?.notifySaved();
|
|
837
|
+
savedListeners.forEach((listener) => listener({ embedId }));
|
|
838
|
+
}
|
|
839
|
+
async function showEmbedIssues(embedId, issues) {
|
|
840
|
+
const entry = entryOf(embedId);
|
|
841
|
+
entry.requests.push({ request: "showIssues", issues: normalizeMindooDBAppIssues(issues) });
|
|
842
|
+
if (!mindooDBAppComponentSupports(entry.supports, "issues")) {
|
|
843
|
+
throw unsupported("The component cannot show issues.");
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
async function revealInEmbed(embedId, anchor) {
|
|
847
|
+
const entry = entryOf(embedId);
|
|
848
|
+
const normalized = normalizeMindooDBAppInspectAnchor(anchor);
|
|
849
|
+
if (!normalized) {
|
|
850
|
+
throw new Error("Invalid anchor.");
|
|
851
|
+
}
|
|
852
|
+
entry.requests.push({ request: "reveal", anchor: normalized });
|
|
853
|
+
if (!mindooDBAppComponentSupports(entry.supports, "reveal")) {
|
|
854
|
+
throw unsupported("The component cannot reveal places.");
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
async function callEmbedTool(embedId, name, input) {
|
|
858
|
+
const entry = entryOf(embedId);
|
|
859
|
+
const prefix = `${toolPrefix(entry.component)}_`;
|
|
860
|
+
const bare = name.startsWith(prefix) ? name.slice(prefix.length) : name;
|
|
861
|
+
entry.requests.push({ request: "callTool", name: bare, input: structuredClone(input) });
|
|
862
|
+
if (!options.embedTools) {
|
|
863
|
+
throw unsupported(`The component has no tool "${bare}".`);
|
|
864
|
+
}
|
|
865
|
+
return structuredClone(await options.embedTools(structuredClone(entry), bare, structuredClone(input)));
|
|
866
|
+
}
|
|
867
|
+
async function validateEmbedding(validateOptions = {}) {
|
|
868
|
+
const interactive = validateOptions.interactive !== false;
|
|
869
|
+
const raw = await options.embeddingValidation?.({ interactive }) ?? { ok: true, issues: [] };
|
|
870
|
+
const result = {
|
|
871
|
+
ok: raw.ok !== false,
|
|
872
|
+
issues: normalizeMindooDBAppIssues(raw.issues),
|
|
873
|
+
...raw.timedOut ? { timedOut: true } : {}
|
|
874
|
+
};
|
|
875
|
+
embeddingValidations.push({ interactive, result: structuredClone(result) });
|
|
876
|
+
return result;
|
|
877
|
+
}
|
|
878
|
+
function unsupportedHandler() {
|
|
879
|
+
throw unsupported("unsupported");
|
|
715
880
|
}
|
|
716
881
|
function setVisible(embedId, visible) {
|
|
717
882
|
const entry = embeds.get(embedId);
|
|
@@ -723,7 +888,7 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
723
888
|
return {
|
|
724
889
|
components: {
|
|
725
890
|
async list(query) {
|
|
726
|
-
return components.filter((entry) => !query?.intent || entry.intents.includes(query.intent)).filter((entry) => !query?.document || mindooDBAppComponentFieldsMatch(entry.match, query.document)).map((entry) => structuredClone(entry));
|
|
891
|
+
return components.filter((entry) => !query?.intent || entry.intents.includes(query.intent)).filter((entry) => (query?.requires ?? []).every((requirement) => mindooDBAppComponentSupports(entry.supports, requirement))).filter((entry) => !query?.document || mindooDBAppComponentFieldsMatch(entry.match, query.document)).map((entry) => structuredClone(entry));
|
|
727
892
|
}
|
|
728
893
|
},
|
|
729
894
|
embeds: {
|
|
@@ -758,6 +923,36 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
758
923
|
saveRequestHandler = null;
|
|
759
924
|
}
|
|
760
925
|
};
|
|
926
|
+
},
|
|
927
|
+
provideInspection(provider) {
|
|
928
|
+
inspectionProvider = provider;
|
|
929
|
+
return () => {
|
|
930
|
+
if (inspectionProvider === provider) inspectionProvider = null;
|
|
931
|
+
};
|
|
932
|
+
},
|
|
933
|
+
onShowIssues(handler) {
|
|
934
|
+
showIssuesHandler = handler;
|
|
935
|
+
return () => {
|
|
936
|
+
if (showIssuesHandler === handler) showIssuesHandler = null;
|
|
937
|
+
};
|
|
938
|
+
},
|
|
939
|
+
onReveal(handler) {
|
|
940
|
+
revealHandler = handler;
|
|
941
|
+
return () => {
|
|
942
|
+
if (revealHandler === handler) revealHandler = null;
|
|
943
|
+
};
|
|
944
|
+
},
|
|
945
|
+
validate: validateEmbedding,
|
|
946
|
+
async save(flush, saveOptions) {
|
|
947
|
+
return await performMindooDBAppEmbeddingSave({
|
|
948
|
+
validate: () => validateEmbedding(saveOptions),
|
|
949
|
+
provider: inspectionProvider,
|
|
950
|
+
showIssues: showIssuesHandler,
|
|
951
|
+
flush,
|
|
952
|
+
saved: () => {
|
|
953
|
+
embeddingSaveCount += 1;
|
|
954
|
+
}
|
|
955
|
+
});
|
|
761
956
|
}
|
|
762
957
|
},
|
|
763
958
|
openEmbed,
|
|
@@ -821,6 +1016,44 @@ function createMockEmbedHost(options, getDatabase, listDatabaseIds = () => []) {
|
|
|
821
1016
|
},
|
|
822
1017
|
setSaveRequestHandler(handler) {
|
|
823
1018
|
saveRequestHandler = handler;
|
|
1019
|
+
},
|
|
1020
|
+
inspectEmbed,
|
|
1021
|
+
setBeforeSave,
|
|
1022
|
+
validateEmbed,
|
|
1023
|
+
notifyEmbedSaved,
|
|
1024
|
+
onSaved(listener) {
|
|
1025
|
+
savedListeners.add(listener);
|
|
1026
|
+
return () => {
|
|
1027
|
+
savedListeners.delete(listener);
|
|
1028
|
+
};
|
|
1029
|
+
},
|
|
1030
|
+
showEmbedIssues,
|
|
1031
|
+
revealInEmbed,
|
|
1032
|
+
callEmbedTool,
|
|
1033
|
+
getEmbedRequests(embedId) {
|
|
1034
|
+
return structuredClone(embeds.get(embedId)?.requests ?? []);
|
|
1035
|
+
},
|
|
1036
|
+
async requestEmbeddingInspection(request) {
|
|
1037
|
+
if (!inspectionProvider) unsupportedHandler();
|
|
1038
|
+
return normalizeMindooDBAppInspection(await inspectionProvider(normalizeMindooDBAppInspectRequest(request)));
|
|
1039
|
+
},
|
|
1040
|
+
async requestEmbeddingShowIssues(issues) {
|
|
1041
|
+
if (!showIssuesHandler) unsupportedHandler();
|
|
1042
|
+
await showIssuesHandler(normalizeMindooDBAppIssues(issues));
|
|
1043
|
+
},
|
|
1044
|
+
async requestEmbeddingReveal(anchor) {
|
|
1045
|
+
if (!revealHandler) unsupportedHandler();
|
|
1046
|
+
await revealHandler(anchor);
|
|
1047
|
+
},
|
|
1048
|
+
getEmbeddingValidations() {
|
|
1049
|
+
return structuredClone(embeddingValidations);
|
|
1050
|
+
},
|
|
1051
|
+
getEmbeddingSaveCount() {
|
|
1052
|
+
return embeddingSaveCount;
|
|
1053
|
+
},
|
|
1054
|
+
validateEmbedding,
|
|
1055
|
+
recordEmbeddingSaved() {
|
|
1056
|
+
embeddingSaveCount += 1;
|
|
824
1057
|
}
|
|
825
1058
|
};
|
|
826
1059
|
}
|
|
@@ -2383,6 +2616,84 @@ Allow?`),
|
|
|
2383
2616
|
return testHost;
|
|
2384
2617
|
}
|
|
2385
2618
|
|
|
2619
|
+
// src/testing/agentManifest.ts
|
|
2620
|
+
function localeKeys(map) {
|
|
2621
|
+
return map ? Object.keys(map).sort().join(",") : "";
|
|
2622
|
+
}
|
|
2623
|
+
function findGuideProblems(name, text, prefix, registered, ignore) {
|
|
2624
|
+
const problems = /* @__PURE__ */ new Set();
|
|
2625
|
+
const prefixed = new RegExp(`(?<![A-Za-z0-9_])${prefix}_([a-z0-9_]+)(?![A-Za-z0-9_*<])`, "g");
|
|
2626
|
+
for (const match of text.matchAll(prefixed)) {
|
|
2627
|
+
const full = match[0];
|
|
2628
|
+
const bare = match[1].replace(/_+$/, "");
|
|
2629
|
+
if (!bare || ignore.has(full) || ignore.has(bare) || registered.has(bare)) continue;
|
|
2630
|
+
problems.add(`${name} names \`${full}\`, which the app does not register.`);
|
|
2631
|
+
}
|
|
2632
|
+
const families = new Set([...registered].filter((tool) => tool.includes("_")).map((tool) => tool.split("_")[0]));
|
|
2633
|
+
for (const match of text.matchAll(/`([a-z][a-z0-9]*_[a-z0-9_]*[a-z0-9])(?:\(\))?`/g)) {
|
|
2634
|
+
const bare = match[1];
|
|
2635
|
+
if (bare.startsWith("haven_") || bare.startsWith(`${prefix}_`)) continue;
|
|
2636
|
+
if (registered.has(bare) || ignore.has(bare) || !families.has(bare.split("_")[0])) continue;
|
|
2637
|
+
problems.add(`${name} names \`${bare}\`, which looks like a tool but the app does not register it.`);
|
|
2638
|
+
}
|
|
2639
|
+
return [...problems];
|
|
2640
|
+
}
|
|
2641
|
+
function checkAgentManifest(options) {
|
|
2642
|
+
const errors = [];
|
|
2643
|
+
const warnings = [];
|
|
2644
|
+
const validation = validateMindooDBAppDefinition(options.definition);
|
|
2645
|
+
errors.push(...validation.errors);
|
|
2646
|
+
const definition = validation.definition;
|
|
2647
|
+
if (!definition) {
|
|
2648
|
+
return { errors, warnings };
|
|
2649
|
+
}
|
|
2650
|
+
const agent = definition.agent;
|
|
2651
|
+
if (!agent) {
|
|
2652
|
+
errors.push("haven-app.json has no agent block.");
|
|
2653
|
+
return { errors, warnings };
|
|
2654
|
+
}
|
|
2655
|
+
const prefix = options.toolPrefix ?? mockAgentToolPrefix(definition.appId, definition.agentToolPrefix);
|
|
2656
|
+
const registered = new Set(options.tools.map((tool) => typeof tool === "string" ? tool : tool.name));
|
|
2657
|
+
const ignore = new Set(options.ignore ?? []);
|
|
2658
|
+
const covered = /* @__PURE__ */ new Set();
|
|
2659
|
+
for (const capability of agent.capabilities) {
|
|
2660
|
+
for (const tool of capability.tools) {
|
|
2661
|
+
covered.add(tool);
|
|
2662
|
+
if (!registered.has(tool)) {
|
|
2663
|
+
const hint = tool.startsWith(`${prefix}_`) ? " Name it without the prefix." : "";
|
|
2664
|
+
errors.push(`Capability "${capability.id}" names the tool "${tool}", which the app does not register.${hint}`);
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
const internal = new Set(options.internalTools ?? []);
|
|
2669
|
+
for (const tool of registered) {
|
|
2670
|
+
if (!covered.has(tool) && !internal.has(tool)) {
|
|
2671
|
+
warnings.push(`The tool "${tool}" belongs to no capability.`);
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
const summaryLocales = localeKeys(agent.summary);
|
|
2675
|
+
const mismatched = [
|
|
2676
|
+
...agent.capabilities.map((capability) => [`capability "${capability.id}" title`, localeKeys(capability.title)]),
|
|
2677
|
+
...agent.examples ? [["examples", localeKeys(agent.examples)]] : []
|
|
2678
|
+
].filter(([, locales]) => locales !== summaryLocales);
|
|
2679
|
+
for (const [what, locales] of mismatched) {
|
|
2680
|
+
errors.push(`The agent ${what} has the locales ${locales || "(none)"}, the summary ${summaryLocales}.`);
|
|
2681
|
+
}
|
|
2682
|
+
const texts = Array.isArray(options.guideTexts) ? options.guideTexts.map((text, index) => [`guide text #${index}`, text]) : Object.entries(options.guideTexts ?? {});
|
|
2683
|
+
for (const [name, text] of texts) {
|
|
2684
|
+
errors.push(...findGuideProblems(name, text, prefix, registered, ignore));
|
|
2685
|
+
}
|
|
2686
|
+
return { errors, warnings };
|
|
2687
|
+
}
|
|
2688
|
+
function assertAgentManifest(options) {
|
|
2689
|
+
const { errors, warnings } = checkAgentManifest(options);
|
|
2690
|
+
if (errors.length) {
|
|
2691
|
+
throw new Error(`The agent profile does not match the app's tools:
|
|
2692
|
+
- ${errors.join("\n- ")}`);
|
|
2693
|
+
}
|
|
2694
|
+
return warnings;
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2386
2697
|
// src/testing/index.ts
|
|
2387
2698
|
var PROTOCOL = "mindoodb-app-bridge";
|
|
2388
2699
|
var MOCK_SIGNING_PUBLIC_KEY_PEM = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmockmockmockmockmockmockmockmockmockmockmoc=\n-----END PUBLIC KEY-----\n";
|
|
@@ -5951,7 +6262,15 @@ function createMockMindooDBAppSession(options = {}) {
|
|
|
5951
6262
|
setEmbedAgentTools: (embedId, names, toolOptions) => state.embedHost.setEmbedAgentTools(embedId, names, toolOptions),
|
|
5952
6263
|
failNextEmbedSave: (message) => state.embedHost.failNextSave(message),
|
|
5953
6264
|
getEmbeddingDirty: () => state.embedHost.getEmbeddingDirty(),
|
|
5954
|
-
requestEmbeddingSave: () => state.embedHost.requestEmbeddingSave()
|
|
6265
|
+
requestEmbeddingSave: () => state.embedHost.requestEmbeddingSave(),
|
|
6266
|
+
validateEmbed: (embedId, validateOptions) => state.embedHost.validateEmbed(embedId, validateOptions),
|
|
6267
|
+
notifyEmbedSaved: (embedId) => state.embedHost.notifyEmbedSaved(embedId),
|
|
6268
|
+
getEmbedRequests: (embedId) => state.embedHost.getEmbedRequests(embedId),
|
|
6269
|
+
requestEmbeddingInspection: (request) => state.embedHost.requestEmbeddingInspection(request),
|
|
6270
|
+
requestEmbeddingShowIssues: (issues) => state.embedHost.requestEmbeddingShowIssues(issues),
|
|
6271
|
+
requestEmbeddingReveal: (anchor) => state.embedHost.requestEmbeddingReveal(anchor),
|
|
6272
|
+
getEmbeddingValidations: () => state.embedHost.getEmbeddingValidations(),
|
|
6273
|
+
getEmbeddingSaveCount: () => state.embedHost.getEmbeddingSaveCount()
|
|
5955
6274
|
};
|
|
5956
6275
|
replicaStates.set(controller, state);
|
|
5957
6276
|
return controller;
|
|
@@ -5997,8 +6316,25 @@ function createFakeBridgeHost(options = {}) {
|
|
|
5997
6316
|
(port) => port.postMessage({ protocol: PROTOCOL, kind: "embed-event", event: { type: "agentTools", ...event } })
|
|
5998
6317
|
);
|
|
5999
6318
|
});
|
|
6319
|
+
state.embedHost.onSaved((event) => {
|
|
6320
|
+
connectedPorts.forEach(
|
|
6321
|
+
(port) => port.postMessage({ protocol: PROTOCOL, kind: "embed-event", event: { type: "saved", ...event } })
|
|
6322
|
+
);
|
|
6323
|
+
});
|
|
6000
6324
|
const embeddingRequests = /* @__PURE__ */ new Map();
|
|
6001
6325
|
let embeddingRequestCounter = 0;
|
|
6326
|
+
function pushEmbeddingRequest(request, params) {
|
|
6327
|
+
embeddingRequestCounter += 1;
|
|
6328
|
+
const requestId = `embedding-request-${embeddingRequestCounter}`;
|
|
6329
|
+
return new Promise((resolve, reject) => {
|
|
6330
|
+
embeddingRequests.set(requestId, { resolve, reject });
|
|
6331
|
+
connectedPorts.forEach(
|
|
6332
|
+
(port) => port.postMessage({ protocol: PROTOCOL, kind: "embedding-request", requestId, request, ...params ? { params } : {} })
|
|
6333
|
+
);
|
|
6334
|
+
});
|
|
6335
|
+
}
|
|
6336
|
+
const embedRequests = /* @__PURE__ */ new Map();
|
|
6337
|
+
let embedRequestCounter = 0;
|
|
6002
6338
|
const beforeCloseWaiters = /* @__PURE__ */ new Map();
|
|
6003
6339
|
let beforeCloseCounter = 0;
|
|
6004
6340
|
const viewSessions = /* @__PURE__ */ new Map();
|
|
@@ -6235,8 +6571,66 @@ function createFakeBridgeHost(options = {}) {
|
|
|
6235
6571
|
case "embeds.open": {
|
|
6236
6572
|
const input = params.input;
|
|
6237
6573
|
const embedId = await state.embedHost.openEmbed(input);
|
|
6238
|
-
|
|
6574
|
+
const supports = state.embedHost.listEmbeds().find((entry) => entry.embedId === embedId)?.supports ?? [];
|
|
6575
|
+
return {
|
|
6576
|
+
embedId,
|
|
6577
|
+
...input.placement === "frame" && options.embedFrameUrl ? { frame: { url: options.embedFrameUrl } } : {},
|
|
6578
|
+
...supports.length ? { supports } : {}
|
|
6579
|
+
};
|
|
6580
|
+
}
|
|
6581
|
+
case "embeds.inspect":
|
|
6582
|
+
return await state.embedHost.inspectEmbed(
|
|
6583
|
+
String(params.embedId),
|
|
6584
|
+
params.request
|
|
6585
|
+
);
|
|
6586
|
+
case "embeds.setBeforeSave": {
|
|
6587
|
+
const embedId = String(params.embedId);
|
|
6588
|
+
state.embedHost.setBeforeSave(
|
|
6589
|
+
embedId,
|
|
6590
|
+
params.enabled === true ? (input) => {
|
|
6591
|
+
embedRequestCounter += 1;
|
|
6592
|
+
const requestId = `embed-request-${embedRequestCounter}`;
|
|
6593
|
+
return new Promise((resolve) => {
|
|
6594
|
+
embedRequests.set(requestId, (result) => resolve(result));
|
|
6595
|
+
connectedPorts.forEach(
|
|
6596
|
+
(port) => port.postMessage({
|
|
6597
|
+
protocol: PROTOCOL,
|
|
6598
|
+
kind: "embed-request",
|
|
6599
|
+
requestId,
|
|
6600
|
+
embedId,
|
|
6601
|
+
request: "beforeSave",
|
|
6602
|
+
params: { inspection: input.inspection, root: input.root }
|
|
6603
|
+
})
|
|
6604
|
+
);
|
|
6605
|
+
});
|
|
6606
|
+
} : null,
|
|
6607
|
+
params.inspect
|
|
6608
|
+
);
|
|
6609
|
+
return { ok: true };
|
|
6239
6610
|
}
|
|
6611
|
+
case "embeds.respond": {
|
|
6612
|
+
const resolve = embedRequests.get(String(params.requestId));
|
|
6613
|
+
embedRequests.delete(String(params.requestId));
|
|
6614
|
+
resolve?.(params.ok === true ? params.result : { issues: [] });
|
|
6615
|
+
return { ok: true };
|
|
6616
|
+
}
|
|
6617
|
+
case "embeds.showIssues":
|
|
6618
|
+
await state.embedHost.showEmbedIssues(String(params.embedId), params.issues);
|
|
6619
|
+
return { ok: true };
|
|
6620
|
+
case "embeds.reveal":
|
|
6621
|
+
await state.embedHost.revealInEmbed(String(params.embedId), params.anchor);
|
|
6622
|
+
return { ok: true };
|
|
6623
|
+
case "embeds.callTool":
|
|
6624
|
+
return await state.embedHost.callEmbedTool(
|
|
6625
|
+
String(params.embedId),
|
|
6626
|
+
String(params.name),
|
|
6627
|
+
params.input ?? {}
|
|
6628
|
+
);
|
|
6629
|
+
case "embedding.validate":
|
|
6630
|
+
return await state.embedHost.validateEmbedding({ interactive: params.interactive !== false });
|
|
6631
|
+
case "embedding.saved":
|
|
6632
|
+
state.embedHost.recordEmbeddingSaved();
|
|
6633
|
+
return { ok: true };
|
|
6240
6634
|
case "embeds.requestAccess":
|
|
6241
6635
|
return await state.embedHost.embeds.requestAccess(
|
|
6242
6636
|
params.input ?? { components: [] }
|
|
@@ -6269,9 +6663,10 @@ function createFakeBridgeHost(options = {}) {
|
|
|
6269
6663
|
const pending = embeddingRequests.get(String(params.requestId));
|
|
6270
6664
|
embeddingRequests.delete(String(params.requestId));
|
|
6271
6665
|
if (params.ok === true) {
|
|
6272
|
-
pending?.resolve();
|
|
6666
|
+
pending?.resolve(params.result);
|
|
6273
6667
|
} else {
|
|
6274
|
-
|
|
6668
|
+
const message = typeof params.error === "string" ? params.error : "Save failed.";
|
|
6669
|
+
pending?.reject(Object.assign(new Error(message), message === "unsupported" ? { name: "unsupported" } : {}));
|
|
6275
6670
|
}
|
|
6276
6671
|
return { ok: true };
|
|
6277
6672
|
}
|
|
@@ -6909,16 +7304,23 @@ function createFakeBridgeHost(options = {}) {
|
|
|
6909
7304
|
setEmbedAgentTools: (embedId, names, toolOptions) => state.embedHost.setEmbedAgentTools(embedId, names, toolOptions),
|
|
6910
7305
|
failNextEmbedSave: (message) => state.embedHost.failNextSave(message),
|
|
6911
7306
|
getEmbeddingDirty: () => state.embedHost.getEmbeddingDirty(),
|
|
6912
|
-
requestEmbeddingSave() {
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
7307
|
+
async requestEmbeddingSave() {
|
|
7308
|
+
await pushEmbeddingRequest("save");
|
|
7309
|
+
},
|
|
7310
|
+
validateEmbed: (embedId, validateOptions) => state.embedHost.validateEmbed(embedId, validateOptions),
|
|
7311
|
+
notifyEmbedSaved: (embedId) => state.embedHost.notifyEmbedSaved(embedId),
|
|
7312
|
+
getEmbedRequests: (embedId) => state.embedHost.getEmbedRequests(embedId),
|
|
7313
|
+
async requestEmbeddingInspection(request) {
|
|
7314
|
+
return await pushEmbeddingRequest("inspect", { request: request ?? {} });
|
|
7315
|
+
},
|
|
7316
|
+
async requestEmbeddingShowIssues(issues) {
|
|
7317
|
+
await pushEmbeddingRequest("showIssues", { issues });
|
|
7318
|
+
},
|
|
7319
|
+
async requestEmbeddingReveal(anchor) {
|
|
7320
|
+
await pushEmbeddingRequest("reveal", { anchor });
|
|
6921
7321
|
},
|
|
7322
|
+
getEmbeddingValidations: () => state.embedHost.getEmbeddingValidations(),
|
|
7323
|
+
getEmbeddingSaveCount: () => state.embedHost.getEmbeddingSaveCount(),
|
|
6922
7324
|
dispose() {
|
|
6923
7325
|
restoreWindow();
|
|
6924
7326
|
connectedPorts.forEach((port) => {
|
|
@@ -7040,7 +7442,9 @@ export {
|
|
|
7040
7442
|
DEFAULT_TEST_HOST_USERS,
|
|
7041
7443
|
MockForbiddenError,
|
|
7042
7444
|
TEST_HOST_LOCALES,
|
|
7445
|
+
assertAgentManifest,
|
|
7043
7446
|
capabilitiesForDefinitionPermissions,
|
|
7447
|
+
checkAgentManifest,
|
|
7044
7448
|
createBrowserTestHost,
|
|
7045
7449
|
createEvaluatingViewNavigator,
|
|
7046
7450
|
createFakeBridgeHost,
|