mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-01-02 22:32:27 +08:00
Compare commits
1 Commits
v0.4.8
...
cloudflare
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dd7b2383e |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -41,4 +41,9 @@ yarn-error.log*
|
|||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
push-via-ec2.sh
|
push-via-ec2.sh
|
||||||
.claude/settings.local.json
|
.claude/settings.local.json
|
||||||
.playwright-mcp/
|
.playwright-mcp/
|
||||||
|
|
||||||
|
# cloudflare
|
||||||
|
.open-next/
|
||||||
|
.dev.vars
|
||||||
|
.wrangler/
|
||||||
3
cloudflare-env.d.ts
vendored
Normal file
3
cloudflare-env.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
interface CloudflareEnv {
|
||||||
|
ASSETS: Fetcher
|
||||||
|
}
|
||||||
@@ -1,7 +1,15 @@
|
|||||||
import { LangfuseSpanProcessor } from "@langfuse/otel"
|
|
||||||
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"
|
|
||||||
|
|
||||||
export function register() {
|
export function register() {
|
||||||
|
// Skip on edge/worker runtime (Cloudflare Workers, Vercel Edge)
|
||||||
|
// OpenTelemetry Node SDK requires Node.js-specific APIs
|
||||||
|
if (
|
||||||
|
typeof process === "undefined" ||
|
||||||
|
!process.versions?.node ||
|
||||||
|
// @ts-expect-error - EdgeRuntime is a global in edge environments
|
||||||
|
typeof EdgeRuntime !== "undefined"
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Skip telemetry if Langfuse env vars are not configured
|
// Skip telemetry if Langfuse env vars are not configured
|
||||||
if (!process.env.LANGFUSE_PUBLIC_KEY || !process.env.LANGFUSE_SECRET_KEY) {
|
if (!process.env.LANGFUSE_PUBLIC_KEY || !process.env.LANGFUSE_SECRET_KEY) {
|
||||||
console.warn(
|
console.warn(
|
||||||
@@ -10,12 +18,16 @@ export function register() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic imports to avoid bundling Node.js-specific modules in edge builds
|
||||||
|
const { LangfuseSpanProcessor } = require("@langfuse/otel")
|
||||||
|
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node")
|
||||||
|
|
||||||
const langfuseSpanProcessor = new LangfuseSpanProcessor({
|
const langfuseSpanProcessor = new LangfuseSpanProcessor({
|
||||||
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
||||||
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
||||||
baseUrl: process.env.LANGFUSE_BASEURL,
|
baseUrl: process.env.LANGFUSE_BASEURL,
|
||||||
// Filter out Next.js HTTP request spans so AI SDK spans become root traces
|
// Filter out Next.js HTTP request spans so AI SDK spans become root traces
|
||||||
shouldExportSpan: ({ otelSpan }) => {
|
shouldExportSpan: ({ otelSpan }: { otelSpan: { name: string } }) => {
|
||||||
const spanName = otelSpan.name
|
const spanName = otelSpan.name
|
||||||
// Skip Next.js HTTP infrastructure spans
|
// Skip Next.js HTTP infrastructure spans
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -4,10 +4,16 @@ import { azure, createAzure } from "@ai-sdk/azure"
|
|||||||
import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
|
import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
|
||||||
import { createGoogleGenerativeAI, google } from "@ai-sdk/google"
|
import { createGoogleGenerativeAI, google } from "@ai-sdk/google"
|
||||||
import { createOpenAI, openai } from "@ai-sdk/openai"
|
import { createOpenAI, openai } from "@ai-sdk/openai"
|
||||||
import { fromNodeProviderChain } from "@aws-sdk/credential-providers"
|
|
||||||
import { createOpenRouter } from "@openrouter/ai-sdk-provider"
|
import { createOpenRouter } from "@openrouter/ai-sdk-provider"
|
||||||
import { createOllama, ollama } from "ollama-ai-provider-v2"
|
import { createOllama, ollama } from "ollama-ai-provider-v2"
|
||||||
|
|
||||||
|
// Detect if running in edge/worker runtime (Cloudflare Workers, Vercel Edge, etc.)
|
||||||
|
const isEdgeRuntime =
|
||||||
|
typeof process === "undefined" ||
|
||||||
|
!process.versions?.node ||
|
||||||
|
// @ts-expect-error - EdgeRuntime is a global in edge environments
|
||||||
|
typeof EdgeRuntime !== "undefined"
|
||||||
|
|
||||||
export type ProviderName =
|
export type ProviderName =
|
||||||
| "bedrock"
|
| "bedrock"
|
||||||
| "openai"
|
| "openai"
|
||||||
@@ -166,12 +172,37 @@ export function getAIModel(): ModelConfig {
|
|||||||
|
|
||||||
switch (provider) {
|
switch (provider) {
|
||||||
case "bedrock": {
|
case "bedrock": {
|
||||||
// Use credential provider chain for IAM role support (Amplify, Lambda, etc.)
|
// Edge runtime (Cloudflare Workers, etc.) requires explicit credentials
|
||||||
// Falls back to env vars (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) for local dev
|
// Node.js runtime can use IAM role chain (Amplify, Lambda, etc.)
|
||||||
const bedrockProvider = createAmazonBedrock({
|
const bedrockConfig: Parameters<typeof createAmazonBedrock>[0] = {
|
||||||
region: process.env.AWS_REGION || "us-west-2",
|
region: process.env.AWS_REGION || "us-west-2",
|
||||||
credentialProvider: fromNodeProviderChain(),
|
}
|
||||||
})
|
|
||||||
|
if (isEdgeRuntime) {
|
||||||
|
// Edge runtime: use explicit credentials from env vars
|
||||||
|
if (
|
||||||
|
!process.env.AWS_ACCESS_KEY_ID ||
|
||||||
|
!process.env.AWS_SECRET_ACCESS_KEY
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
"AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are required for Bedrock on edge runtime (Cloudflare Workers)",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
bedrockConfig.accessKeyId = process.env.AWS_ACCESS_KEY_ID
|
||||||
|
bedrockConfig.secretAccessKey =
|
||||||
|
process.env.AWS_SECRET_ACCESS_KEY
|
||||||
|
if (process.env.AWS_SESSION_TOKEN) {
|
||||||
|
bedrockConfig.sessionToken = process.env.AWS_SESSION_TOKEN
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Node.js runtime: use credential provider chain for IAM role support
|
||||||
|
const {
|
||||||
|
fromNodeProviderChain,
|
||||||
|
} = require("@aws-sdk/credential-providers")
|
||||||
|
bedrockConfig.credentialProvider = fromNodeProviderChain()
|
||||||
|
}
|
||||||
|
|
||||||
|
const bedrockProvider = createAmazonBedrock(bedrockConfig)
|
||||||
model = bedrockProvider(modelId)
|
model = bedrockProvider(modelId)
|
||||||
// Add Anthropic beta options if using Claude models via Bedrock
|
// Add Anthropic beta options if using Claude models via Bedrock
|
||||||
if (modelId.includes("anthropic.claude")) {
|
if (modelId.includes("anthropic.claude")) {
|
||||||
|
|||||||
3
open-next.config.ts
Normal file
3
open-next.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { defineCloudflareConfig } from "@opennextjs/cloudflare"
|
||||||
|
|
||||||
|
export default defineCloudflareConfig()
|
||||||
8354
package-lock.json
generated
8354
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -10,7 +10,11 @@
|
|||||||
"lint": "biome lint .",
|
"lint": "biome lint .",
|
||||||
"format": "biome check --write .",
|
"format": "biome check --write .",
|
||||||
"check": "biome ci",
|
"check": "biome ci",
|
||||||
"prepare": "husky"
|
"prepare": "husky",
|
||||||
|
"cf:build": "opennextjs-cloudflare build",
|
||||||
|
"cf:preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
|
||||||
|
"cf:deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
|
||||||
|
"cf:typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/amazon-bedrock": "^3.0.62",
|
"@ai-sdk/amazon-bedrock": "^3.0.62",
|
||||||
@@ -25,6 +29,7 @@
|
|||||||
"@langfuse/otel": "^4.4.4",
|
"@langfuse/otel": "^4.4.4",
|
||||||
"@langfuse/tracing": "^4.4.9",
|
"@langfuse/tracing": "^4.4.9",
|
||||||
"@next/third-parties": "^16.0.6",
|
"@next/third-parties": "^16.0.6",
|
||||||
|
"@opennextjs/cloudflare": "^1.14.4",
|
||||||
"@openrouter/ai-sdk-provider": "^1.2.3",
|
"@openrouter/ai-sdk-provider": "^1.2.3",
|
||||||
"@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
|
"@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
|
||||||
"@opentelemetry/sdk-trace-node": "^2.2.0",
|
"@opentelemetry/sdk-trace-node": "^2.2.0",
|
||||||
@@ -79,6 +84,7 @@
|
|||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"lint-staged": "^16.2.7",
|
"lint-staged": "^16.2.7",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"typescript": "^5"
|
"typescript": "^5",
|
||||||
|
"wrangler": "^4.53.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
|
"cloudflare-env.d.ts",
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
".next/types/**/*.ts",
|
".next/types/**/*.ts",
|
||||||
|
|||||||
8
wrangler.toml
Normal file
8
wrangler.toml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
main = ".open-next/worker.js"
|
||||||
|
name = "next-ai-draw-io"
|
||||||
|
compatibility_date = "2024-09-23"
|
||||||
|
compatibility_flags = ["nodejs_compat"]
|
||||||
|
|
||||||
|
[assets]
|
||||||
|
directory = ".open-next/assets"
|
||||||
|
binding = "ASSETS"
|
||||||
Reference in New Issue
Block a user