@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
package/dist/index.js CHANGED
@@ -65,44 +65,64 @@ var OntologyRecordBaseSchema = z.object({
65
65
  }).passthrough();
66
66
  var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
67
67
  properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
68
- storage: z.record(z.string(), z.unknown()).optional()
69
- });
68
+ storage: z.record(z.string(), z.unknown()).optional(),
69
+ // Carried by the legacy entity projection (`addLegacyEntityProjections`); not
70
+ // authored directly, but a real key an authored record must not collide with.
71
+ rowSchema: z.string().trim().min(1).optional(),
72
+ stateCatalogId: z.string().trim().min(1).optional()
73
+ }).strict();
70
74
  var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
71
75
  from: OntologyIdSchema,
72
76
  to: OntologyIdSchema,
73
77
  cardinality: z.string().trim().min(1).max(80).optional(),
74
78
  via: z.string().trim().min(1).max(255).optional()
75
- });
79
+ }).strict();
76
80
  var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
77
81
  actsOn: OntologyReferenceListSchema,
78
82
  input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
79
- effects: z.array(z.record(z.string(), z.unknown())).optional()
80
- });
83
+ effects: z.array(z.record(z.string(), z.unknown())).optional(),
84
+ resourceId: z.string().trim().min(1).optional(),
85
+ invocations: z.array(z.unknown()).optional(),
86
+ lifecycle: z.string().trim().min(1).optional(),
87
+ // Carried by the legacy action projection (`addLegacyActionProjections`); not
88
+ // authored directly, but a real key an authored record must not collide with.
89
+ legacyActionId: z.string().trim().min(1).optional()
90
+ }).strict();
81
91
  var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
82
92
  kind: z.string().trim().min(1).max(120).optional(),
83
93
  appliesTo: OntologyIdSchema.optional(),
84
- entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
85
- });
94
+ entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
95
+ // Carried by lead-gen's legacy stage-catalog projection
96
+ // (`createLeadGenStageCatalog`); not authored directly, but a real key an
97
+ // authored record must not collide with.
98
+ legacyCatalogKey: z.string().trim().min(1).optional(),
99
+ // Carried in live tenant configs (Elevasis, `nirvana-marketing`, and the
100
+ // `_template` scaffold all author these on `sales.crm:catalog/crm.pipeline`)
101
+ // as a cross-reference to the pre-ontology CRM pipeline key/entity id. No
102
+ // code currently reads them back — do not silently normalize them away.
103
+ legacyPipelineKey: z.string().trim().min(1).optional(),
104
+ legacyEntityKey: z.string().trim().min(1).optional()
105
+ }).strict();
86
106
  var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
87
107
  payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
88
- });
108
+ }).strict();
89
109
  var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
90
110
  properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
91
- });
111
+ }).strict();
92
112
  var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
93
113
  primitive: z.string().trim().min(1).max(120).optional()
94
- });
114
+ }).strict();
95
115
  var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
96
116
  valueType: OntologyIdSchema.optional(),
97
117
  searchable: z.boolean().optional(),
98
118
  pii: z.boolean().optional()
99
- });
119
+ }).strict();
100
120
  var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
101
121
  members: OntologyReferenceListSchema
