refactor: rename swift → cortex in code and documentation

Complete rename of "swift" terminology to "cortex" across the codebase:

Code Changes:
- Rename directories: lib/swift → lib/cortex, components/swift → components/cortex
- Rename API routes: /api/swift/* → /api/cortex/*
- Rename page routes: /epd/swift → /epd/cortex
- Rename store: swift-store.ts → cortex-store.ts

Type Renames:
- SwiftIntent → CortexIntent
- SwiftStore → CortexStore
- useSwiftStore → useCortexStore
- SwiftContext → CortexContext
- useSwiftVoice → useCortexVoice

Documentation Updates (docs/intent/):
- Safety Net → Nudge (Layer 3 rename)
- SafetySuggestion → NudgeSuggestion
- evaluateSafetyNet → evaluateNudge
- SWIFT_* feature flags → CORTEX_*
- All path references updated to match new structure

Files affected: 47 files, ~700 lines changed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
colinislit
2025-12-30 09:18:06 +01:00
parent c8aaba657e
commit 2170b23348
62 changed files with 364 additions and 355 deletions

View File

@@ -1,14 +1,14 @@
/**
* Action Parser for Swift Assistent
* Action Parser for Cortex Assistent
*
* Parses JSON action objects from AI responses and validates them.
*
* Epic: E3 (Chat API & Swift Assistent)
* Epic: E3 (Chat API & Cortex Assistent)
* Story: E3.S4 (Intent detection in response)
*/
import { z } from 'zod';
import type { ChatAction, SwiftIntent, BlockType } from '@/stores/swift-store';
import type { ChatAction, CortexIntent, BlockType } from '@/stores/cortex-store';
// Validation schema for action objects
const ActionSchema = z.object({
@@ -156,10 +156,19 @@ export function parseActionFromResponse(responseText: string): ParsedActionResul
};
}
// Normalize entities - convert complex identifier to string
const normalizedEntities = {
...validation.data.entities,
// Convert object identifier to string if needed
identifier: typeof validation.data.entities.identifier === 'object'
? validation.data.entities.identifier.encounterId || JSON.stringify(validation.data.entities.identifier)
: validation.data.entities.identifier,
};
// Valid action found
const action: ChatAction = {
intent: validation.data.intent,
entities: validation.data.entities,
entities: normalizedEntities,
confidence: validation.data.confidence,
artifact: validation.data.artifact,
};
@@ -191,7 +200,7 @@ export function getConfidenceLabel(confidence: number): string {
/**
* Validate that artifact type matches intent
*/
export function validateArtifactType(intent: SwiftIntent, artifactType?: BlockType): boolean {
export function validateArtifactType(intent: CortexIntent, artifactType?: BlockType): boolean {
if (!artifactType) return true; // No artifact is valid
if (artifactType === 'patient-dashboard') return true;
@@ -199,14 +208,14 @@ export function validateArtifactType(intent: SwiftIntent, artifactType?: BlockTy
if (intent === 'unknown') return artifactType === 'fallback';
// For agenda intents, all map to agenda block types
const agendaIntents: SwiftIntent[] = [
const agendaIntents: CortexIntent[] = [
'agenda_query',
'create_appointment',
'cancel_appointment',
'reschedule_appointment',
];
if (agendaIntents.includes(intent)) {
return agendaIntents.includes(artifactType as SwiftIntent);
return agendaIntents.includes(artifactType as CortexIntent);
}
return intent === artifactType;
@@ -224,7 +233,7 @@ export function validateArtifactType(intent: SwiftIntent, artifactType?: BlockTy
* @returns Artifact configuration or null if confidence too low or required data missing
*/
export function routeIntentToArtifact(
intent: SwiftIntent,
intent: CortexIntent,
entities: Record<string, any>,
confidence: number
): { type: BlockType; prefill: Record<string, any>; title: string } | null {

View File

@@ -1,13 +1,13 @@
/**
* Swift Chat API Client
* Cortex Chat API Client
*
* Client-side helper voor het aanroepen van de Swift chat API met streaming support.
* Client-side helper voor het aanroepen van de Cortex chat API met streaming support.
*
* Epic: E3 (Chat API & Swift Assistent)
* Epic: E3 (Chat API & Cortex Assistent)
* Story: E3.S1 (Chat API endpoint skeleton)
*/
import type { ChatMessage } from '@/stores/swift-store';
import type { ChatMessage } from '@/stores/cortex-store';
export interface ChatContext {
activePatient?: {
@@ -36,7 +36,7 @@ export async function sendChatMessage(
onError?: (error: string) => void
): Promise<void> {
try {
const response = await fetch('/api/swift/chat', {
const response = await fetch('/api/cortex/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',

View File

@@ -2,7 +2,7 @@
* Date/Time Parser Utilities
*
* Parses natural language date and time expressions (Dutch)
* for Swift agenda functionality.
* for Cortex agenda functionality.
*/
import {

View File

@@ -5,7 +5,7 @@
*/
import type { VerpleegkundigCategory } from '@/lib/types/report';
import type { ExtractedEntities, SwiftIntent } from './types';
import type { ExtractedEntities, CortexIntent } from './types';
import {
parseRelativeDate,
parseTime,
@@ -90,7 +90,7 @@ const COMMON_NAMES = new Set([
/**
* Extract entities from user input based on the detected intent.
*/
export function extractEntities(input: string, intent: SwiftIntent): ExtractedEntities {
export function extractEntities(input: string, intent: CortexIntent): ExtractedEntities {
const trimmedInput = input.trim().toLowerCase();
const entities: ExtractedEntities = {};

View File

@@ -1,6 +1,6 @@
/**
* Error Handler Utility voor Swift
*
* Error Handler Utility voor Cortex
*
* E5.S2: Gecentraliseerde error handling met network detection,
* gebruiksvriendelijke berichten en retry logic.
*/

View File

@@ -1,9 +1,9 @@
/**
* Swift Library Barrel Export
* Cortex Library Barrel Export
*/
export * from './types';
export * from './use-swift-voice';
export * from './use-cortex-voice';
export * from './intent-classifier';
export * from './intent-classifier-ai';
export * from './entity-extractor';

View File

@@ -6,7 +6,7 @@
*/
import { z } from 'zod';
import type { SwiftIntent, ExtractedEntities } from './types';
import type { CortexIntent, ExtractedEntities } from './types';
import type { VerpleegkundigCategory } from '@/lib/types/report';
// Zod schema for AI response validation
@@ -37,7 +37,7 @@ const AIIntentResponseSchema = z.object({
type AIIntentResponse = z.infer<typeof AIIntentResponseSchema>;
export interface AIClassificationResult {
intent: SwiftIntent;
intent: CortexIntent;
confidence: number;
entities: ExtractedEntities;
source: 'ai';
@@ -45,7 +45,7 @@ export interface AIClassificationResult {
reasoning?: string;
}
const INTENT_CLASSIFIER_SYSTEM_PROMPT = `Je bent een intent classifier voor een Nederlands EPD (Elektronisch Patiënten Dossier) systeem genaamd Swift.
const INTENT_CLASSIFIER_SYSTEM_PROMPT = `Je bent een intent classifier voor een Nederlands EPD (Elektronisch Patiënten Dossier) systeem genaamd Cortex.
Je taak is om de intentie van een zorgmedewerker te classificeren in één van deze categorieën:
@@ -199,7 +199,7 @@ export async function classifyIntentWithAI(input: string): Promise<AIClassificat
// and the local extractor will structure them properly
return {
intent: validated.intent as SwiftIntent,
intent: validated.intent as CortexIntent,
confidence: validated.confidence,
entities,
source: 'ai',

View File

@@ -1,14 +1,14 @@
/**
* Local Intent Classifier
*
* Fast regex-based intent classification for Swift.
* Fast regex-based intent classification for Cortex.
* Target: <50ms response time.
*/
import type { SwiftIntent } from './types';
import type { CortexIntent } from './types';
export interface ClassificationResult {
intent: SwiftIntent;
intent: CortexIntent;
confidence: number;
matchedPattern?: string;
processingTimeMs: number;
@@ -21,7 +21,7 @@ interface PatternConfig {
// Intent patterns with weights
// Weight 1.0 = exact match, 0.8 = strong match, 0.6 = partial match
const INTENT_PATTERNS: Record<Exclude<SwiftIntent, 'unknown'>, PatternConfig[]> = {
const INTENT_PATTERNS: Record<Exclude<CortexIntent, 'unknown'>, PatternConfig[]> = {
dagnotitie: [
// Exact commands
{ pattern: /^dagnotitie\b/i, weight: 1.0 },
@@ -159,7 +159,7 @@ const HELP_PATTERNS: PatternConfig[] = [
{ pattern: /^help\b/i, weight: 1.0 },
{ pattern: /^hulp\b/i, weight: 1.0 },
{ pattern: /^\?\s*$/i, weight: 1.0 },
{ pattern: /^wat\s+kan\s+(ik|je|swift)\b/i, weight: 1.0 },
{ pattern: /^wat\s+kan\s+(ik|je|cortex)\b/i, weight: 1.0 },
{ pattern: /^hoe\s+werkt\b/i, weight: 0.9 },
{ pattern: /^voorbeelden?\b/i, weight: 0.9 },
];
@@ -194,14 +194,14 @@ export function classifyIntent(input: string): ClassificationResult {
}
// Find best matching intent
let bestMatch: { intent: SwiftIntent; confidence: number; pattern: string } | null = null;
let bestMatch: { intent: CortexIntent; confidence: number; pattern: string } | null = null;
for (const [intent, patterns] of Object.entries(INTENT_PATTERNS)) {
for (const { pattern, weight } of patterns) {
if (pattern.test(trimmedInput)) {
if (!bestMatch || weight > bestMatch.confidence) {
bestMatch = {
intent: intent as SwiftIntent,
intent: intent as CortexIntent,
confidence: weight,
pattern: pattern.toString(),
};

View File

@@ -1,13 +1,13 @@
/**
* Swift Type Definitions
* Cortex Type Definitions
*
* Core types for the Swift Contextual UI system.
* Core types for the Cortex Contextual UI system.
*/
import type { VerpleegkundigCategory } from '@/lib/types/report';
// Intent types
export type SwiftIntent =
export type CortexIntent =
| 'dagnotitie'
| 'zoeken'
| 'overdracht'
@@ -17,14 +17,14 @@ export type SwiftIntent =
| 'reschedule_appointment'
| 'unknown';
export type BlockType = Exclude<SwiftIntent, 'unknown'> | 'patient-dashboard';
export type BlockType = Exclude<CortexIntent, 'unknown'> | 'patient-dashboard';
// Shift types
export type ShiftType = 'nacht' | 'ochtend' | 'middag' | 'avond';
// Intent classification result
export interface IntentClassificationResult {
intent: SwiftIntent;
intent: CortexIntent;
confidence: number;
entities: ExtractedEntities;
source: 'local' | 'ai';
@@ -140,7 +140,7 @@ export const BLOCK_CONFIGS: Record<BlockType, BlockConfig> = {
// Recent action type
export interface RecentAction {
id: string;
intent: SwiftIntent;
intent: CortexIntent;
label: string;
timestamp: Date;
patientName?: string;

View File

@@ -1,20 +1,20 @@
'use client';
/**
* Swift Voice Hook
* Cortex Voice Hook
*
* Wraps useDeepgramStreaming for Swift-specific voice input behavior.
* Wraps useDeepgramStreaming for Cortex-specific voice input behavior.
* Streams transcript directly to the command input.
*/
import { useCallback, useEffect, useRef } from 'react';
import { useSwiftStore } from '@/stores/swift-store';
import { useCortexStore } from '@/stores/cortex-store';
import {
useDeepgramStreaming,
type TranscriptResult,
} from '@/hooks/use-deepgram-streaming';
export interface UseSwiftVoiceReturn {
export interface UseCortexVoiceReturn {
isRecording: boolean;
isConnecting: boolean;
isConnected: boolean;
@@ -25,8 +25,8 @@ export interface UseSwiftVoiceReturn {
isBrowserSupported: boolean;
}
export function useSwiftVoice(): UseSwiftVoiceReturn {
const { setInputValue, setVoiceActive, inputValue } = useSwiftStore();
export function useCortexVoice(): UseCortexVoiceReturn {
const { setInputValue, setVoiceActive, inputValue } = useCortexStore();
// Track the base text (what was in input before recording started)
const baseTextRef = useRef('');
@@ -59,7 +59,7 @@ export function useSwiftVoice(): UseSwiftVoiceReturn {
const handleError = useCallback(
(error: Error) => {
console.error('[SwiftVoice] Error:', error.message);
console.error('[CortexVoice] Error:', error.message);
},
[]
);

View File

@@ -1,6 +1,6 @@
/**
* Manual verification script for entity extraction with date/time parser
* Run with: pnpm tsx lib/swift/verify-entity-extraction.ts
* Run with: pnpm tsx lib/cortex/verify-entity-extraction.ts
*/
import { extractEntities } from './entity-extractor';

View File

@@ -1,6 +1,6 @@
/**
* Manual verification script for date-time parser
* Run with: pnpm tsx lib/swift/verify-parser.ts
* Run with: pnpm tsx lib/cortex/verify-parser.ts
*/
import {