@elevasis/sdk 1.48.0 → 1.49.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.
Files changed (46) hide show
  1. package/dist/cli.cjs +742 -231
  2. package/dist/index.d.ts +685 -47
  3. package/dist/index.js +274 -40
  4. package/dist/node/index.d.ts +108 -24
  5. package/dist/test-utils/index.d.ts +647 -34
  6. package/dist/test-utils/index.js +240 -38
  7. package/dist/worker/index.d.ts +663 -39
  8. package/dist/worker/index.js +115 -6
  9. package/package.json +4 -4
  10. package/reference/_navigation.md +4 -4
  11. package/reference/_reference-manifest.json +1 -1
  12. package/reference/core/index.mdx +6 -4
  13. package/reference/index.mdx +11 -5
  14. package/reference/packages/core/src/README.md +46 -44
  15. package/reference/packages/core/src/content/README.md +13 -12
  16. package/reference/rules/ui.md +1 -1
  17. package/reference/rules/vibe-intents.md +2 -2
  18. package/reference/rules/vibe.md +30 -10
  19. package/reference/scaffold/recipes/extend-content.md +82 -3
  20. package/reference/sdk/cli-management.mdx +184 -41
  21. package/reference/sdk/cli.mdx +103 -64
  22. package/reference/sdk/define-builders.mdx +1 -1
  23. package/reference/sdk/deployment/command-center.mdx +2 -2
  24. package/reference/sdk/deployment/index.mdx +1 -1
  25. package/reference/sdk/exports.mdx +4 -4
  26. package/reference/sdk/framework/agent.mdx +4 -3
  27. package/reference/sdk/framework/index.mdx +1 -1
  28. package/reference/sdk/framework/project-structure.mdx +34 -23
  29. package/reference/sdk/framework/tutorial-system.mdx +1 -1
  30. package/reference/sdk/getting-started.mdx +25 -52
  31. package/reference/sdk/index.mdx +3 -3
  32. package/reference/sdk/platform-tools/adapters-integration.mdx +1 -1
  33. package/reference/sdk/platform-tools/adapters-platform.mdx +1 -1
  34. package/reference/sdk/platform-tools/type-safety.mdx +1 -1
  35. package/reference/sdk/resources/patterns.mdx +10 -11
  36. package/reference/sdk/resources/types.mdx +15 -9
  37. package/reference/sdk/templates/data-enrichment.mdx +1 -1
  38. package/reference/sdk/templates/email-sender.mdx +1 -1
  39. package/reference/sdk/templates/index.mdx +47 -47
  40. package/reference/sdk/templates/lead-scorer.mdx +1 -1
  41. package/reference/sdk/templates/pdf-generator.mdx +42 -24
  42. package/reference/sdk/templates/recurring-job.mdx +20 -15
  43. package/reference/sdk/templates/text-classifier.mdx +1 -1
  44. package/reference/sdk/templates/web-scraper.mdx +9 -5
  45. package/reference/ui/exports.mdx +1 -1
  46. package/reference/ui/index.mdx +2 -2
@@ -4102,6 +4102,34 @@ function detectCycle(visited, executionPath, currentStepId) {
4102
4102
  });
4103
4103
  }
4104
4104
  }
