---
name: ai-prompt
description: |
  Integrates AI capabilities into SmartStack features.
  Use this skill when:
  - User wants to integrate AI into a feature
  - User mentions "prompt", "GPT", "Claude", "IA", "AI"
  - Creating an assistant or chatbot
  - Automatic content generation
  - AI response validation with schema
  Types: Prompt, OutputSchema, Provider, Model
---

# Skill AI Prompt SmartStack

> **Architecture:** Prompt + Blocks → Provider + Model → Completion → Schema Validation
> Multi-provider: OpenAI, Anthropic (Claude), Azure OpenAI, Google Gemini

**Reference:** [_shared.md](../_shared.md) for common patterns

## WHEN THIS SKILL ACTIVATES

| Trigger | Example |
|---------|---------|
| Explicit request | "Integrate GPT to generate descriptions" |
| Chatbot/Assistant | "Create an assistant for support" |
| Content generation | "Auto-generate responses" |
| Text analysis | "Analyze the sentiment of comments" |
| Keywords | "prompt", "GPT", "Claude", "IA", "completion", "LLM" |

## AI FLOW

```
Feature → IAiCompletionService.ExecutePromptAsync()
    ↓
Prompt + Blocks → Provider Instance → External API (OpenAI/Claude/Azure/Gemini)
    ↓
AI Response → OutputSchema Validation → Typed Result<T>
```

## MAIN ENTITIES

### AiProvider & AiModel
- **Providers:** OpenAI, Anthropic, Azure OpenAI, Google
- **Models:** gpt-4o, claude-3-opus/sonnet/haiku, gemini-pro
- Properties: Code, ContextWindow, MaxOutputTokens, InputCost, OutputCost, SupportsVision, SupportsStreaming

### AiProviderInstance
Configured instance: Code, Name, SystemContext, DefaultModel, MonthlyBudgetLimit, EncryptedApiKey

### Prompt & PromptBlock
```csharp
// Prompt: Code, Name, Version, Status, IsTemplate, OutputSchemaId, Blocks
// PromptBlockType: System, User, Assistant, Tool, Context, Examples
// Block: Label, Content, DisplayOrder, IsRequired, Condition
```

### OutputSchema
JSON Schema for validation: Code, Name, JsonSchema, DotNetType

## WORKFLOW INTEGRATION

### 1. Define the Use Case
| Question | Impact |
|----------|--------|
| Content type? | Model choice |
| Structured response? | OutputSchema |
| Multi-language? | Language variables |
| Budget limited? | ProviderInstance |
| Real-time? | Streaming |

### 2. Create the Prompt
```csharp
var promptId = await _promptService.CreatePromptAsync(new CreatePromptRequest
{
    Code = "ticket-analyzer",
    Name = "Ticket Analyzer",
    Blocks = new[] {
        new CreateBlockRequest {
            BlockType = PromptBlockType.System,
            Content = "Instructions...",
            IsRequired = true
        },
        new CreateBlockRequest {
            BlockType = PromptBlockType.User,
            Content = "Ticket: {{ticketTitle}}\nDescription: {{ticketDescription}}",
            IsRequired = true
        }
    }
});
```

### 3. Define OutputSchema (if structured response)
```csharp
var schemaId = await _schemaService.CreateAsync(new CreateSchemaRequest
{
    Code = "ticket-analysis-result",
    JsonSchema = @"{ ""type"": ""object"", ""required"": [""category"", ""priority""], ... }",
    DotNetType = "SmartStack.Application.AI.TicketAnalysisResult"
});
```

### 4. Execute the Prompt
```csharp
// Simple execution
var result = await _aiService.ExecutePromptAsync(promptId, new Dictionary<string, object>
{
    ["ticketTitle"] = ticket.Title,
    ["ticketDescription"] = ticket.Description
});

// With typed validation
var typedResult = await _aiService.ExecutePromptWithValidationAsync<TicketAnalysisResult>(
    promptId, variables);
if (typedResult.Success && typedResult.IsValid) { /* use typedResult.Data */ }
```

## AI SERVICES

### IAiCompletionService
```csharp
Task<AiCompletionResult> CompleteAsync(AiCompletionRequest request, CancellationToken ct);
Task<AiCompletionResult> ExecutePromptAsync(Guid promptId, Dictionary<string, object>? variables, ...);
Task<AiValidatedCompletionResult<T>> ExecutePromptWithValidationAsync<T>(Guid promptId, ...);
Task<AiValidatedCompletionResult<T>> ExecutePromptByCodeWithValidationAsync<T>(string promptCode, ...);
```

### IPromptService
```csharp
Task<PromptDto> GetPromptByCodeAsync(string code, string? version = null);
Task<string> RenderPromptAsync(string code, Dictionary<string, object>? variables);
Task<Guid> CreatePromptAsync(CreatePromptRequest request);
Task ActivatePromptAsync(Guid promptId);
// Block management: AddBlockToPromptAsync, UpdateBlockAsync, ReorderBlocksAsync
```

## FRONTEND INTEGRATION

### API
```typescript
aiApi.getPrompts(status?, isTemplate?)
aiApi.executePrompt(promptId, variables)
aiApi.previewPrompt(promptId, variables)
aiApi.getProviders() / aiApi.getModels(providerId?)
aiApi.getSchemas() / aiApi.createSchema(data)
```

### Hook useAiCompletion
```typescript
const { execute, loading, error, result } = useAiCompletion<T>(promptCode);
const data = await execute(variables);
```

### Component AiAssistantButton
```tsx
<AiAssistantButton
  promptCode="ticket-analyzer"
  variables={{ ticketTitle, ticketDescription }}
  onResult={(result) => handleAnalysis(result)}
  label="Analyze with AI"
/>
```

## ADVANCED PATTERNS

### Streaming Response
```typescript
const reader = response.body?.getReader();
while (true) { const { done, value } = await reader.read(); if (done) break; /* append chunk */ }
```

### Fallback Provider
```csharp
foreach (var provider in providers.OrderBy(p => p.Priority)) {
    var result = await _aiService.ExecutePromptAsync(promptId, variables, providerId: provider.Id);
    if (result.Success) return result;
}
```

## CHECKLIST

```
□ Prompt created (unique Code, Blocks, Variables, Version)
□ OutputSchema if structured response
□ Service with IAiCompletionService injected
□ Error handling + Logging (tokens, time)
□ Frontend: Hook/component, Loading, Error handling
□ ProviderInstance with budget limit
□ Tests: execution, variables, schema validation
```

## ABSOLUTE RULES

| DO | DON'T |
|----|-------|
| IAiCompletionService for executions | Direct API calls |
| OutputSchema for structured responses | Unvalidated responses |
| Error handling (API down, quota) | Ignore token limits |
| Log executions (tokens, duration) | Hardcode API keys |
| Variables for dynamic content | Expose system prompts to frontend |

## KEY FILES

| File | Role |
|------|------|
| `Domain/AI/Prompts/Prompt.cs` | Prompt entity |
| `Domain/AI/Schemas/OutputSchema.cs` | Schema validation |
| `Domain/AI/AiProviderInstance.cs` | Configured instance |
| `Application/Common/Interfaces/IAiCompletionService.cs` | Service interface |
| `Infrastructure/Services/AI/AiCompletionService.cs` | Implementation |
| `web/src/services/api/aiApi.ts` | Frontend API |
