feat(ai): add ADR-036 unified OCR architecture and frontend test coverage
- Add ADR-036 unified OCR architecture (typhoon-ocr via Ollama) - Extend AI execution profiles for OCR sandbox configuration - Add comprehensive frontend test coverage (components, hooks, services) - Add backend test coverage for document-numbering services - Update OCR sidecar with typhoon-ocr integration - Add AI policy service and execution profile management - Update AGENTS.md and architecture documentation
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
# Backend API Contracts for Unified AI Model Architecture
|
||||
# OpenAPI 3.0 specification for new endpoints
|
||||
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: LCBP3 AI Parameter Management API
|
||||
version: 1.0.0
|
||||
description: API endpoints for sandbox parameter testing and production parameter application
|
||||
|
||||
paths:
|
||||
/api/ai/sandbox-profiles/{profileName}:
|
||||
get:
|
||||
summary: Get sandbox parameters for a profile
|
||||
tags:
|
||||
- Sandbox Parameters
|
||||
parameters:
|
||||
- name: profileName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [interactive, standard, quality, deep-analysis, ocr-extract]
|
||||
responses:
|
||||
'200':
|
||||
description: Sandbox parameters retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SandboxProfile'
|
||||
'404':
|
||||
description: Profile not found
|
||||
put:
|
||||
summary: Save sandbox parameters for a profile
|
||||
tags:
|
||||
- Sandbox Parameters
|
||||
parameters:
|
||||
- name: profileName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [interactive, standard, quality, deep-analysis, ocr-extract]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SandboxProfileUpdate'
|
||||
responses:
|
||||
'200':
|
||||
description: Sandbox parameters saved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SandboxProfile'
|
||||
'400':
|
||||
description: Validation error
|
||||
post:
|
||||
summary: Reset sandbox parameters to production defaults
|
||||
tags:
|
||||
- Sandbox Parameters
|
||||
parameters:
|
||||
- name: profileName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [interactive, standard, quality, deep-analysis, ocr-extract]
|
||||
responses:
|
||||
'200':
|
||||
description: Sandbox parameters reset successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SandboxProfile'
|
||||
|
||||
/api/ai/profiles/{profileName}:
|
||||
get:
|
||||
summary: Get production parameters for a profile (read-only)
|
||||
tags:
|
||||
- Production Parameters
|
||||
parameters:
|
||||
- name: profileName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [interactive, standard, quality, deep-analysis, ocr-extract]
|
||||
responses:
|
||||
'200':
|
||||
description: Production parameters retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ProductionProfile'
|
||||
'404':
|
||||
description: Profile not found
|
||||
post:
|
||||
summary: Apply sandbox parameters to production
|
||||
tags:
|
||||
- Production Parameters
|
||||
parameters:
|
||||
- name: profileName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [interactive, standard, quality, deep-analysis, ocr-extract]
|
||||
- name: Idempotency-Key
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApplyProfileRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Parameters applied successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApplyProfileResult'
|
||||
'400':
|
||||
description: Validation error (parameter ranges, etc.)
|
||||
'403':
|
||||
description: Permission denied (CASL)
|
||||
'409':
|
||||
description: Duplicate apply (Idempotency-Key already used)
|
||||
|
||||
components:
|
||||
schemas:
|
||||
SandboxProfile:
|
||||
type: object
|
||||
properties:
|
||||
profileName:
|
||||
type: string
|
||||
canonicalModel:
|
||||
type: string
|
||||
enum: [np-dms-ai, np-dms-ocr]
|
||||
temperature:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
topP:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
repeatPenalty:
|
||||
type: number
|
||||
minimum: 0
|
||||
numCtx:
|
||||
type: integer
|
||||
nullable: true
|
||||
maxTokens:
|
||||
type: integer
|
||||
nullable: true
|
||||
keepAliveSeconds:
|
||||
type: integer
|
||||
nullable: true
|
||||
|
||||
SandboxProfileUpdate:
|
||||
type: object
|
||||
properties:
|
||||
temperature:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
topP:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
repeatPenalty:
|
||||
type: number
|
||||
minimum: 0
|
||||
numCtx:
|
||||
type: integer
|
||||
nullable: true
|
||||
maxTokens:
|
||||
type: integer
|
||||
nullable: true
|
||||
keepAliveSeconds:
|
||||
type: integer
|
||||
nullable: true
|
||||
|
||||
ProductionProfile:
|
||||
type: object
|
||||
properties:
|
||||
profileName:
|
||||
type: string
|
||||
canonicalModel:
|
||||
type: string
|
||||
enum: [np-dms-ai, np-dms-ocr]
|
||||
temperature:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
topP:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
repeatPenalty:
|
||||
type: number
|
||||
minimum: 0
|
||||
numCtx:
|
||||
type: integer
|
||||
nullable: true
|
||||
maxTokens:
|
||||
type: integer
|
||||
nullable: true
|
||||
keepAliveSeconds:
|
||||
type: integer
|
||||
nullable: true
|
||||
isActive:
|
||||
type: boolean
|
||||
|
||||
ApplyProfileRequest:
|
||||
type: object
|
||||
properties:
|
||||
canonicalModel:
|
||||
type: string
|
||||
enum: [np-dms-ai, np-dms-ocr]
|
||||
|
||||
ApplyProfileResult:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
profileName:
|
||||
type: string
|
||||
oldValues:
|
||||
type: object
|
||||
newValues:
|
||||
type: object
|
||||
appliedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
@@ -0,0 +1,93 @@
|
||||
# Frontend API Service Contracts for Unified AI Model Architecture
|
||||
# TypeScript interface definitions for frontend API calls
|
||||
|
||||
# Sandbox Parameters Service
|
||||
getSandboxParameters:
|
||||
function: getSandboxParameters(profileName: string)
|
||||
returns: Promise<SandboxProfile>
|
||||
endpoint: GET /api/ai/sandbox-profiles/:profileName
|
||||
description: Retrieve sandbox parameters for a specific profile
|
||||
|
||||
saveSandboxDraft:
|
||||
function: saveSandboxDraft(profileName: string, params: SandboxProfileUpdate)
|
||||
returns: Promise<SandboxProfile>
|
||||
endpoint: PUT /api/ai/sandbox-profiles/:profileName
|
||||
description: Save sandbox parameters for a specific profile
|
||||
|
||||
resetSandboxToProduction:
|
||||
function: resetSandboxToProduction(profileName: string)
|
||||
returns: Promise<SandboxProfile>
|
||||
endpoint: POST /api/ai/sandbox-profiles/:profileName/reset
|
||||
description: Reset sandbox parameters to production defaults
|
||||
|
||||
# Production Parameters Service
|
||||
getProductionDefaults:
|
||||
function: getProductionDefaults(profileName: string)
|
||||
returns: Promise<ProductionProfile>
|
||||
endpoint: GET /api/ai/profiles/:profileName
|
||||
description: Retrieve production parameters (read-only)
|
||||
|
||||
applyProfile:
|
||||
function: applyProfile(profileName: string, idempotencyKey: string, canonicalModel?: string)
|
||||
returns: Promise<ApplyProfileResult>
|
||||
endpoint: POST /api/ai/profiles/:profileName/apply
|
||||
headers:
|
||||
Idempotency-Key: string
|
||||
description: Apply sandbox parameters to production
|
||||
|
||||
# TypeScript Interfaces
|
||||
interface SandboxProfile {
|
||||
profileName: string
|
||||
canonicalModel: 'np-dms-ai' | 'np-dms-ocr'
|
||||
temperature: number
|
||||
topP: number
|
||||
repeatPenalty: number
|
||||
numCtx?: number | null
|
||||
maxTokens?: number | null
|
||||
keepAliveSeconds?: number | null
|
||||
}
|
||||
|
||||
interface SandboxProfileUpdate {
|
||||
temperature: number
|
||||
topP: number
|
||||
repeatPenalty: number
|
||||
numCtx?: number | null
|
||||
maxTokens?: number | null
|
||||
keepAliveSeconds?: number | null
|
||||
}
|
||||
|
||||
interface ProductionProfile {
|
||||
profileName: string
|
||||
canonicalModel: 'np-dms-ai' | 'np-dms-ocr'
|
||||
temperature: number
|
||||
topP: number
|
||||
repeatPenalty: number
|
||||
numCtx?: number | null
|
||||
maxTokens?: number | null
|
||||
keepAliveSeconds?: number | null
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
interface ApplyProfileRequest {
|
||||
canonicalModel?: 'np-dms-ai' | 'np-dms-ocr'
|
||||
}
|
||||
|
||||
interface ApplyProfileResult {
|
||||
success: boolean
|
||||
profileName: string
|
||||
oldValues: Record<string, unknown>
|
||||
newValues: Record<string, unknown>
|
||||
appliedAt: string
|
||||
}
|
||||
|
||||
# Sandbox Test Parameters (for context parity)
|
||||
interface SandboxTestContext {
|
||||
projectPublicId: string
|
||||
contractPublicId?: string
|
||||
}
|
||||
|
||||
# Model Selection
|
||||
type ModelType = 'np-dms-ai' | 'np-dms-ocr'
|
||||
|
||||
# Profile Names
|
||||
type ProfileName = 'interactive' | 'standard' | 'quality' | 'deep-analysis' | 'ocr-extract'
|
||||
Reference in New Issue
Block a user