| @@ -207,9 +207,9 @@ Class AdminController_Class | |||||
| End If | End If | ||||
| On Error GoTo 0 | On Error GoTo 0 | ||||
| Dim generatedSummary, generatedBody | |||||
| Dim generatedSummary, generatedBody, generatedImagePrompt, generatedImageHtml | |||||
| On Error Resume Next | On Error Resume Next | ||||
| GeneratePostContentFromAI post, generatedSummary, generatedBody | |||||
| GeneratePostContentFromAI post, generatedSummary, generatedBody, generatedImagePrompt | |||||
| If Err.Number <> 0 Then | If Err.Number <> 0 Then | ||||
| Flash().AddError "AI content generation failed: " & Err.Description | Flash().AddError "AI content generation failed: " & Err.Description | ||||
| Err.Clear | Err.Clear | ||||
| @@ -225,8 +225,10 @@ Class AdminController_Class | |||||
| Exit Sub | Exit Sub | ||||
| End If | End If | ||||
| generatedImageHtml = BuildGeneratedImageHtml(generatedImagePrompt, post.Title, generatedSummary) | |||||
| post.Summary = generatedSummary | post.Summary = generatedSummary | ||||
| post.Body = generatedBody | |||||
| post.Body = generatedImageHtml & generatedBody | |||||
| post.UpdatedDate = Now() | post.UpdatedDate = Now() | ||||
| PostsRepository().Update post | PostsRepository().Update post | ||||
| @@ -234,7 +236,7 @@ Class AdminController_Class | |||||
| Response.Redirect PostEditUrl(post.PostID) | Response.Redirect PostEditUrl(post.PostID) | ||||
| End Sub | End Sub | ||||
| Private Sub GeneratePostContentFromAI(ByRef post, ByRef generatedSummary, ByRef generatedBody) | |||||
| Private Sub GeneratePostContentFromAI(ByRef post, ByRef generatedSummary, ByRef generatedBody, ByRef generatedImagePrompt) | |||||
| Dim apiKey : apiKey = Trim(CStr(GetSecureSetting("AbacusApiKey", "ABACUS_API_KEY"))) | Dim apiKey : apiKey = Trim(CStr(GetSecureSetting("AbacusApiKey", "ABACUS_API_KEY"))) | ||||
| If Len(apiKey) = 0 Then | If Len(apiKey) = 0 Then | ||||
| Err.Raise 1, "AdminController.GeneratePostContentFromAI", "Abacus API key is not configured." | Err.Raise 1, "AdminController.GeneratePostContentFromAI", "Abacus API key is not configured." | ||||
| @@ -248,9 +250,10 @@ Class AdminController_Class | |||||
| If Len(modelName) = 0 Or LCase(modelName) = "nothing" Then modelName = "route-llm" | If Len(modelName) = 0 Or LCase(modelName) = "nothing" Then modelName = "route-llm" | ||||
| Dim systemPrompt, userPrompt, payload, responseText, parsed, choices, choice, message, content, contentJson | Dim systemPrompt, userPrompt, payload, responseText, parsed, choices, choice, message, content, contentJson | ||||
| systemPrompt = "You write clear, engaging blog post content for a classic ASP blog. Return only valid JSON with two keys: summary and body. Summary must be 1 to 2 sentences. Body must be 3 to 5 short paragraphs separated by blank lines. Do not use markdown fences, bullets, or code blocks." | |||||
| systemPrompt = "You write clear, engaging blog post content for a classic ASP blog. Return only valid JSON with three keys: summary, image_prompt, and body. Summary must be 1 to 2 sentences. image_prompt must be a concise visual description suitable for an AI image generator and should not mention markdown. Body must be 3 to 5 short paragraphs of HTML with simple semantic tags like p, strong, em, ul, ol, and h2. Do not use markdown fences or code blocks." | |||||
| userPrompt = BuildGenerationPrompt(post) | |||||
| userPrompt = BuildGenerationPrompt(post) & vbCrLf & vbCrLf & _ | |||||
| "Also return an image_prompt field that describes a magazine-style feature image for this post." | |||||
| payload = "{""model"":""" & JsonEscape(modelName) & """,""messages"":[{""role"":""system"",""content"":""" & JsonEscape(systemPrompt) & """},{""role"":""user"",""content"":""" & JsonEscape(userPrompt) & """}],""temperature"":0.7}" | payload = "{""model"":""" & JsonEscape(modelName) & """,""messages"":[{""role"":""system"",""content"":""" & JsonEscape(systemPrompt) & """},{""role"":""user"",""content"":""" & JsonEscape(userPrompt) & """}],""temperature"":0.7}" | ||||
| @@ -286,6 +289,7 @@ Class AdminController_Class | |||||
| If parsed.data.Exists("summary") Then generatedSummary = Trim(CStr(parsed.data.Item("summary"))) | If parsed.data.Exists("summary") Then generatedSummary = Trim(CStr(parsed.data.Item("summary"))) | ||||
| If parsed.data.Exists("body") Then generatedBody = Trim(CStr(parsed.data.Item("body"))) | If parsed.data.Exists("body") Then generatedBody = Trim(CStr(parsed.data.Item("body"))) | ||||
| If parsed.data.Exists("image_prompt") Then generatedImagePrompt = Trim(CStr(parsed.data.Item("image_prompt"))) | |||||
| End Sub | End Sub | ||||
| Private Sub UpdateCommentApproval(ByVal id, ByVal isApproved, ByVal successMessage) | Private Sub UpdateCommentApproval(ByVal id, ByVal isApproved, ByVal successMessage) | ||||
| @@ -323,6 +327,25 @@ Class AdminController_Class | |||||
| HttpPostJson = http.responseText | HttpPostJson = http.responseText | ||||
| End Function | End Function | ||||
| Private Function BuildGeneratedImageHtml(ByVal imagePrompt, ByVal titleText, ByVal summaryText) | |||||
| Dim promptText, altText, imageUrl | |||||
| promptText = Trim(CStr(imagePrompt)) | |||||
| If Len(promptText) = 0 Then | |||||
| BuildGeneratedImageHtml = "" | |||||
| Exit Function | |||||
| End If | |||||
| altText = Trim(CStr(summaryText)) | |||||
| If Len(altText) = 0 Then altText = Trim(CStr(titleText)) | |||||
| If Len(altText) = 0 Then altText = "Feature image" | |||||
| imageUrl = AiImageUrl(promptText) | |||||
| BuildGeneratedImageHtml = "<figure class=""post-feature-image mb-4"">" & _ | |||||
| "<img class=""img-fluid rounded-4"" src=""" & Server.HTMLEncode(imageUrl) & """ alt=""" & Server.HTMLEncode(altText) & """ />" & _ | |||||
| "</figure>" | |||||
| End Function | |||||
| Private Function ExtractJsonObject(ByVal text) | Private Function ExtractJsonObject(ByVal text) | ||||
| Dim startPos, endPos | Dim startPos, endPos | ||||
| startPos = InStr(text, "{") | startPos = InStr(text, "{") | ||||
Powered by TurnKey Linux.