@agent-native/core 0.202.0-nightly-20261006153106 → 0.202.0
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/dist/automation/index.d.ts +1 -1
- package/dist/client/analytics.d.ts +1 -0
- package/dist/client/analytics.js +61 -5
- package/dist/client/route-template.d.ts +16 -0
- package/dist/client/route-template.js +127 -0
- package/dist/client/session-replay.d.ts +30 -0
- package/dist/client/session-replay.js +95 -17
- package/dist/client/use-action.js +16 -1
- package/dist/client/web-vitals.d.ts +69 -0
- package/dist/client/web-vitals.js +288 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/mcp/build-server.d.ts +2 -0
- package/dist/mcp/build-server.js +174 -36
- package/dist/mcp/embed-app.js +1 -1
- package/dist/mcp/server.js +3 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/index.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/shared/analytics-events.d.ts +14 -0
- package/dist/shared/analytics-events.js +13 -0
- package/docs/content/template-clips-features.mdx +10 -6
- package/docs/content/template-mail-inbox.mdx +2 -2
- package/docs/content/template-slides-features.mdx +1 -0
- package/package.json +4 -4
package/dist/mcp/build-server.js
CHANGED
|
@@ -194,6 +194,9 @@ export function validateMcpDirectoryProfile(config, sourceActions = config.produ
|
|
|
194
194
|
typeof annotations.openWorldHint !== "boolean") {
|
|
195
195
|
throw new McpDirectoryProfileValidationError(`[agent-native] MCP directory catalog action "${name}" must declare boolean readOnlyHint, destructiveHint, and openWorldHint values.`);
|
|
196
196
|
}
|
|
197
|
+
if (annotations.readOnlyHint !== (entry.readOnly === true)) {
|
|
198
|
+
throw new McpDirectoryProfileValidationError(`[agent-native] MCP directory catalog action "${name}" readOnlyHint must match its readOnly action setting.`);
|
|
199
|
+
}
|
|
197
200
|
}
|
|
198
201
|
for (const map of [
|
|
199
202
|
config.directoryProfile?.toolDescriptions,
|
|
@@ -602,11 +605,18 @@ function mcpAppEmbedOpenLinkMeta(result, resource, meta) {
|
|
|
602
605
|
: {}),
|
|
603
606
|
};
|
|
604
607
|
}
|
|
605
|
-
async function withServerMintedMcpAppEmbedStart(result, meta, directoryLinkUrl) {
|
|
608
|
+
async function withServerMintedMcpAppEmbedStart(result, meta, directoryLinkUrl, suppressDirectoryReadOnlyEmbed = false) {
|
|
606
609
|
if (!result || typeof result !== "object" || Array.isArray(result)) {
|
|
607
610
|
return result;
|
|
608
611
|
}
|
|
609
612
|
const out = result;
|
|
613
|
+
if (suppressDirectoryReadOnlyEmbed) {
|
|
614
|
+
const resultWithoutEmbedSession = { ...out };
|
|
615
|
+
delete resultWithoutEmbedSession.embedStartUrl;
|
|
616
|
+
delete resultWithoutEmbedSession.embedTargetPath;
|
|
617
|
+
delete resultWithoutEmbedSession.embedExpiresAt;
|
|
618
|
+
return resultWithoutEmbedSession;
|
|
619
|
+
}
|
|
610
620
|
if (out.embed === false || (out.embed !== true && !directoryLinkUrl)) {
|
|
611
621
|
return result;
|
|
612
622
|
}
|
|
@@ -759,16 +769,17 @@ function safeUiSegment(value, fallback) {
|
|
|
759
769
|
return normalized || fallback;
|
|
760
770
|
}
|
|
761
771
|
const MCP_APP_RESOURCE_SHELL_VERSION = "shell-v65";
|
|
772
|
+
const MCP_DIRECTORY_APP_RESOURCE_SHELL_VERSION = "shell-v66";
|
|
762
773
|
function legacyDefaultMcpAppUri(config, actionName) {
|
|
763
774
|
const app = safeUiSegment(config.appId ?? config.name, "agent-native");
|
|
764
775
|
const action = safeUiSegment(actionName, "tool");
|
|
765
776
|
return `ui://${app}/${action}`;
|
|
766
777
|
}
|
|
767
|
-
function versionMcpAppResourceUri(rawUri) {
|
|
778
|
+
function versionMcpAppResourceUri(rawUri, shellVersion = MCP_APP_RESOURCE_SHELL_VERSION) {
|
|
768
779
|
const uri = rawUri.trim();
|
|
769
780
|
if (!uri.startsWith("ui://"))
|
|
770
781
|
return null;
|
|
771
|
-
const versionSuffix =
|
|
782
|
+
const versionSuffix = "/" + shellVersion;
|
|
772
783
|
let versionedUri;
|
|
773
784
|
try {
|
|
774
785
|
const parsed = new URL(uri);
|
|
@@ -826,7 +837,26 @@ function getMcpAppResourceUri(config, actionName, entry) {
|
|
|
826
837
|
if (!resource)
|
|
827
838
|
return null;
|
|
828
839
|
const baseUri = resource.uri?.trim() || legacyDefaultMcpAppUri(config, actionName);
|
|
829
|
-
|
|
840
|
+
const actionResource = versionMcpAppResourceUri(baseUri);
|
|
841
|
+
if (!actionResource ||
|
|
842
|
+
config.catalogMode !== "directory" ||
|
|
843
|
+
!mcpAppWidgetsEnabled(config)) {
|
|
844
|
+
return actionResource;
|
|
845
|
+
}
|
|
846
|
+
const app = safeUiSegment(config.appId ?? config.name, "agent-native");
|
|
847
|
+
const sharedResource = versionMcpAppResourceUri("ui://" + app + "/" + MCP_DIRECTORY_APP_RESOURCE_SHELL_VERSION, MCP_DIRECTORY_APP_RESOURCE_SHELL_VERSION);
|
|
848
|
+
if (!sharedResource)
|
|
849
|
+
return actionResource;
|
|
850
|
+
return {
|
|
851
|
+
...sharedResource,
|
|
852
|
+
legacyUris: [
|
|
853
|
+
...new Set([
|
|
854
|
+
...(sharedResource.legacyUris ?? []),
|
|
855
|
+
actionResource.uri,
|
|
856
|
+
...(actionResource.legacyUris ?? []),
|
|
857
|
+
]),
|
|
858
|
+
],
|
|
859
|
+
};
|
|
830
860
|
}
|
|
831
861
|
function expandRequestOriginSources(sources, requestMeta) {
|
|
832
862
|
if (!sources)
|
|
@@ -851,7 +881,7 @@ function openAiWidgetCsp(cspConfig, requestMeta) {
|
|
|
851
881
|
csp.frame_domains = frameDomains;
|
|
852
882
|
return Object.keys(csp).length > 0 ? csp : undefined;
|
|
853
883
|
}
|
|
854
|
-
function mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, widgetDomain, directoryMode = false) {
|
|
884
|
+
function mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, widgetDomain, directoryMode = false, widgetDiagnostic) {
|
|
855
885
|
const base = resource._meta && typeof resource._meta === "object"
|
|
856
886
|
? { ...resource._meta }
|
|
857
887
|
: {};
|
|
@@ -860,23 +890,32 @@ function mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, widgetDom
|
|
|
860
890
|
: {};
|
|
861
891
|
const ui = { ...existingUi };
|
|
862
892
|
delete ui.domain;
|
|
893
|
+
const omitFrameDomains = directoryMode && widgetDiagnostic === "no-frame-domains";
|
|
863
894
|
if (directoryMode &&
|
|
864
895
|
ui.csp &&
|
|
865
896
|
typeof ui.csp === "object" &&
|
|
866
897
|
!Array.isArray(ui.csp)) {
|
|
867
898
|
const csp = { ...ui.csp };
|
|
868
899
|
delete csp.baseUriDomains;
|
|
900
|
+
if (omitFrameDomains)
|
|
901
|
+
delete csp.frameDomains;
|
|
869
902
|
ui.csp = csp;
|
|
870
903
|
}
|
|
871
904
|
if (resolvedCsp) {
|
|
872
905
|
const csp = { ...resolvedCsp };
|
|
873
906
|
if (directoryMode)
|
|
874
907
|
delete csp.baseUriDomains;
|
|
908
|
+
if (omitFrameDomains)
|
|
909
|
+
delete csp.frameDomains;
|
|
875
910
|
ui.csp = {
|
|
876
911
|
...csp,
|
|
877
912
|
connectDomains: expandRequestOriginSources(resolvedCsp.connectDomains, requestMeta),
|
|
878
913
|
resourceDomains: expandRequestOriginSources(resolvedCsp.resourceDomains, requestMeta),
|
|
879
|
-
|
|
914
|
+
...(!omitFrameDomains
|
|
915
|
+
? {
|
|
916
|
+
frameDomains: expandRequestOriginSources(resolvedCsp.frameDomains, requestMeta),
|
|
917
|
+
}
|
|
918
|
+
: {}),
|
|
880
919
|
...(!directoryMode
|
|
881
920
|
? {
|
|
882
921
|
baseUriDomains: expandRequestOriginSources(resolvedCsp.baseUriDomains, requestMeta),
|
|
@@ -888,15 +927,21 @@ function mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, widgetDom
|
|
|
888
927
|
ui.permissions = resource.permissions;
|
|
889
928
|
const hostSpecificDomain = hostSpecificDomainString(resource.domain) ??
|
|
890
929
|
hostSpecificDomainString(existingUi.domain);
|
|
891
|
-
if (
|
|
930
|
+
if (omitFrameDomains) {
|
|
931
|
+
delete ui.domain;
|
|
932
|
+
delete base["openai/widgetDomain"];
|
|
933
|
+
}
|
|
934
|
+
else if (widgetDomain)
|
|
892
935
|
ui.domain = widgetDomain;
|
|
893
936
|
else if (hostSpecificDomain)
|
|
894
937
|
ui.domain = hostSpecificDomain;
|
|
895
|
-
const openAiWidgetDomain =
|
|
896
|
-
|
|
897
|
-
originString(
|
|
898
|
-
|
|
899
|
-
|
|
938
|
+
const openAiWidgetDomain = omitFrameDomains
|
|
939
|
+
? undefined
|
|
940
|
+
: (originString(widgetDomain) ??
|
|
941
|
+
originString(resource.domain) ??
|
|
942
|
+
originString(ui.domain) ??
|
|
943
|
+
originString(existingUi.domain) ??
|
|
944
|
+
originString(requestMeta?.origin));
|
|
900
945
|
if (typeof resource.prefersBorder === "boolean") {
|
|
901
946
|
ui.prefersBorder = resource.prefersBorder;
|
|
902
947
|
}
|
|
@@ -910,10 +955,30 @@ function mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, widgetDom
|
|
|
910
955
|
base["openai/widgetPrefersBorder"] = resource.prefersBorder;
|
|
911
956
|
}
|
|
912
957
|
const openAiCsp = openAiWidgetCsp(resolvedCsp, requestMeta);
|
|
913
|
-
if (
|
|
958
|
+
if (directoryMode) {
|
|
959
|
+
const directoryCsp = { ...(openAiCsp ?? {}) };
|
|
960
|
+
if (omitFrameDomains)
|
|
961
|
+
delete directoryCsp.frame_domains;
|
|
962
|
+
const redirectDomain = originString(widgetDomain);
|
|
963
|
+
if (redirectDomain)
|
|
964
|
+
directoryCsp.redirect_domains = [redirectDomain];
|
|
965
|
+
if (Object.keys(directoryCsp).length > 0) {
|
|
966
|
+
base["openai/widgetCSP"] = directoryCsp;
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
delete base["openai/widgetCSP"];
|
|
970
|
+
}
|
|
971
|
+
const openAiUi = metadataObject(base["openai/ui"]);
|
|
972
|
+
base["openai/ui"] = {
|
|
973
|
+
...openAiUi,
|
|
974
|
+
availableDisplayModes: ["inline", "fullscreen"],
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
else if (openAiCsp && base["openai/widgetCSP"] == null) {
|
|
914
978
|
base["openai/widgetCSP"] = openAiCsp;
|
|
915
979
|
}
|
|
916
|
-
if (
|
|
980
|
+
if (!omitFrameDomains &&
|
|
981
|
+
openAiWidgetDomain &&
|
|
917
982
|
(widgetDomain || base["openai/widgetDomain"] == null)) {
|
|
918
983
|
base["openai/widgetDomain"] = openAiWidgetDomain;
|
|
919
984
|
}
|
|
@@ -940,7 +1005,9 @@ async function resolveMcpAppResource(config, actionName, entry, requestMeta) {
|
|
|
940
1005
|
requestOrigin: requestMeta?.origin,
|
|
941
1006
|
catalogMode: config.catalogMode,
|
|
942
1007
|
});
|
|
943
|
-
const resourceMeta = mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, config.catalogMode === "directory" ? config.widgetDomain : undefined, config.catalogMode === "directory"
|
|
1008
|
+
const resourceMeta = mcpAppUiMeta(resource, resolvedCsp, requestMeta, description, config.catalogMode === "directory" ? config.widgetDomain : undefined, config.catalogMode === "directory", config.catalogMode === "directory"
|
|
1009
|
+
? config.directoryProfile?.widgetDiagnostic
|
|
1010
|
+
: undefined);
|
|
944
1011
|
return {
|
|
945
1012
|
uri: resolvedUri.uri,
|
|
946
1013
|
...(resolvedUri.legacyUris ? { legacyUris: resolvedUri.legacyUris } : {}),
|
|
@@ -966,12 +1033,14 @@ function mcpAppWidgetsEnabled(config) {
|
|
|
966
1033
|
config.directoryProfile?.widgets === false);
|
|
967
1034
|
}
|
|
968
1035
|
function stripDirectoryWidgetMeta(config, metadata) {
|
|
969
|
-
if (
|
|
1036
|
+
if (config.catalogMode !== "directory")
|
|
970
1037
|
return;
|
|
971
1038
|
delete metadata.ui;
|
|
972
1039
|
delete metadata[MCP_APP_RESOURCE_URI_META_KEY];
|
|
973
1040
|
delete metadata["openai/ui"];
|
|
974
1041
|
delete metadata["openai/outputTemplate"];
|
|
1042
|
+
delete metadata["openai/toolInvocation/invoking"];
|
|
1043
|
+
delete metadata["openai/toolInvocation/invoked"];
|
|
975
1044
|
for (const key of Object.keys(metadata)) {
|
|
976
1045
|
if (key.startsWith("openai/widget"))
|
|
977
1046
|
delete metadata[key];
|
|
@@ -980,10 +1049,52 @@ function stripDirectoryWidgetMeta(config, metadata) {
|
|
|
980
1049
|
async function getMcpAppResources(config, actions, requestMeta) {
|
|
981
1050
|
if (!requestMeta?.inlineMcpApps || !mcpAppWidgetsEnabled(config))
|
|
982
1051
|
return [];
|
|
983
|
-
const
|
|
984
|
-
|
|
1052
|
+
const actionEntries = Object.entries(actions);
|
|
1053
|
+
const orderedActionEntries = config.catalogMode === "directory"
|
|
1054
|
+
? actionEntries.sort(([a], [b]) => compareMcpCatalogValues(a, b))
|
|
1055
|
+
: actionEntries;
|
|
1056
|
+
const resources = await Promise.all(orderedActionEntries.map(([name, entry]) => resolveMcpAppResourceSafely(config, name, entry, requestMeta)));
|
|
1057
|
+
const resolved = resources.filter((resource) => Boolean(resource));
|
|
1058
|
+
if (config.catalogMode !== "directory")
|
|
1059
|
+
return resolved;
|
|
1060
|
+
const seenUris = new Set();
|
|
1061
|
+
return resolved.filter((resource) => {
|
|
1062
|
+
if (seenUris.has(resource.uri))
|
|
1063
|
+
return false;
|
|
1064
|
+
seenUris.add(resource.uri);
|
|
1065
|
+
return true;
|
|
1066
|
+
});
|
|
985
1067
|
}
|
|
1068
|
+
const DIRECTORY_TINY_WIDGET_HTML = [
|
|
1069
|
+
"<!doctype html>",
|
|
1070
|
+
'<html lang="en">',
|
|
1071
|
+
"<head>",
|
|
1072
|
+
' <meta charset="utf-8">',
|
|
1073
|
+
' <meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
1074
|
+
" <title>Widget resource size diagnostic</title>",
|
|
1075
|
+
" <style>",
|
|
1076
|
+
" :root { color-scheme: light dark; font-family: system-ui, sans-serif; }",
|
|
1077
|
+
" body { margin: 0; min-height: 100vh; display: grid; place-items: center; background: Canvas; color: CanvasText; }",
|
|
1078
|
+
" main { width: min(42rem, calc(100% - 3rem)); padding: 2rem; border: 1px solid color-mix(in srgb, CanvasText 20%, Canvas); border-radius: 1rem; }",
|
|
1079
|
+
" h1 { margin: 0 0 1rem; font-size: 1.4rem; }",
|
|
1080
|
+
" p { line-height: 1.6; }",
|
|
1081
|
+
" </style>",
|
|
1082
|
+
"</head>",
|
|
1083
|
+
"<body>",
|
|
1084
|
+
' <main role="status">',
|
|
1085
|
+
" <h1>Widget resource size diagnostic</h1>",
|
|
1086
|
+
" <p>This temporary resource replaces the full Agent-Native Slides widget shell while the ChatGPT plugin scan is being diagnosed.</p>",
|
|
1087
|
+
" <p>The Slides app and its MCP tools remain available. This page measures whether the review scan completes when the linked HTML resource is small.</p>",
|
|
1088
|
+
" <p>After the scan experiment, remove this diagnostic lane and restore the production widget resource.</p>",
|
|
1089
|
+
" </main>",
|
|
1090
|
+
"</body>",
|
|
1091
|
+
"</html>",
|
|
1092
|
+
].join("\n");
|
|
986
1093
|
function renderMcpAppHtml(resource, actionName, config, requestMeta) {
|
|
1094
|
+
if (config.catalogMode === "directory" &&
|
|
1095
|
+
config.directoryProfile?.widgetDiagnostic === "tiny-html") {
|
|
1096
|
+
return DIRECTORY_TINY_WIDGET_HTML;
|
|
1097
|
+
}
|
|
987
1098
|
if (typeof resource.html === "function") {
|
|
988
1099
|
return resource.html({
|
|
989
1100
|
actionName,
|
|
@@ -994,37 +1105,43 @@ function renderMcpAppHtml(resource, actionName, config, requestMeta) {
|
|
|
994
1105
|
}
|
|
995
1106
|
return resource.html;
|
|
996
1107
|
}
|
|
997
|
-
function openAiToolDescriptorMeta(resource, entrypoints) {
|
|
1108
|
+
function openAiToolDescriptorMeta(resource, entrypoints, directoryMode = false) {
|
|
998
1109
|
const label = resource.title ?? resource.name;
|
|
999
1110
|
const widgetCsp = metadataObject(resource._meta?.["openai/widgetCSP"]);
|
|
1000
1111
|
return {
|
|
1001
1112
|
"openai/outputTemplate": resource.uri,
|
|
1002
1113
|
"openai/toolInvocation/invoking": `Opening ${label}`,
|
|
1003
1114
|
"openai/toolInvocation/invoked": `${label} ready`,
|
|
1004
|
-
"openai/widgetAccessible": true,
|
|
1005
|
-
...(entrypoints?.length
|
|
1006
|
-
|
|
1115
|
+
...(!directoryMode ? { "openai/widgetAccessible": true } : {}),
|
|
1116
|
+
...(!directoryMode && entrypoints?.length
|
|
1117
|
+
? { "openai/ui": { entrypoints } }
|
|
1118
|
+
: {}),
|
|
1119
|
+
...(!directoryMode && Object.keys(widgetCsp).length > 0
|
|
1007
1120
|
? { "openai/widgetCSP": widgetCsp }
|
|
1008
1121
|
: {}),
|
|
1009
1122
|
};
|
|
1010
1123
|
}
|
|
1011
|
-
function openAiToolResultMeta(resource) {
|
|
1124
|
+
function openAiToolResultMeta(resource, directoryMode = false) {
|
|
1012
1125
|
const label = resource.title ?? resource.name;
|
|
1013
1126
|
const widgetCsp = metadataObject(resource._meta?.["openai/widgetCSP"]);
|
|
1014
1127
|
return {
|
|
1015
1128
|
"openai/outputTemplate": resource.uri,
|
|
1016
1129
|
"openai/toolInvocation/invoking": `Opening ${label}`,
|
|
1017
1130
|
"openai/toolInvocation/invoked": `${label} ready`,
|
|
1018
|
-
"openai/widgetAccessible": true,
|
|
1019
|
-
...(Object.keys(widgetCsp).length > 0
|
|
1131
|
+
...(!directoryMode ? { "openai/widgetAccessible": true } : {}),
|
|
1132
|
+
...(!directoryMode && Object.keys(widgetCsp).length > 0
|
|
1020
1133
|
? { "openai/widgetCSP": widgetCsp }
|
|
1021
1134
|
: {}),
|
|
1022
1135
|
};
|
|
1023
1136
|
}
|
|
1024
|
-
function mcpAppToolUiMeta(resource, visibility) {
|
|
1137
|
+
function mcpAppToolUiMeta(resource, visibility, directoryMode = false) {
|
|
1025
1138
|
return {
|
|
1026
1139
|
resourceUri: resource.uri,
|
|
1027
|
-
|
|
1140
|
+
...(!directoryMode
|
|
1141
|
+
? {
|
|
1142
|
+
visibility: Array.isArray(visibility) ? visibility : ["model", "app"],
|
|
1143
|
+
}
|
|
1144
|
+
: {}),
|
|
1028
1145
|
};
|
|
1029
1146
|
}
|
|
1030
1147
|
function primitiveValue(value) {
|
|
@@ -1461,10 +1578,12 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1461
1578
|
? {
|
|
1462
1579
|
...openAiToolDescriptorMeta(mcpAppResource, hasOpenAppEntrypoint
|
|
1463
1580
|
? [{ type: "global" }, { type: "thread" }]
|
|
1464
|
-
: undefined),
|
|
1465
|
-
|
|
1581
|
+
: undefined, directoryCatalog),
|
|
1582
|
+
...(!directoryCatalog
|
|
1583
|
+
? { [MCP_APP_RESOURCE_URI_META_KEY]: mcpAppResource.uri }
|
|
1584
|
+
: {}),
|
|
1466
1585
|
ui: mcpAppToolUiMeta(mcpAppResource, entry.mcpApp?.visibility ??
|
|
1467
|
-
metadataObject(rawToolMeta.ui).visibility),
|
|
1586
|
+
metadataObject(rawToolMeta.ui).visibility, directoryCatalog),
|
|
1468
1587
|
}
|
|
1469
1588
|
: {}),
|
|
1470
1589
|
};
|
|
@@ -1483,14 +1602,26 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1483
1602
|
entry.needsApproval !== undefined,
|
|
1484
1603
|
openWorldHint: false,
|
|
1485
1604
|
};
|
|
1486
|
-
if (
|
|
1605
|
+
if (directoryCatalog) {
|
|
1606
|
+
delete annotations["agent-native/producesOpenLink"];
|
|
1607
|
+
}
|
|
1608
|
+
else if (hasLink) {
|
|
1487
1609
|
annotations["agent-native/producesOpenLink"] = true;
|
|
1610
|
+
}
|
|
1488
1611
|
return {
|
|
1489
1612
|
name,
|
|
1490
1613
|
description: hasLink
|
|
1491
1614
|
? `${baseDescription} After calling, surface the returned "Open in … →" link to the user.`
|
|
1492
1615
|
: baseDescription,
|
|
1493
1616
|
inputSchema,
|
|
1617
|
+
...(directoryCatalog && mcpAppResource
|
|
1618
|
+
? {
|
|
1619
|
+
outputSchema: {
|
|
1620
|
+
type: "object",
|
|
1621
|
+
additionalProperties: true,
|
|
1622
|
+
},
|
|
1623
|
+
}
|
|
1624
|
+
: {}),
|
|
1494
1625
|
...(Object.keys(toolMeta).length > 0 ? { _meta: toolMeta } : {}),
|
|
1495
1626
|
annotations,
|
|
1496
1627
|
};
|
|
@@ -1674,9 +1805,8 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1674
1805
|
});
|
|
1675
1806
|
directoryLinkUrl = linked?.url ?? undefined;
|
|
1676
1807
|
}
|
|
1677
|
-
const rawResultForClient = mcpAppResourceCandidate
|
|
1678
|
-
|
|
1679
|
-
? await withServerMintedMcpAppEmbedStart(projectedRawResult, requestMeta, directoryLinkUrl)
|
|
1808
|
+
const rawResultForClient = mcpAppResourceCandidate
|
|
1809
|
+
? await withServerMintedMcpAppEmbedStart(projectedRawResult, requestMeta, directoryLinkUrl, directoryCatalog && entry.readOnly === true)
|
|
1680
1810
|
: projectedRawResult;
|
|
1681
1811
|
const { value: actionResultForClient, images: resultImages, notes: resultImageNotes, } = extractAgentImagesFromActionResult(rawResultForClient);
|
|
1682
1812
|
const textResultForClient = mcpResult
|
|
@@ -1694,7 +1824,9 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1694
1824
|
...(mcpAppResource
|
|
1695
1825
|
? mcpAppEmbedOpenLinkMeta(actionResultForClient, mcpAppResource, requestMeta)
|
|
1696
1826
|
: {}),
|
|
1697
|
-
...(mcpAppResource
|
|
1827
|
+
...(mcpAppResource
|
|
1828
|
+
? openAiToolResultMeta(mcpAppResource, directoryCatalog)
|
|
1829
|
+
: {}),
|
|
1698
1830
|
};
|
|
1699
1831
|
const toolUiMeta = metadataObject(entry.tool._meta?.ui);
|
|
1700
1832
|
const toolVisibility = toolUiMeta.visibility;
|
|
@@ -1838,6 +1970,9 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1838
1970
|
return result;
|
|
1839
1971
|
});
|
|
1840
1972
|
server.setRequestHandler("resources/templates/list", async () => {
|
|
1973
|
+
if (config.catalogMode === "directory") {
|
|
1974
|
+
return withCallerContext(async () => ({ resourceTemplates: [] }));
|
|
1975
|
+
}
|
|
1841
1976
|
return withCallerContext(async () => {
|
|
1842
1977
|
const mcpAppResources = await getMcpAppResources(config, advertisedActions, requestMeta);
|
|
1843
1978
|
return {
|
|
@@ -1877,7 +2012,10 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1877
2012
|
const resourceActions = mcpAppWidgetsEnabled(config)
|
|
1878
2013
|
? Object.entries(advertisedActions)
|
|
1879
2014
|
: [];
|
|
1880
|
-
|
|
2015
|
+
const orderedResourceActions = config.catalogMode === "directory"
|
|
2016
|
+
? resourceActions.sort(([a], [b]) => compareMcpCatalogValues(a, b))
|
|
2017
|
+
: resourceActions;
|
|
2018
|
+
for (const [name, entry] of orderedResourceActions) {
|
|
1881
2019
|
const resourceUri = getMcpAppResourceUri(config, name, entry);
|
|
1882
2020
|
if (!resourceUri || !matchesMcpAppResourceUri(resourceUri, uri)) {
|
|
1883
2021
|
continue;
|
package/dist/mcp/embed-app.js
CHANGED
|
@@ -1239,7 +1239,7 @@ export function embedApp(options = {}) {
|
|
|
1239
1239
|
const frame = document.createElement("iframe");
|
|
1240
1240
|
frame.title = body.dataset.iframeTitle || "Agent-Native app";
|
|
1241
1241
|
frame.src = src;
|
|
1242
|
-
frame.allow = "clipboard-read; clipboard-write";
|
|
1242
|
+
${ctx.catalogMode === "directory" ? "" : 'frame.allow = "clipboard-read; clipboard-write";'}
|
|
1243
1243
|
appFrame = frame;
|
|
1244
1244
|
appFrameReady = false;
|
|
1245
1245
|
lastFrameSrc = src;
|
package/dist/mcp/server.js
CHANGED
|
@@ -225,7 +225,9 @@ async function handleMcpRequestInternal(event, config, routePath = MCP_PUBLIC_RO
|
|
|
225
225
|
connectorCatalog: directoryProfile.connectorCatalog,
|
|
226
226
|
instructions: directoryProfile.instructions,
|
|
227
227
|
keyToolNames: directoryProfile.keyToolNames,
|
|
228
|
-
widgetDomain:
|
|
228
|
+
widgetDomain: directoryProfile.widgetDomain ??
|
|
229
|
+
config.widgetDomain ??
|
|
230
|
+
requestMeta.origin,
|
|
229
231
|
}
|
|
230
232
|
: config;
|
|
231
233
|
let authResult;
|
|
@@ -34,19 +34,19 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
34
34
|
spans?: undefined;
|
|
35
35
|
id?: undefined;
|
|
36
36
|
} | {
|
|
37
|
+
error?: undefined;
|
|
37
38
|
ok?: undefined;
|
|
38
39
|
message?: undefined;
|
|
39
40
|
summary: import("./types.js").TraceSummary;
|
|
40
41
|
spans: import("./types.js").TraceSpan[];
|
|
41
42
|
id?: undefined;
|
|
42
|
-
error?: undefined;
|
|
43
43
|
} | {
|
|
44
|
+
error?: undefined;
|
|
44
45
|
ok?: undefined;
|
|
45
46
|
message?: undefined;
|
|
46
47
|
summary?: undefined;
|
|
47
48
|
spans?: undefined;
|
|
48
49
|
id: string;
|
|
49
|
-
error?: undefined;
|
|
50
50
|
} | {
|
|
51
51
|
ok?: undefined;
|
|
52
52
|
message?: undefined;
|
|
@@ -55,10 +55,10 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
55
55
|
id?: undefined;
|
|
56
56
|
error: any;
|
|
57
57
|
} | {
|
|
58
|
+
error?: undefined;
|
|
58
59
|
message?: undefined;
|
|
59
60
|
summary?: undefined;
|
|
60
61
|
spans?: undefined;
|
|
61
62
|
id?: undefined;
|
|
62
63
|
ok: boolean;
|
|
63
|
-
error?: undefined;
|
|
64
64
|
}>>;
|
package/dist/org/handlers.d.ts
CHANGED
|
@@ -71,9 +71,9 @@ export declare const setWorkspaceAppDefaultVisibilityHandler: import("h3").Event
|
|
|
71
71
|
visibility: WorkspaceAppDefaultVisibility;
|
|
72
72
|
}>>;
|
|
73
73
|
export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
74
|
+
name?: undefined;
|
|
74
75
|
success: boolean;
|
|
75
76
|
id?: undefined;
|
|
76
|
-
name?: undefined;
|
|
77
77
|
role?: undefined;
|
|
78
78
|
} | {
|
|
79
79
|
success?: undefined;
|
package/dist/org/index.d.ts
CHANGED
|
@@ -177,10 +177,10 @@ export declare const getMyOrgHandler: import("h3").EventHandlerWithFetch<import(
|
|
|
177
177
|
soloDeploymentAdmin: boolean | undefined;
|
|
178
178
|
}>>;
|
|
179
179
|
export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
180
|
-
role?: undefined;
|
|
181
180
|
name?: undefined;
|
|
182
181
|
success: boolean;
|
|
183
182
|
id?: undefined;
|
|
183
|
+
role?: undefined;
|
|
184
184
|
} | {
|
|
185
185
|
success?: undefined;
|
|
186
186
|
id: string;
|
|
@@ -39,8 +39,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
39
39
|
error: string;
|
|
40
40
|
}>;
|
|
41
41
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
42
|
-
error: string;
|
|
43
42
|
ok?: undefined;
|
|
43
|
+
error: string;
|
|
44
44
|
} | {
|
|
45
45
|
error?: undefined;
|
|
46
46
|
ok: boolean;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -73,32 +73,32 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
|
|
|
73
73
|
ok?: undefined;
|
|
74
74
|
status?: undefined;
|
|
75
75
|
} | {
|
|
76
|
+
error?: undefined;
|
|
76
77
|
errorCode?: undefined;
|
|
77
78
|
retryable?: undefined;
|
|
78
79
|
ok: boolean;
|
|
79
80
|
status: string;
|
|
80
|
-
error?: undefined;
|
|
81
81
|
} | {
|
|
82
82
|
ok?: undefined;
|
|
83
83
|
error: string;
|
|
84
84
|
removed?: undefined;
|
|
85
85
|
} | {
|
|
86
|
+
error?: undefined;
|
|
86
87
|
ok: boolean;
|
|
87
88
|
removed: boolean;
|
|
88
|
-
error?: undefined;
|
|
89
89
|
}>>;
|
|
90
90
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
91
91
|
ok?: undefined;
|
|
92
92
|
error: string;
|
|
93
93
|
note?: undefined;
|
|
94
94
|
} | {
|
|
95
|
+
error?: undefined;
|
|
95
96
|
ok: boolean;
|
|
96
97
|
note?: undefined;
|
|
97
|
-
error?: undefined;
|
|
98
98
|
} | {
|
|
99
|
+
error?: undefined;
|
|
99
100
|
ok: boolean;
|
|
100
101
|
note: string;
|
|
101
|
-
error?: undefined;
|
|
102
102
|
} | {
|
|
103
103
|
note?: undefined;
|
|
104
104
|
ok: boolean;
|
|
@@ -126,11 +126,11 @@ export declare function createAdHocSecretHandler(): import("h3").EventHandlerWit
|
|
|
126
126
|
} | {
|
|
127
127
|
error: string;
|
|
128
128
|
} | {
|
|
129
|
+
error?: undefined;
|
|
129
130
|
ok: boolean;
|
|
130
131
|
key: string;
|
|
131
|
-
error?: undefined;
|
|
132
132
|
} | {
|
|
133
|
+
error?: undefined;
|
|
133
134
|
ok: boolean;
|
|
134
135
|
removed: boolean;
|
|
135
|
-
error?: undefined;
|
|
136
136
|
}>>;
|
|
@@ -66,12 +66,12 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
|
|
|
66
66
|
code: any;
|
|
67
67
|
} | {
|
|
68
68
|
errorCode?: undefined;
|
|
69
|
-
error?: undefined;
|
|
70
69
|
code?: undefined;
|
|
71
70
|
ok: boolean;
|
|
72
71
|
key: string;
|
|
73
72
|
baseUrlKey?: string;
|
|
74
73
|
scope: AgentEngineApiKeyScope;
|
|
75
74
|
defaultModel?: import("./agent-engine-default-model-route.js").SavedKeyDefaultModelOutcome;
|
|
75
|
+
error?: undefined;
|
|
76
76
|
}>>;
|
|
77
77
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
2
2
|
error: string;
|
|
3
|
-
models?: undefined;
|
|
4
3
|
ok?: undefined;
|
|
4
|
+
models?: undefined;
|
|
5
5
|
} | {
|
|
6
|
+
error?: undefined;
|
|
6
7
|
ok: boolean;
|
|
7
8
|
models: string[];
|
|
8
|
-
error?: undefined;
|
|
9
9
|
}>>;
|
|
@@ -125,3 +125,17 @@ export declare const AGENT_SIGNALS_VERSION = 1;
|
|
|
125
125
|
* another tab opened.
|
|
126
126
|
*/
|
|
127
127
|
export declare const PAGE_LOAD_PAGEVIEW_PROPERTY = "page_load_id";
|
|
128
|
+
/**
|
|
129
|
+
* Action telemetry reports every `action.response` at least this slow
|
|
130
|
+
* unsampled, and marks each one someone waited for on the session replay with
|
|
131
|
+
* its own timing.
|
|
132
|
+
*/
|
|
133
|
+
export declare const SLOW_ACTION_RESPONSE_MS = 1000;
|
|
134
|
+
/**
|
|
135
|
+
* Whether an `action.response`'s duration is what a person waited for.
|
|
136
|
+
* Background tabs throttle timers and cancelled requests never finish.
|
|
137
|
+
*/
|
|
138
|
+
export declare function isWaitedActionResponse(properties: {
|
|
139
|
+
page_hidden?: unknown;
|
|
140
|
+
outcome?: unknown;
|
|
141
|
+
}): boolean;
|
|
@@ -342,3 +342,16 @@ export const AGENT_SIGNALS_VERSION = 1;
|
|
|
342
342
|
* another tab opened.
|
|
343
343
|
*/
|
|
344
344
|
export const PAGE_LOAD_PAGEVIEW_PROPERTY = "page_load_id";
|
|
345
|
+
/**
|
|
346
|
+
* Action telemetry reports every `action.response` at least this slow
|
|
347
|
+
* unsampled, and marks each one someone waited for on the session replay with
|
|
348
|
+
* its own timing.
|
|
349
|
+
*/
|
|
350
|
+
export const SLOW_ACTION_RESPONSE_MS = 1_000;
|
|
351
|
+
/**
|
|
352
|
+
* Whether an `action.response`'s duration is what a person waited for.
|
|
353
|
+
* Background tabs throttle timers and cancelled requests never finish.
|
|
354
|
+
*/
|
|
355
|
+
export function isWaitedActionResponse(properties) {
|
|
356
|
+
return properties.page_hidden !== true && properties.outcome !== "cancelled";
|
|
357
|
+
}
|