Files
sim/apps/sim/lib/copilot/api.ts
Siddharth Ganesan 0c7a8efc8d feat(copilot): add depths (#974)
* Checkpont

* can edit names and types

* Add reasoning and thinking

* Update agent max

* Max mode v1

* Add best practices

* Todo list shows up

* Todolist works

* Updates to todo

* Updates

* Updates

* Checkpoitn

* Yaml export updates

* Updates

* Checkpoint fr

* Fix diff veiw on new workflow

* Subflow autolayout fix v1

* Autolayout fixes 2

* Gdrive list files

* Get oauth credential (email)

* Gdrive file picker

* Gdrive file access prompt

* Api request

* Copilot ui for some tool calls

* Updates

* Fix overflow

* Openai

* Streaming

* Checkpoint

* Update

* Openai responses api

* Depth skeleton

* Depth tooltips

* Mode selector tool tips

* Update ui

* Update ordering

* Lint

* Remove migrations

* Add migrations back

* Lint

* Fix isdev

* Fix tests

* Comments

---------

Co-authored-by: Waleed Latif <walif6@gmail.com>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Adam Gough <77861281+aadamgough@users.noreply.github.com>
Co-authored-by: Adam Gough <adamgough@Mac.attlocal.net>
2025-08-15 11:37:58 -07:00

142 lines
3.2 KiB
TypeScript

import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotAPI')
/**
* Citation interface for documentation references
*/
export interface Citation {
id: number
title: string
url: string
similarity?: number
}
/**
* Message interface for copilot conversations
*/
export interface CopilotMessage {
id: string
role: 'user' | 'assistant' | 'system'
content: string
timestamp: string
citations?: Citation[]
}
/**
* Chat interface for copilot conversations
*/
export interface CopilotChat {
id: string
title: string | null
model: string
messages: CopilotMessage[]
messageCount: number
previewYaml: string | null
createdAt: Date
updatedAt: Date
}
/**
* File attachment interface for message requests
*/
export interface MessageFileAttachment {
id: string
s3_key: string
filename: string
media_type: string
size: number
}
/**
* Request interface for sending messages
*/
export interface SendMessageRequest {
message: string
userMessageId?: string // ID from frontend for the user message
chatId?: string
workflowId?: string
mode?: 'ask' | 'agent'
depth?: 0 | 1 | 2 | 3
createNewChat?: boolean
stream?: boolean
implicitFeedback?: string
fileAttachments?: MessageFileAttachment[]
abortSignal?: AbortSignal
}
/**
* Base API response interface
*/
export interface ApiResponse {
success: boolean
error?: string
}
/**
* Streaming response interface
*/
export interface StreamingResponse extends ApiResponse {
stream?: ReadableStream
}
/**
* Handle API errors and return user-friendly error messages
*/
async function handleApiError(response: Response, defaultMessage: string): Promise<string> {
try {
const data = await response.json()
return data.error || defaultMessage
} catch {
return `${defaultMessage} (${response.status})`
}
}
/**
* Send a streaming message to the copilot chat API
* This is the main API endpoint that handles all chat operations
*/
export async function sendStreamingMessage(
request: SendMessageRequest
): Promise<StreamingResponse> {
try {
const { abortSignal, ...requestBody } = request
const response = await fetch('/api/copilot/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...requestBody, stream: true }),
signal: abortSignal,
credentials: 'include', // Include cookies for session authentication
})
if (!response.ok) {
const errorMessage = await handleApiError(response, 'Failed to send streaming message')
throw new Error(errorMessage)
}
if (!response.body) {
throw new Error('No response body received')
}
return {
success: true,
stream: response.body,
}
} catch (error) {
// Handle AbortError gracefully - this is expected when user aborts
if (error instanceof Error && error.name === 'AbortError') {
logger.info('Streaming message was aborted by user')
return {
success: false,
error: 'Request was aborted',
}
}
logger.error('Failed to send streaming message:', error)
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
}
}
}