4105
+ function validateWorkflowGraph(steps, entryPoint, workflowId) {
4106
+ const onPath = /* @__PURE__ */ new Set();
4107
+ const executionPath = [];
4108
+ const reached = /* @__PURE__ */ new Set();
4109
+ const walk = (stepId) => {
4110
+ detectCycle(onPath, executionPath, stepId);
4111
+ onPath.add(stepId);
4112
+ executionPath.push(stepId);
4113
+ reached.add(stepId);
4114
+ const step = steps[stepId];
4115
+ if (step && step.next !== null) {
4116
+ const targets = step.next.type === StepType.LINEAR ? [step.next.target] : [...step.next.routes.map((route) => route.target), step.next.default];
4117
+ for (const target of targets) {
4118
+ if (target in steps) walk(target);
4119
+ }
4120
+ }
4121
+ executionPath.pop();
4122
+ onPath.delete(stepId);
4123
+ };
4124
+ if (entryPoint in steps) walk(entryPoint);
4125
+ const orphanIds = Object.keys(steps).filter((id) => !reached.has(id));
4126
+ if (orphanIds.length > 0) {
4127
+ throw new WorkflowValidationError(
4128
+ `Workflow '${workflowId}' has step(s) unreachable from entry point '${entryPoint}': ${orphanIds.join(", ")}`,
4129
+ { workflowId, entryPoint, orphanIds }
4130
+ );
4131
+ }
4132
+ }
4105
4133
  function validateTerminalOutput(stepId, output, outputSchema) {
4106
4134
  if (!outputSchema) {
4107
4135
  return;
@@ -4627,6 +4655,12 @@ function buildReasoningRequest(iterationContext) {
4627
4655
  capabilities
4628
4656
  };
4629
4657
  }
4658
+
4659
+ // ../core/src/execution/engine/llm/types.ts
4660
+ function extractMessageText(content2) {
4661
+ if (typeof content2 === "string") return content2;
4662
+ return content2.filter((part) => part.type === "text").map((part) => part.text).join("\n");
4663
+ }
4630
4664
  var ToolCallActionSchema = z.object({
4631
4665
  type: z.literal("tool-call"),
4632
4666
  id: z.string().optional(),
@@ -4706,6 +4740,19 @@ var GPT5ConfigSchema = z.object({
4706
4740
  topP: z.number().min(0).max(1).optional(),
4707
4741
  modelOptions: GPT5OptionsSchema.optional()
4708
4742
  });
4743
+ var GPT56OptionsSchema = z.object({
4744
+ reasoning_effort: z.enum(["none", "low", "medium", "high", "xhigh", "max"]).optional(),
4745
+ verbosity: z.enum(["low", "medium", "high"]).optional()
4746
+ });
4747
+ var GPT56ConfigSchema = z.object({
4748
+ model: z.enum(["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]),
4749
+ provider: z.enum(["openai"]),
4750
+ apiKey: z.string(),
4751
+ temperature: z.literal(1).optional(),
4752
+ maxOutputTokens: z.number().min(4e3).optional(),
4753
+ topP: z.number().min(0).max(1).optional(),
4754
+ modelOptions: GPT56OptionsSchema.optional()
4755
+ });
4709
4756
  var MockConfigSchema = z.object({
4710
4757
  model: z.enum(["mock"]),
4711
4758
  provider: z.enum(["mock"]),
@@ -4758,9 +4805,12 @@ var AnthropicConfigSchema = z.discriminatedUnion("model", [
4758
4805
  AnthropicClaude5ConfigSchema,
4759
4806
  AnthropicStandardConfigSchema
4760
4807
  ]);
4808
+ var GPT56_CACHE_READ_RATE_MULTIPLIER = 0.1;
4809
+ var CACHE_CREATION_RATE_MULTIPLIER = 1.25;
4761
4810
  var MODEL_INFO = {
4762
4811
  // OpenAI GPT-5 (Reasoning Models)
4763
4812
  "gpt-5": {
4813
+ provider: "openai",
4764
4814
  inputCostPer1M: 125,
4765
4815
  // $1.25 per 1M tokens
4766
4816
  outputCostPer1M: 1e3,
@@ -4774,6 +4824,7 @@ var MODEL_INFO = {
4774
4824
  configSchema: GPT5ConfigSchema
4775
4825
  },
4776
4826
  "gpt-5.4-mini": {
4827
+ provider: "openai",
4777
4828
  inputCostPer1M: 75,
4778
4829
  // $0.75 per 1M tokens
4779
4830
  outputCostPer1M: 450,
@@ -4787,6 +4838,7 @@ var MODEL_INFO = {
4787
4838
  configSchema: GPT5ConfigSchema
4788
4839
  },
4789
4840
  "gpt-5.4-nano": {
4841
+ provider: "openai",
4790
4842
  inputCostPer1M: 20,
4791
4843
  // $0.20 per 1M tokens
4792
4844
  outputCostPer1M: 125,
@@ -4798,8 +4850,60 @@ var MODEL_INFO = {
4798
4850
  category: "standard",
4799
4851
  configSchema: GPT5ConfigSchema
4800
4852
  },
4853
+ // OpenAI GPT-5.6 family (GA 2026-07-09). All three tiers share 1.05M context, 128K max output,
4854
+ // image input, tool use, structured outputs, and prompt caching -- they differ in reasoning depth
4855
+ // and price, not capability. The bare `gpt-5.6` alias is deliberately unregistered; see OpenAIModel.
4856
+ "gpt-5.6-sol": {
4857
+ provider: "openai",
4858
+ inputCostPer1M: 500,
4859
+ // $5.00 per 1M tokens
4860
+ outputCostPer1M: 3e3,
4861
+ // $30.00 per 1M tokens
4862
+ minTokens: 4e3,
4863
+ recommendedTokens: 8e3,
4864
+ maxTokens: 105e4,
4865
+ // 1.05M context window
4866
+ maxOutputTokens: 128e3,
4867
+ category: "reasoning",
4868
+ configSchema: GPT56ConfigSchema,
4869
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
4870
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
4871
+ },
4872
+ "gpt-5.6-terra": {
4873
+ provider: "openai",
4874
+ inputCostPer1M: 250,
4875
+ // $2.50 per 1M tokens
4876
+ outputCostPer1M: 1500,
4877
+ // $15.00 per 1M tokens
4878
+ minTokens: 4e3,
4879
+ recommendedTokens: 8e3,
4880
+ maxTokens: 105e4,
4881
+ // 1.05M context window
4882
+ maxOutputTokens: 128e3,
4883
+ category: "standard",
4884
+ configSchema: GPT56ConfigSchema,
4885
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
4886
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
4887
+ },
4888
+ "gpt-5.6-luna": {
4889
+ provider: "openai",
4890
+ inputCostPer1M: 100,
4891
+ // $1.00 per 1M tokens
4892
+ outputCostPer1M: 600,
4893
+ // $6.00 per 1M tokens
4894
+ minTokens: 4e3,
4895
+ recommendedTokens: 8e3,
4896
+ maxTokens: 105e4,
4897
+ // 1.05M context window
4898
+ maxOutputTokens: 128e3,
4899
+ category: "standard",
4900
+ configSchema: GPT56ConfigSchema,
4901
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
4902
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
4903
+ },
4801
4904
  // Mock model for testing
4802
4905
  mock: {
4906
+ provider: "mock",
4803
4907
  inputCostPer1M: 0,
4804
4908
  // Free for tests
4805
4909
  outputCostPer1M: 0,
@@ -4813,6 +4917,7 @@ var MODEL_INFO = {
4813
4917
  },
4814
4918
  // OpenRouter Models (via openrouter.ai)
4815
4919
  "openrouter/z-ai/glm-5": {
4920
+ provider: "openrouter",
4816
4921
  inputCostPer1M: 72,
4817
4922
  // $0.72 per 1M tokens
4818
4923
  outputCostPer1M: 230,
@@ -4826,6 +4931,7 @@ var MODEL_INFO = {
4826
4931
  },
4827
4932
  // Anthropic Claude Models (direct SDK access via @anthropic-ai/sdk)
4828
4933
  "claude-opus-5": {
4934
+ provider: "anthropic",
4829
4935
  inputCostPer1M: 500,
4830
4936
  // $5.00 per 1M tokens
4831
4937
  outputCostPer1M: 2500,
@@ -4839,6 +4945,7 @@ var MODEL_INFO = {
4839
4945
  configSchema: AnthropicConfigSchema
4840
4946
  },
4841
4947
  "claude-sonnet-5": {
4948
+ provider: "anthropic",
4842
4949
  // List pricing. An introductory rate of $2.00/$10.00 runs through 2026-08-31; encoding the
4843
4950
  // temporary rate would make historical cost analytics wrong once it lapses.
4844
4951
  inputCostPer1M: 300,
@@ -4854,6 +4961,7 @@ var MODEL_INFO = {
4854
4961
  configSchema: AnthropicConfigSchema
4855
4962
  },
4856
4963
  "claude-haiku-4-5-20251001": {
4964
+ provider: "anthropic",
4857
4965
  inputCostPer1M: 100,
4858
4966
  // $1.00 per 1M tokens
4859
4967
  outputCostPer1M: 500,
@@ -4867,6 +4975,7 @@ var MODEL_INFO = {
4867
4975
  configSchema: AnthropicConfigSchema
4868
4976
  },
4869
4977
  "claude-haiku-4-5": {
4978
+ provider: "anthropic",
4870
4979
  inputCostPer1M: 100,
4871
4980
  // $1.00 per 1M tokens
4872
4981
  outputCostPer1M: 500,
@@ -4886,7 +4995,7 @@ function getModelInfo(model) {
4886
4995
  return MODEL_INFO[model];
4887
4996
  }
4888
4997
  for (const knownModel of MODEL_KEYS_BY_SPECIFICITY) {
4889
- if (model.startsWith(knownModel)) {
4998
+ if (model.startsWith(`${knownModel}-`)) {
4890
4999
  return MODEL_INFO[knownModel];
4891
5000
  }
4892
5001
  }
@@ -5257,7 +5366,9 @@ async function callLLMForAgentIteration(adapter, request) {
5257
5366
  message: request.capabilities.message,
5258
5367
  memoryOps: request.capabilities.memoryOps,
5259
5368
  historyTurns: request.conversationHistory?.length ?? 0,
5260
- messages: messages.map((m2) => ({ role: m2.role, ...preview(m2.content) }))
5369
+ // `preview` reads text; `extractMessageText` is the identity function for the plain-string case
5370
+ // this always was, and drops image parts (nothing to preview) rather than stringify them.
5371
+ messages: messages.map((m2) => ({ role: m2.role, ...preview(extractMessageText(m2.content)) }))
5261
5372
  });
5262
5373
  let acceptedOutput;
5263
5374
  const response = await adapter.generate({
@@ -5280,7 +5391,10 @@ async function callLLMForAgentIteration(adapter, request) {
5280
5391
  // Same text the real request was billed for -- `estimateTokens`'s bias is a property of the
5281
5392
  // heuristic itself, not of which text it measures, so this is what calibrates the correction
5282
5393
  // `MemoryManager` applies to its own (much smaller) slice of the same request.
5283
- estimatedRequestTokens: estimateTokens(messages.map((m2) => m2.content).join(""))
5394
+ // Same text-only reasoning as the `preview` call above -- an image part contributes no text
5395
+ // tokens to this estimate (the real request's image token cost is a separate, provider-billed
5396
+ // line item this heuristic was never calibrated against).
5397
+ estimatedRequestTokens: estimateTokens(messages.map((m2) => extractMessageText(m2.content)).join(""))
5284
5398
  };
5285
5399
  } catch (error) {
5286
5400
  flowLog("agent.iteration.validationFailed", {
@@ -5318,7 +5432,7 @@ async function callLLMForAgentCompletion(adapter, request) {
5318
5432
  return {
5319
5433
  output: response.output,
5320
5434
  usage: response.usage,
5321
- estimatedRequestTokens: estimateTokens(messages.map((m2) => m2.content).join(""))
5435
+ estimatedRequestTokens: estimateTokens(messages.map((m2) => extractMessageText(m2.content)).join(""))
5322
5436
  };
5323
5437
  }
5324
5438
 
@@ -8667,6 +8781,10 @@ var METHODS = [
8667
8781
  "getItem",
8668
8782
  "listItems",
8669
8783
  "updateItem",
8784
+ "addItemSourceAsset",
8785
+ "removeItemSourceAsset",
8786
+ "reorderItemSourceAssets",
8787
+ "updateItemSourceAsset",
8670
8788
  "createAttempt",
8671
8789
  "listAttempts",
8672
8790
  "updateAttempt",
@@ -8674,6 +8792,8 @@ var METHODS = [
8674
8792
  "getSourceAsset",
8675
8793
  "listSourceAssets",
8676
8794
  "updateSourceAsset",
8795
+ "getDistribution",
8796
+ "listDistributions",
8677
8797
  "createDistribution",
8678
8798
  "updateDistribution"
8679
8799
  ];
@@ -8734,44 +8854,64 @@ var OntologyRecordBaseSchema = z.object({
8734
8854
  }).passthrough();
8735
8855
  var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
8736
8856
  properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
8737
- storage: z.record(z.string(), z.unknown()).optional()
8738
- });
8857
+ storage: z.record(z.string(), z.unknown()).optional(),
8858
+ // Carried by the legacy entity projection (`addLegacyEntityProjections`); not
8859
+ // authored directly, but a real key an authored record must not collide with.
8860
+ rowSchema: z.string().trim().min(1).optional(),
8861
+ stateCatalogId: z.string().trim().min(1).optional()
8862
+ }).strict();
8739
8863
  var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
8740
8864
  from: OntologyIdSchema,
8741
8865
  to: OntologyIdSchema,
8742
8866
  cardinality: z.string().trim().min(1).max(80).optional(),
8743
8867
  via: z.string().trim().min(1).max(255).optional()
8744
- });
8868
+ }).strict();
8745
8869
  var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
8746
8870
  actsOn: OntologyReferenceListSchema,
8747
8871
  input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
8748
- effects: z.array(z.record(z.string(), z.unknown())).optional()
8749
- });
8872
+ effects: z.array(z.record(z.string(), z.unknown())).optional(),
8873
+ resourceId: z.string().trim().min(1).optional(),
8874
+ invocations: z.array(z.unknown()).optional(),
8875
+ lifecycle: z.string().trim().min(1).optional(),
8876
+ // Carried by the legacy action projection (`addLegacyActionProjections`); not
8877
+ // authored directly, but a real key an authored record must not collide with.
8878
+ legacyActionId: z.string().trim().min(1).optional()
8879
+ }).strict();
8750
8880
  var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
8751
8881
  kind: z.string().trim().min(1).max(120).optional(),
8752
8882
  appliesTo: OntologyIdSchema.optional(),
8753
- entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
8754
- });
8883
+ entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
8884
+ // Carried by lead-gen's legacy stage-catalog projection
8885
+ // (`createLeadGenStageCatalog`); not authored directly, but a real key an
8886
+ // authored record must not collide with.
8887
+ legacyCatalogKey: z.string().trim().min(1).optional(),
8888
+ // Carried in live tenant configs (Elevasis, `nirvana-marketing`, and the
8889
+ // `_template` scaffold all author these on `sales.crm:catalog/crm.pipeline`)
8890
+ // as a cross-reference to the pre-ontology CRM pipeline key/entity id. No
8891
+ // code currently reads them back — do not silently normalize them away.
8892
+ legacyPipelineKey: z.string().trim().min(1).optional(),
8893
+ legacyEntityKey: z.string().trim().min(1).optional()
8894
+ }).strict();
8755
8895
  var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
8756
8896
  payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
8757
- });
8897
+ }).strict();
8758
8898
  var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
8759
8899
  properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
8760
- });
8900
+ }).strict();
8761
8901
  var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
