@a5c-ai/kradle 5.0.1-staging.3abdf9534c25

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 (295) hide show
  1. package/Dockerfile +31 -0
  2. package/README.md +187 -0
  3. package/bin/kradle-demo.mjs +23 -0
  4. package/bin/kradle-server.mjs +14 -0
  5. package/dist/kradle-controller-ui.json +3482 -0
  6. package/dist/kradle-lifecycle.json +201 -0
  7. package/dist/kradle-runtime-snapshot.json +3125 -0
  8. package/dist/kradle-summary.json +724 -0
  9. package/docs/README.md +61 -0
  10. package/docs/agents/README.md +83 -0
  11. package/docs/agents/acceptance-test-matrix.md +193 -0
  12. package/docs/agents/agent-mux-adapter-contract.md +167 -0
  13. package/docs/agents/agent-mux-source-map.md +310 -0
  14. package/docs/agents/agent-run-memory-import-spec.md +256 -0
  15. package/docs/agents/agent-stack-management-spec.md +421 -0
  16. package/docs/agents/api-contract-spec.md +309 -0
  17. package/docs/agents/artifacts-writeback-spec.md +145 -0
  18. package/docs/agents/chart-packaging-spec.md +128 -0
  19. package/docs/agents/ci-orchestration-spec.md +140 -0
  20. package/docs/agents/context-assembly-spec.md +219 -0
  21. package/docs/agents/controller-reconciliation-spec.md +255 -0
  22. package/docs/agents/crd-schema-spec.md +315 -0
  23. package/docs/agents/decision-log-open-questions.md +169 -0
  24. package/docs/agents/developer-implementation-checklist.md +329 -0
  25. package/docs/agents/dispatching-design.md +262 -0
  26. package/docs/agents/gaps-agent-mux-to-kradle-crds.md +298 -0
  27. package/docs/agents/glossary.md +66 -0
  28. package/docs/agents/implementation-blueprint.md +324 -0
  29. package/docs/agents/implementation-rollout-slices.md +251 -0
  30. package/docs/agents/memory-context-integration-spec.md +194 -0
  31. package/docs/agents/memory-ontology-schema-spec.md +253 -0
  32. package/docs/agents/memory-operations-runbook.md +121 -0
  33. package/docs/agents/mvp-vertical-slice-spec.md +146 -0
  34. package/docs/agents/observability-audit-spec.md +265 -0
  35. package/docs/agents/operator-runbook.md +174 -0
  36. package/docs/agents/org-memory-api-payload-examples.md +333 -0
  37. package/docs/agents/org-memory-controller-sequence-spec.md +181 -0
  38. package/docs/agents/org-memory-e2e-fixture-plan.md +161 -0
  39. package/docs/agents/org-memory-ui-implementation-map.md +114 -0
  40. package/docs/agents/org-memory-vertical-slice-spec.md +168 -0
  41. package/docs/agents/org-resource-model-delta-spec.md +111 -0
  42. package/docs/agents/org-route-resource-model-spec.md +183 -0
  43. package/docs/agents/org-scoping-namespace-spec.md +114 -0
  44. package/docs/agents/rbac-secrets-management-spec.md +406 -0
  45. package/docs/agents/repository-page-integration-spec.md +255 -0
  46. package/docs/agents/resource-contract-examples.md +808 -0
  47. package/docs/agents/resource-relationship-map.md +190 -0
  48. package/docs/agents/security-threat-model.md +188 -0
  49. package/docs/agents/shared-memory-company-brain-spec.md +358 -0
  50. package/docs/agents/storage-migration-spec.md +168 -0
  51. package/docs/agents/subagent-orchestration-spec.md +152 -0
  52. package/docs/agents/system-overview.md +88 -0
  53. package/docs/agents/tools-mcp-skills-spec.md +189 -0
  54. package/docs/agents/traceability-matrix.md +79 -0
  55. package/docs/agents/ui-flow-spec.md +211 -0
  56. package/docs/agents/ui-ux-system-spec.md +426 -0
  57. package/docs/agents/workspace-lifecycle-spec.md +166 -0
  58. package/docs/architecture-spec.md +78 -0
  59. package/docs/architecture-v2.md +2759 -0
  60. package/docs/components/control-plane.md +78 -0
  61. package/docs/components/data-plane.md +69 -0
  62. package/docs/components/hooks-events.md +67 -0
  63. package/docs/components/identity-rbac-policy.md +73 -0
  64. package/docs/components/kubevela-oam.md +70 -0
  65. package/docs/components/operations-publishing.md +81 -0
  66. package/docs/components/runners-ci.md +66 -0
  67. package/docs/components/web-ui.md +94 -0
  68. package/docs/crd-behaviors-and-relationships.md +3926 -0
  69. package/docs/external/README.md +47 -0
  70. package/docs/external/bidirectional-sync-design.md +134 -0
  71. package/docs/external/cicd-interface.md +64 -0
  72. package/docs/external/external-backend-controllers.md +170 -0
  73. package/docs/external/external-backend-crds.md +234 -0
  74. package/docs/external/external-backend-ui-spec.md +151 -0
  75. package/docs/external/external-backend-ux-flows.md +115 -0
  76. package/docs/external/external-object-mapping.md +125 -0
  77. package/docs/external/git-forge-interface.md +68 -0
  78. package/docs/external/github-integration-design.md +151 -0
  79. package/docs/external/issue-tracking-interface.md +66 -0
  80. package/docs/external/provider-capability-manifests.md +204 -0
  81. package/docs/external/provider-catalog.md +139 -0
  82. package/docs/external/provider-rollout-testing.md +78 -0
  83. package/docs/external/research-results.md +48 -0
  84. package/docs/external/security-auth-permissions.md +81 -0
  85. package/docs/external/sync-state-machines.md +108 -0
  86. package/docs/external/unified-external-backend-model.md +107 -0
  87. package/docs/external/user-facing-changes.md +67 -0
  88. package/docs/gaps.md +161 -0
  89. package/docs/install.md +94 -0
  90. package/docs/integration-and-design-decisions.md +1530 -0
  91. package/docs/kradle-design.md +334 -0
  92. package/docs/local-minikube.md +55 -0
  93. package/docs/ontology/README.md +32 -0
  94. package/docs/ontology/bounded-contexts.md +29 -0
  95. package/docs/ontology/events-and-hooks.md +32 -0
  96. package/docs/ontology/oam-kubevela.md +32 -0
  97. package/docs/ontology/operations-and-release.md +25 -0
  98. package/docs/ontology/personas-and-actors.md +32 -0
  99. package/docs/ontology/policies-and-invariants.md +33 -0
  100. package/docs/ontology/problem-space.md +30 -0
  101. package/docs/ontology/resource-contracts.md +40 -0
  102. package/docs/ontology/resource-taxonomy.md +42 -0
  103. package/docs/ontology/runners-and-ci.md +29 -0
  104. package/docs/ontology/solution-space.md +24 -0
  105. package/docs/ontology/storage-and-data-boundaries.md +29 -0
  106. package/docs/ontology/validation-matrix.md +24 -0
  107. package/docs/ontology/web-ui-excellent-flows.md +32 -0
  108. package/docs/ontology/workflows.md +39 -0
  109. package/docs/ontology/world.md +35 -0
  110. package/docs/openapi.yaml +1291 -0
  111. package/docs/product-requirements.md +62 -0
  112. package/docs/requirements-v2.md +235 -0
  113. package/docs/roadmap-mvp.md +87 -0
  114. package/docs/sdk-api-reference.md +1108 -0
  115. package/docs/system-requirements.md +90 -0
  116. package/docs/system-spec-v2.md +1230 -0
  117. package/docs/tests/README.md +53 -0
  118. package/docs/tests/agent-qa-plan.md +63 -0
  119. package/docs/tests/browser-ui-tests.md +62 -0
  120. package/docs/tests/ci-quality-gates.md +48 -0
  121. package/docs/tests/coverage-model.md +64 -0
  122. package/docs/tests/e2e-scenario-tests.md +53 -0
  123. package/docs/tests/fixtures-test-data.md +63 -0
  124. package/docs/tests/observability-reliability-tests.md +54 -0
  125. package/docs/tests/product-test-matrix.md +145 -0
  126. package/docs/tests/qa-adoption-roadmap.md +130 -0
  127. package/docs/tests/qa-automation-plan.md +101 -0
  128. package/docs/tests/security-compliance-tests.md +57 -0
  129. package/docs/tests/test-framework-tools.md +88 -0
  130. package/docs/tests/test-suite-layout.md +121 -0
  131. package/docs/tests/unit-integration-tests.md +48 -0
  132. package/docs/todo-kyverno +714 -0
  133. package/docs/todos.md +4 -0
  134. package/docs/user-stories.md +78 -0
  135. package/docs/web-console-spec.md +533 -0
  136. package/examples/minikube-demo.yaml +190 -0
  137. package/examples/oam-application.yaml +23 -0
  138. package/examples/policy-kyverno-pr-title.yaml +18 -0
  139. package/package.json +66 -0
  140. package/scripts/build.mjs +29 -0
  141. package/scripts/setup-minikube.mjs +65 -0
  142. package/scripts/smoke.mjs +37 -0
  143. package/scripts/validate-doc-coverage.mjs +152 -0
  144. package/scripts/validate-package.mjs +95 -0
  145. package/scripts/validate-ui.mjs +305 -0
  146. package/src/agent-adapter-controller.js +169 -0
  147. package/src/agent-approval-controller.js +170 -0
  148. package/src/agent-context-bundles.js +242 -0
  149. package/src/agent-dispatch-controller.js +549 -0
  150. package/src/agent-gateway-config-controller.js +147 -0
  151. package/src/agent-identity-migration.js +115 -0
  152. package/src/agent-memory-controller.js +357 -0
  153. package/src/agent-memory-import.js +327 -0
  154. package/src/agent-memory-query.js +292 -0
  155. package/src/agent-memory-repository-source-controller.js +255 -0
  156. package/src/agent-mux-client.js +589 -0
  157. package/src/agent-permission-review.js +250 -0
  158. package/src/agent-persona-controller.js +135 -0
  159. package/src/agent-project-controller.js +117 -0
  160. package/src/agent-prompt-composition.js +55 -0
  161. package/src/agent-provider-config-controller.js +151 -0
  162. package/src/agent-secret-config-grant-controller.js +282 -0
  163. package/src/agent-session-transcript-controller.js +189 -0
  164. package/src/agent-stack-controller.js +421 -0
  165. package/src/agent-subagent-controller.js +160 -0
  166. package/src/agent-transport-binding-controller.js +121 -0
  167. package/src/agent-trigger-controller.js +387 -0
  168. package/src/agent-workspace-controller.js +702 -0
  169. package/src/agent-writeback-controller.js +302 -0
  170. package/src/api-controller.js +621 -0
  171. package/src/argocd-gitops.js +43 -0
  172. package/src/artifact-registry-controller.js +542 -0
  173. package/src/assistant-runtime.js +284 -0
  174. package/src/async-controller.js +207 -0
  175. package/src/audit-controller.js +191 -0
  176. package/src/auth.js +310 -0
  177. package/src/component-catalog.js +41 -0
  178. package/src/control-plane.js +136 -0
  179. package/src/controller-client.js +112 -0
  180. package/src/controller-ui.js +620 -0
  181. package/src/data-plane.js +179 -0
  182. package/src/event-bus.js +397 -0
  183. package/src/external/conflict-controller.js +225 -0
  184. package/src/external/github/auth.js +96 -0
  185. package/src/external/github/cicd.js +180 -0
  186. package/src/external/github/git-forge.js +240 -0
  187. package/src/external/github/index.js +144 -0
  188. package/src/external/github/issue-tracking.js +163 -0
  189. package/src/external/provider-adapter.js +161 -0
  190. package/src/external/provider-resource-factory.js +221 -0
  191. package/src/external/sync-controller.js +235 -0
  192. package/src/external/webhook-controller.js +144 -0
  193. package/src/external/write-controller.js +283 -0
  194. package/src/gitea-backend.js +131 -0
  195. package/src/gitea-service.js +173 -0
  196. package/src/handoff.js +98 -0
  197. package/src/health-probes.js +134 -0
  198. package/src/hooks-events.js +63 -0
  199. package/src/hooks-lifecycle.js +117 -0
  200. package/src/http-server.js +409 -0
  201. package/src/identity-policy.js +86 -0
  202. package/src/index.js +71 -0
  203. package/src/jitsi-agent-bridge.js +141 -0
  204. package/src/jitsi-meeting-controller.js +291 -0
  205. package/src/jitsi-sync-controller.js +198 -0
  206. package/src/kradle-inference-service-controller.js +246 -0
  207. package/src/kubernetes-controller-async.js +531 -0
  208. package/src/kubernetes-controller.js +904 -0
  209. package/src/kubernetes-resource-gateway.js +48 -0
  210. package/src/model-route-controller.js +364 -0
  211. package/src/notification-controller.js +178 -0
  212. package/src/operations.js +112 -0
  213. package/src/org-scoping.js +5 -0
  214. package/src/resource-model.js +282 -0
  215. package/src/runner-controller.js +272 -0
  216. package/src/runners-ci.js +48 -0
  217. package/src/runtime.js +196 -0
  218. package/src/snapshot-cache.js +157 -0
  219. package/src/virtual-model-controller.js +538 -0
  220. package/src/virtual-model-hook-bridge.js +200 -0
  221. package/src/web-ui.js +40 -0
  222. package/tests/agent-adapter-controller.test.js +361 -0
  223. package/tests/agent-approval-controller.test.js +173 -0
  224. package/tests/agent-context-bundles.test.js +278 -0
  225. package/tests/agent-dispatch-controller.test.js +679 -0
  226. package/tests/agent-gateway-config-controller.test.js +386 -0
  227. package/tests/agent-identity-migration.test.js +87 -0
  228. package/tests/agent-memory-controller.test.js +461 -0
  229. package/tests/agent-memory-import-snapshot.test.js +477 -0
  230. package/tests/agent-memory-query.test.js +404 -0
  231. package/tests/agent-memory-repository-source.test.js +514 -0
  232. package/tests/agent-mux-client.test.js +389 -0
  233. package/tests/agent-mux-integration.test.js +971 -0
  234. package/tests/agent-permission-review-v2.test.js +317 -0
  235. package/tests/agent-permission-review.test.js +209 -0
  236. package/tests/agent-persona-controller.test.js +127 -0
  237. package/tests/agent-project-controller.test.js +302 -0
  238. package/tests/agent-prompt-composition.test.js +76 -0
  239. package/tests/agent-provider-config-controller.test.js +376 -0
  240. package/tests/agent-resources.test.js +303 -0
  241. package/tests/agent-secret-config-grant.test.js +231 -0
  242. package/tests/agent-session-transcript-controller.test.js +499 -0
  243. package/tests/agent-stack-controller.test.js +283 -0
  244. package/tests/agent-subagent-controller.test.js +201 -0
  245. package/tests/agent-transport-binding-controller.test.js +294 -0
  246. package/tests/agent-trigger-controller.test.js +271 -0
  247. package/tests/agent-trigger-routes.test.js +190 -0
  248. package/tests/agent-trigger-sources.test.js +245 -0
  249. package/tests/agent-workspace-controller.test.js +181 -0
  250. package/tests/agent-writeback.test.js +292 -0
  251. package/tests/approval-persistence.test.js +171 -0
  252. package/tests/artifact-registry.test.js +511 -0
  253. package/tests/assistant-runtime.test.js +506 -0
  254. package/tests/async-controller.test.js +252 -0
  255. package/tests/audit-controller.test.js +227 -0
  256. package/tests/codespace-controller.test.js +318 -0
  257. package/tests/controller-client.test.js +133 -0
  258. package/tests/deployment.test.js +527 -0
  259. package/tests/e2e/lifecycle.test.js +120 -0
  260. package/tests/event-bus-integration.test.js +355 -0
  261. package/tests/external-github-forge.test.js +560 -0
  262. package/tests/external-github-issues-cicd.test.js +520 -0
  263. package/tests/external-integration.test.js +470 -0
  264. package/tests/external-persistence.test.js +415 -0
  265. package/tests/external-provider-adapter.test.js +365 -0
  266. package/tests/external-resource-model.test.js +223 -0
  267. package/tests/external-webhook-sync.test.js +287 -0
  268. package/tests/external-write-conflict.test.js +353 -0
  269. package/tests/gitea-service.test.js +253 -0
  270. package/tests/health-check-real.test.js +165 -0
  271. package/tests/health-probes.test.js +90 -0
  272. package/tests/hooks-lifecycle.test.js +364 -0
  273. package/tests/integration/full-flow.test.js +266 -0
  274. package/tests/jitsi-agent-bridge.test.js +119 -0
  275. package/tests/jitsi-helm-integration.test.js +77 -0
  276. package/tests/jitsi-meeting-controller.test.js +170 -0
  277. package/tests/jitsi-resource-model.test.js +73 -0
  278. package/tests/jitsi-sync-controller.test.js +112 -0
  279. package/tests/kradle-inference-service.test.js +689 -0
  280. package/tests/kradle.test.js +779 -0
  281. package/tests/memory-search-wiring.test.js +270 -0
  282. package/tests/model-route-controller.test.js +733 -0
  283. package/tests/notification-controller.test.js +196 -0
  284. package/tests/notification-integration.test.js +179 -0
  285. package/tests/org-scoping.test.js +687 -0
  286. package/tests/runner-controller.test.js +327 -0
  287. package/tests/runner-integration.test.js +231 -0
  288. package/tests/session-cookie-hmac.test.js +151 -0
  289. package/tests/snapshot-performance.test.js +315 -0
  290. package/tests/sse-events.test.js +107 -0
  291. package/tests/virtual-model-controller.test.js +877 -0
  292. package/tests/virtual-model-hook-bridge.test.js +384 -0
  293. package/tests/webhook-trigger.test.js +198 -0
  294. package/tests/workspace-volumes.test.js +312 -0
  295. package/tests/writeback-persistence.test.js +207 -0
