Commit Graph

5 Commits

Author SHA1 Message Date
Félix Malfait a281f2a773 feat: add configurable response format for AI agents (text/JSON) (#15953)
## Summary
This PR adds configurable response format support for AI agents,
allowing them to return either plain text or structured JSON data based
on a defined schema.

## Key Features

### 1. Agent Response Format Configuration
- Added `AgentResponseFormat` type supporting:
  - `text`: Returns plain text responses (default)
  - `json`: Returns structured JSON based on defined schema
- New `AgentResponseSchema` type moved to `twenty-shared/ai` for sharing
between frontend/backend

### 2. Settings UI
- New `SettingsAgentResponseFormat` component for configuring response
format
- Visual schema builder for defining JSON output structure
- Real-time validation and preview
- Integrated into agent settings tab

### 3. Workflow Integration
- AI Agent workflow action automatically uses agent's configured
response format
- Output schema dynamically generated from agent's response format
- Workflow variable picker shows structured fields for JSON responses
- Backward compatible with existing text-only agents

### 4. Backend Implementation
- Added `convertAgentSchemaToZod` utility to validate JSON responses
- Agent executor service handles both text and JSON generation
- Automatic agent creation/cloning when adding AI agent steps to
workflows
- Unique agent naming with conflict resolution

### 5. Database Migration
- Migration `1763622159656-update-agent-response-format.ts` 
- Sets default `responseFormat` to `{"type":"text"}` for existing agents
- Updated all standard agents with proper response format

## Changes by Module

### Frontend (`twenty-front`)
- 🆕 `AgentResponseFormat` type
- 🆕 `SettingsAgentResponseFormat` component
- ✏️ Updated `WorkflowEditActionAiAgent` to support response format
configuration
- 🗑️ Removed deprecated `useAiAgentOutputSchema` hook and
`AiAgentOutputSchema` type

### Backend (`twenty-server`)
- 🆕 `AgentResponseFormat` type in agent entity
- 🆕 `convertAgentSchemaToZod` utility for schema validation
- ✏️ Updated `AiAgentExecutorService` to handle both text and JSON
generation
- ✏️ Updated `WorkflowSchemaWorkspaceService` to generate output schema
from agent config
- ✏️ Enhanced `WorkflowVersionStepOperationsWorkspaceService` with agent
creation/cloning
- 🆕 Agent naming constants for conflict resolution

### Shared (`twenty-shared`)
- 🆕 `AgentResponseSchema` type
- 🆕 `ModelConfiguration` type moved to shared package
- Updated exports in `ai/index.ts`

## Code Quality
- Removed useless comments following code style guidelines
- All linter checks passed
- Type-safe implementation with proper TypeScript types

## Testing
-  Database migration tested
-  Agent creation/cloning in workflows verified
-  Response format switching (text ↔ JSON) validated
-  Backward compatibility with existing agents confirmed

## Migration Notes
- Existing agents will have `responseFormat: {type: 'text'}` set
automatically
- No breaking changes - all existing functionality preserved
- Agents can be updated to use JSON format through settings UI
2025-11-20 18:32:44 +01:00
Félix Malfait f9c61833ec Add debug info in AI chat (#15758)
## 🐛 Critical Bug Fix

### Cost Calculation Error (1000x undercharge)
- **Fixed**: Cost conversion utility was calculating credits at 1/1000th
of actual value
- **Before**: `cents * 10` 
- **After**: `(cents / 100) * DOLLAR_TO_CREDIT_MULTIPLIER` 
- **Impact**: Users were being undercharged by 1000x
  - Example: 0.75 cents should = 7,500 credits
  - Bug calculated it as 7.5 credits

---

## 🎯 Code Centralization & DRY

### Unified Cost Calculation
- Centralized all cost conversions to use `convertCentsToBillingCredits`
utility
- Refactored 3 different implementations into 1 single source of truth
- Files updated:
  - `ai-billing.service.ts`
  - `agent-streaming.service.ts` (2 usages)

**Before** (multiple implementations):
```typescript
// Wrong implementation
const credits = cents * 10;

// Verbose implementation  
const costInDollars = costInCents / 100;
const creditsUsed = Math.round(costInDollars * DOLLAR_TO_CREDIT_MULTIPLIER);
```

**After** (unified):
```typescript
const creditsUsed = Math.round(convertCentsToBillingCredits(costInCents));
```

---

##  UI Component Refactoring

### RoutingDebugDisplay.tsx
- **Reduced from 118 lines to 34 lines** (71% reduction)
- Extracted `renderTimingRow` helper to eliminate 15 repetitive JSX
blocks
- Added `formatTokenBreakdown` helper for token display logic
- Much easier to add new debug metrics

**Before**: 15 nearly-identical blocks of repetitive JSX  
**After**: Clean, DRY implementation with reusable helpers

---

## 🧹 Code Quality Improvements

### Removed Debug Code
- Removed `console.log` accidentally left in `RoutingStatusDisplay.tsx`

### Cleaned Up Comments (18+ removed)
Removed redundant comments that stated the obvious:
-  "Calculate routing cost if we have token usage"
-  "Send the updated routing status with execution metrics to the
client"
-  "Count tool calls in the response"
-  "AI SDK's LanguageModelUsage uses inputTokens/outputTokens"
- And 14+ more...

Kept meaningful comments:
-  "Timing is optional, ignore errors" (explains catch block)
-  Type definition grouping comments

---

## 📊 Statistics

**Files Modified**: 10
- `convert-cents-to-billing-credits.util.ts` (fixed formula)
- `ai-billing.service.ts` (use centralized utility)
- `agent-streaming.service.ts` (use utility, remove comments)
- `agent-execution.service.ts` (remove comments)
- `ai-router.service.ts` (remove comments)
- `RoutingStatusDisplay.tsx` (remove debug code)
- `RoutingDebugDisplay.tsx` (major refactor) 
- `isDebugModeState.ts` (new file)
- `DataMessagePart.ts` (type extensions)
- `useClientConfig.ts` (debug mode support)

**Impact**:
- Lines removed: ~130 (redundant code + comments)
- Lines added: ~45 (helper functions)
- **Net reduction**: ~85 lines
- **Bug fixes**: 1 critical (1000x cost error)
- **Centralizations**: 3 locations now using shared utility
- **Major refactors**: 1 UI component (71% reduction)

---

##  Verification

-  All linter checks pass
-  All tests pass (`ai-billing.service.spec.ts` verified)
-  No `any` types in affected code
-  No TODO/FIXME markers

---

## 🎯 Principles Applied

1.  **Fix Root Causes, Not Symptoms** - Fixed utility function, then
used it everywhere
2.  **DRY (Don't Repeat Yourself)** - Centralized cost calculation and
UI rendering
3.  **Single Source of Truth** - One place for cost conversion formula
4.  **Code as Documentation** - Removed comments that repeated what
code says
5.  **Composability** - Created reusable helper functions
6.  **Type Safety** - Maintained strict typing throughout
2025-11-13 13:34:46 +01:00
Abdul Rahman 32558673c6 feat: Implement AI Router for Dynamic Agent Selection (#15227)
Adds intelligent routing system that automatically selects the best
agent for user queries based on conversation context.

### Changes:
- Added `routerModel` column to workspace table for configurable router
LLM selection
- Implemented `RouterService` with conversation history analysis and
agent matching logic
- Created router settings UI in AI Settings page with model dropdown
- Removed agent-specific thread associations - threads are now
agent-agnostic
- Added real-time routing status notification in chat UI with shimmer
effect
- Removed automatic default assistant agent creation
- Renamed GraphQL operations from agent-specific to generic (e.g.,
`agentChatThreads` → `chatThreads`)

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-22 15:02:41 +02:00
Abdul Rahman 2685f4a5b9 Restructure agent chat messages with parts-based architecture (#14749)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-29 13:31:55 +02:00
Abdul Rahman 216d72b5d7 AI SDK v5 migration (#14549)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-22 22:13:43 +02:00