Skip to content
Closed

Develop #9824

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
fa64479
Update pnpm-lock.yaml
CAPTAIN320 Jan 23, 2025
1d0b7c8
Update package.json
CAPTAIN320 Jan 23, 2025
f7323ee
Update pnpm-lock.yaml
CAPTAIN320 Jan 23, 2025
4f4b248
update
CAPTAIN320 Jan 23, 2025
4d3ed9d
Update stream-text.ts
CAPTAIN320 Jan 23, 2025
16fe3b5
Update package.json
CAPTAIN320 Jan 23, 2025
4fb31a4
Update stream-text.ts
CAPTAIN320 Jan 23, 2025
09682b5
Update stream-text.ts
CAPTAIN320 Jan 23, 2025
7c47c2f
Update pnpm-lock.yaml
CAPTAIN320 Jan 23, 2025
5eaf404
Update package.json
CAPTAIN320 Jan 23, 2025
d6546cd
Update pnpm-lock.yaml
CAPTAIN320 Jan 23, 2025
3443e0d
Create .env.template
CAPTAIN320 Jan 23, 2025
856f1fa
Update .gitignore
CAPTAIN320 Jan 23, 2025
3a3bea9
Update stream-text.ts
CAPTAIN320 Jan 23, 2025
09501f2
Update package.json
CAPTAIN320 Jan 23, 2025
7d31edb
Update pnpm-lock.yaml
CAPTAIN320 Jan 23, 2025
c52c6db
Update stream-text.ts
CAPTAIN320 Jan 27, 2025
da05fe9
Update package.json
CAPTAIN320 Jan 27, 2025
a570b94
Update pnpm-lock.yaml
CAPTAIN320 Jan 27, 2025
7eefa0d
Update stream-text.ts
CAPTAIN320 Jan 27, 2025
c489144
Update stream-text.ts
CAPTAIN320 Jan 27, 2025
f66fb8c
Merge pull request #1 from CAPTAIN320/new-model
CAPTAIN320 Jan 27, 2025
91940c4
Update stream-text.ts
CAPTAIN320 Jan 27, 2025
9cce045
Update stream-text.ts
CAPTAIN320 Jan 27, 2025
55dc81e
Update stream-text.ts
CAPTAIN320 Jan 28, 2025
8b828c7
Update api.chat.ts
CAPTAIN320 Jan 28, 2025
1de1481
Merge pull request #3 from CAPTAIN320/attach-document
CAPTAIN320 Jan 28, 2025
e14526f
Update pnpm-lock.yaml
CAPTAIN320 Jan 28, 2025
795cb21
Update Workbench.client.tsx
CAPTAIN320 Jan 28, 2025
c5270a0
Update package.json
CAPTAIN320 Jan 28, 2025
4241f10
Create api.copy-files.ts
CAPTAIN320 Jan 28, 2025
a066f5a
Update api.copy-files.ts
CAPTAIN320 Jan 28, 2025
60062b7
Update package.json
CAPTAIN320 Jan 28, 2025
4c7e58f
Update pnpm-lock.yaml
CAPTAIN320 Jan 28, 2025
5613b40
Delete api.copy-files.ts
CAPTAIN320 Jan 28, 2025
f25a3e4
Merge pull request #5 from CAPTAIN320/export-files
CAPTAIN320 Jan 28, 2025
7041250
Update Workbench.client.tsx
CAPTAIN320 Jan 28, 2025
ece2038
Update stream-text.ts
CAPTAIN320 Jan 29, 2025
d6ebcd2
Update package.json
CAPTAIN320 Jan 29, 2025
9502955
Update pnpm-lock.yaml
CAPTAIN320 Jan 29, 2025
4d7b955
Update stream-text.ts
CAPTAIN320 Jan 29, 2025
0e091d9
Update stream-text.ts
CAPTAIN320 Jan 29, 2025
9dfaaca
Update Header.tsx
CAPTAIN320 Feb 13, 2025
96bfaeb
Update stream-text.ts
CAPTAIN320 Feb 13, 2025
f7cdcc7
Merge pull request #8 from CAPTAIN320/ollama
CAPTAIN320 Feb 13, 2025
48bf897
Update .env.template
CAPTAIN320 May 2, 2025
cd4d27e
Update stream-text.ts
CAPTAIN320 May 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ANTHROPIC
ANTHROPIC_API_KEY=""