8762
8902
  primitive: z.string().trim().min(1).max(120).optional()
8763
- });
8903
+ }).strict();
8764
8904
  var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
8765
8905
  valueType: OntologyIdSchema.optional(),
8766
8906
  searchable: z.boolean().optional(),
8767
8907
  pii: z.boolean().optional()
8768
- });
8908
+ }).strict();
8769
8909
  var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
8770
8910
  members: OntologyReferenceListSchema
8771
- });
8911
+ }).strict();
8772
8912
  var OntologyEndpointTypeSchema = OntologyRecordBaseSchema.extend({
8773
8913
  route: z.string().trim().min(1).max(500).optional()
8774
- });
8914
+ }).strict();
8775
8915
  var OntologyScopeSchema = z.object({
8776
8916
  objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
8777
8917
  linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
@@ -9727,11 +9867,12 @@ var PROVIDER_DIALECTS = {
9727
9867
 
9728
9868
  // ../core/src/platform/registry/validation.ts
9729
9869
  var RegistryValidationError = class extends Error {
9730
- constructor(orgName, resourceId, field, message) {
9870
+ constructor(orgName, resourceId, field, message, issues) {
9731
9871
  super(message);
9732
9872
  this.orgName = orgName;
9733
9873
  this.resourceId = resourceId;
9734
9874
  this.field = field;
9875
+ this.issues = issues;
9735
9876
  this.name = "RegistryValidationError";
9736
9877
  }
9737
9878
  };
@@ -9752,7 +9893,14 @@ function emitGovernanceIssues(issues, mode, onWarning) {
9752
9893
  if (issues.length === 0) return;
9753
9894
  if (mode === "strict") {
9754
9895
  const first = issues[0];
9755
- throw new RegistryValidationError(first.orgName, first.resourceId, "organizationModel.resources", first.message);
9896
+ const messages = issues.map((issue) => issue.message);
9897
+ throw new RegistryValidationError(
9898
+ first.orgName,
9899
+ first.resourceId,
9900
+ "organizationModel.resources",
9901
+ messages.join("\n"),
9902
+ messages
9903
+ );
9756
9904
  }
9757
9905
  const warn = onWarning ?? ((issue) => console.warn(issue.message));
9758
9906
  for (const issue of issues) {
@@ -9913,7 +10061,7 @@ function addTopologyIssues(issues, orgName, deployment, organizationModel, syste
9913
10061
  if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
9914
10062
  if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
9915
10063
  if (ref.kind === "ontology") {
9916
- if (ontologyIndex === void 0) return true;
10064
+ if (ontologyIndex === void 0) return false;
9917
10065
  return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
9918
10066
  }
9919
10067
  return false;
@@ -10071,7 +10219,8 @@ function addSystemInterfaceIssue(issues, orgName, systemPath, interfaceKey, issu
10071
10219
  message: `[${orgName}] ${issue.family}:${issue.code}: ${issue.message}`
10072
10220
  });
10073
10221
  }
10074
- function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
10222
+ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel, options = {}) {
10223
+ const mode = getResourceValidatorMode(options.mode);
10075
10224
  const issues = [];
10076
10225
  if (organizationModel === void 0) return { valid: true, issues };
10077
10226
  const model = organizationModel;
@@ -10097,17 +10246,27 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
10097
10246
  }
10098
10247
  }
10099
10248
  if (issues.length > 0) {
10100
- const first = issues[0];
10101
- throw new RegistryValidationError(
10102
- first.orgName,
10103
- `${first.systemPath}/${first.interfaceKey}`,
10104
- first.path ?? "organizationModel.systems.apiInterface",
10105
- first.message
10106
- );
10249
+ if (mode === "strict") {
10250
+ const first = issues[0];
10251
+ const messages = issues.map((issue) => issue.message);
10252
+ throw new RegistryValidationError(
10253
+ first.orgName,
10254
+ `${first.systemPath}/${first.interfaceKey}`,
10255
+ first.path ?? "organizationModel.systems.apiInterface",
10256
+ messages.join("\n"),
10257
+ messages
10258
+ );
10259
+ }
10260
+ const warn = options.onWarning ?? ((issue) => console.warn(issue.message));
10261
+ for (const issue of issues) {
10262
+ warn(issue);
10263
+ }
10264
+ return { valid: false, issues };
10107
10265
  }
10108
10266
  return { valid: true, issues };
10109
10267
  }
10110
- function validateDeploymentSpec(orgName, resources) {
10268
+ function validateDeploymentSpec(orgName, resources, options = {}) {
10269
+ const warn = options.onWarning ?? ((message) => console.warn(message));
10111
10270
  const seenIds = /* @__PURE__ */ new Set();
10112
10271
  resources.workflows?.forEach((workflow) => {
10113
10272
  const id = workflow.config.resourceId;
@@ -10126,6 +10285,14 @@ function validateDeploymentSpec(orgName, resources) {
10126
10285
  if (workflow.interface) {
10127
10286
  validateExecutionInterface(orgName, id, workflow.interface, workflow.contract.inputSchema);
10128
10287
  }
10288
+ try {
10289
+ validateEntryPoint(workflow.steps, workflow.entryPoint);
10290
+ validateTerminalSteps(workflow.steps, id);
10291
+ validateStepReferences(workflow.steps);
10292
+ validateWorkflowGraph(workflow.steps, workflow.entryPoint, id);
10293
+ } catch (error) {
10294
+ warn(`[${orgName}] Workflow '${id}' graph validation: ${error instanceof Error ? error.message : String(error)}`);
10295
+ }
10129
10296
  });
10130
10297
  resources.agents?.forEach((agent) => {
10131
10298
  const id = agent.config.resourceId;
@@ -10139,14 +10306,20 @@ function validateDeploymentSpec(orgName, resources) {
10139
10306
  }
10140
10307
  seenIds.add(id);
10141
10308
  validateResourceModelConfig(orgName, id, agent.modelConfig);
10142
- validateAgentGrammar(orgName, id, agent);
10143
- validateAgentCheapAssertions(orgName, id, agent);
10309
+ validateAgentGrammar(orgName, id, agent, options.mode);
10310
+ validateAgentCheapAssertions(orgName, id, agent, options.mode);
10144
10311
  if (agent.interface) {
10145
10312
  validateExecutionInterface(orgName, id, agent.interface, agent.contract.inputSchema);
10146
10313
  }
10147
10314
  });
10148
- validateResourceGovernance(orgName, resources);
10149
- validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel);
10315
+ validateResourceGovernance(orgName, resources, void 0, {
10316
+ mode: options.mode,
10317
+ onWarning: (issue) => warn(issue.message)
10318
+ });
10319
+ validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel, {
10320
+ mode: options.mode,
10321
+ onWarning: (issue) => warn(issue.message)
10322
+ });
10150
10323
  }
10151
10324
  function validateResourceModelConfig(orgName, resourceId, modelConfig) {
10152
10325
  try {
@@ -10221,7 +10394,7 @@ function describeGrammarRefusal(reasons, toolInputSchema) {
10221
10394
  }
10222
10395
  return `refused strict mode: ${reasons.join(", ")}`;
10223
10396
  }
10224
- function validateAgentGrammar(orgName, agentId, agent) {
10397
+ function validateAgentGrammar(orgName, agentId, agent, mode) {
10225
10398
  const dialect = dialectForProvider(agent.modelConfig.provider);
10226
10399
  if (!dialect) return;
10227
10400
  const capabilities = agentCapabilitiesForGrammarCheck(agent.config);
@@ -10242,12 +10415,12 @@ function validateAgentGrammar(orgName, agentId, agent) {
10242
10415
  compileSchema(offending.inputSchema, dialect).refusalReasons,
10243
10416
  offending.inputSchema
10244
10417
  )}. This silently drops strict-mode enforcement for the agent's ENTIRE iteration schema on every call, not just this tool -- compileSchema refuses whole-schema, never per-tool.` : `[${orgName}] Agent '${agentId}' iteration schema refused strict mode for provider '${agent.modelConfig.provider}': ${compiled.refusalReasons.join(", ")}. No single tool is independently responsible -- this is a whole-schema limit (e.g. total optional properties across every tool exceeding the provider's cap).`;
10245
- if (getResourceValidatorMode() === "strict") {
10418
+ if (getResourceValidatorMode(mode) === "strict") {
10246
10419
  throw new RegistryValidationError(orgName, agentId, "tools", message);
10247
10420
  }
10248
10421
  console.warn(message);
10249
10422
  }
10250
- function validateAgentCheapAssertions(orgName, agentId, agent) {
10423
+ function validateAgentCheapAssertions(orgName, agentId, agent, mode) {
10251
10424
  const issues = [];
10252
10425
  const config2 = agent.config;
10253
10426
  if (config2.sessionCapable && config2.securityLevel === "none") {
@@ -10277,7 +10450,7 @@ function validateAgentCheapAssertions(orgName, agentId, agent) {
10277
10450
  }
10278
10451
  if (issues.length === 0) return;
10279
10452
  const message = `[${orgName}] Agent '${agentId}': ${issues.join(" ")}`;
10280
- if (getResourceValidatorMode() === "strict") {
10453
+ if (getResourceValidatorMode(mode) === "strict") {
10281
10454
  throw new RegistryValidationError(orgName, agentId, "config", message);
10282
10455
  }
10283
10456
  console.warn(message);
@@ -10738,6 +10911,16 @@ function startWorker(org) {
10738
10911
  // real tier rather than silently passing on an absent one.
10739
10912
  systemPrompt: a3.config.systemPrompt,
10740
10913
  securityLevel: a3.config.securityLevel,
10914
+ // Wave 2b / Decision 2: redacted model config (no `apiKey`) so the platform can re-run
10915
+ // `validateAgentGrammar` and the token-floor check against what the org actually deployed
10916
+ // instead of only ever seeing the platform's own placeholder stub config. `apiKey` is
10917
+ // deliberately excluded -- this manifest crosses into apps/api's process and is logged.
10918
+ modelConfig: a3.modelConfig ? {
10919
+ model: a3.modelConfig.model,
10920
+ provider: a3.modelConfig.provider,
10921
+ temperature: a3.modelConfig.temperature,
10922
+ maxOutputTokens: a3.modelConfig.maxOutputTokens
10923
+ } : void 0,
10741
10924
  status: a3.config.status,
10742
10925
  description: a3.config.description,
10743
10926
  version: a3.config.version,
@@ -27774,6 +27957,10 @@ var mockContent = (overrides) => createMockAdapter(
27774
27957
  "getItem",
27775
27958
  "listItems",
27776
27959
  "updateItem",
27960
+ "addItemSourceAsset",
27961
+ "removeItemSourceAsset",
27962
+ "reorderItemSourceAssets",
27963
+ "updateItemSourceAsset",
27777
27964
  "createAttempt",
27778
27965
  "listAttempts",
27779
27966
  "updateAttempt",
@@ -27781,6 +27968,8 @@ var mockContent = (overrides) => createMockAdapter(
27781
27968
  "getSourceAsset",
27782
27969
  "listSourceAssets",
27783
27970
  "updateSourceAsset",
27971
+ "getDistribution",
27972
+ "listDistributions",
27784
27973
  "createDistribution",
27785
27974
  "updateDistribution"
27786
27975
  ],
@@ -27808,7 +27997,20 @@ var createMockAttio = (_credential, overrides) => createMockAdapter(
27808
27997
  overrides
27809
27998
  );
27810
27999
  var createMockApify = (_credential, overrides) => createMockAdapter(["runActor", "getDatasetItems", "startActor"], overrides);
27811
- var createMockDropbox = (_credential, overrides) => createMockAdapter(["uploadFile", "createFolder"], overrides);
28000
+ var createMockDropbox = (_credential, overrides) => createMockAdapter(
28001
+ [
28002
+ "uploadFile",
28003
+ "createFolder",
28004
+ "listFolder",
28005
+ "getMetadata",
28006
+ "getTemporaryLink",
28007
+ "createSharedLink",
28008
+ "download",
28009
+ "getThumbnail",
28010
+ "getThumbnailBatch"
28011
+ ],
28012
+ overrides
28013
+ );
27812
28014
  var createMockGmail = (_credential, overrides) => createMockAdapter(["sendEmail"], overrides);
27813
28015
  var createMockGoogleSheets = (_credential, overrides) => createMockAdapter(
27814
28016
  [