102
- });
122
+ }).strict();
103
123
  var OntologyEndpointTypeSchema = OntologyRecordBaseSchema.extend({
104
124
  route: z.string().trim().min(1).max(500).optional()
105
- });
125
+ }).strict();
106
126
  var OntologyScopeSchema = z.object({
107
127
  objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
108
128
  linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
@@ -3868,6 +3888,19 @@ var GPT5ConfigSchema = z.object({
3868
3888
  topP: z.number().min(0).max(1).optional(),
3869
3889
  modelOptions: GPT5OptionsSchema.optional()
3870
3890
  });
3891
+ var GPT56OptionsSchema = z.object({
3892
+ reasoning_effort: z.enum(["none", "low", "medium", "high", "xhigh", "max"]).optional(),
3893
+ verbosity: z.enum(["low", "medium", "high"]).optional()
3894
+ });
3895
+ var GPT56ConfigSchema = z.object({
3896
+ model: z.enum(["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]),
3897
+ provider: z.enum(["openai"]),
3898
+ apiKey: z.string(),
3899
+ temperature: z.literal(1).optional(),
3900
+ maxOutputTokens: z.number().min(4e3).optional(),
3901
+ topP: z.number().min(0).max(1).optional(),
3902
+ modelOptions: GPT56OptionsSchema.optional()
3903
+ });
3871
3904
  var MockConfigSchema = z.object({
3872
3905
  model: z.enum(["mock"]),
3873
3906
  provider: z.enum(["mock"]),
@@ -3920,9 +3953,12 @@ var AnthropicConfigSchema = z.discriminatedUnion("model", [
3920
3953
  AnthropicClaude5ConfigSchema,
3921
3954
  AnthropicStandardConfigSchema
3922
3955
  ]);
3956
+ var GPT56_CACHE_READ_RATE_MULTIPLIER = 0.1;
3957
+ var CACHE_CREATION_RATE_MULTIPLIER = 1.25;
3923
3958
  var MODEL_INFO = {
3924
3959
  // OpenAI GPT-5 (Reasoning Models)
3925
3960
  "gpt-5": {
3961
+ provider: "openai",
3926
3962
  inputCostPer1M: 125,
3927
3963
  // $1.25 per 1M tokens
3928
3964
  outputCostPer1M: 1e3,
@@ -3936,6 +3972,7 @@ var MODEL_INFO = {
3936
3972
  configSchema: GPT5ConfigSchema
3937
3973
  },
3938
3974
  "gpt-5.4-mini": {
3975
+ provider: "openai",
3939
3976
  inputCostPer1M: 75,
3940
3977
  // $0.75 per 1M tokens
3941
3978
  outputCostPer1M: 450,
@@ -3949,6 +3986,7 @@ var MODEL_INFO = {
3949
3986
  configSchema: GPT5ConfigSchema
3950
3987
  },
3951
3988
  "gpt-5.4-nano": {
3989
+ provider: "openai",
3952
3990
  inputCostPer1M: 20,
3953
3991
  // $0.20 per 1M tokens
3954
3992
  outputCostPer1M: 125,
@@ -3960,8 +3998,60 @@ var MODEL_INFO = {
3960
3998
  category: "standard",
3961
3999
  configSchema: GPT5ConfigSchema
3962
4000
  },
4001
+ // OpenAI GPT-5.6 family (GA 2026-07-09). All three tiers share 1.05M context, 128K max output,
4002
+ // image input, tool use, structured outputs, and prompt caching -- they differ in reasoning depth
4003
+ // and price, not capability. The bare `gpt-5.6` alias is deliberately unregistered; see OpenAIModel.
4004
+ "gpt-5.6-sol": {
4005
+ provider: "openai",
4006
+ inputCostPer1M: 500,
4007
+ // $5.00 per 1M tokens
4008
+ outputCostPer1M: 3e3,
4009
+ // $30.00 per 1M tokens
4010
+ minTokens: 4e3,
4011
+ recommendedTokens: 8e3,
4012
+ maxTokens: 105e4,
4013
+ // 1.05M context window
4014
+ maxOutputTokens: 128e3,
4015
+ category: "reasoning",
4016
+ configSchema: GPT56ConfigSchema,
4017
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
4018
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
4019
+ },
4020
+ "gpt-5.6-terra": {
4021
+ provider: "openai",
4022
+ inputCostPer1M: 250,
4023
+ // $2.50 per 1M tokens
4024
+ outputCostPer1M: 1500,
4025
+ // $15.00 per 1M tokens
4026
+ minTokens: 4e3,
4027
+ recommendedTokens: 8e3,
4028
+ maxTokens: 105e4,
4029
+ // 1.05M context window
4030
+ maxOutputTokens: 128e3,
4031
+ category: "standard",
4032
+ configSchema: GPT56ConfigSchema,
4033
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
4034
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
4035
+ },
4036
+ "gpt-5.6-luna": {
4037
+ provider: "openai",
4038
+ inputCostPer1M: 100,
4039
+ // $1.00 per 1M tokens
4040
+ outputCostPer1M: 600,
4041
+ // $6.00 per 1M tokens
4042
+ minTokens: 4e3,
4043
+ recommendedTokens: 8e3,
4044
+ maxTokens: 105e4,
4045
+ // 1.05M context window
4046
+ maxOutputTokens: 128e3,
4047
+ category: "standard",
4048
+ configSchema: GPT56ConfigSchema,
4049
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
4050
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
4051
+ },
3963
4052
  // Mock model for testing
3964
4053
  mock: {
4054
+ provider: "mock",
3965
4055
  inputCostPer1M: 0,
3966
4056
  // Free for tests
3967
4057
  outputCostPer1M: 0,
@@ -3975,6 +4065,7 @@ var MODEL_INFO = {
3975
4065
  },
3976
4066
  // OpenRouter Models (via openrouter.ai)
3977
4067
  "openrouter/z-ai/glm-5": {
4068
+ provider: "openrouter",
3978
4069
  inputCostPer1M: 72,
3979
4070
  // $0.72 per 1M tokens
3980
4071
  outputCostPer1M: 230,
@@ -3988,6 +4079,7 @@ var MODEL_INFO = {
3988
4079
  },
3989
4080
  // Anthropic Claude Models (direct SDK access via @anthropic-ai/sdk)
3990
4081
  "claude-opus-5": {
4082
+ provider: "anthropic",
3991
4083
  inputCostPer1M: 500,
3992
4084
  // $5.00 per 1M tokens
3993
4085
  outputCostPer1M: 2500,
@@ -4001,6 +4093,7 @@ var MODEL_INFO = {
4001
4093
  configSchema: AnthropicConfigSchema
4002
4094
  },
4003
4095
  "claude-sonnet-5": {
4096
+ provider: "anthropic",
4004
4097
  // List pricing. An introductory rate of $2.00/$10.00 runs through 2026-08-31; encoding the
4005
4098
  // temporary rate would make historical cost analytics wrong once it lapses.
4006
4099
  inputCostPer1M: 300,
@@ -4016,6 +4109,7 @@ var MODEL_INFO = {
4016
4109
  configSchema: AnthropicConfigSchema
4017
4110
  },
4018
4111
  "claude-haiku-4-5-20251001": {
4112
+ provider: "anthropic",
4019
4113
  inputCostPer1M: 100,
4020
4114
  // $1.00 per 1M tokens
4021
4115
  outputCostPer1M: 500,
@@ -4029,6 +4123,7 @@ var MODEL_INFO = {
4029
4123
  configSchema: AnthropicConfigSchema
4030
4124
  },
4031
4125
  "claude-haiku-4-5": {
4126
+ provider: "anthropic",
4032
4127
  inputCostPer1M: 100,
4033
4128
  // $1.00 per 1M tokens
4034
4129
  outputCostPer1M: 500,
@@ -4048,7 +4143,7 @@ function getModelInfo(model) {
4048
4143
  return MODEL_INFO[model];
4049
4144
  }
4050
4145
  for (const knownModel of MODEL_KEYS_BY_SPECIFICITY) {
4051
- if (model.startsWith(knownModel)) {
4146
+ if (model.startsWith(`${knownModel}-`)) {
4052
4147
  return MODEL_INFO[knownModel];
4053
4148
  }
4054
4149
  }
@@ -4420,13 +4515,126 @@ function buildIterationResponseSchemaUncached(tools, capabilities) {
4420
4515
  };
4421
4516
  }
4422
4517
 
4518
+ // ../core/src/execution/engine/workflow/types.ts
4519
+ var StepType2 = {
4520
+ LINEAR: "linear",
4521
+ CONDITIONAL: "conditional"
4522
+ };
4523
+
4524
+ // ../core/src/execution/engine/workflow/errors.ts
4525
+ var WorkflowStepError = class extends ExecutionError2 {
4526
+ type = "workflow_step_error";
4527
+ severity = "critical";
4528
+ category = "workflow";
4529
+ /**
4530
+ * @param cause - The error the step actually threw. Kept so the original stack and any
4531
+ * non-`ExecutionError` throw survive the wrap; its classification is additionally copied into
4532
+ * `context` by the caller, because `type`/`severity`/`category` are fixed on this class.
4533
+ */
4534
+ constructor(message, context, cause) {
4535
+ super(message, context);
4536
+ if (cause !== void 0) this.cause = cause;
4537
+ }
4538
+ };
4539
+ var WorkflowValidationError = class extends ExecutionError2 {
4540
+ type = "workflow_validation_error";
4541
+ severity = "info";
4542
+ category = "validation";
4543
+ constructor(message, context) {
4544
+ super(message, context);
4545
+ }
4546
+ };
4547
+
4548
+ // ../core/src/execution/engine/workflow/utils.ts
4549
+ function validateEntryPoint(steps, entryPoint) {
4550
+ if (!(entryPoint in steps)) {
4551
+ throw new WorkflowValidationError(`Entry point step '${entryPoint}' not found in workflow`, {
4552
+ entryPoint
4553
+ });
4554
+ }
4555
+ }
4556
+ function findTerminalSteps(steps) {
4557
+ return Object.values(steps).filter((step) => step.next === null);
4558
+ }
4559
+ function validateTerminalSteps(steps, workflowId) {
4560
+ const terminalSteps = findTerminalSteps(steps);
4561
+ if (terminalSteps.length === 0) {
4562
+ throw new WorkflowValidationError(`Workflow '${workflowId}' must have at least one terminal step (next: null)`, {
4563
+ workflowId
4564
+ });
4565
+ }
4566
+ }
4567
+ function validateStepReferences(steps) {
4568
+ for (const [id, step] of Object.entries(steps)) {
4569
+ if (step.next === null) {
4570
+ continue;
4571
+ }
4572
+ if (step.next.type === StepType2.LINEAR) {
4573
+ if (!(step.next.target in steps)) {
4574
+ throw new WorkflowValidationError(`Step '${id}' references non-existent target '${step.next.target}'`, {
4575
+ stepId: id,
4576
+ target: step.next.target
4577
+ });
4578
+ }
4579
+ } else if (step.next.type === StepType2.CONDITIONAL) {
4580
+ const targets = [...step.next.routes.map((r) => r.target), step.next.default];
4581
+ for (const target of targets) {
4582
+ if (!(target in steps)) {
4583
+ throw new WorkflowValidationError(`Step '${id}' references non-existent target '${target}'`, {
4584
+ stepId: id,
4585
+ target
4586
+ });
4587
+ }
4588
+ }
4589
+ }
4590
+ }
4591
+ }
4592
+ function detectCycle(visited, executionPath, currentStepId) {
4593
+ if (visited.has(currentStepId)) {
4594
+ const cycle = executionPath.slice(executionPath.indexOf(currentStepId));
4595
+ throw new WorkflowStepError(`Cycle detected in workflow: ${cycle.join(" -> ")} -> ${currentStepId}`, {
4596
+ stepId: currentStepId,
4597
+ cycle: [...cycle, currentStepId]
4598
+ });
4599
+ }
4600
+ }
4601
+ function validateWorkflowGraph(steps, entryPoint, workflowId) {
4602
+ const onPath = /* @__PURE__ */ new Set();
4603
+ const executionPath = [];
4604
+ const reached = /* @__PURE__ */ new Set();
4605
+ const walk = (stepId) => {
4606
+ detectCycle(onPath, executionPath, stepId);
4607
+ onPath.add(stepId);
4608
+ executionPath.push(stepId);
4609
+ reached.add(stepId);
4610
+ const step = steps[stepId];
4611
+ if (step && step.next !== null) {
4612
+ const targets = step.next.type === StepType2.LINEAR ? [step.next.target] : [...step.next.routes.map((route) => route.target), step.next.default];
4613
+ for (const target of targets) {
4614
+ if (target in steps) walk(target);
4615
+ }
4616
+ }
4617
+ executionPath.pop();
4618
+ onPath.delete(stepId);
4619
+ };
4620
+ if (entryPoint in steps) walk(entryPoint);
4621
+ const orphanIds = Object.keys(steps).filter((id) => !reached.has(id));
4622
+ if (orphanIds.length > 0) {
4623
+ throw new WorkflowValidationError(
4624
+ `Workflow '${workflowId}' has step(s) unreachable from entry point '${entryPoint}': ${orphanIds.join(", ")}`,
4625
+ { workflowId, entryPoint, orphanIds }
4626
+ );
4627
+ }
4628
+ }
4629
+
4423
4630
  // ../core/src/platform/registry/validation.ts
4424
4631
  var RegistryValidationError = class extends Error {
4425
- constructor(orgName, resourceId, field, message) {
4632
+ constructor(orgName, resourceId, field, message, issues) {
4426
4633
  super(message);
4427
4634
  this.orgName = orgName;
4428
4635
  this.resourceId = resourceId;
4429
4636
  this.field = field;
4637
+ this.issues = issues;
4430
4638
  this.name = "RegistryValidationError";
4431
4639
  }
4432
4640
  };
@@ -4447,7 +4655,14 @@ function emitGovernanceIssues(issues, mode, onWarning) {
4447
4655
  if (issues.length === 0) return;
4448
4656
  if (mode === "strict") {
4449
4657
  const first = issues[0];
4450
- throw new RegistryValidationError(first.orgName, first.resourceId, "organizationModel.resources", first.message);
4658
+ const messages = issues.map((issue) => issue.message);
4659
+ throw new RegistryValidationError(
4660
+ first.orgName,
4661
+ first.resourceId,
4662
+ "organizationModel.resources",
4663
+ messages.join("\n"),
4664
+ messages
4665
+ );
4451
4666
  }
4452
4667
  const warn = onWarning ?? ((issue) => console.warn(issue.message));
4453
4668
  for (const issue of issues) {
@@ -4608,7 +4823,7 @@ function addTopologyIssues(issues, orgName, deployment, organizationModel, syste
4608
4823
  if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
4609
4824
  if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
4610
4825
  if (ref.kind === "ontology") {
4611
- if (ontologyIndex === void 0) return true;
4826
+ if (ontologyIndex === void 0) return false;
4612
4827
  return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
4613
4828
  }
4614
4829
  return false;
@@ -4766,7 +4981,8 @@ function addSystemInterfaceIssue(issues, orgName, systemPath, interfaceKey, issu
4766
4981
  message: `[${orgName}] ${issue.family}:${issue.code}: ${issue.message}`
4767
4982
  });
4768
4983
  }
4769
- function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
4984
+ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel, options = {}) {
4985
+ const mode = getResourceValidatorMode(options.mode);
4770
4986
  const issues = [];
4771
4987
  if (organizationModel === void 0) return { valid: true, issues };
4772
4988
  const model = organizationModel;
@@ -4792,17 +5008,27 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
4792
5008
  }
4793
5009
  }
4794
5010
  if (issues.length > 0) {
4795
- const first = issues[0];
4796
- throw new RegistryValidationError(
4797
- first.orgName,
4798
- `${first.systemPath}/${first.interfaceKey}`,
4799
- first.path ?? "organizationModel.systems.apiInterface",
4800
- first.message
4801
- );
5011
+ if (mode === "strict") {
5012
+ const first = issues[0];
5013
+ const messages = issues.map((issue) => issue.message);
5014
+ throw new RegistryValidationError(
5015
+ first.orgName,
5016
+ `${first.systemPath}/${first.interfaceKey}`,
5017
+ first.path ?? "organizationModel.systems.apiInterface",
5018
+ messages.join("\n"),
5019
+ messages
5020
+ );
5021
+ }
5022
+ const warn = options.onWarning ?? ((issue) => console.warn(issue.message));
5023
+ for (const issue of issues) {
5024
+ warn(issue);
5025
+ }
5026
+ return { valid: false, issues };
4802
5027
  }
4803
5028
  return { valid: true, issues };
4804
5029
  }
4805
- function validateDeploymentSpec(orgName, resources) {
5030
+ function validateDeploymentSpec(orgName, resources, options = {}) {
5031
+ const warn = options.onWarning ?? ((message) => console.warn(message));
4806
5032
  const seenIds = /* @__PURE__ */ new Set();
4807
5033
  resources.workflows?.forEach((workflow) => {
4808
5034
  const id = workflow.config.resourceId;
@@ -4821,6 +5047,14 @@ function validateDeploymentSpec(orgName, resources) {
4821
5047
  if (workflow.interface) {
4822
5048
  validateExecutionInterface(orgName, id, workflow.interface, workflow.contract.inputSchema);
4823
5049
  }
5050
+ try {
5051
+ validateEntryPoint(workflow.steps, workflow.entryPoint);
5052
+ validateTerminalSteps(workflow.steps, id);
5053
+ validateStepReferences(workflow.steps);
5054
+ validateWorkflowGraph(workflow.steps, workflow.entryPoint, id);
5055
+ } catch (error) {
5056
+ warn(`[${orgName}] Workflow '${id}' graph validation: ${error instanceof Error ? error.message : String(error)}`);
5057
+ }
4824
5058
  });
4825
5059
  resources.agents?.forEach((agent) => {
4826
5060
  const id = agent.config.resourceId;
@@ -4834,14 +5068,20 @@ function validateDeploymentSpec(orgName, resources) {
4834
5068
  }
4835
5069
  seenIds.add(id);
4836
5070
  validateResourceModelConfig(orgName, id, agent.modelConfig);
4837
- validateAgentGrammar(orgName, id, agent);
4838
- validateAgentCheapAssertions(orgName, id, agent);
5071
+ validateAgentGrammar(orgName, id, agent, options.mode);
5072
+ validateAgentCheapAssertions(orgName, id, agent, options.mode);
4839
5073
  if (agent.interface) {
4840
5074
  validateExecutionInterface(orgName, id, agent.interface, agent.contract.inputSchema);
4841
5075
  }
4842
5076
  });
4843
- validateResourceGovernance(orgName, resources);
4844
- validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel);
5077
+ validateResourceGovernance(orgName, resources, void 0, {
5078
+ mode: options.mode,
5079
+ onWarning: (issue) => warn(issue.message)
5080
+ });
5081
+ validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel, {
5082
+ mode: options.mode,
5083
+ onWarning: (issue) => warn(issue.message)
5084
+ });
4845
5085
  }
4846
5086
  function validateResourceModelConfig(orgName, resourceId, modelConfig) {
4847
5087
  try {
@@ -4916,7 +5156,7 @@ function describeGrammarRefusal(reasons, toolInputSchema) {
4916
5156
  }
4917
5157
  return `refused strict mode: ${reasons.join(", ")}`;
4918
5158
  }
4919
- function validateAgentGrammar(orgName, agentId, agent) {
5159
+ function validateAgentGrammar(orgName, agentId, agent, mode) {
4920
5160
  const dialect = dialectForProvider(agent.modelConfig.provider);
4921
5161
  if (!dialect) return;
4922
5162
  const capabilities = agentCapabilitiesForGrammarCheck(agent.config);
@@ -4937,12 +5177,12 @@ function validateAgentGrammar(orgName, agentId, agent) {
4937
5177
  compileSchema(offending.inputSchema, dialect).refusalReasons,
4938
5178
  offending.inputSchema
4939
5179
  )}. 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).`;
4940
- if (getResourceValidatorMode() === "strict") {
5180
+ if (getResourceValidatorMode(mode) === "strict") {
4941
5181
  throw new RegistryValidationError(orgName, agentId, "tools", message);
4942
5182
  }
4943
5183
  console.warn(message);
4944
5184
  }
4945
- function validateAgentCheapAssertions(orgName, agentId, agent) {
5185
+ function validateAgentCheapAssertions(orgName, agentId, agent, mode) {
4946
5186
  const issues = [];
4947
5187
  const config = agent.config;
4948
5188
  if (config.sessionCapable && config.securityLevel === "none") {
@@ -4972,7 +5212,7 @@ function validateAgentCheapAssertions(orgName, agentId, agent) {
4972
5212
  }
4973
5213
  if (issues.length === 0) return;
4974
5214
  const message = `[${orgName}] Agent '${agentId}': ${issues.join(" ")}`;
4975
- if (getResourceValidatorMode() === "strict") {
5215
+ if (getResourceValidatorMode(mode) === "strict") {
4976
5216
  throw new RegistryValidationError(orgName, agentId, "config", message);
4977
5217
  }
4978
5218
  console.warn(message);
@@ -5228,12 +5468,6 @@ function validateHumanCheckpoints(orgName, humanCheckpoints, allInternalIds, val
5228
5468
  });
5229
5469
  }
5230
5470
 
5231
- // ../core/src/execution/engine/workflow/types.ts
5232
- var StepType2 = {
5233
- LINEAR: "linear",
5234
- CONDITIONAL: "conditional"
5235
- };
5236
-
5237
5471
  // ../core/src/execution/engine/base/serialization.ts
5238
5472
  function serializeDefinition(definition, options) {
5239
5473
  const opts = {