@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.js CHANGED
@@ -3927,6 +3927,54 @@ function mergeSignals(a, b) {
3927
3927
  return controller.signal;
3928
3928
  }
3929
3929
 
3930
+ // src/agent-output.ts
3931
+ function compactActionCatalogEntry(action) {
3932
+ const required = Array.isArray(action.inputSchema["required"]) ? action.inputSchema["required"].filter((value) => typeof value === "string") : [];
3933
+ const examples = action.agentContract?.examples ?? [];
3934
+ return {
3935
+ actionId: action.actionId,
3936
+ title: action.title,
3937
+ description: action.description,
3938
+ method: action.method,
3939
+ readOnly: action.readOnly,
3940
+ requiresConfirmation: action.requiresConfirmation,
3941
+ agentAccess: action.agentAccess ?? (action.requiresConfirmation ? "confirm" : action.readOnly ? "auto" : "confirm"),
3942
+ requiredPermission: action.requiredPermission,
3943
+ requiredInput: required,
3944
+ resourceType: action.agentContract?.resource?.kind ?? null,
3945
+ exampleInput: examples[0]?.input ?? null,
3946
+ docsUrl: action.agentContract?.docsUrl ?? null
3947
+ };
3948
+ }
3949
+ function compactActionValidation(actionId, validation) {
3950
+ return { actionId, valid: validation.valid, errors: validation.errors };
3951
+ }
3952
+ function compactActionPlan(plan) {
3953
+ return {
3954
+ actionId: plan.action.actionId,
3955
+ valid: plan.validation.valid,
3956
+ errors: plan.validation.errors,
3957
+ executable: plan.executable,
3958
+ confirmationRequired: plan.confirmationRequired,
3959
+ confirmationProvided: plan.confirmationProvided,
3960
+ request: plan.request,
3961
+ verification: plan.verification,
3962
+ rollbackActionId: plan.rollbackActionId,
3963
+ nextActionIds: plan.nextActionIds
3964
+ };
3965
+ }
3966
+ function compactApplicationAudit(report) {
3967
+ return {
3968
+ version: report.version,
3969
+ applications: report.applications.map((audit) => ({
3970
+ applicationId: audit.application.id,
3971
+ applicationName: audit.application.name,
3972
+ score: audit.score
3973
+ })),
3974
+ migrationQueueCount: report.migrationQueue.length
3975
+ };
3976
+ }
3977
+
3930
3978
  // src/action-catalog-digest.ts
3931
3979
  var ACTION_CATALOG_DIGEST_ALGORITHM = "sha256-v1";
3932
3980
  function canonicalPermission(value, appId) {
@@ -4140,25 +4188,92 @@ function derivedOutputSchema(action) {
4140
4188
  ...provenance
4141
4189
  };
4142
4190
  }
