mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 08:33:36 +00:00
Merge pull request #123 from AutoMaker-Org/enhance-feature-with-ai
feat: add AI enhancement feature to settings and board views
This commit is contained in:
22
apps/server/src/routes/enhance-prompt/index.ts
Normal file
22
apps/server/src/routes/enhance-prompt/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Enhance prompt routes - HTTP API for AI-powered text enhancement
|
||||
*
|
||||
* Provides endpoints for enhancing user input text using Claude AI
|
||||
* with different enhancement modes (improve, expand, simplify, etc.)
|
||||
*/
|
||||
|
||||
import { Router } from "express";
|
||||
import { createEnhanceHandler } from "./routes/enhance.js";
|
||||
|
||||
/**
|
||||
* Create the enhance-prompt router
|
||||
*
|
||||
* @returns Express router with enhance-prompt endpoints
|
||||
*/
|
||||
export function createEnhancePromptRoutes(): Router {
|
||||
const router = Router();
|
||||
|
||||
router.post("/", createEnhanceHandler());
|
||||
|
||||
return router;
|
||||
}
|
||||
195
apps/server/src/routes/enhance-prompt/routes/enhance.ts
Normal file
195
apps/server/src/routes/enhance-prompt/routes/enhance.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* POST /enhance-prompt endpoint - Enhance user input text
|
||||
*
|
||||
* Uses Claude AI to enhance text based on the specified enhancement mode.
|
||||
* Supports modes: improve, technical, simplify, acceptance
|
||||
*/
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import {
|
||||
getSystemPrompt,
|
||||
buildUserPrompt,
|
||||
isValidEnhancementMode,
|
||||
type EnhancementMode,
|
||||
} from "../../../lib/enhancement-prompts.js";
|
||||
import { resolveModelString, CLAUDE_MODEL_MAP } from "../../../lib/model-resolver.js";
|
||||
|
||||
const logger = createLogger("EnhancePrompt");
|
||||
|
||||
/**
|
||||
* Request body for the enhance endpoint
|
||||
*/
|
||||
interface EnhanceRequestBody {
|
||||
/** The original text to enhance */
|
||||
originalText: string;
|
||||
/** The enhancement mode to apply */
|
||||
enhancementMode: string;
|
||||
/** Optional model override */
|
||||
model?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Success response from the enhance endpoint
|
||||
*/
|
||||
interface EnhanceSuccessResponse {
|
||||
success: true;
|
||||
enhancedText: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error response from the enhance endpoint
|
||||
*/
|
||||
interface EnhanceErrorResponse {
|
||||
success: false;
|
||||
error: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract text content from Claude SDK response messages
|
||||
*
|
||||
* @param stream - The async iterable from the query function
|
||||
* @returns The extracted text content
|
||||
*/
|
||||
async function extractTextFromStream(
|
||||
stream: AsyncIterable<{
|
||||
type: string;
|
||||
subtype?: string;
|
||||
result?: string;
|
||||
message?: {
|
||||
content?: Array<{ type: string; text?: string }>;
|
||||
};
|
||||
}>
|
||||
): Promise<string> {
|
||||
let responseText = "";
|
||||
|
||||
for await (const msg of stream) {
|
||||
if (msg.type === "assistant" && msg.message?.content) {
|
||||
for (const block of msg.message.content) {
|
||||
if (block.type === "text" && block.text) {
|
||||
responseText += block.text;
|
||||
}
|
||||
}
|
||||
} else if (msg.type === "result" && msg.subtype === "success") {
|
||||
responseText = msg.result || responseText;
|
||||
}
|
||||
}
|
||||
|
||||
return responseText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the enhance request handler
|
||||
*
|
||||
* @returns Express request handler for text enhancement
|
||||
*/
|
||||
export function createEnhanceHandler(): (
|
||||
req: Request,
|
||||
res: Response
|
||||
) => Promise<void> {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { originalText, enhancementMode, model } =
|
||||
req.body as EnhanceRequestBody;
|
||||
|
||||
// Validate required fields
|
||||
if (!originalText || typeof originalText !== "string") {
|
||||
const response: EnhanceErrorResponse = {
|
||||
success: false,
|
||||
error: "originalText is required and must be a string",
|
||||
};
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enhancementMode || typeof enhancementMode !== "string") {
|
||||
const response: EnhanceErrorResponse = {
|
||||
success: false,
|
||||
error: "enhancementMode is required and must be a string",
|
||||
};
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate text is not empty
|
||||
const trimmedText = originalText.trim();
|
||||
if (trimmedText.length === 0) {
|
||||
const response: EnhanceErrorResponse = {
|
||||
success: false,
|
||||
error: "originalText cannot be empty",
|
||||
};
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate and normalize enhancement mode
|
||||
const normalizedMode = enhancementMode.toLowerCase();
|
||||
const validMode: EnhancementMode = isValidEnhancementMode(normalizedMode)
|
||||
? normalizedMode
|
||||
: "improve";
|
||||
|
||||
logger.info(
|
||||
`Enhancing text with mode: ${validMode}, length: ${trimmedText.length} chars`
|
||||
);
|
||||
|
||||
// Get the system prompt for this mode
|
||||
const systemPrompt = getSystemPrompt(validMode);
|
||||
|
||||
// Build the user prompt with few-shot examples
|
||||
// This helps the model understand this is text transformation, not a coding task
|
||||
const userPrompt = buildUserPrompt(validMode, trimmedText, true);
|
||||
|
||||
// Resolve the model - use the passed model, default to sonnet for quality
|
||||
const resolvedModel = resolveModelString(model, CLAUDE_MODEL_MAP.sonnet);
|
||||
|
||||
logger.debug(`Using model: ${resolvedModel}`);
|
||||
|
||||
// Call Claude SDK with minimal configuration for text transformation
|
||||
// Key: no tools, just text completion
|
||||
const stream = query({
|
||||
prompt: userPrompt,
|
||||
options: {
|
||||
model: resolvedModel,
|
||||
systemPrompt,
|
||||
maxTurns: 1,
|
||||
allowedTools: [],
|
||||
permissionMode: "acceptEdits",
|
||||
},
|
||||
});
|
||||
|
||||
// Extract the enhanced text from the response
|
||||
const enhancedText = await extractTextFromStream(stream);
|
||||
|
||||
if (!enhancedText || enhancedText.trim().length === 0) {
|
||||
logger.warn("Received empty response from Claude");
|
||||
const response: EnhanceErrorResponse = {
|
||||
success: false,
|
||||
error: "Failed to generate enhanced text - empty response",
|
||||
};
|
||||
res.status(500).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`Enhancement complete, output length: ${enhancedText.length} chars`
|
||||
);
|
||||
|
||||
const response: EnhanceSuccessResponse = {
|
||||
success: true,
|
||||
enhancedText: enhancedText.trim(),
|
||||
};
|
||||
res.json(response);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : "Unknown error occurred";
|
||||
logger.error("Enhancement failed:", errorMessage);
|
||||
|
||||
const response: EnhanceErrorResponse = {
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
};
|
||||
res.status(500).json(response);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user