AI Integration Overview
ONECMS exposes a pluggable AI infrastructure under src/lib/external/ai/. Today, the main product consumer is Enhance With AI in Content Details, which uses AI to generate structured metadata and then saves through the existing content update pipeline.
Related Decisions
- ADR-011: Introduce Pluggable AI Infra
- ADR-012: Separate AI Domain and Data Access
- ADR-013: Use Stateless Generation in v1
- ADR-014: Strict Schema Validation in Domain
- ADR-015: Single Runtime Entry
Integration Boundary

Source Layout
src/
lib/external/ai/
core/
bootstrap.ts # initAI() - one-time provider registration
runtime.ts # aiRuntime.complete() and getProviderName()
errors.ts # AIError + AIErrorCode
types.ts # AIProvider contract + completion types
providers/
registry.ts # register/resolve default provider
openai/index.ts # OpenAI provider implementation
domain/content/
generate.ts # generateContent() domain entry
prompt.ts # prompt construction with creative controls
schema.ts # Zod schema validation for requested fields
types.ts # GenerateInput / GeneratedContent contracts
enhance.ts # Placeholder (not implemented)
audit/
index.ts # Audit payload builder and timing helpers
app/api/ai/content/[contentType]/[intent]/route.ts
services/content/ContentDetailService.ts
hooks/content/useContentEnhanceWithAi.ts
modules/content/details/content-tools/enhance-ai/
| File/Area |
Role |
core/bootstrap.ts |
Registers provider instances (initAI) once per runtime |
core/runtime.ts |
Thin runtime that delegates to the resolved provider |
providers/registry.ts |
Maintains provider map and default provider resolution |
providers/openai/index.ts |
Calls openai.chat.completions.create() and normalizes output |
domain/content/* |
Prompting + strict parsing/validation for content generation |
audit/index.ts |
Creates structured generation audit payloads |
| API route |
Auth + intent dispatch + audit + HTTP status mapping |
ContentDetailService.aiGenerate() |
Client-side transport to /api/ai/content/:contentType/generate |
useContentEnhanceWithAi() |
UI orchestration: generate, review selection, apply and save |
Configuration
| Config |
Location |
Usage |
OPENAI_API_KEY |
environment variable |
Passed into OpenAIProvider inside initAI() |
| API path |
Endpoints.ContentTools.Ai.Generate |
/api/ai/content/:contentType/generate |
| Proxy matcher |
src/proxy.ts |
Includes /api/ai/content/:path* for auth enforcement |
| Route auth cookies |
API route |
Requires siteId, id, and site cookies |
Invariants
- Provider SDK calls stay inside
src/lib/external/ai/ implementations.
- Domain accepts structured input and does not fetch CMS data directly.
- Generation is stateless; AI output is returned to client and not persisted by AI layer.
- Domain enforces strict JSON output validation before returning data to module code.
- Infrastructure stays minimal with one runtime entry (
aiRuntime.complete()).
Current State
generate intent is active.
enhance intent currently returns 501 ENHANCE_NOT_IMPLEMENTED.
- Audit payloads are created and logged via
console.debug as a temporary sink.
AI_OUTPUT_ACCEPTED exists as an audit event type but is not emitted in apply flow yet.
- ADRs reference
src/lib/ai; implementation currently lives in src/lib/external/ai.
Doc Index
| Page |
Covers |
| Architecture |
Layer responsibilities, provider/runtime boundary, validation, errors, audit |
| Content Generation |
End-to-end Enhance With AI flow from generate to save |