4143
- function sampleForSchema(schema, depth = 0) {
4144
- if (!isRecord4(schema) || depth > 5) return null;
4191
+ function patternedString(pattern, hint) {
4192
+ const candidates = [
4193
+ hint.toLowerCase().includes("email") ? "agent@topolo.app" : null,
4194
+ hint.toLowerCase().includes("url") || hint.toLowerCase().includes("uri") ? "https://topolo.app" : null,
4195
+ hint.toLowerCase().includes("app") && hint.toLowerCase().includes("id") ? "app_topolo_example" : null,
4196
+ hint.toLowerCase().includes("file") ? "sample.ply" : null,
4197
+ hint.toLowerCase().includes("slug") ? "/sample" : null,
4198
+ hint.toLowerCase().includes("year") ? "2026" : null,
4199
+ hint.toLowerCase().includes("date") || hint.toLowerCase().endsWith("at") ? "2026-01-15T12:00:00Z" : null,
4200
+ hint.toLowerCase().includes("period") || hint.toLowerCase().includes("month") ? "2026-01" : null,
4201
+ hint.toLowerCase().includes("event") || hint.toLowerCase().includes("type") ? "resource.created" : null,
4202
+ "app_topolo_example",
4203
+ "2026-01-15T12:00:00Z",
4204
+ "sample.ply",
4205
+ "/sample",
4206
+ "2026-01-15",
4207
+ "2026-01",
4208
+ "2026",
4209
+ "resource.created",
4210
+ "sample-value",
4211
+ "sample_value",
4212
+ "sample"
4213
+ ].filter(Boolean);
4214
+ try {
4215
+ const expression = new RegExp(pattern);
4216
+ return candidates.find((candidate) => expression.test(candidate)) ?? "sample";
4217
+ } catch {
4218
+ return "sample";
4219
+ }
4220
+ }
4221
+ function sampleString(schema, hint) {
4222
+ if (schema.format === "email") return "agent@topolo.app";
4223
+ if (schema.format === "uri" || schema.format === "url") return "https://topolo.app";
4224
+ if (schema.format === "date-time") return patternedString(schema.pattern || "", hint) || "2026-01-15T12:00:00Z";
4225
+ const words = String(hint || "value").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
4226
+ 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}`;
4227
+ const minimum = Number.isInteger(schema.minLength) ? schema.minLength : 0;
4228
+ const maximum = Number.isInteger(schema.maxLength) ? schema.maxLength : null;
4229
+ if (value.length < minimum) value = value.padEnd(minimum, "x");
4230
+ if (maximum !== null && value.length > maximum) value = value.slice(0, maximum);
4231
+ return value;
4232
+ }
4233
+ function localReference(rootSchema, reference) {
4234
+ if (!isRecord4(rootSchema) || typeof reference !== "string" || !reference.startsWith("#/")) return null;
4235
+ return reference.slice(2).split("/").reduce((value, segment) => {
4236
+ const key = segment.replaceAll("~1", "/").replaceAll("~0", "~");
4237
+ return isRecord4(value) ? value[key] : void 0;
4238
+ }, rootSchema);
4239
+ }
4240
+ function representativeNumber(schema, hint) {
4241
+ const integer = schema.type === "integer";
4242
+ const words = String(hint || "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
4243
+ 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;
4244
+ const exclusiveOffset = (value2) => Math.max(Number.EPSILON * Math.max(1, Math.abs(value2)) * 2, Number.MIN_VALUE);
4245
+ 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;
4246
+ 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;
4247
+ const value = Math.min(Math.max(preferred, lower), upper);
4248
+ return integer ? Math.round(value) : value;
4249
+ }
4250
+ function sampleForSchema(schema, depth = 0, hint = "value", rootSchema = schema) {
4251
+ if (!isRecord4(schema) || depth > 20) return null;
4252
+ const referenced = localReference(rootSchema, schema.$ref);
4253
+ if (isRecord4(referenced)) return sampleForSchema(referenced, depth + 1, hint, rootSchema);
4145
4254
  if (schema.const !== void 0) return schema.const;
4146
4255
  if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
4147
- if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0) return sampleForSchema(schema.oneOf[0], depth + 1);
4148
- if (Array.isArray(schema.anyOf) && schema.anyOf.length > 0) return sampleForSchema(schema.anyOf[0], depth + 1);
4149
- if (schema.type === "array") return [];
4256
+ if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0) return sampleForSchema(schema.oneOf[0], depth + 1, hint, rootSchema);
4257
+ if (Array.isArray(schema.anyOf) && schema.anyOf.length > 0) return sampleForSchema(schema.anyOf[0], depth + 1, hint, rootSchema);
4258
+ if (Array.isArray(schema.type)) {
4259
+ return sampleForSchema({ ...schema, type: schema.type.find((type) => type !== "null") ?? schema.type[0] }, depth + 1, hint, rootSchema);
4260
+ }
4261
+ if (schema.type === "array") {
4262
+ const minimum = Number.isInteger(schema.minItems) ? schema.minItems : 0;
4263
+ const maximum = Number.isInteger(schema.maxItems) ? schema.maxItems : null;
4264
+ const count = maximum === 0 ? 0 : minimum > 0 ? minimum : depth >= 4 ? 0 : 1;
4265
+ return Array.from({ length: count }, () => sampleForSchema(schema.items, depth + 1, singularize(hint), rootSchema));
4266
+ }
4150
4267
  if (schema.type === "boolean") return false;
4151
- if (schema.type === "integer" || schema.type === "number") return schema.minimum ?? 0;
4152
- if (schema.type === "string") {
4153
- if (schema.format === "email") return "agent@example.com";
4154
- if (schema.format === "uri" || schema.format === "url") return "https://example.com";
4155
- return schema.minLength > 1 ? "example".padEnd(schema.minLength, "x") : "example";
4268
+ if (schema.type === "integer" || schema.type === "number") {
4269
+ return representativeNumber(schema, hint);
4156
4270
  }
4271
+ if (schema.type === "string") return sampleString(schema, hint);
4157
4272
  if (schema.type === "null") return null;
4158
4273
  if (schema.type === "object" || isRecord4(schema.properties)) {
4159
4274
  const properties = isRecord4(schema.properties) ? schema.properties : {};
4160
4275
  const required = new Set(Array.isArray(schema.required) ? schema.required : []);
4161
- const entries = Object.entries(properties).filter(([key]) => required.has(key)).map(([key, child]) => [key, sampleForSchema(child, depth + 1)]);
4276
+ const entries = Object.entries(properties).filter(([key]) => required.has(key)).map(([key, child]) => [key, sampleForSchema(child, depth + 1, key, rootSchema)]);
4162
4277
  return Object.fromEntries(entries);
4163
4278
  }
4164
4279
  return null;
@@ -4234,7 +4349,11 @@ function enrichActionContract(manifest, action, allActions = manifest.actions ||
4234
4349
  const recovery = isRecord4(existing.recovery) ? existing.recovery : recoveryFor(action, allActions, appId);
4235
4350
  const rollbackActionId = typeof existing.rollbackActionId === "string" && existing.rollbackActionId.trim() ? existing.rollbackActionId.trim() : recovery.mode === "compensating_action" ? recovery.actionId : void 0;
4236
4351
  const inputExample = sampleForSchema(action.inputSchema);
4237
- const examples = Array.isArray(existing.examples) && existing.examples.length > 0 ? existing.examples : [{ input: inputExample ?? {}, expected: `A response matching the published outputSchema for ${action.name}.` }];
4352
+ 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.`;
4353
+ 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 }) : [{
4354
+ input: inputExample ?? {},
4355
+ expected: expectedExample
4356
+ }];
4238
4357
  const docsUrl = `https://docs.topolo.app/reference/actions?service=${encodeURIComponent(service)}&action=${encodeURIComponent(action.name)}`;
4239
4358
  const existingDocsUrl = typeof existing.docsUrl === "string" && existing.docsUrl.trim() ? existing.docsUrl.trim() : void 0;
4240
4359
  return {
@@ -4879,6 +4998,10 @@ export {
4879
4998
  auditAllApplicationRequirements,
4880
4999
  auditApplicationEntries,
4881
5000
  auditApplicationRequirements,
5001
+ compactActionCatalogEntry,
5002
+ compactActionPlan,
5003
+ compactActionValidation,
5004
+ compactApplicationAudit,
4882
5005
  createTopolo,
4883
5006
  createTopoloWidgetError,
4884
5007
  createTopoloWidgetResponse,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/sdk",
3
- "version": "0.10.0",
4
- "topoloPublishedVersion": "0.10.0",
3
+ "version": "0.10.2",
4
+ "topoloPublishedVersion": "0.10.2",
5
5
  "description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",