@@ -0,0 +1,246 @@
1
+ // KServe Inference Service Controller
2
+ // Manages KradleInferenceService and KradleServingRuntime resources:
3
+ // validation, KServe manifest generation, endpoint resolution,
4
+ // provider config bridge, inference calls, and health checks.
5
+
6
+ export const KSERVE_API_GROUP = 'serving.kserve.io';
7
+ export const KSERVE_API_VERSION = 'v1beta1';
8
+
9
+ export const SUPPORTED_MODEL_FORMATS = [
10
+ 'sklearn', 'xgboost', 'lightgbm', 'tensorflow', 'pytorch',
11
+ 'onnx', 'triton', 'huggingface', 'custom'
12
+ ];
13
+
14
+ export const INFERENCE_PROTOCOLS = { V1: 'v1', V2: 'v2' };
15
+
16
+ export const KRADLE_INFERENCE_SERVICE_CONTROLLER_BOUNDARY = {
17
+ role: 'kradle-inference-service-controller',
18
+ scope: 'KradleInferenceService lifecycle: validation, KServe manifest generation, endpoint resolution, provider config bridge, inference calls',
19
+ owns: ['inference service validation', 'KServe manifest generation', 'endpoint resolution', 'provider config bridge', 'inference protocol handling', 'health checks'],
20
+ delegatesTo: ['resource-model', 'agent-provider-config-controller'],
21
+ mustNotOwn: ['secret values', 'Kubernetes Job execution', 'model training', 'data pipeline orchestration']
22
+ };
23
+
24
+ /**
25
+ * Validate a KradleInferenceService resource. Returns { valid, errors }.
26
+ * @param {object} resource
27
+ * @returns {{ valid: boolean, errors: string[] }}
28
+ */
29
+ export function validateKradleInferenceService(resource) {
30
+ const errors = [];
31
+
32
+ if (resource == null) {
33
+ errors.push('resource must not be null or undefined');
34
+ return { valid: false, errors };
35
+ }
36
+
37
+ if (!resource?.metadata?.name) {
38
+ errors.push('metadata.name is required');
39
+ }
40
+
41
+ const spec = resource?.spec || {};
42
+
43
+ if (!spec.organizationRef) {
44
+ errors.push('spec.organizationRef is required');
45
+ }
46
+
47
+ // Validate modelFormat
48
+ const modelFormat = spec.modelFormat;
49
+ if (!modelFormat) {
50
+ errors.push(`spec.modelFormat is required; supported formats are: ${SUPPORTED_MODEL_FORMATS.join(', ')}`);
51
+ } else if (!SUPPORTED_MODEL_FORMATS.includes(modelFormat)) {
52
+ errors.push(`spec.modelFormat "${modelFormat}" is not supported; supported formats are: ${SUPPORTED_MODEL_FORMATS.join(', ')}`);
53
+ }
54
+
55
+ // Validate storageUri
56
+ const storageUri = spec.storageUri;
57
+ if (!storageUri) {
58
+ errors.push('spec.storageUri is required; use s3://, gs://, pvc://, or http(s):// URI');
59
+ } else if (!/^(s3|gs|pvc|https?):\/\/.+/.test(storageUri)) {
60
+ errors.push(`spec.storageUri "${storageUri}" must use s3://, gs://, pvc://, or http(s):// scheme`);
61
+ }
62
+
63
+ // Validate inferenceProtocol if set
64
+ if (spec.inferenceProtocol && !['v1', 'v2'].includes(spec.inferenceProtocol)) {
65
+ errors.push(`spec.inferenceProtocol "${spec.inferenceProtocol}" is not supported; valid values are: v1, v2`);
66
+ }
67
+
68
+ return { valid: errors.length === 0, errors };
69
+ }
70
+
71
+ /**
72
+ * Factory that returns a KradleInferenceService controller instance.
73
+ */
74
+ export function createInferenceServiceController() {
75
+ return {
76
+ role: 'kradle-inference-service-controller',
77
+
78
+ /**
79
+ * Validate a KradleInferenceService resource.
80
+ * @param {object} resource
81
+ * @returns {{ valid: boolean, errors: string[] }}
82
+ */
83
+ validate(resource) {
84
+ return validateKradleInferenceService(resource);
85
+ },
86
+
87
+ /**
88
+ * Generate the native KServe InferenceService manifest from a KradleInferenceService.
89
+ * @param {object} kradleResource
90
+ * @returns {object}
91
+ */
92
+ generateKServeManifest(kradleResource) {
93
+ const spec = kradleResource?.spec || {};
94
+ const metadata = kradleResource?.metadata || {};
95
+
96
+ return {
97
+ apiVersion: `${KSERVE_API_GROUP}/${KSERVE_API_VERSION}`,
98
+ kind: 'InferenceService',
99
+ metadata: {
100
+ name: metadata.name,
101
+ namespace: metadata.namespace,
102
+ labels: {
103
+ 'kradle.a5c.ai/managed': 'true',
104
+ 'kradle.a5c.ai/org': spec.organizationRef
105
+ }
106
+ },
107
+ spec: {
108
+ predictor: {
109
+ modelFormat: { name: spec.modelFormat, version: spec.modelVersion || '0' },
110
+ storageUri: spec.storageUri,
111
+ ...(spec.runtime ? { runtime: spec.runtime } : {}),
112
+ resources: spec.resources || { limits: { cpu: '1', memory: '2Gi' } }
113
+ },
114
+ ...(spec.transformer ? { transformer: spec.transformer } : {}),
115
+ ...(spec.explainer ? { explainer: spec.explainer } : {})
116
+ }
117
+ };
118
+ },
119
+
120
+ /**
121
+ * Resolve the inference endpoint from an InferenceService status object.
122
+ * Falls back to a cluster-internal URL if status URL is not available.
123
+ * @param {object} inferenceService - KServe InferenceService object with status
124
+ * @returns {string}
125
+ */
126
+ resolveEndpoint(inferenceService) {
127
+ const url = inferenceService?.status?.url || inferenceService?.status?.address?.url;
128
+ if (url) return url;
129
+ const name = inferenceService?.metadata?.name;
130
+ const ns = inferenceService?.metadata?.namespace || 'default';
131
+ return `http://${name}.${ns}.svc.cluster.local`;
132
+ },
133
+
134
+ /**
135
+ * Generate provider config that agents can use to call this inference service.
136
+ * @param {object} kradleResource
137
+ * @param {string} resolvedEndpoint
138
+ * @returns {object}
139
+ */
140
+ toProviderConfig(kradleResource, resolvedEndpoint) {
141
+ const spec = kradleResource?.spec || {};
142
+ const metadata = kradleResource?.metadata || {};
143
+
144
+ return {
145
+ providerType: 'kserve',
146
+ endpoint: resolvedEndpoint,
147
+ protocol: spec.inferenceProtocol || 'v2',
148
+ modelCatalog: spec.modelCatalog || [{ name: metadata.name, framework: spec.modelFormat }],
149
+ featureFlags: {
150
+ v1_protocol: spec.inferenceProtocol === 'v1',
151
+ v2_protocol: spec.inferenceProtocol !== 'v1',
152
+ streaming: spec.featureFlags?.streaming || false,
153
+ batch_inference: spec.featureFlags?.batchInference || false,
154
+ explainability: !!spec.explainer
155
+ },
156
+ rateLimits: spec.rateLimits || { inferenceRequestsPerMinute: 1000 }
157
+ };
158
+ },
159
+
160
+ /**
161
+ * Call the inference endpoint using V1 or V2 protocol.
162
+ * @param {string} endpoint
163
+ * @param {string} modelName
164
+ * @param {Array} inputs
165
+ * @param {object} options
166
+ * @returns {Promise<object>}
167
+ */
168
+ async infer(endpoint, modelName, inputs, options = {}) {
169
+ const protocol = options.protocol || 'v2';
170
+ const path = protocol === 'v2'
171
+ ? `/v2/models/${modelName}/infer`
172
+ : `/v1/models/${modelName}:predict`;
173
+
174
+ const body = protocol === 'v2'
175
+ ? { inputs: inputs.map(i => ({ name: i.name, shape: i.shape, datatype: i.datatype, data: i.data })) }
176
+ : { instances: inputs.map(i => i.data) };
177
+
178
+ const fetchImpl = options.fetchImpl || globalThis.fetch;
179
+ const res = await fetchImpl(`${endpoint}${path}`, {
180
+ method: 'POST',
181
+ headers: {
182
+ 'Content-Type': 'application/json',
183
+ ...(options.authToken ? { Authorization: `Bearer ${options.authToken}` } : {})
184
+ },
185
+ body: JSON.stringify(body)
186
+ });
187
+
188
+ if (!res.ok) throw new Error(`Inference failed: ${res.status} ${await res.text()}`);
189
+ return res.json();
190
+ },
191
+
192
+ /**
193
+ * Check if the inference endpoint is healthy.
194
+ * @param {string} endpoint
195
+ * @param {object} options
196
+ * @returns {Promise<{ healthy: boolean, status?: number, error?: string }>}
197
+ */
198
+ async checkHealth(endpoint, options = {}) {
199
+ const fetchImpl = options.fetchImpl || globalThis.fetch;
200
+ try {
201
+ const res = await fetchImpl(`${endpoint}/v2/health/ready`, { signal: AbortSignal.timeout(3000) });
202
+ return { healthy: res.ok, status: res.status };
203
+ } catch (err) {
204
+ return { healthy: false, error: err.message };
205
+ }
206
+ },
207
+
208
+ /**
209
+ * Get model metadata from the inference endpoint.
210
+ * @param {string} endpoint
211
+ * @param {string} modelName
212
+ * @param {object} options
213
+ * @returns {Promise<object|null>}
214
+ */
215
+ async getModelMetadata(endpoint, modelName, options = {}) {
216
+ const fetchImpl = options.fetchImpl || globalThis.fetch;
217
+ const res = await fetchImpl(`${endpoint}/v2/models/${modelName}`);
218
+ if (!res.ok) return null;
219
+ return res.json();
220
+ },
221
+
222
+ /**
223
+ * List available models from the inference endpoint.
224
+ * @param {string} endpoint
225
+ * @param {object} options
226
+ * @returns {Promise<string[]>}
227
+ */
228
+ async listModels(endpoint, options = {}) {
229
+ const fetchImpl = options.fetchImpl || globalThis.fetch;
230
+ try {
231
+ const res = await fetchImpl(`${endpoint}/v2/models`);
232
+ if (!res.ok) return [];
233
+ const data = await res.json();
234
+ return data.models || [];
235
+ } catch { return []; }
236
+ },
237
+
238
+ /**
239
+ * Return the list of supported model formats.
240
+ * @returns {string[]}
241
+ */
242
+ getSupportedModelFormats() {
243
+ return [...SUPPORTED_MODEL_FORMATS];
244
+ }
245
+ };
246
+ }