# AZURE AI
AZURE_RESOURCE_NAME=""
AZURE_RESOURCE_NAME_API_KEY=""

# RAKUTEN AI
RAKUTEN_AI_GATEWAY_KEY=""
RAKUTEN_AI_ANTHROPIC_URL=""
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ dist-ssr

/.cache
/build
.env*
.env
.env.local
*.vars
.wrangler
_worker.bundle
3 changes: 2 additions & 1 deletion app/components/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export function Header() {
<div className="flex items-center gap-2 z-logo text-bolt-elements-textPrimary cursor-pointer">
<div className="i-ph:sidebar-simple-duotone text-xl" />
<a href="/" className="text-2xl font-semibold text-accent flex items-center">
<span className="i-bolt:logo-text?mask w-[46px] inline-block" />
{/* <span className="i-bolt:logo-text?mask w-[46px] inline-block" /> */}
<span className="ml-2">Flora</span>
</a>
</div>
<span className="flex-1 px-4 truncate text-center text-bolt-elements-textPrimary">
Expand Down
56 changes: 56 additions & 0 deletions app/components/workbench/Workbench.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { cubicEasingFn } from '~/utils/easings';
import { renderLogger } from '~/utils/logger';
import { EditorPanel } from './EditorPanel';
import { Preview } from './Preview';
import JSZip from 'jszip';

interface WorkspaceProps {
chatStarted?: boolean;
Expand Down Expand Up @@ -52,6 +53,53 @@ const workbenchVariants = {
},
} satisfies Variants;

async function downloadAsZip(files: Record<string, any>) {
const zip = new JSZip();

// add files to zip
for (const [path, dirent] of Object.entries(files)) {
if (dirent?.type === 'file' && dirent.content) {
zip.file(path.startsWith('/') ? path.slice(1) : path, dirent.content);
}
}

// generate and download zip
const blob = await zip.generateAsync({ type: 'blob' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'files.zip';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}

async function copyFilesToDirectory(files: Record<string, any>) {
try {
// using the Fetch API to send files to your backend
const response = await fetch('/api/copy-files', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
files,
targetDirectory: '/Users/yaqub.mahmoud/github/ai-website-microservice/web-projects/project_name',
}),
});

if (!response.ok) {
throw new Error('Failed to copy files');
}

toast.success('Files copied successfully');
} catch (error) {
console.error('Error copying files:', error);
toast.error('Failed to copy files');
}
}

