@topolo/sdk 0.10.0 → 0.10.2
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/index.cjs +139 -12
- package/dist/index.d.cts +284 -232
- package/dist/index.d.ts +284 -232
- package/dist/index.js +135 -12
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,10 @@ __export(index_exports, {
|
|
|
44
44
|
auditAllApplicationRequirements: () => auditAllApplicationRequirements,
|
|
45
45
|
auditApplicationEntries: () => auditApplicationEntries,
|
|
46
46
|
auditApplicationRequirements: () => auditApplicationRequirements,
|
|
47
|
+
compactActionCatalogEntry: () => compactActionCatalogEntry,
|
|
48
|
+
compactActionPlan: () => compactActionPlan,
|
|
49
|
+
compactActionValidation: () => compactActionValidation,
|
|
50
|
+
compactApplicationAudit: () => compactApplicationAudit,
|
|
47
51
|
createTopolo: () => createTopolo,
|
|
48
52
|
createTopoloWidgetError: () => createTopoloWidgetError,
|
|
49
53
|
createTopoloWidgetResponse: () => createTopoloWidgetResponse,
|
|
@@ -3999,6 +4003,54 @@ function mergeSignals(a, b) {
|
|
|
3999
4003
|
return controller.signal;
|
|
4000
4004
|
}
|
|
4001
4005
|
|
|
4006
|
+
// src/agent-output.ts
|
|
4007
|
+
function compactActionCatalogEntry(action) {
|
|
4008
|
+
const required = Array.isArray(action.inputSchema["required"]) ? action.inputSchema["required"].filter((value) => typeof value === "string") : [];
|
|
4009
|
+
const examples = action.agentContract?.examples ?? [];
|
|
4010
|
+
return {
|
|
4011
|
+
actionId: action.actionId,
|
|
4012
|
+
title: action.title,
|
|
4013
|
+
description: action.description,
|
|
4014
|
+
method: action.method,
|
|
4015
|
+
readOnly: action.readOnly,
|
|
4016
|
+
requiresConfirmation: action.requiresConfirmation,
|
|
4017
|
+
agentAccess: action.agentAccess ?? (action.requiresConfirmation ? "confirm" : action.readOnly ? "auto" : "confirm"),
|
|
4018
|
+
requiredPermission: action.requiredPermission,
|
|
4019
|
+
requiredInput: required,
|
|
4020
|
+
resourceType: action.agentContract?.resource?.kind ?? null,
|
|
4021
|
+
exampleInput: examples[0]?.input ?? null,
|
|
4022
|
+
docsUrl: action.agentContract?.docsUrl ?? null
|
|
4023
|
+
};
|
|
4024
|
+
}
|
|
4025
|
+
function compactActionValidation(actionId, validation) {
|
|
4026
|
+
return { actionId, valid: validation.valid, errors: validation.errors };
|
|
4027
|
+
}
|
|
4028
|
+
function compactActionPlan(plan) {
|
|
4029
|
+
return {
|
|
4030
|
+
actionId: plan.action.actionId,
|
|
4031
|
+
valid: plan.validation.valid,
|
|
4032
|
+
errors: plan.validation.errors,
|
|
4033
|
+
executable: plan.executable,
|
|
4034
|
+
confirmationRequired: plan.confirmationRequired,
|
|
4035
|
+
confirmationProvided: plan.confirmationProvided,
|
|
4036
|
+
request: plan.request,
|
|
4037
|
+
verification: plan.verification,
|
|
4038
|
+
rollbackActionId: plan.rollbackActionId,
|
|
4039
|
+
nextActionIds: plan.nextActionIds
|
|
4040
|
+
};
|
|
4041
|
+
}
|
|
4042
|
+
function compactApplicationAudit(report) {
|
|
4043
|
+
return {
|
|
4044
|
+
version: report.version,
|
|
4045
|
+
applications: report.applications.map((audit) => ({
|
|
4046
|
+
applicationId: audit.application.id,
|
|
4047
|
+
applicationName: audit.application.name,
|
|
4048
|
+
score: audit.score
|
|
4049
|
+
})),
|
|
4050
|
+
migrationQueueCount: report.migrationQueue.length
|
|
4051
|
+
};
|
|
4052
|
+
}
|
|
4053
|
+
|
|
4002
4054
|
// src/action-catalog-digest.ts
|
|
4003
4055
|
var ACTION_CATALOG_DIGEST_ALGORITHM = "sha256-v1";
|
|
4004
4056
|
function canonicalPermission(value, appId) {
|
|
@@ -4212,25 +4264,92 @@ function derivedOutputSchema(action) {
|
|
|
4212
4264
|
...provenance
|
|
4213
4265
|
};
|
|
4214
4266
|
}
|
|
4215
|
-
function
|
|
4216
|
-
|
|
4267
|
+
function patternedString(pattern, hint) {
|
|
4268
|
+
const candidates = [
|
|
4269
|
+
hint.toLowerCase().includes("email") ? "agent@topolo.app" : null,
|
|
4270
|
+
hint.toLowerCase().includes("url") || hint.toLowerCase().includes("uri") ? "https://topolo.app" : null,
|
|
4271
|
+
hint.toLowerCase().includes("app") && hint.toLowerCase().includes("id") ? "app_topolo_example" : null,
|
|
4272
|
+
hint.toLowerCase().includes("file") ? "sample.ply" : null,
|
|
4273
|
+
hint.toLowerCase().includes("slug") ? "/sample" : null,
|
|
4274
|
+
hint.toLowerCase().includes("year") ? "2026" : null,
|
|
4275
|
+
hint.toLowerCase().includes("date") || hint.toLowerCase().endsWith("at") ? "2026-01-15T12:00:00Z" : null,
|
|
4276
|
+
hint.toLowerCase().includes("period") || hint.toLowerCase().includes("month") ? "2026-01" : null,
|
|
4277
|
+
hint.toLowerCase().includes("event") || hint.toLowerCase().includes("type") ? "resource.created" : null,
|
|
4278
|
+
"app_topolo_example",
|
|
4279
|
+
"2026-01-15T12:00:00Z",
|
|
4280
|
+
"sample.ply",
|
|
4281
|
+
"/sample",
|
|
4282
|
+
"2026-01-15",
|
|
4283
|
+
"2026-01",
|
|
4284
|
+
"2026",
|
|
4285
|
+
"resource.created",
|
|
4286
|
+
"sample-value",
|
|
4287
|
+
"sample_value",
|
|
4288
|
+
"sample"
|
|
4289
|
+
].filter(Boolean);
|
|
4290
|
+
try {
|
|
4291
|
+
const expression = new RegExp(pattern);
|
|
4292
|
+
return candidates.find((candidate) => expression.test(candidate)) ?? "sample";
|
|
4293
|
+
} catch {
|
|
4294
|
+
return "sample";
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
function sampleString(schema, hint) {
|
|
4298
|
+
if (schema.format === "email") return "agent@topolo.app";
|
|
4299
|
+
if (schema.format === "uri" || schema.format === "url") return "https://topolo.app";
|
|
4300
|
+
if (schema.format === "date-time") return patternedString(schema.pattern || "", hint) || "2026-01-15T12:00:00Z";
|
|
4301
|
+
const words = String(hint || "value").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
|
|
4302
|
+
let value = typeof schema.pattern === "string" ? patternedString(schema.pattern, hint) : /(^|\s)id$/.test(words) ? `${slugify(words.replace(/\sid$/, "") || "resource")}_01` : words.includes("date") ? "2026-01-15" : words.includes("period") || words.includes("month") ? "2026-01" : words.includes("year") ? "2026" : `Sample ${words}`;
|
|
4303
|
+
const minimum = Number.isInteger(schema.minLength) ? schema.minLength : 0;
|
|
4304
|
+
const maximum = Number.isInteger(schema.maxLength) ? schema.maxLength : null;
|
|
4305
|
+
if (value.length < minimum) value = value.padEnd(minimum, "x");
|
|
4306
|
+
if (maximum !== null && value.length > maximum) value = value.slice(0, maximum);
|
|
4307
|
+
return value;
|
|
4308
|
+
}
|
|
4309
|
+
function localReference(rootSchema, reference) {
|
|
4310
|
+
if (!isRecord4(rootSchema) || typeof reference !== "string" || !reference.startsWith("#/")) return null;
|
|
4311
|
+
return reference.slice(2).split("/").reduce((value, segment) => {
|
|
4312
|
+
const key = segment.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
4313
|
+
return isRecord4(value) ? value[key] : void 0;
|
|
4314
|
+
}, rootSchema);
|
|
4315
|
+
}
|
|
4316
|
+
function representativeNumber(schema, hint) {
|
|
4317
|
+
const integer = schema.type === "integer";
|
|
4318
|
+
const words = String(hint || "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
|
|
4319
|
+
const preferred = /\b(?:percent|percentage|ratio|rate)\b/.test(words) ? 0.5 : /\b(?:amount|balance|cent|cents|minor)\b/.test(words) ? 1e3 : words.includes("year") ? 2026 : 1;
|
|
4320
|
+
const exclusiveOffset = (value2) => Math.max(Number.EPSILON * Math.max(1, Math.abs(value2)) * 2, Number.MIN_VALUE);
|
|
4321
|
+
const lower = typeof schema.exclusiveMinimum === "number" ? integer ? Math.floor(schema.exclusiveMinimum) + 1 : schema.exclusiveMinimum + exclusiveOffset(schema.exclusiveMinimum) : typeof schema.minimum === "number" ? integer ? Math.ceil(schema.minimum) : schema.minimum : -Infinity;
|
|
4322
|
+
const upper = typeof schema.exclusiveMaximum === "number" ? integer ? Math.ceil(schema.exclusiveMaximum) - 1 : schema.exclusiveMaximum - exclusiveOffset(schema.exclusiveMaximum) : typeof schema.maximum === "number" ? integer ? Math.floor(schema.maximum) : schema.maximum : Infinity;
|
|
4323
|
+
const value = Math.min(Math.max(preferred, lower), upper);
|
|
4324
|
+
return integer ? Math.round(value) : value;
|
|
4325
|
+
}
|
|
4326
|
+
function sampleForSchema(schema, depth = 0, hint = "value", rootSchema = schema) {
|
|
4327
|
+
if (!isRecord4(schema) || depth > 20) return null;
|
|
4328
|
+
const referenced = localReference(rootSchema, schema.$ref);
|
|
4329
|
+
if (isRecord4(referenced)) return sampleForSchema(referenced, depth + 1, hint, rootSchema);
|
|
4217
4330
|
if (schema.const !== void 0) return schema.const;
|
|
4218
4331
|
if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
|
|
4219
|
-
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0) return sampleForSchema(schema.oneOf[0], depth + 1);
|
|
4220
|
-
if (Array.isArray(schema.anyOf) && schema.anyOf.length > 0) return sampleForSchema(schema.anyOf[0], depth + 1);
|
|
4221
|
-
if (schema.type
|
|
4332
|
+
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0) return sampleForSchema(schema.oneOf[0], depth + 1, hint, rootSchema);
|
|
4333
|
+
if (Array.isArray(schema.anyOf) && schema.anyOf.length > 0) return sampleForSchema(schema.anyOf[0], depth + 1, hint, rootSchema);
|
|
4334
|
+
if (Array.isArray(schema.type)) {
|
|
4335
|
+
return sampleForSchema({ ...schema, type: schema.type.find((type) => type !== "null") ?? schema.type[0] }, depth + 1, hint, rootSchema);
|
|
4336
|
+
}
|
|
4337
|
+
if (schema.type === "array") {
|
|
4338
|
+
const minimum = Number.isInteger(schema.minItems) ? schema.minItems : 0;
|
|
4339
|
+
const maximum = Number.isInteger(schema.maxItems) ? schema.maxItems : null;
|
|
4340
|
+
const count = maximum === 0 ? 0 : minimum > 0 ? minimum : depth >= 4 ? 0 : 1;
|
|
4341
|
+
return Array.from({ length: count }, () => sampleForSchema(schema.items, depth + 1, singularize(hint), rootSchema));
|
|
4342
|
+
}
|
|
4222
4343
|
if (schema.type === "boolean") return false;
|
|
4223
|
-
if (schema.type === "integer" || schema.type === "number")
|
|
4224
|
-
|
|
4225
|
-
if (schema.format === "email") return "agent@example.com";
|
|
4226
|
-
if (schema.format === "uri" || schema.format === "url") return "https://example.com";
|
|
4227
|
-
return schema.minLength > 1 ? "example".padEnd(schema.minLength, "x") : "example";
|
|
4344
|
+
if (schema.type === "integer" || schema.type === "number") {
|
|
4345
|
+
return representativeNumber(schema, hint);
|
|
4228
4346
|
}
|
|
4347
|
+
if (schema.type === "string") return sampleString(schema, hint);
|
|
4229
4348
|
if (schema.type === "null") return null;
|
|
4230
4349
|
if (schema.type === "object" || isRecord4(schema.properties)) {
|
|
4231
4350
|
const properties = isRecord4(schema.properties) ? schema.properties : {};
|
|
4232
4351
|
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
4233
|
-
const entries = Object.entries(properties).filter(([key]) => required.has(key)).map(([key, child]) => [key, sampleForSchema(child, depth + 1)]);
|
|
4352
|
+
const entries = Object.entries(properties).filter(([key]) => required.has(key)).map(([key, child]) => [key, sampleForSchema(child, depth + 1, key, rootSchema)]);
|
|
4234
4353
|
return Object.fromEntries(entries);
|
|
4235
4354
|
}
|
|
4236
4355
|
return null;
|
|
@@ -4306,7 +4425,11 @@ function enrichActionContract(manifest, action, allActions = manifest.actions ||
|
|
|
4306
4425
|
const recovery = isRecord4(existing.recovery) ? existing.recovery : recoveryFor(action, allActions, appId);
|
|
4307
4426
|
const rollbackActionId = typeof existing.rollbackActionId === "string" && existing.rollbackActionId.trim() ? existing.rollbackActionId.trim() : recovery.mode === "compensating_action" ? recovery.actionId : void 0;
|
|
4308
4427
|
const inputExample = sampleForSchema(action.inputSchema);
|
|
4309
|
-
const
|
|
4428
|
+
const expectedExample = readOnly ? `A successful response conforming to outputSchema; verify the returned ${resource.replaceAll("_", " ")} belongs to the selected resource context.` : `A successful response conforming to outputSchema; re-read the affected ${resource.replaceAll("_", " ")} to verify the intended change.`;
|
|
4429
|
+
const examples = Array.isArray(existing.examples) && existing.examples.length > 0 ? existing.examples.map((example) => isRecord4(example) && Object.hasOwn(example, "input") ? { ...example, expected: typeof example.expected === "string" && example.expected.trim() ? example.expected : expectedExample } : { input: example, expected: expectedExample }) : [{
|
|
4430
|
+
input: inputExample ?? {},
|
|
4431
|
+
expected: expectedExample
|
|
4432
|
+
}];
|
|
4310
4433
|
const docsUrl = `https://docs.topolo.app/reference/actions?service=${encodeURIComponent(service)}&action=${encodeURIComponent(action.name)}`;
|
|
4311
4434
|
const existingDocsUrl = typeof existing.docsUrl === "string" && existing.docsUrl.trim() ? existing.docsUrl.trim() : void 0;
|
|
4312
4435
|
return {
|
|
@@ -4952,6 +5075,10 @@ function createTopolo(options) {
|
|
|
4952
5075
|
auditAllApplicationRequirements,
|
|
4953
5076
|
auditApplicationEntries,
|
|
4954
5077
|
auditApplicationRequirements,
|
|
5078
|
+
compactActionCatalogEntry,
|
|
5079
|
+
compactActionPlan,
|
|
5080
|
+
compactActionValidation,
|
|
5081
|
+
compactApplicationAudit,
|
|
4955
5082
|
createTopolo,
|
|
4956
5083
|
createTopoloWidgetError,
|
|
4957
5084
|
createTopoloWidgetResponse,
|