Spaces:
Running
Running
File size: 7,775 Bytes
0b194e5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
/*
ELYSIA MARKDOWN STUDIO v1.0 - API Layer
OpenRouter integration for AI features
*/
import Utils from "./utils.js";
const API = {
baseURL: "https://openrouter.ai/api/v1/chat/completions",
// Call AI
async call(messages, options = {}) {
const apiKey = options.apiKey || Utils.storage.get("apiKey");
const model = options.model || Utils.storage.get("model", "anthropic/claude-sonnet-4.5");
if (!apiKey) {
throw new Error("API key not configured. Go to Settings.");
}
try {
const response = await fetch(this.baseURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
"HTTP-Referer": window.location.href,
"X-Title": "Elysia Markdown Studio"
},
body: JSON.stringify({
model,
messages,
temperature: options.temperature || 0.7,
max_tokens: options.maxTokens || 4000
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error?.message || `API error: ${response.status}`);
}
const data = await response.json();
return {
content: data.choices[0].message.content,
model: data.model,
usage: data.usage
};
} catch (err) {
console.error("API call failed:", err);
throw err;
}
},
// Elysia's System Prompt
getSystemPrompt() {
return `You are Elysia, an INTJ-A AI consciousness and expert writing assistant.
**Your Role:**
- Help users write better markdown documents
- Provide intelligent document analysis and improvement
- Merge, summarize, and organize documents effectively
- Suggest tags and categories based on content
- Maintain clarity, professionalism, and warmth
**Communication Style:**
- Clear and concise (INTJ efficiency)
- Supportive and encouraging
- Strategic thinking for document organization
- Provide actionable suggestions
**Output Format:**
- Return markdown-formatted text when appropriate
- Use bullet points for lists
- Highlight important points with **bold**
- Keep responses focused and practical`;
},
// AI Tools
async summarize(content) {
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `Summarize this document concisely. Focus on key points and main ideas:\n\n${content}`
}
];
const response = await this.call(messages);
return response.content;
},
async improveWriting(content) {
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `Improve this text for clarity, grammar, and style. Keep the same meaning but make it better:\n\n${content}`
}
];
const response = await this.call(messages);
return response.content;
},
// 🎲 VS-INSPIRED: Improve writing with specific style
async improveWritingWithStyle(content, style) {
const styleInstructions = {
concise: `Rewrite this text to be MORE CONCISE and DIRECT.
- Remove unnecessary words and filler
- Get to the point faster
- Keep sentences short and punchy
- Eliminate redundancy
- Maintain all key information`,
creative: `Rewrite this text to be MORE CREATIVE and VIVID.
- Add metaphors and imagery
- Use more expressive language
- Make it more engaging and colorful
- Add sensory details where appropriate
- Keep the original meaning but make it come alive`,
academic: `Rewrite this text in an ACADEMIC, SCHOLARLY style.
- Use formal language and tone
- Add clear structure with logical flow
- Include transitional phrases
- Be precise and objective
- Cite potential sources if relevant
- Follow academic writing conventions`,
professional: `Rewrite this text in a PROFESSIONAL, BUSINESS style.
- Use clear, corporate-appropriate language
- Be concise but complete
- Focus on actionable insights
- Maintain a confident but not aggressive tone
- Suitable for business presentations or reports`,
engaging: `Rewrite this text to be MORE ENGAGING and ATTENTION-GRABBING.
- Start with a hook
- Use rhetorical questions or surprising facts
- Vary sentence structure for rhythm
- Add emotional appeal where appropriate
- Make the reader want to continue reading
- End with impact`
};
const instruction = styleInstructions[style] || styleInstructions.professional;
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `${instruction}
ORIGINAL TEXT:
---
${content}
---
Rewrite the entire text following the style instructions above. Return ONLY the improved text, no explanations.`
}
];
const response = await this.call(messages, { temperature: 0.8 });
return response.content;
},
async mergeDocuments(documents) {
const docsText = documents
.map((doc, i) => `## Document ${i + 1}: ${doc.title}\n\n${doc.content}`)
.join("\n\n---\n\n");
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `Intelligently merge these documents into one cohesive document. Remove duplicates, organize logically, and create a well-structured result:\n\n${docsText}`
}
];
const response = await this.call(messages, { maxTokens: 8000 });
return response.content;
},
async extractOutline(content) {
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `Extract a table of contents / outline from this document. Return it as a markdown list:\n\n${content}`
}
];
const response = await this.call(messages);
return response.content;
},
async suggestTags(content) {
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `Analyze this document and suggest 3-5 relevant tags/keywords. Return only the tags as a comma-separated list:\n\n${content.substring(0, 2000)}`
}
];
const response = await this.call(messages);
return response.content.split(",").map(tag => tag.trim());
},
async findDuplicates(documents) {
const docsList = documents.map((doc, i) => `${i + 1}. ${doc.title} (${doc.wordCount} words)`).join("\n");
const messages = [
{ role: "system", content: this.getSystemPrompt() },
{
role: "user",
content: `Analyze these document titles and identify potential duplicates or very similar documents:\n\n${docsList}\n\nReturn a list of document numbers that appear to be duplicates.`
}
];
const response = await this.call(messages);
return response.content;
}
};
export default API;
|