feat: redesign agents page (architectural-grid style), add image description, fix AI limits, remove dead code
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 53s
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 53s
- Redesign agents page with architectural-grid (8) design system: rounded-2xl cards, serif headings, motion tabs, dashed templates section - Replace agent form popup with full-page detail view (SettingsView style) with dark planning card, section tooltips, and help button - Hide advanced mode for slide/excalidraw generators - Add 'describe images' action to contextual AI assistant - Add copy button to action/resource preview with HTTP fallback - Add delete history button to agent run log panel - Increase AI word limit from 2000 to 5000 (reformulate + transform-markdown) - Increase max steps slider from 25 to 50 - Fix image description error with clear model compatibility message - Fix doubled execution count display in agent detail view - Remove dead files: notes-list-view.tsx, notes-view-toggle.tsx - Remove 'list' view mode from NotesViewMode type - Add missing i18n keys (back, configuration, options, copy, cleared)
This commit is contained in:
@@ -75,10 +75,18 @@ export async function describeImages(
|
||||
}
|
||||
const langName = langMap[language] || 'English'
|
||||
|
||||
// Resolve all images as base64 data URLs — skip any that can't be found
|
||||
const resolved = await Promise.all(imageUrls.map(url => resolveImageAsBase64(url)))
|
||||
const imageDataUrls = resolved.filter((d): d is string => d !== null)
|
||||
|
||||
if (imageDataUrls.length === 0) {
|
||||
throw new Error('Could not load any of the provided images. Please check the image URLs.')
|
||||
}
|
||||
|
||||
const buildImageContent = (dataUrl: string) => ({
|
||||
type: 'image' as const,
|
||||
image: dataUrl,
|
||||
})
|
||||
|
||||
if (isTitleMode) {
|
||||
const prompt = imageUrls.length === 1
|
||||
? `Look carefully at this image and identify every concrete detail you can see: objects, people, animals, text, logos, colors, location/setting, actions, weather, time of day, style (photo/illustration/diagram), and any notable elements.
|
||||
@@ -100,13 +108,22 @@ Respond ONLY with a JSON array: [{"title": "title1", "confidence": 0.95}, {"titl
|
||||
|
||||
const content: any[] = [{ type: 'text', text: prompt }]
|
||||
for (const dataUrl of imageDataUrls) {
|
||||
content.push({ type: 'image', image: dataUrl })
|
||||
content.push(buildImageContent(dataUrl))
|
||||
}
|
||||
|
||||
const { text } = await generateText({
|
||||
model,
|
||||
messages: [{ role: 'user', content }],
|
||||
})
|
||||
let text: string
|
||||
try {
|
||||
const result = await generateText({
|
||||
model,
|
||||
messages: [{ role: 'user', content }],
|
||||
})
|
||||
text = result.text
|
||||
} catch (e: any) {
|
||||
if (e.message?.includes('image_url') || e.message?.includes('image') || e.message?.includes('vision') || e.message?.includes('multimodal')) {
|
||||
throw new Error('Your AI model does not support image analysis. Please switch to a vision-capable model (e.g., gpt-4o, claude-3.5-sonnet, gemini-2.0-flash).')
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
// Parse JSON response
|
||||
const jsonMatch = text.match(/\[[\s\S]*\]/)
|
||||
@@ -128,13 +145,22 @@ Respond ONLY with a JSON array: [{"title": "title1", "confidence": 0.95}, {"titl
|
||||
if (imageUrls.length === 1) {
|
||||
const content: any[] = [
|
||||
{ type: 'text', text: `Describe this image in detail in ${langName}. Be specific about what you see: objects, people, colors, setting, mood, text visible. Keep it under 100 words.` },
|
||||
{ type: 'image', image: imageDataUrls[0] },
|
||||
buildImageContent(imageDataUrls[0]),
|
||||
]
|
||||
|
||||
const { text } = await generateText({
|
||||
model,
|
||||
messages: [{ role: 'user', content }],
|
||||
})
|
||||
let text: string
|
||||
try {
|
||||
const result = await generateText({
|
||||
model,
|
||||
messages: [{ role: 'user', content }],
|
||||
})
|
||||
text = result.text
|
||||
} catch (e: any) {
|
||||
if (e.message?.includes('image_url') || e.message?.includes('image') || e.message?.includes('vision') || e.message?.includes('multimodal')) {
|
||||
throw new Error('Your AI model does not support image analysis. Please switch to a vision-capable model (e.g., gpt-4o, claude-3.5-sonnet, gemini-2.0-flash).')
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
return {
|
||||
descriptions: [{ index: 0, description: text.trim() }],
|
||||
@@ -147,13 +173,22 @@ Respond ONLY with a JSON array: [{"title": "title1", "confidence": 0.95}, {"titl
|
||||
for (let i = 0; i < imageDataUrls.length; i++) {
|
||||
const content: any[] = [
|
||||
{ type: 'text', text: `Describe this image (image ${i + 1} of ${imageDataUrls.length}) in ${langName}. Be specific: objects, people, colors, setting, text visible. Under 80 words.` },
|
||||
{ type: 'image', image: imageDataUrls[i] },
|
||||
buildImageContent(imageDataUrls[i]),
|
||||
]
|
||||
|
||||
const { text } = await generateText({
|
||||
model,
|
||||
messages: [{ role: 'user', content }],
|
||||
})
|
||||
let text: string
|
||||
try {
|
||||
const result = await generateText({
|
||||
model,
|
||||
messages: [{ role: 'user', content }],
|
||||
})
|
||||
text = result.text
|
||||
} catch (e: any) {
|
||||
if (e.message?.includes('image_url') || e.message?.includes('image') || e.message?.includes('vision') || e.message?.includes('multimodal')) {
|
||||
throw new Error('Your AI model does not support image analysis. Please switch to a vision-capable model (e.g., gpt-4o, claude-3.5-sonnet, gemini-2.0-flash).')
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
descriptions.push({ index: i, description: text.trim() })
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export const REFACTOR_OPTIONS: RefactorOption[] = [
|
||||
export class ParagraphRefactorService {
|
||||
private languageDetection: LanguageDetectionService
|
||||
private readonly MIN_WORDS = 10
|
||||
private readonly MAX_WORDS = 2000
|
||||
private readonly MAX_WORDS = 5000
|
||||
|
||||
constructor() {
|
||||
this.languageDetection = new LanguageDetectionService()
|
||||
|
||||
Reference in New Issue
Block a user