@klarkxy/dsh-deep-view 0.1.0 → 0.2.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/lib/answer-text.d.ts +15 -0
- package/lib/answer-text.js +110 -0
- package/lib/answer-text.js.map +1 -0
- package/lib/answers.d.ts +49 -0
- package/lib/answers.js +60 -0
- package/lib/answers.js.map +1 -0
- package/lib/client.inner.cjs +362 -12
- package/lib/client.inner.cjs.map +1 -1
- package/lib/client.js +362 -12
- package/lib/contracts.d.ts +2 -98
- package/lib/contracts.js +2 -1
- package/lib/contracts.js.map +1 -1
- package/lib/contracts2.d.ts +103 -0
- package/lib/copy.d.ts +37 -0
- package/lib/copy.js +69 -0
- package/lib/copy.js.map +1 -0
- package/lib/core.d.ts +57 -0
- package/lib/core.js +2 -0
- package/lib/core2.js +1079 -0
- package/lib/core2.js.map +1 -0
- package/lib/index.d.ts +35 -4
- package/lib/index.js +847 -1130
- package/lib/index.js.map +1 -1
- package/lib/widget.d.ts +71 -0
- package/lib/widget.js +1365 -0
- package/lib/widget.js.map +1 -0
- package/package.json +28 -3
package/lib/client.js
CHANGED
|
@@ -1033,6 +1033,281 @@ function validateForm(node, values) {
|
|
|
1033
1033
|
return { fields };
|
|
1034
1034
|
}
|
|
1035
1035
|
//#endregion
|
|
1036
|
+
//#region ../dsh-plugin-kit/src/log-shared.ts
|
|
1037
|
+
const PLUGIN_LOG_LEVELS = [
|
|
1038
|
+
"debug",
|
|
1039
|
+
"info",
|
|
1040
|
+
"warn",
|
|
1041
|
+
"error",
|
|
1042
|
+
"fault"
|
|
1043
|
+
];
|
|
1044
|
+
const DEFAULT_PLUGIN_LOG_LEVEL = "info";
|
|
1045
|
+
const PLUGIN_LOG_MAX_MESSAGE_CHARS = 16e3;
|
|
1046
|
+
const SOURCE_RE = /^[a-z][a-z0-9-]{0,63}$/;
|
|
1047
|
+
const EVENT_RE = /^[a-z][a-z0-9._-]{0,127}$/;
|
|
1048
|
+
const CONTEXT_KEY_RE = /^[a-zA-Z][a-zA-Z0-9._-]{0,63}$/;
|
|
1049
|
+
const SECRET_KEY_RE = /(?:api[_-]?key|access[_-]?token|refresh[_-]?token|bearer|authorization|cookie|set[_-]?cookie|nonce|credential|private[_-]?key|password|secret|app[_-]?secret|client[_-]?secret|z_c0|d_c0)$/i;
|
|
1050
|
+
const CHAT_PAYLOAD_RE = /"role"\s*:\s*"(?:system|user|assistant|tool)"|"(?:messages|content|prompt|input_text|input_image|image_url)"\s*:\s*[\[{"']/i;
|
|
1051
|
+
const CREDENTIAL_BODY_RE = /-----BEGIN (?:RSA |EC |OPENSSH |PRIVATE )?PRIVATE KEY-----|"type"\s*:\s*"service_account"|credentials\.json|\.dsh[/\\](?:credentials|auth)/i;
|
|
1052
|
+
const AUTH_HEADER_RE = /\b(Authorization|Proxy-Authorization|Cookie|Set-Cookie)\s*:\s*[^\r\n]*/gi;
|
|
1053
|
+
const BEARER_RE = /\bBearer\s+[A-Za-z0-9._\-+=/]{8,}/g;
|
|
1054
|
+
const SECRET_FIELD_RE = /(["']?(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|bearer|authorization|cookie|set-cookie|nonce|credential|private[_-]?key|password|secret|app[_-]?secret|client[_-]?secret|password|z_c0|d_c0)["']?\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,&;}]+)/gi;
|
|
1055
|
+
const SECRET_QUERY_RE = /([?&](?:token|api[_-]?key|key|secret|password|bootstrap|code|sig|signature|credential|password)=)[^\s&#"']+/gi;
|
|
1056
|
+
const URL_CREDENTIAL_RE = /\b(https?:\/\/)[^\s/:@]+:[^\s/@]+@/gi;
|
|
1057
|
+
const BOOTSTRAP_RE = /\/bootstrap\/[^\s"'?&#]+/gi;
|
|
1058
|
+
const KNOWN_TOKEN_RE = /\b(?:sk-[A-Za-z0-9_-]{10,}|gh[pousr]_[A-Za-z0-9_]{16,}|github_pat_[A-Za-z0-9_]{20,}|tvly-[A-Za-z0-9_-]{10,}|AKIA[0-9A-Z]{16})\b/g;
|
|
1059
|
+
const PATH_RE = /(?:[A-Za-z]:\\|\\\\)[^\s"'`<>|]+|(?:\/(?:home|Users|tmp|var|root)\/|~\/)[^\s"'`<>|]+/g;
|
|
1060
|
+
function isPluginLogLevel(value) {
|
|
1061
|
+
return typeof value === "string" && PLUGIN_LOG_LEVELS.includes(value);
|
|
1062
|
+
}
|
|
1063
|
+
function pluginLogLevelEnabled(level, minimum) {
|
|
1064
|
+
return PLUGIN_LOG_LEVELS.indexOf(level) >= PLUGIN_LOG_LEVELS.indexOf(minimum);
|
|
1065
|
+
}
|
|
1066
|
+
function normalizePluginLogSource(raw) {
|
|
1067
|
+
const stripped = String(raw || "").trim().replace(/^@[^/]+\//, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1068
|
+
const bounded = (/^[a-z]/.test(stripped) ? stripped : `p-${stripped}`).slice(0, 64).replace(/-+$/g, "");
|
|
1069
|
+
return SOURCE_RE.test(bounded) ? bounded : "dsh-plugin";
|
|
1070
|
+
}
|
|
1071
|
+
function normalizePluginLogEvent(raw) {
|
|
1072
|
+
const cleaned = String(raw || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[^a-z]+/, "").slice(0, 128);
|
|
1073
|
+
return EVENT_RE.test(cleaned) ? cleaned : "plugin.event";
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Parse a level specification like `debug` or `dsh-zhihu=debug,dsh-dot:warn,info`.
|
|
1077
|
+
* Source-specific rules win over a bare fallback level.
|
|
1078
|
+
*/
|
|
1079
|
+
function parsePluginLogLevel(spec, source, fallback = DEFAULT_PLUGIN_LOG_LEVEL) {
|
|
1080
|
+
if (!spec || typeof spec !== "string") return fallback;
|
|
1081
|
+
const normalizedSource = source ? normalizePluginLogSource(source) : void 0;
|
|
1082
|
+
let wildcard;
|
|
1083
|
+
for (const token of spec.split(",").map((part) => part.trim()).filter(Boolean)) {
|
|
1084
|
+
const lowered = token.toLowerCase();
|
|
1085
|
+
if (isPluginLogLevel(lowered)) {
|
|
1086
|
+
wildcard = lowered;
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const match = /^([^=:]+)[=:]([a-z]+)$/i.exec(token);
|
|
1090
|
+
if (!match) continue;
|
|
1091
|
+
const target = match[1].trim();
|
|
1092
|
+
const candidate = match[2].trim().toLowerCase();
|
|
1093
|
+
if (!isPluginLogLevel(candidate)) continue;
|
|
1094
|
+
if (target === "*") {
|
|
1095
|
+
wildcard = candidate;
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
if (normalizedSource && normalizePluginLogSource(target) === normalizedSource) return candidate;
|
|
1099
|
+
}
|
|
1100
|
+
return wildcard ?? fallback;
|
|
1101
|
+
}
|
|
1102
|
+
function sanitizePluginLogText(text, maxChars = PLUGIN_LOG_MAX_MESSAGE_CHARS) {
|
|
1103
|
+
if (!text) return "";
|
|
1104
|
+
if (CREDENTIAL_BODY_RE.test(text)) return "[omitted credential material]";
|
|
1105
|
+
if (CHAT_PAYLOAD_RE.test(text)) return "[omitted chat payload]";
|
|
1106
|
+
return truncateLogText(text.replace(AUTH_HEADER_RE, "$1: [redacted]").replace(BEARER_RE, "Bearer [redacted]").replace(SECRET_FIELD_RE, (full, prefix) => {
|
|
1107
|
+
const value = full.slice(prefix.length);
|
|
1108
|
+
if (value.startsWith("\"")) return `${prefix}"[redacted]"`;
|
|
1109
|
+
if (value.startsWith("'")) return `${prefix}'[redacted]'`;
|
|
1110
|
+
return `${prefix}[redacted]`;
|
|
1111
|
+
}).replace(SECRET_QUERY_RE, "$1[redacted]").replace(URL_CREDENTIAL_RE, "$1[redacted]@").replace(BOOTSTRAP_RE, "/bootstrap/[redacted]").replace(KNOWN_TOKEN_RE, "[redacted]").replace(PATH_RE, "[path]"), maxChars);
|
|
1112
|
+
}
|
|
1113
|
+
function sanitizePluginLogContext(input) {
|
|
1114
|
+
if (!input) return void 0;
|
|
1115
|
+
const output = {};
|
|
1116
|
+
for (const [key, value] of Object.entries(input).slice(0, 32)) {
|
|
1117
|
+
if (value === void 0 || !CONTEXT_KEY_RE.test(key)) continue;
|
|
1118
|
+
if (typeof value === "number" && !Number.isFinite(value)) continue;
|
|
1119
|
+
if (SECRET_KEY_RE.test(key)) {
|
|
1120
|
+
output[key] = "[redacted]";
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
output[key] = typeof value === "string" ? sanitizePluginLogText(value, 1e3) : value;
|
|
1124
|
+
}
|
|
1125
|
+
if (!Object.keys(output).length) return void 0;
|
|
1126
|
+
if (JSON.stringify(output).length <= 8e3) return output;
|
|
1127
|
+
return {
|
|
1128
|
+
omitted: true,
|
|
1129
|
+
reason: "Diagnostic context exceeded its size limit."
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
function sanitizePluginLogError(error) {
|
|
1133
|
+
if (error === void 0) return void 0;
|
|
1134
|
+
const row = error && typeof error === "object" ? error : {};
|
|
1135
|
+
const rawMessage = typeof row.message === "string" ? row.message : String(error);
|
|
1136
|
+
const result = {
|
|
1137
|
+
name: typeof row.name === "string" && row.name.trim() ? truncateLogText(row.name.trim(), 100) : "Error",
|
|
1138
|
+
message: sanitizePluginLogText(rawMessage) || "Unknown error"
|
|
1139
|
+
};
|
|
1140
|
+
if (typeof row.stack === "string" && row.stack.trim()) result.stack = sanitizePluginLogText(row.stack, 24e3);
|
|
1141
|
+
if (typeof row.code === "string" && /^[A-Za-z0-9_./:-]{1,100}$/.test(row.code)) result.code = row.code;
|
|
1142
|
+
else if (typeof row.code === "number" && Number.isFinite(row.code)) result.code = String(row.code);
|
|
1143
|
+
return result;
|
|
1144
|
+
}
|
|
1145
|
+
function mergePluginLogContext(base, extra) {
|
|
1146
|
+
if (!base) return extra;
|
|
1147
|
+
if (!extra) return base;
|
|
1148
|
+
return {
|
|
1149
|
+
...base,
|
|
1150
|
+
...extra
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
function buildPluginLogEntry(input, meta) {
|
|
1154
|
+
const entry = {
|
|
1155
|
+
version: 1,
|
|
1156
|
+
at: meta.at.toISOString(),
|
|
1157
|
+
level: isPluginLogLevel(input.level) ? input.level : "info",
|
|
1158
|
+
source: normalizePluginLogSource(meta.source),
|
|
1159
|
+
surface: meta.surface,
|
|
1160
|
+
...meta.profile ? { profile: meta.profile } : {},
|
|
1161
|
+
event: normalizePluginLogEvent(input.event),
|
|
1162
|
+
message: sanitizePluginLogText(input.message || "No diagnostic message was provided.", PLUGIN_LOG_MAX_MESSAGE_CHARS),
|
|
1163
|
+
...meta.pid !== void 0 ? { pid: meta.pid } : {}
|
|
1164
|
+
};
|
|
1165
|
+
const context = sanitizePluginLogContext(mergePluginLogContext(meta.correlation, input.context));
|
|
1166
|
+
if (context) entry.context = context;
|
|
1167
|
+
const error = sanitizePluginLogError(input.error);
|
|
1168
|
+
if (error) entry.error = error;
|
|
1169
|
+
return entry;
|
|
1170
|
+
}
|
|
1171
|
+
function createChildPluginLogger(parent, bound) {
|
|
1172
|
+
return {
|
|
1173
|
+
get source() {
|
|
1174
|
+
return parent.source;
|
|
1175
|
+
},
|
|
1176
|
+
get file() {
|
|
1177
|
+
return parent.file;
|
|
1178
|
+
},
|
|
1179
|
+
get lastWriteError() {
|
|
1180
|
+
return parent.lastWriteError;
|
|
1181
|
+
},
|
|
1182
|
+
debug: (event, message, context) => parent.debug(event, message, mergePluginLogContext(bound, context)),
|
|
1183
|
+
info: (event, message, context) => parent.info(event, message, mergePluginLogContext(bound, context)),
|
|
1184
|
+
warn: (event, message, error, context) => parent.warn(event, message, error, mergePluginLogContext(bound, context)),
|
|
1185
|
+
error: (event, message, error, context) => parent.error(event, message, error, mergePluginLogContext(bound, context)),
|
|
1186
|
+
fault: (event, message, error, context) => parent.fault(event, message, error, mergePluginLogContext(bound, context)),
|
|
1187
|
+
write: (input) => parent.write({
|
|
1188
|
+
...input,
|
|
1189
|
+
context: mergePluginLogContext(bound, input.context)
|
|
1190
|
+
}),
|
|
1191
|
+
child: (next) => createChildPluginLogger(parent, mergePluginLogContext(bound, next) ?? {})
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
function truncateLogText(text, maxChars) {
|
|
1195
|
+
if (text.length <= maxChars) return text;
|
|
1196
|
+
const marker = "[truncated]\n";
|
|
1197
|
+
if (maxChars <= 12) return text.slice(0, Math.max(0, maxChars));
|
|
1198
|
+
return `${marker}${text.slice(-(maxChars - 12))}`;
|
|
1199
|
+
}
|
|
1200
|
+
//#endregion
|
|
1201
|
+
//#region ../dsh-plugin-kit/src/client-logger.ts
|
|
1202
|
+
const CLIENT_PLUGIN_LOG_GLOBAL = "__KLARKXY_PLUGIN_LOGS__";
|
|
1203
|
+
function readStorageFlag(key) {
|
|
1204
|
+
try {
|
|
1205
|
+
const value = (globalThis.window?.localStorage)?.getItem?.(key);
|
|
1206
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1207
|
+
} catch {
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
function sharedClientBuffer(limit) {
|
|
1212
|
+
const carrier = globalThis;
|
|
1213
|
+
if (!Array.isArray(carrier["__KLARKXY_PLUGIN_LOGS__"])) try {
|
|
1214
|
+
carrier[CLIENT_PLUGIN_LOG_GLOBAL] = [];
|
|
1215
|
+
} catch {
|
|
1216
|
+
return [];
|
|
1217
|
+
}
|
|
1218
|
+
const list = carrier[CLIENT_PLUGIN_LOG_GLOBAL];
|
|
1219
|
+
const overflow = list.length - limit;
|
|
1220
|
+
if (overflow > 0) list.splice(0, overflow);
|
|
1221
|
+
return list;
|
|
1222
|
+
}
|
|
1223
|
+
function createClientPluginLogger(source, ctx, options = {}) {
|
|
1224
|
+
const normalized = normalizePluginLogSource(source);
|
|
1225
|
+
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
1226
|
+
const limit = Math.max(10, options.bufferLimit ?? 500);
|
|
1227
|
+
const browserCtx = ctx && typeof ctx === "object" ? ctx : void 0;
|
|
1228
|
+
const resolveMinimum = () => {
|
|
1229
|
+
if (options.minimumLevel) return options.minimumLevel;
|
|
1230
|
+
return parsePluginLogLevel(readStorageFlag("dsh-plugin-log-level"), normalized, DEFAULT_PLUGIN_LOG_LEVEL);
|
|
1231
|
+
};
|
|
1232
|
+
const logger = {
|
|
1233
|
+
source: normalized,
|
|
1234
|
+
file: null,
|
|
1235
|
+
lastWriteError: null,
|
|
1236
|
+
debug: (event, message, context) => logger.write({
|
|
1237
|
+
level: "debug",
|
|
1238
|
+
event,
|
|
1239
|
+
message,
|
|
1240
|
+
...context ? { context } : {}
|
|
1241
|
+
}),
|
|
1242
|
+
info: (event, message, context) => logger.write({
|
|
1243
|
+
level: "info",
|
|
1244
|
+
event,
|
|
1245
|
+
message,
|
|
1246
|
+
...context ? { context } : {}
|
|
1247
|
+
}),
|
|
1248
|
+
warn: (event, message, error, context) => logger.write({
|
|
1249
|
+
level: "warn",
|
|
1250
|
+
event,
|
|
1251
|
+
message,
|
|
1252
|
+
...error !== void 0 ? { error } : {},
|
|
1253
|
+
...context ? { context } : {}
|
|
1254
|
+
}),
|
|
1255
|
+
error: (event, message, error, context) => logger.write({
|
|
1256
|
+
level: "error",
|
|
1257
|
+
event,
|
|
1258
|
+
message,
|
|
1259
|
+
...error !== void 0 ? { error } : {},
|
|
1260
|
+
...context ? { context } : {}
|
|
1261
|
+
}),
|
|
1262
|
+
fault: (event, message, error, context) => logger.write({
|
|
1263
|
+
level: "fault",
|
|
1264
|
+
event,
|
|
1265
|
+
message,
|
|
1266
|
+
...error !== void 0 ? { error } : {},
|
|
1267
|
+
...context ? { context } : {}
|
|
1268
|
+
}),
|
|
1269
|
+
child: (context) => createChildPluginLogger(logger, context),
|
|
1270
|
+
write(input) {
|
|
1271
|
+
try {
|
|
1272
|
+
if (!pluginLogLevelEnabled(input.level, resolveMinimum())) return false;
|
|
1273
|
+
const entry = buildPluginLogEntry(input, {
|
|
1274
|
+
at: now(),
|
|
1275
|
+
source: normalized,
|
|
1276
|
+
surface: "client"
|
|
1277
|
+
});
|
|
1278
|
+
const buffer = sharedClientBuffer(limit);
|
|
1279
|
+
buffer.push(entry);
|
|
1280
|
+
const overflow = buffer.length - limit;
|
|
1281
|
+
if (overflow > 0) buffer.splice(0, overflow);
|
|
1282
|
+
if (options.forwardToHostLogger !== false && browserCtx?.logger) {
|
|
1283
|
+
const summary = sanitizePluginLogText(`${normalized} [${entry.event}]: ${entry.message}`, 500);
|
|
1284
|
+
if (entry.level === "warn" && typeof browserCtx.logger.warn === "function") browserCtx.logger.warn(summary);
|
|
1285
|
+
else if ((entry.level === "error" || entry.level === "fault") && typeof browserCtx.logger.error === "function") browserCtx.logger.error(summary);
|
|
1286
|
+
}
|
|
1287
|
+
if (readStorageFlag("dsh-plugin-log-console") === "1") {
|
|
1288
|
+
const con = globalThis.console;
|
|
1289
|
+
(entry.level === "debug" ? con?.debug : entry.level === "info" ? con?.info : entry.level === "warn" ? con?.warn : con?.error)?.call(con, `[${normalized}] ${entry.event}: ${entry.message}`, entry);
|
|
1290
|
+
}
|
|
1291
|
+
return true;
|
|
1292
|
+
} catch {
|
|
1293
|
+
return false;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
return logger;
|
|
1298
|
+
}
|
|
1299
|
+
function installClientPluginLogger(ctx, source, options = {}) {
|
|
1300
|
+
const logger = createClientPluginLogger(source, ctx, options);
|
|
1301
|
+
logger.info("client.loaded", "Client plugin initialized.", options.loadedContext);
|
|
1302
|
+
const browserCtx = ctx && typeof ctx === "object" ? ctx : void 0;
|
|
1303
|
+
if (typeof browserCtx?.effect === "function") try {
|
|
1304
|
+
browserCtx.effect(() => () => {
|
|
1305
|
+
logger.debug("client.disposed", "Client plugin disposed.");
|
|
1306
|
+
}, `${logger.source}.client-logger`);
|
|
1307
|
+
} catch {}
|
|
1308
|
+
return logger;
|
|
1309
|
+
}
|
|
1310
|
+
//#endregion
|
|
1036
1311
|
//#region src/contracts.ts
|
|
1037
1312
|
const PLUGIN_NAME = "@klarkxy/dsh-deep-view";
|
|
1038
1313
|
const RPC_CHANNEL = "/dsh-deep-view";
|
|
@@ -2699,14 +2974,7 @@ function sameAnswers(left, right) {
|
|
|
2699
2974
|
});
|
|
2700
2975
|
}
|
|
2701
2976
|
//#endregion
|
|
2702
|
-
//#region src/
|
|
2703
|
-
const name = "dsh-deep-view-client";
|
|
2704
|
-
const inject = [
|
|
2705
|
-
"slots",
|
|
2706
|
-
"connection",
|
|
2707
|
-
"locale"
|
|
2708
|
-
];
|
|
2709
|
-
const LOCALE = "deep-view";
|
|
2977
|
+
//#region src/copy.ts
|
|
2710
2978
|
const uiZh = {
|
|
2711
2979
|
copy: "复制",
|
|
2712
2980
|
copied: "已复制",
|
|
@@ -2771,6 +3039,15 @@ const uiEn = {
|
|
|
2771
3039
|
send: "Send",
|
|
2772
3040
|
selected: "Selected"
|
|
2773
3041
|
};
|
|
3042
|
+
//#endregion
|
|
3043
|
+
//#region src/client.tsx
|
|
3044
|
+
const name = "dsh-deep-view-client";
|
|
3045
|
+
const inject = [
|
|
3046
|
+
"slots",
|
|
3047
|
+
"connection",
|
|
3048
|
+
"locale"
|
|
3049
|
+
];
|
|
3050
|
+
const LOCALE = "deep-view";
|
|
2774
3051
|
const viewT = (t) => (key, params) => {
|
|
2775
3052
|
const keys = {
|
|
2776
3053
|
Copy: "copy",
|
|
@@ -2927,15 +3204,29 @@ function ToolCallView(props) {
|
|
|
2927
3204
|
action,
|
|
2928
3205
|
values
|
|
2929
3206
|
}).then((result) => {
|
|
2930
|
-
|
|
3207
|
+
const envelope = result;
|
|
3208
|
+
if (envelope?.ok) {
|
|
2931
3209
|
setAnswer({
|
|
2932
3210
|
id: pending.id,
|
|
2933
3211
|
action,
|
|
2934
3212
|
values
|
|
2935
3213
|
});
|
|
2936
3214
|
setPending(null);
|
|
2937
|
-
} else
|
|
2938
|
-
|
|
3215
|
+
} else {
|
|
3216
|
+
createClientPluginLogger(PLUGIN_NAME).warn("reply.rejected", "Deep View reply was rejected by host.", void 0, {
|
|
3217
|
+
sessionId: props.sessionId,
|
|
3218
|
+
viewId: pending.id,
|
|
3219
|
+
code: envelope && !envelope.ok ? envelope.error.code : null
|
|
3220
|
+
});
|
|
3221
|
+
setFailed(true);
|
|
3222
|
+
}
|
|
3223
|
+
}).catch((error) => {
|
|
3224
|
+
createClientPluginLogger(PLUGIN_NAME).error("reply.transport-error", "Deep View reply RPC failed.", error, {
|
|
3225
|
+
sessionId: props.sessionId,
|
|
3226
|
+
viewId: pending.id
|
|
3227
|
+
});
|
|
3228
|
+
setFailed(true);
|
|
3229
|
+
}).finally(() => setBusy(false));
|
|
2939
3230
|
}, [
|
|
2940
3231
|
props.call,
|
|
2941
3232
|
props.sessionId,
|
|
@@ -2967,7 +3258,7 @@ function ToolCallView(props) {
|
|
|
2967
3258
|
view: shown.view,
|
|
2968
3259
|
onSubmit: canAnswer ? submit : void 0,
|
|
2969
3260
|
busy,
|
|
2970
|
-
settled: answer !== null || !canAnswer,
|
|
3261
|
+
settled: answer !== null || shown.awaitReply && !canAnswer,
|
|
2971
3262
|
answer,
|
|
2972
3263
|
t: viewT(t),
|
|
2973
3264
|
labels,
|
|
@@ -3035,8 +3326,65 @@ function ToolCallStatus(props) {
|
|
|
3035
3326
|
children: props.t(read.isError ? "error" : read.phase === "result" && !read.presentation ? "invalid" : read.phase === "result" ? "prepared" : "preparing")
|
|
3036
3327
|
});
|
|
3037
3328
|
}
|
|
3329
|
+
/** Client service name other plugins read to draw show_view cards in their own surfaces. */
|
|
3330
|
+
const CARDS_SERVICE = "dshDeepView";
|
|
3331
|
+
function staticArgs(values) {
|
|
3332
|
+
return {
|
|
3333
|
+
has: (key) => values[key] !== void 0,
|
|
3334
|
+
complete: (key) => values[key] !== void 0,
|
|
3335
|
+
text: (key) => typeof values[key] === "string" ? values[key] : void 0,
|
|
3336
|
+
value: (key) => values[key]
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
/** One show_view card for a plugin-drawn chat: same card, same answer channel as the host chat. */
|
|
3340
|
+
function createCards(call, locale) {
|
|
3341
|
+
const subscribe = (listener) => locale?.subscribe?.(listener) ?? (() => {});
|
|
3342
|
+
const active = () => locale?.getSnapshot?.().active ?? "en";
|
|
3343
|
+
function Card(props) {
|
|
3344
|
+
const language = (0, react.useSyncExternalStore)(subscribe, active);
|
|
3345
|
+
const t = (0, react.useMemo)(() => {
|
|
3346
|
+
const table = language.toLowerCase().startsWith("zh") ? uiZh : uiEn;
|
|
3347
|
+
return (key, params) => (table[key] ?? key).replace(/\{(\w+)\}/g, (_, name) => String(params?.[name] ?? `{${name}}`));
|
|
3348
|
+
}, [language]);
|
|
3349
|
+
const block = (0, react.useMemo)(() => props.presentation !== void 0 ? {
|
|
3350
|
+
callId: props.callId,
|
|
3351
|
+
kind: "tool-result",
|
|
3352
|
+
meta: props.presentation,
|
|
3353
|
+
isError: false
|
|
3354
|
+
} : props.failed ? {
|
|
3355
|
+
callId: props.callId,
|
|
3356
|
+
kind: "tool-result",
|
|
3357
|
+
isError: true
|
|
3358
|
+
} : {
|
|
3359
|
+
callId: props.callId,
|
|
3360
|
+
args: staticArgs({
|
|
3361
|
+
title: props.title,
|
|
3362
|
+
view: props.view
|
|
3363
|
+
})
|
|
3364
|
+
}, [
|
|
3365
|
+
props.callId,
|
|
3366
|
+
props.presentation,
|
|
3367
|
+
props.failed,
|
|
3368
|
+
props.title,
|
|
3369
|
+
props.view
|
|
3370
|
+
]);
|
|
3371
|
+
const phase = props.presentation !== void 0 || props.failed ? "result" : "start";
|
|
3372
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallView, {
|
|
3373
|
+
sessionId: props.sessionId,
|
|
3374
|
+
callId: props.callId,
|
|
3375
|
+
phase,
|
|
3376
|
+
block,
|
|
3377
|
+
t,
|
|
3378
|
+
call,
|
|
3379
|
+
...props.answer ? { restoredAnswer: props.answer } : {}
|
|
3380
|
+
});
|
|
3381
|
+
}
|
|
3382
|
+
return { Card };
|
|
3383
|
+
}
|
|
3038
3384
|
function apply(ctx) {
|
|
3039
3385
|
const client = ctx;
|
|
3386
|
+
installClientPluginLogger(ctx, PLUGIN_NAME);
|
|
3387
|
+
client.provide(CARDS_SERVICE, createCards((endpoint, payload) => client.connection.rpc.call(RPC_CHANNEL, endpoint, payload), client.locale));
|
|
3040
3388
|
ctx.effect(() => client.locale.register(LOCALE, {
|
|
3041
3389
|
zh: { ...uiZh },
|
|
3042
3390
|
en: { ...uiEn }
|
|
@@ -3063,11 +3411,13 @@ function apply(ctx) {
|
|
|
3063
3411
|
}, ReplyView)), "deep-view.reply");
|
|
3064
3412
|
}
|
|
3065
3413
|
//#endregion
|
|
3414
|
+
exports.CARDS_SERVICE = CARDS_SERVICE;
|
|
3066
3415
|
exports.LOCALE = LOCALE;
|
|
3067
3416
|
exports.ReplyView = ReplyView;
|
|
3068
3417
|
exports.ToolCallStatus = ToolCallStatus;
|
|
3069
3418
|
exports.ToolCallView = ToolCallView;
|
|
3070
3419
|
exports.apply = apply;
|
|
3420
|
+
exports.createCards = createCards;
|
|
3071
3421
|
exports.inject = inject;
|
|
3072
3422
|
exports.name = name;
|
|
3073
3423
|
exports.readToolCall = readToolCall;
|
package/lib/contracts.d.ts
CHANGED
|
@@ -1,98 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type RpcResult<T = unknown> = RpcResult$1<T>;
|
|
4
|
-
declare const PLUGIN_NAME = "@klarkxy/dsh-deep-view";
|
|
5
|
-
declare const RPC_CHANNEL = "/dsh-deep-view";
|
|
6
|
-
declare const VIEW_OWNER = "dsh-deep-view";
|
|
7
|
-
type Scalar = string | number | boolean;
|
|
8
|
-
type Formula = {
|
|
9
|
-
'=': string;
|
|
10
|
-
};
|
|
11
|
-
type Value = Scalar | Formula;
|
|
12
|
-
type ChoiceOption = {
|
|
13
|
-
label: string;
|
|
14
|
-
value?: Scalar;
|
|
15
|
-
};
|
|
16
|
-
type ViewNode = {
|
|
17
|
-
type: 'stack' | 'row' | 'text' | 'metric' | 'table' | 'chart' | 'progress' | 'callout' | 'sources' | 'slider' | 'number' | 'choice' | 'toggle' | 'options' | 'confirm' | 'form' | 'submit';
|
|
18
|
-
id?: string;
|
|
19
|
-
children?: ViewNode[];
|
|
20
|
-
let?: Record<string, string>;
|
|
21
|
-
text?: Value;
|
|
22
|
-
label?: string;
|
|
23
|
-
value?: Value;
|
|
24
|
-
tone?: Value;
|
|
25
|
-
caption?: Value;
|
|
26
|
-
columns?: {
|
|
27
|
-
key: string;
|
|
28
|
-
label: string;
|
|
29
|
-
}[];
|
|
30
|
-
rows?: Value[][];
|
|
31
|
-
kind?: 'bar' | 'hbar' | 'line' | 'area' | 'donut';
|
|
32
|
-
categories?: Scalar[];
|
|
33
|
-
series?: {
|
|
34
|
-
name?: string;
|
|
35
|
-
values: (number | Formula)[];
|
|
36
|
-
}[];
|
|
37
|
-
unit?: string;
|
|
38
|
-
percent?: Value;
|
|
39
|
-
max?: Value;
|
|
40
|
-
valueLabel?: Value;
|
|
41
|
-
items?: {
|
|
42
|
-
label: string;
|
|
43
|
-
url: string;
|
|
44
|
-
}[];
|
|
45
|
-
min?: number;
|
|
46
|
-
step?: number;
|
|
47
|
-
options?: ChoiceOption[] | {
|
|
48
|
-
label: string;
|
|
49
|
-
description?: string;
|
|
50
|
-
}[];
|
|
51
|
-
multi?: boolean;
|
|
52
|
-
confirmLabel?: string;
|
|
53
|
-
cancelLabel?: string;
|
|
54
|
-
fields?: {
|
|
55
|
-
id: string;
|
|
56
|
-
label: string;
|
|
57
|
-
placeholder?: string;
|
|
58
|
-
}[];
|
|
59
|
-
submitLabel?: string;
|
|
60
|
-
};
|
|
61
|
-
type ShownView = {
|
|
62
|
-
title: string;
|
|
63
|
-
view: ViewNode;
|
|
64
|
-
interactive: boolean;
|
|
65
|
-
};
|
|
66
|
-
type ViewFailure = {
|
|
67
|
-
error: string;
|
|
68
|
-
};
|
|
69
|
-
type PendingView = {
|
|
70
|
-
id: string;
|
|
71
|
-
sessionId: string;
|
|
72
|
-
callId?: string;
|
|
73
|
-
title: string;
|
|
74
|
-
view: ViewNode;
|
|
75
|
-
};
|
|
76
|
-
type ViewAnswer = {
|
|
77
|
-
id: string;
|
|
78
|
-
action: string;
|
|
79
|
-
values: Record<string, unknown>;
|
|
80
|
-
};
|
|
81
|
-
/** Stored on the same user message as its readable answer, outside model text. */
|
|
82
|
-
type ViewAnswerMetadata = {
|
|
83
|
-
owner: typeof VIEW_OWNER;
|
|
84
|
-
version: 1;
|
|
85
|
-
answer: ViewAnswer;
|
|
86
|
-
};
|
|
87
|
-
type ViewPresentation = {
|
|
88
|
-
owner: typeof VIEW_OWNER;
|
|
89
|
-
viewId?: string;
|
|
90
|
-
title: string;
|
|
91
|
-
view: ViewNode;
|
|
92
|
-
interactive: boolean;
|
|
93
|
-
awaitReply: boolean;
|
|
94
|
-
};
|
|
95
|
-
declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
96
|
-
//#endregion
|
|
97
|
-
export { ChoiceOption, Formula, PLUGIN_NAME, PendingView, RPC_CHANNEL, RpcResult, Scalar, ShownView, VIEW_OWNER, Value, ViewAnswer, ViewAnswerMetadata, ViewFailure, ViewNode, ViewPresentation, isRecord };
|
|
98
|
-
//# sourceMappingURL=contracts.d.ts.map
|
|
1
|
+
import { _ as ViewPresentation, a as PLUGIN_NAME, c as RpcResult, d as VIEW_OWNER, f as Value, g as ViewNode, h as ViewFailure, i as HOST_SERVICE, l as Scalar, m as ViewAnswerMetadata, n as DeepViewHost, o as PendingView, p as ViewAnswer, r as Formula, s as RPC_CHANNEL, t as ChoiceOption, u as ShownView, v as isRecord } from "./contracts2.js";
|
|
2
|
+
export { ChoiceOption, DeepViewHost, Formula, HOST_SERVICE, PLUGIN_NAME, PendingView, RPC_CHANNEL, RpcResult, Scalar, ShownView, VIEW_OWNER, Value, ViewAnswer, ViewAnswerMetadata, ViewFailure, ViewNode, ViewPresentation, isRecord };
|
package/lib/contracts.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
const PLUGIN_NAME = "@klarkxy/dsh-deep-view";
|
|
3
3
|
const RPC_CHANNEL = "/dsh-deep-view";
|
|
4
4
|
const VIEW_OWNER = "dsh-deep-view";
|
|
5
|
+
const HOST_SERVICE = "dshDeepView";
|
|
5
6
|
function isRecord(value) {
|
|
6
7
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7
8
|
}
|
|
8
9
|
//#endregion
|
|
9
|
-
export { PLUGIN_NAME, RPC_CHANNEL, VIEW_OWNER, isRecord };
|
|
10
|
+
export { HOST_SERVICE, PLUGIN_NAME, RPC_CHANNEL, VIEW_OWNER, isRecord };
|
|
10
11
|
|
|
11
12
|
//# sourceMappingURL=contracts.js.map
|
package/lib/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","names":[],"sources":["../src/contracts.ts"],"sourcesContent":["import type { RpcResult as SharedRpcResult } from '@klarkxy/dsh-plugin-kit/contracts'\nexport type RpcResult<T = unknown> = SharedRpcResult<T>\nexport const PLUGIN_NAME = '@klarkxy/dsh-deep-view'\nexport const RPC_CHANNEL = '/dsh-deep-view'\nexport const VIEW_OWNER = 'dsh-deep-view'\n\nexport type Scalar = string | number | boolean\nexport type Formula = { '=': string }\nexport type Value = Scalar | Formula\nexport type ChoiceOption = { label: string; value?: Scalar }\nexport type ViewNode = {\n type: 'stack' | 'row' | 'text' | 'metric' | 'table' | 'chart' | 'progress' | 'callout' | 'sources'\n | 'slider' | 'number' | 'choice' | 'toggle' | 'options' | 'confirm' | 'form' | 'submit'\n id?: string\n children?: ViewNode[]\n let?: Record<string, string>\n text?: Value\n label?: string\n value?: Value\n tone?: Value\n caption?: Value\n columns?: { key: string; label: string }[]\n rows?: Value[][]\n kind?: 'bar' | 'hbar' | 'line' | 'area' | 'donut'\n categories?: Scalar[]\n series?: { name?: string; values: (number | Formula)[] }[]\n unit?: string\n percent?: Value\n max?: Value\n valueLabel?: Value\n items?: { label: string; url: string }[]\n min?: number\n step?: number\n options?: ChoiceOption[] | { label: string; description?: string }[]\n multi?: boolean\n confirmLabel?: string\n cancelLabel?: string\n fields?: { id: string; label: string; placeholder?: string }[]\n submitLabel?: string\n}\nexport type ShownView = { title: string; view: ViewNode; interactive: boolean }\nexport type ViewFailure = { error: string }\nexport type PendingView = { id: string; sessionId: string; callId?: string; title: string; view: ViewNode }\nexport type ViewAnswer = { id: string; action: string; values: Record<string, unknown> }\n/** Stored on the same user message as its readable answer, outside model text. */\nexport type ViewAnswerMetadata = { owner: typeof VIEW_OWNER; version: 1; answer: ViewAnswer }\nexport type ViewPresentation = {\n owner: typeof VIEW_OWNER\n viewId?: string\n title: string\n view: ViewNode\n interactive: boolean\n awaitReply: boolean\n}\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n"],"mappings":";AAEA,MAAa,cAAc;AAC3B,MAAa,cAAc;AAC3B,MAAa,aAAa;
|
|
1
|
+
{"version":3,"file":"contracts.js","names":[],"sources":["../src/contracts.ts"],"sourcesContent":["import type { RpcResult as SharedRpcResult } from '@klarkxy/dsh-plugin-kit/contracts'\nexport type RpcResult<T = unknown> = SharedRpcResult<T>\nexport const PLUGIN_NAME = '@klarkxy/dsh-deep-view'\nexport const RPC_CHANNEL = '/dsh-deep-view'\nexport const VIEW_OWNER = 'dsh-deep-view'\nexport const HOST_SERVICE = 'dshDeepView'\nexport type DeepViewHost = {\n /** Move an open card and route stale session lookups to a replacement root session. */\n handoffSession(fromSessionId: string, toSessionId: string): boolean\n}\n\nexport type Scalar = string | number | boolean\nexport type Formula = { '=': string }\nexport type Value = Scalar | Formula\nexport type ChoiceOption = { label: string; value?: Scalar }\nexport type ViewNode = {\n type: 'stack' | 'row' | 'text' | 'metric' | 'table' | 'chart' | 'progress' | 'callout' | 'sources'\n | 'slider' | 'number' | 'choice' | 'toggle' | 'options' | 'confirm' | 'form' | 'submit'\n id?: string\n children?: ViewNode[]\n let?: Record<string, string>\n text?: Value\n label?: string\n value?: Value\n tone?: Value\n caption?: Value\n columns?: { key: string; label: string }[]\n rows?: Value[][]\n kind?: 'bar' | 'hbar' | 'line' | 'area' | 'donut'\n categories?: Scalar[]\n series?: { name?: string; values: (number | Formula)[] }[]\n unit?: string\n percent?: Value\n max?: Value\n valueLabel?: Value\n items?: { label: string; url: string }[]\n min?: number\n step?: number\n options?: ChoiceOption[] | { label: string; description?: string }[]\n multi?: boolean\n confirmLabel?: string\n cancelLabel?: string\n fields?: { id: string; label: string; placeholder?: string }[]\n submitLabel?: string\n}\nexport type ShownView = { title: string; view: ViewNode; interactive: boolean }\nexport type ViewFailure = { error: string }\nexport type PendingView = { id: string; sessionId: string; callId?: string; title: string; view: ViewNode }\nexport type ViewAnswer = { id: string; action: string; values: Record<string, unknown> }\n/** Stored on the same user message as its readable answer, outside model text. */\nexport type ViewAnswerMetadata = { owner: typeof VIEW_OWNER; version: 1; answer: ViewAnswer }\nexport type ViewPresentation = {\n owner: typeof VIEW_OWNER\n viewId?: string\n title: string\n view: ViewNode\n interactive: boolean\n awaitReply: boolean\n}\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n"],"mappings":";AAEA,MAAa,cAAc;AAC3B,MAAa,cAAc;AAC3B,MAAa,aAAa;AAC1B,MAAa,eAAe;AAsD5B,SAAgB,SAAS,OAAkD;CACzE,OAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { RpcResult } from "@klarkxy/dsh-plugin-kit/contracts";
|
|
2
|
+
//#region src/contracts.d.ts
|
|
3
|
+
type RpcResult$1<T = unknown> = RpcResult<T>;
|
|
4
|
+
declare const PLUGIN_NAME = "@klarkxy/dsh-deep-view";
|
|
5
|
+
declare const RPC_CHANNEL = "/dsh-deep-view";
|
|
6
|
+
declare const VIEW_OWNER = "dsh-deep-view";
|
|
7
|
+
declare const HOST_SERVICE = "dshDeepView";
|
|
8
|
+
type DeepViewHost = {
|
|
9
|
+
/** Move an open card and route stale session lookups to a replacement root session. */
|
|
10
|
+
handoffSession(fromSessionId: string, toSessionId: string): boolean;
|
|
11
|
+
};
|
|
12
|
+
type Scalar = string | number | boolean;
|
|
13
|
+
type Formula = {
|
|
14
|
+
'=': string;
|
|
15
|
+
};
|
|
16
|
+
type Value = Scalar | Formula;
|
|
17
|
+
type ChoiceOption = {
|
|
18
|
+
label: string;
|
|
19
|
+
value?: Scalar;
|
|
20
|
+
};
|
|
21
|
+
type ViewNode = {
|
|
22
|
+
type: 'stack' | 'row' | 'text' | 'metric' | 'table' | 'chart' | 'progress' | 'callout' | 'sources' | 'slider' | 'number' | 'choice' | 'toggle' | 'options' | 'confirm' | 'form' | 'submit';
|
|
23
|
+
id?: string;
|
|
24
|
+
children?: ViewNode[];
|
|
25
|
+
let?: Record<string, string>;
|
|
26
|
+
text?: Value;
|
|
27
|
+
label?: string;
|
|
28
|
+
value?: Value;
|
|
29
|
+
tone?: Value;
|
|
30
|
+
caption?: Value;
|
|
31
|
+
columns?: {
|
|
32
|
+
key: string;
|
|
33
|
+
label: string;
|
|
34
|
+
}[];
|
|
35
|
+
rows?: Value[][];
|
|
36
|
+
kind?: 'bar' | 'hbar' | 'line' | 'area' | 'donut';
|
|
37
|
+
categories?: Scalar[];
|
|
38
|
+
series?: {
|
|
39
|
+
name?: string;
|
|
40
|
+
values: (number | Formula)[];
|
|
41
|
+
}[];
|
|
42
|
+
unit?: string;
|
|
43
|
+
percent?: Value;
|
|
44
|
+
max?: Value;
|
|
45
|
+
valueLabel?: Value;
|
|
46
|
+
items?: {
|
|
47
|
+
label: string;
|
|
48
|
+
url: string;
|
|
49
|
+
}[];
|
|
50
|
+
min?: number;
|
|
51
|
+
step?: number;
|
|
52
|
+
options?: ChoiceOption[] | {
|
|
53
|
+
label: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
}[];
|
|
56
|
+
multi?: boolean;
|
|
57
|
+
confirmLabel?: string;
|
|
58
|
+
cancelLabel?: string;
|
|
59
|
+
fields?: {
|
|
60
|
+
id: string;
|
|
61
|
+
label: string;
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
}[];
|
|
64
|
+
submitLabel?: string;
|
|
65
|
+
};
|
|
66
|
+
type ShownView = {
|
|
67
|
+
title: string;
|
|
68
|
+
view: ViewNode;
|
|
69
|
+
interactive: boolean;
|
|
70
|
+
};
|
|
71
|
+
type ViewFailure = {
|
|
72
|
+
error: string;
|
|
73
|
+
};
|
|
74
|
+
type PendingView = {
|
|
75
|
+
id: string;
|
|
76
|
+
sessionId: string;
|
|
77
|
+
callId?: string;
|
|
78
|
+
title: string;
|
|
79
|
+
view: ViewNode;
|
|
80
|
+
};
|
|
81
|
+
type ViewAnswer = {
|
|
82
|
+
id: string;
|
|
83
|
+
action: string;
|
|
84
|
+
values: Record<string, unknown>;
|
|
85
|
+
};
|
|
86
|
+
/** Stored on the same user message as its readable answer, outside model text. */
|
|
87
|
+
type ViewAnswerMetadata = {
|
|
88
|
+
owner: typeof VIEW_OWNER;
|
|
89
|
+
version: 1;
|
|
90
|
+
answer: ViewAnswer;
|
|
91
|
+
};
|
|
92
|
+
type ViewPresentation = {
|
|
93
|
+
owner: typeof VIEW_OWNER;
|
|
94
|
+
viewId?: string;
|
|
95
|
+
title: string;
|
|
96
|
+
view: ViewNode;
|
|
97
|
+
interactive: boolean;
|
|
98
|
+
awaitReply: boolean;
|
|
99
|
+
};
|
|
100
|
+
declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
101
|
+
//#endregion
|
|
102
|
+
export { ViewPresentation as _, PLUGIN_NAME as a, RpcResult$1 as c, VIEW_OWNER as d, Value as f, ViewNode as g, ViewFailure as h, HOST_SERVICE as i, Scalar as l, ViewAnswerMetadata as m, DeepViewHost as n, PendingView as o, ViewAnswer as p, Formula as r, RPC_CHANNEL as s, ChoiceOption as t, ShownView as u, isRecord as v };
|
|
103
|
+
//# sourceMappingURL=contracts2.d.ts.map
|