export const Workbench = memo(({ chatStarted, isStreaming }: WorkspaceProps) => {
renderLogger.trace('Workbench');

Expand Down Expand Up @@ -132,6 +180,14 @@ export const Workbench = memo(({ chatStarted, isStreaming }: WorkspaceProps) =>
Toggle Terminal
</PanelHeaderButton>
)}
<PanelHeaderButton className="mr-1 text-sm" onClick={() => downloadAsZip(files)}>
<div className="i-ph:download mr-1" />
Download ZIP
</PanelHeaderButton>
{/* <PanelHeaderButton className="mr-1 text-sm" onClick={() => copyFilesToDirectory(files)}>
<div className="i-ph:rocket mr-1" />
Deploy
</PanelHeaderButton> */}
<IconButton
icon="i-ph:x-circle"
className="-mr-1"
Expand Down
90 changes: 79 additions & 11 deletions app/lib/.server/llm/stream-text.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { streamText as _streamText, convertToCoreMessages } from 'ai';
import { getAPIKey } from '~/lib/.server/llm/api-key';
import { getAnthropicModel } from '~/lib/.server/llm/model';
import { MAX_TOKENS } from './constants';
import { getSystemPrompt } from './prompts';

import { createAnthropic } from '@ai-sdk/anthropic';
import { createAzure } from '@ai-sdk/azure';
import { createOllama } from 'ollama-ai-provider';

interface ToolResult<Name extends string, Args, Result> {
toolCallId: string;
toolName: Name;
Expand All @@ -22,14 +25,79 @@ export type Messages = Message[];
export type StreamingOptions = Omit<Parameters<typeof _streamText>[0], 'model'>;

export function streamText(messages: Messages, env: Env, options?: StreamingOptions) {
return _streamText({
model: getAnthropicModel(getAPIKey(env)),
system: getSystemPrompt(),
maxTokens: MAX_TOKENS,
headers: {
'anthropic-beta': 'max-tokens-3-5-sonnet-2024-07-15',
},
messages: convertToCoreMessages(messages),
...options,
});
try {
const azureResourceName = process.env.AZURE_RESOURCE_NAME;
const azureResourceNameApiKey = process.env.AZURE_RESOURCE_NAME_API_KEY;
const azure = createAzure({
resourceName: azureResourceName,
apiKey: azureResourceNameApiKey,
headers: {
api_version: '2024-11-20',
},
});

// `
// For all designs I ask you to make, have them be beautiful, not cookie cutter. Make webpages that are fully featured and worthy for production.
// By default, this template supports JSX syntax with Tailwind CSS classes, React hooks, and Lucide React for icons. Do not install other packages for UI themes, icons, etc unless absolutely necessary or I request them.
// Use icons from lucide-react for logos.
// Use stock photos from unsplash where appropriate, only valid URLs you know exist. Do not download the images, only link to them in image tags.
// `;

// return _streamText({
// // model: azure('gpt-4o'),
// model: azure('gpt-4o-2'),
// system: getSystemPrompt(),
// messages: convertToCoreMessages(messages),
// maxTokens: 8192,
// ...options,
// });

const anthropic = createAnthropic({
baseURL: process.env.RAKUTEN_AI_ANTHROPIC_URL,
apiKey: 'test',
});

return _streamText({
model: anthropic('claude-3-7-sonnet-20250219'),
system: getSystemPrompt(),
maxTokens: 16384,
headers: {
Authorization: `Bearer ${process.env.RAKUTEN_AI_GATEWAY_KEY}`,
},
messages: convertToCoreMessages(messages),
...options,
});

// const ollama = createOllama({
// baseURL: 'http://localhost:11434/api',
// });

// return _streamText({
// // model: ollama('llava'),
// // model: ollama('deepseek-r1:7b'),
// model: ollama('deepseek-r1:70b'),
// system: getSystemPrompt(),
// messages: convertToCoreMessages(messages),
// maxTokens: MAX_TOKENS,
// ...options,
// });

// const anthropic = createAnthropic({
// apiKey: getAPIKey(env),
// });

// return _streamText({
// model: anthropic('claude-3-5-sonnet-20240620'),
// system: getSystemPrompt(),
// maxTokens: MAX_TOKENS,
// headers: {
// 'anthropic-beta': 'max-tokens-3-5-sonnet-2024-07-15',
// },
// messages: convertToCoreMessages(messages),
// ...options,
// });
} catch (error) {
console.error('Error streaming text:', error);
throw error;
}
}
4 changes: 2 additions & 2 deletions app/routes/api.chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ async function chatAction({ context, request }: ActionFunctionArgs) {

const result = await streamText(messages, context.cloudflare.env, options);

return stream.switchSource(result.toAIStream());
return stream.switchSource(result.toDataStream());
},
};

const result = await streamText(messages, context.cloudflare.env, options);

stream.switchSource(result.toAIStream());
stream.switchSource(result.toDataStream());

return new Response(stream.readable, {
status: 200,
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
},
"dependencies": {
"@ai-sdk/anthropic": "^0.0.39",
"@ai-sdk/azure": "^0.0.39",
"@codemirror/autocomplete": "^6.17.0",
"@codemirror/commands": "^6.6.0",
"@codemirror/lang-cpp": "^6.0.2",
Expand Down Expand Up @@ -61,7 +62,9 @@
"isbot": "^4.1.0",
"istextorbinary": "^9.5.0",
"jose": "^5.6.3",
"jszip": "^3.10.1",
"nanostores": "^0.10.3",
"ollama-ai-provider": "^1.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.5.0",
Expand All @@ -81,13 +84,15 @@
"@cloudflare/workers-types": "^4.20240620.0",
"@remix-run/dev": "^2.10.0",
"@types/diff": "^5.2.1",
"@types/node": "^22.10.10",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"fast-glob": "^3.3.2",
"is-ci": "^3.0.1",
"node-fetch": "^3.3.2",
"prettier": "^3.3.2",
"typescript": "^5.5.2",
"sass-embedded": "^1.83.4",
"typescript": "^5.7.3",
"unified": "^11.0.5",
"unocss": "^0.61.3",
"vite": "^5.3.1",
Expand Down
Loading
Loading