Compare commits
10 Commits
d09b0a13e6
...
8a51997fae
Author | SHA1 | Date |
---|---|---|
|
8a51997fae | |
|
14baccffa2 | |
|
195f6873c8 | |
|
d8655657a8 | |
|
00a04bc016 | |
|
6e187fd927 | |
|
3c994834b4 | |
|
f89a41eee1 | |
|
734504dcf1 | |
|
f11ce0d914 |
|
@ -1,45 +0,0 @@
|
||||||
name: '🐛 反馈缺陷 Bug Report'
|
|
||||||
description: '反馈一个问题缺陷 | Report an bug'
|
|
||||||
title: '[Bug] '
|
|
||||||
labels: '🐛 Bug'
|
|
||||||
body:
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: '💻 系统环境 | Operating System'
|
|
||||||
options:
|
|
||||||
- Windows
|
|
||||||
- macOS
|
|
||||||
- Ubuntu
|
|
||||||
- Other Linux
|
|
||||||
- Other
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: '🌐 浏览器 | Browser'
|
|
||||||
options:
|
|
||||||
- Chrome
|
|
||||||
- Edge
|
|
||||||
- Safari
|
|
||||||
- Firefox
|
|
||||||
- Other
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '🐛 问题描述 | Bug Description'
|
|
||||||
description: A clear and concise description of the bug.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '🚦 期望结果 | Expected Behavior'
|
|
||||||
description: A clear and concise description of what you expected to happen.
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '📷 复现步骤 | Recurrence Steps'
|
|
||||||
description: A clear and concise description of how to recurrence.
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '📝 补充信息 | Additional Information'
|
|
||||||
description: If your problem needs further explanation, or if the issue you're seeing cannot be reproduced in a gist, please add more information here.
|
|
|
@ -1,21 +0,0 @@
|
||||||
name: '🌠 功能需求 Feature Request'
|
|
||||||
description: '需求或建议 | Suggest an idea'
|
|
||||||
title: '[Request] '
|
|
||||||
labels: '🌠 Feature Request'
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '🥰 需求描述 | Feature Description'
|
|
||||||
description: Please add a clear and concise description of the problem you are seeking to solve with this feature request.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '🧐 解决方案 | Proposed Solution'
|
|
||||||
description: Describe the solution you'd like in a clear and concise manner.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '📝 补充信息 | Additional Information'
|
|
||||||
description: Add any other context about the problem here.
|
|
|
@ -1,15 +0,0 @@
|
||||||
name: '😇 疑问或帮助 Help Wanted'
|
|
||||||
description: '疑问或需要帮助 | Need help'
|
|
||||||
title: '[Question] '
|
|
||||||
labels: '😇 Help Wanted'
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '🧐 问题描述 | Proposed Solution'
|
|
||||||
description: A clear and concise description of the proplem.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: '📝 补充信息 | Additional Information'
|
|
||||||
description: Add any other context about the problem here.
|
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
name: '📝 其他 Other'
|
|
||||||
about: '其他问题 | Other issues'
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
|
@ -1,18 +0,0 @@
|
||||||
#### 💻 变更类型 | Change Type
|
|
||||||
|
|
||||||
<!-- For change type, change [ ] to [x]. -->
|
|
||||||
|
|
||||||
- [ ] ✨ feat
|
|
||||||
- [ ] 🐛 fix
|
|
||||||
- [ ] ♻️ refactor
|
|
||||||
- [ ] 💄 style
|
|
||||||
- [ ] 🔨 chore
|
|
||||||
- [ ] 📝 docs
|
|
||||||
|
|
||||||
#### 🔀 变更说明 | Description of Change
|
|
||||||
|
|
||||||
<!-- Thank you for your Pull Request. Please provide a description above. -->
|
|
||||||
|
|
||||||
#### 📝 补充信息 | Additional Information
|
|
||||||
|
|
||||||
<!-- Add any other context about the Pull Request here. -->
|
|
|
@ -1,72 +0,0 @@
|
||||||
name: Issue Auto Comment
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- closed
|
|
||||||
- assigned
|
|
||||||
pull_request_target:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- closed
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
run:
|
|
||||||
permissions:
|
|
||||||
issues: write # for actions-cool/issues-helper to update issues
|
|
||||||
pull-requests: write # for actions-cool/issues-helper to update PRs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Auto Comment on Issues Opened
|
|
||||||
uses: wow-actions/auto-comment@v1
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN}}
|
|
||||||
issuesOpened: |
|
|
||||||
👀 @{{ author }}
|
|
||||||
Thank you for raising an issue. We will investigate into the matter and get back to you as soon as possible.
|
|
||||||
Please make sure you have given us as much context as possible.\
|
|
||||||
非常感谢您提交 issue。我们会尽快调查此事,并尽快回复您。 请确保您已经提供了尽可能多的背景信息。
|
|
||||||
- name: Auto Comment on Issues Closed
|
|
||||||
uses: wow-actions/auto-comment@v1
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN}}
|
|
||||||
issuesClosed: |
|
|
||||||
✅ @{{ author }}
|
|
||||||
<br/>
|
|
||||||
This issue is closed, If you have any questions, you can comment and reply.\
|
|
||||||
此问题已经关闭。如果您有任何问题,可以留言并回复。
|
|
||||||
- name: Auto Comment on Pull Request Opened
|
|
||||||
uses: wow-actions/auto-comment@v1
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN}}
|
|
||||||
pullRequestOpened: |
|
|
||||||
👍 @{{ author }}
|
|
||||||
<br>
|
|
||||||
Thank you for raising your pull request and contributing to our Community
|
|
||||||
Please make sure you have followed our contributing guidelines. We will review it as soon as possible.
|
|
||||||
If you encounter any problems, please feel free to connect with us.\
|
|
||||||
非常感谢您提出拉取请求并为我们的社区做出贡献,请确保您已经遵循了我们的贡献指南,我们会尽快审查它。
|
|
||||||
如果您遇到任何问题,请随时与我们联系。
|
|
||||||
- name: Auto Comment on Pull Request Merged
|
|
||||||
uses: actions-cool/pr-welcome@main
|
|
||||||
if: github.event.pull_request.merged == true
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
comment: |
|
|
||||||
❤️ Great PR @${{ github.event.pull_request.user.login }} ❤️
|
|
||||||
<br>
|
|
||||||
The growth of project is inseparable from user feedback and contribution, thanks for your contribution!\
|
|
||||||
项目的成长离不开用户反馈和贡献,感谢您的贡献!
|
|
||||||
emoji: 'hooray'
|
|
||||||
pr-emoji: '+1, heart'
|
|
||||||
- name: Remove inactive
|
|
||||||
if: github.event.issue.state == 'open' && github.actor == github.event.issue.user.login
|
|
||||||
uses: actions-cool/issues-helper@v3
|
|
||||||
with:
|
|
||||||
actions: 'remove-labels'
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
issue-number: ${{ github.event.issue.number }}
|
|
||||||
labels: 'Inactive'
|
|
|
@ -1,23 +0,0 @@
|
||||||
name: Issue Check Inactive
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 */15 * *'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
issue-check-inactive:
|
|
||||||
permissions:
|
|
||||||
issues: write # for actions-cool/issues-helper to update issues
|
|
||||||
pull-requests: write # for actions-cool/issues-helper to update PRs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: check-inactive
|
|
||||||
uses: actions-cool/issues-helper@v3
|
|
||||||
with:
|
|
||||||
actions: 'check-inactive'
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
inactive-label: 'Inactive'
|
|
||||||
inactive-day: 30
|
|
|
@ -1,52 +0,0 @@
|
||||||
name: Issue Close Require
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
issue-close-require:
|
|
||||||
permissions:
|
|
||||||
issues: write # for actions-cool/issues-helper to update issues
|
|
||||||
pull-requests: write # for actions-cool/issues-helper to update PRs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: need reproduce
|
|
||||||
uses: actions-cool/issues-helper@v3
|
|
||||||
with:
|
|
||||||
actions: 'close-issues'
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
labels: '✅ Fixed'
|
|
||||||
inactive-day: 3
|
|
||||||
body: |
|
|
||||||
👋 @{{ github.event.issue.user.login }}
|
|
||||||
<br/>
|
|
||||||
Since the issue was labeled with `✅ Fixed`, but no response in 3 days. This issue will be closed. If you have any questions, you can comment and reply.\
|
|
||||||
由于该 issue 被标记为已修复,同时 3 天未收到回应。现关闭 issue,若有任何问题,可评论回复。
|
|
||||||
- name: need reproduce
|
|
||||||
uses: actions-cool/issues-helper@v3
|
|
||||||
with:
|
|
||||||
actions: 'close-issues'
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
labels: '🤔 Need Reproduce'
|
|
||||||
inactive-day: 3
|
|
||||||
body: |
|
|
||||||
👋 @{{ github.event.issue.user.login }}
|
|
||||||
<br/>
|
|
||||||
Since the issue was labeled with `🤔 Need Reproduce`, but no response in 3 days. This issue will be closed. If you have any questions, you can comment and reply.\
|
|
||||||
由于该 issue 被标记为需要更多信息,却 3 天未收到回应。现关闭 issue,若有任何问题,可评论回复。
|
|
||||||
- name: need reproduce
|
|
||||||
uses: actions-cool/issues-helper@v3
|
|
||||||
with:
|
|
||||||
actions: 'close-issues'
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
labels: "🙅🏻♀️ WON'T DO"
|
|
||||||
inactive-day: 3
|
|
||||||
body: |
|
|
||||||
👋 @{{ github.event.issue.user.login }}
|
|
||||||
<br/>
|
|
||||||
Since the issue was labeled with `🙅🏻♀️ WON'T DO`, and no response in 3 days. This issue will be closed. If you have any questions, you can comment and reply.\
|
|
||||||
由于该 issue 被标记为暂不处理,同时 3 天未收到回应。现关闭 issue,若有任何问题,可评论回复。
|
|
|
@ -1,33 +0,0 @@
|
||||||
name: Release CI
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install bun
|
|
||||||
uses: oven-sh/setup-bun@v1
|
|
||||||
|
|
||||||
- name: Install deps
|
|
||||||
run: bun i
|
|
||||||
|
|
||||||
- name: CI
|
|
||||||
run: bun run ci
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: bun run test
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: bun run build
|
|
||||||
|
|
||||||
- name: Release
|
|
||||||
run: bun run release
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
|
@ -1,27 +0,0 @@
|
||||||
name: Test CI
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '!main'
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install bun
|
|
||||||
uses: oven-sh/setup-bun@v1
|
|
||||||
|
|
||||||
- name: Install deps
|
|
||||||
run: bun i
|
|
||||||
|
|
||||||
- name: CI
|
|
||||||
run: bun run ci
|
|
||||||
|
|
||||||
- name: Test and coverage
|
|
||||||
run: bun run test:coverage
|
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
|
||||||
uses: codecov/codecov-action@v3
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Barry Wang
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,66 @@
|
||||||
|
# LobeChat Cloudflare Workers AI Image Generation Plugin
|
||||||
|
|
||||||
|
This is a LobeChat plugin that generates high-quality images using the `@cf/black-forest-labs/flux-1-schnell` model from [Cloudflare Workers AI](https://developers.cloudflare.com/workers-ai/).
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Generate high-quality images using Cloudflare's Flux-1-Schnell model
|
||||||
|
- Request proxying through Cloudflare Worker for simplified authentication
|
||||||
|
- Generate and view images directly in LobeChat conversations
|
||||||
|
|
||||||
|
## Setup Steps
|
||||||
|
|
||||||
|
1. Set up Cloudflare Worker
|
||||||
|
- Deploy the provided Worker code to Cloudflare Workers
|
||||||
|
- Configure the following environment variables (Secrets) in your Worker settings:
|
||||||
|
- `WORKER_API_KEY`: Set a secure API key for client authentication
|
||||||
|
- `CLOUDFLARE_API_TOKEN`: Your Cloudflare API token
|
||||||
|
- `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID
|
||||||
|
|
||||||
|
2. Configure the plugin in LobeChat
|
||||||
|
- Add this plugin to LobeChat
|
||||||
|
- In the configuration page:
|
||||||
|
- Configure your Worker API key as `WORKER_API_KEY`
|
||||||
|
- Ensure the Worker URL is correctly configured
|
||||||
|
|
||||||
|
## Authentication and Parameters
|
||||||
|
|
||||||
|
This plugin uses the following configuration to access your Cloudflare Worker:
|
||||||
|
- Worker API key: Used as the X-Api-Key request header
|
||||||
|
- You only need to provide the image description (prompt) when using this plugin
|
||||||
|
- The Worker automatically calls the Cloudflare AI API using the configured credentials
|
||||||
|
|
||||||
|
## Usage Instructions
|
||||||
|
|
||||||
|
1. In the chat, request to generate an image, for example:
|
||||||
|
- "Draw a cat standing on a mountain top"
|
||||||
|
- "Generate a beach sunset landscape"
|
||||||
|
|
||||||
|
2. Supported parameters:
|
||||||
|
- prompt: Image description (required, maximum 2048 characters)
|
||||||
|
- steps: Number of diffusion steps (optional, default 4, maximum 8)
|
||||||
|
|
||||||
|
Example: "Generate an image of an astronaut riding a horse, using 8 diffusion steps"
|
||||||
|
|
||||||
|
## API Format Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://schnell-worker.foryoung365.workers.dev \
|
||||||
|
-X POST \
|
||||||
|
-H "X-Api-Key: <YOUR_WORKER_API_KEY>" \
|
||||||
|
-d '{ "prompt": "cyberpunk cat", "steps": 8 }'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- There may be usage limitations based on your Cloudflare account type
|
||||||
|
- The Flux-1-Schnell model has its own capability range; not all prompts will produce ideal results
|
||||||
|
- Higher diffusion steps take longer to generate but may produce higher quality
|
||||||
|
|
||||||
|
## Privacy
|
||||||
|
|
||||||
|
- Your prompt text is sent to the Cloudflare AI API through the Worker
|
||||||
|
- This plugin does not collect or store your personal data
|
||||||
|
- Generated images are returned directly to your browser through the Worker
|
||||||
|
|
||||||
|
`(Not affiliated with any of the above entities)`
|
|
@ -0,0 +1,66 @@
|
||||||
|
# LobeChat Cloudflare Workers AI 图像生成插件
|
||||||
|
|
||||||
|
这是一个LobeChat插件,使用[Cloudflare Workers AI](https://developers.cloudflare.com/workers-ai/)的`@cf/black-forest-labs/flux-1-schnell`模型生成高质量图像。
|
||||||
|
|
||||||
|
## 功能特点
|
||||||
|
|
||||||
|
- 使用Cloudflare的Flux-1-Schnell模型生成高质量图像
|
||||||
|
- 通过Cloudflare Worker代理请求,简化认证过程
|
||||||
|
- 直接在LobeChat对话中生成和查看图像
|
||||||
|
|
||||||
|
## 设置步骤
|
||||||
|
|
||||||
|
1. 设置Cloudflare Worker
|
||||||
|
- 将提供的Worker代码部署到Cloudflare Workers
|
||||||
|
- 在Worker设置中配置以下环境变量(Secrets):
|
||||||
|
- `WORKER_API_KEY`: 设置一个安全的API密钥,用于客户端认证
|
||||||
|
- `CLOUDFLARE_API_TOKEN`: 你的Cloudflare API令牌
|
||||||
|
- `CLOUDFLARE_ACCOUNT_ID`: 你的Cloudflare账户ID
|
||||||
|
|
||||||
|
2. 在LobeChat中配置插件
|
||||||
|
- 将此插件添加到LobeChat
|
||||||
|
- 在配置页面中:
|
||||||
|
- 将你的Worker API密钥配置为`WORKER_API_KEY`
|
||||||
|
- 确保Worker URL配置正确
|
||||||
|
|
||||||
|
## 身份验证和参数
|
||||||
|
|
||||||
|
此插件使用以下配置访问你的Cloudflare Worker:
|
||||||
|
- Worker API密钥:用作X-Api-Key请求头
|
||||||
|
- 每次使用此插件时,你只需要提供图像描述(prompt)
|
||||||
|
- Worker会自动使用配置的凭证调用Cloudflare AI API
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
1. 在聊天中,请求生成图像,例如:
|
||||||
|
- "画一只站在山顶上的猫"
|
||||||
|
- "生成一幅海滩日落的风景画"
|
||||||
|
|
||||||
|
2. 支持的参数:
|
||||||
|
- prompt:图像描述(必需,最大2048字符)
|
||||||
|
- steps:扩散步骤数(可选,默认4,最大8)
|
||||||
|
|
||||||
|
例如:"生成一幅宇航员骑马的图像,使用8个扩散步骤"
|
||||||
|
|
||||||
|
## API格式示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://[your-worker-name].[your-account-name].workers.dev \
|
||||||
|
-X POST \
|
||||||
|
-H "X-Api-Key: <YOUR_WORKER_API_KEY>" \
|
||||||
|
-d '{ "prompt": "cyberpunk cat", "steps": 8 }'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 限制
|
||||||
|
|
||||||
|
- 根据你的Cloudflare账户类型,可能有使用限制
|
||||||
|
- Flux-1-Schnell模型有自己的能力范围,不是所有提示都能产生理想结果
|
||||||
|
- 扩散步骤数越大,生成时间越长,但质量可能更高
|
||||||
|
|
||||||
|
## 隐私
|
||||||
|
|
||||||
|
- 你的提示文本将通过Worker发送到Cloudflare AI API
|
||||||
|
- 此插件不会收集或存储你的个人数据
|
||||||
|
- 生成的图像通过Worker直接返回给你的浏览器
|
||||||
|
|
||||||
|
`(与上述任何实体均无关联)`
|
|
@ -1,18 +1,20 @@
|
||||||
{
|
{
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://raw.githubusercontent.com/GithuBarry/chat-plugin-search-engine/main/public/openapi.json",
|
"url": "https://raw.githubusercontent.com/foryoung365/lobechat-plugin-workers-schnell/main/public/openapi.json",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "service_http",
|
||||||
|
"authorization_type": "custom",
|
||||||
|
"custom_auth_header": "X-Api-Key: ${WORKER_API_KEY}"
|
||||||
},
|
},
|
||||||
"contact_email": "33831597+GithuBarry@users.noreply.github.com",
|
"contact_email": "1758359+foryoung365@users.noreply.github.com",
|
||||||
"description_for_human": "Google search engine via Serper.dev free API (2500x🆓/month)",
|
"description_for_human": "Generate images with Cloudflare Workers AI's flux-1-schnell model",
|
||||||
"description_for_model": "Plugin for performing web searches using the Serper.dev API to access Google search results.",
|
"description_for_model": "This plugin uses the Cloudflare Workers AI's flux-1-schnell model to generate beautiful images.",
|
||||||
"legal_info_url": "https://serper.dev/terms",
|
"legal_info_url": "https://developers.cloudflare.com/ai/",
|
||||||
"logo_url": "https://serper.dev/favicon.ico",
|
"logo_url": "https://developers.cloudflare.com/favicon.ico",
|
||||||
"name_for_human": "Search Google via Serper",
|
"name_for_human": "AI Image Generator (Flux-1-Schnell)",
|
||||||
"name_for_model": "search-engine-serper",
|
"name_for_model": "ai-image-generator-flux-schnell",
|
||||||
"schema_version": "v1"
|
"schema_version": "v1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
{
|
{
|
||||||
"components": {
|
"components": {
|
||||||
"securitySchemes": {
|
"securitySchemes": {
|
||||||
"apiAuth": {
|
"apiKeyAuth": {
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "X-API-KEY",
|
"in": "header",
|
||||||
"in": "header"
|
"name": "X-Api-Key",
|
||||||
|
"description": "API Key for authentication"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"title": "Web Search",
|
"title": "AI Image Generator",
|
||||||
"version": "1.0.0"
|
"version": "1.0.0",
|
||||||
|
"description": "Generate images using Cloudflare Workers AI's @cf/black-forest-labs/flux-1-schnell model"
|
||||||
},
|
},
|
||||||
"openapi": "3.0.0",
|
"openapi": "3.0.0",
|
||||||
"paths": {
|
"paths": {
|
||||||
"/search": {
|
"/": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "Search Google and return top 10 results",
|
"summary": "Generate Image",
|
||||||
"operationId": "searchGoogle",
|
"operationId": "generateImage",
|
||||||
|
"description": "Generate an image based on text prompt using Cloudflare Workers AI's flux-1-schnell model",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"required": true,
|
"required": true,
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": ["prompt"],
|
||||||
"q"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"q": {
|
"prompt": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "今天吃什么"
|
"description": "Text description of the image you want to generate(English only)",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 2048
|
||||||
},
|
},
|
||||||
"gl": {
|
"steps": {
|
||||||
"type": "string",
|
"type": "integer",
|
||||||
"description": "Google Geo location parameter",
|
"description": "The number of diffusion steps; higher values can improve quality but take longer",
|
||||||
"example": "cn"
|
"default": 4,
|
||||||
},
|
"minimum": 1,
|
||||||
"hl": {
|
"maximum": 8
|
||||||
"type": "string",
|
|
||||||
"description": "Google Geo locale parameter",
|
|
||||||
"example": "zh-cn"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,29 +49,30 @@
|
||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful search results",
|
"description": "Successfully generated image",
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"image/png": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "string",
|
||||||
"required": [
|
"format": "binary",
|
||||||
"result"
|
"description": "Generated image data"
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"result": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Top 10 search results",
|
|
||||||
"example": "\"title\": \"周末游推荐\",\n\"link\": \"https://www.example.com/destinations-for-weekends\",\n\"snippet\": \"周末去哪玩?周末旅游频道,精心推荐数百个周末游经典线路\",\n\"position\": 1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid request parameters"
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized, invalid API key"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Server error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"apiAuth": []
|
"apiKeyAuth": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -79,12 +80,13 @@
|
||||||
},
|
},
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"apiAuth": []
|
"apiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "https://google.serper.dev"
|
"url": "https://schnell-worker.foryoung365.workers.dev",
|
||||||
|
"description": "Cloudflare Worker for Image Generation"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"author": "Barry",
|
"author": "foryoung365",
|
||||||
"homepage": "https://github.com/GithuBarry/chat-plugin-search-engine",
|
"homepage": "https://github.com/foryoung365/lobechat-plugin-workers-schnell",
|
||||||
"identifier": "search-engine-serper",
|
"identifier": "ai-image-generator-flux-schnell",
|
||||||
"manifest": "https://raw.githubusercontent.com/GithuBarry/chat-plugin-search-engine/main/public/openapi.json",
|
"manifest": "https://raw.githubusercontent.com/foryoung365/lobechat-plugin-workers-schnell/main/public/manifest.json",
|
||||||
"meta": {
|
"meta": {
|
||||||
"avatar": "🔍",
|
"avatar": "🖼️",
|
||||||
"description": "Google search engine via Serper.dev free API (2500x🆓/month)",
|
"description": "Generate images with Cloudflare Workers AI's flux-1-schnell model",
|
||||||
"tags": ["web", "search"],
|
"tags": ["image", "ai", "generation"],
|
||||||
"title": "Search Google via Serper"
|
"title": "AI Image Generator (Flux-1-Schnell)"
|
||||||
},
|
},
|
||||||
"schemaVersion": 1
|
"schemaVersion": 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Cloudflare Worker 部署说明
|
||||||
|
|
||||||
|
本文档提供关于如何部署 Cloudflare Worker 代码的说明,该代码用于处理和代理 LobeChat 插件的请求到 Cloudflare AI API。
|
||||||
|
|
||||||
|
## 前提条件
|
||||||
|
|
||||||
|
1. 一个 Cloudflare 账户
|
||||||
|
2. 已启用 Cloudflare Workers 服务
|
||||||
|
3. 安装并配置了 [Wrangler CLI](https://developers.cloudflare.com/workers/cli-wrangler/install-update)(Cloudflare 的 Worker CLI 工具)
|
||||||
|
|
||||||
|
## 部署步骤
|
||||||
|
|
||||||
|
### 1. 准备工作
|
||||||
|
|
||||||
|
首先,确保你已经获取了以下信息:
|
||||||
|
|
||||||
|
- 你的 Cloudflare 账户 ID(可在 Cloudflare 控制台中找到)
|
||||||
|
- 一个有权限访问 Cloudflare Workers 和 AI API 的 API Token
|
||||||
|
|
||||||
|
### 2. 创建 Worker 项目
|
||||||
|
|
||||||
|
使用 Wrangler 创建一个新的 Worker 项目:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建新项目
|
||||||
|
wrangler init ai-image-proxy-worker
|
||||||
|
cd ai-image-proxy-worker
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 配置 Worker
|
||||||
|
|
||||||
|
将本仓库中的 `src/worker.ts` 文件内容复制到你的 Worker 项目的主文件中(通常是 `src/index.ts`)。
|
||||||
|
|
||||||
|
然后,创建或修改 `wrangler.toml` 文件如下:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
name = "ai-image-proxy-worker"
|
||||||
|
compatibility_date = "2023-10-30"
|
||||||
|
|
||||||
|
[vars]
|
||||||
|
# 这里不要填写敏感信息,这些只是占位符
|
||||||
|
# 实际密钥应使用 Secrets 设置
|
||||||
|
|
||||||
|
# 可选:如果你需要绑定自定义域名
|
||||||
|
# [routes]
|
||||||
|
# pattern = "your-domain.com/*"
|
||||||
|
# zone_id = "your-zone-id"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 设置环境变量(Secrets)
|
||||||
|
|
||||||
|
使用 Wrangler 设置必要的 Secrets:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 设置客户端 API 密钥(你自己定义的值,用于客户端访问你的 Worker)
|
||||||
|
wrangler secret put WORKER_API_KEY
|
||||||
|
|
||||||
|
# 设置 Cloudflare API Token(从 Cloudflare 控制台获取)
|
||||||
|
wrangler secret put CLOUDFLARE_API_TOKEN
|
||||||
|
|
||||||
|
# 设置 Cloudflare 账户 ID
|
||||||
|
wrangler secret put CLOUDFLARE_ACCOUNT_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
每条命令运行后,将提示你输入相应的值。
|
||||||
|
|
||||||
|
### 5. 部署 Worker
|
||||||
|
|
||||||
|
完成配置后,部署 Worker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wrangler deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
成功部署后,Wrangler 将显示你的 Worker 的 URL,例如:`https://ai-image-proxy-worker.yourusername.workers.dev`。
|
||||||
|
|
||||||
|
### 6. 配置 LobeChat 插件
|
||||||
|
|
||||||
|
按照 README 中的说明配置 LobeChat 插件,将 `WORKER_API_KEY` 设置为你在步骤 4 中配置的客户端 API 密钥。
|
||||||
|
|
||||||
|
## 故障排除
|
||||||
|
|
||||||
|
如果遇到问题,请检查:
|
||||||
|
|
||||||
|
1. Cloudflare 控制台中的 Worker 日志
|
||||||
|
2. 确保所有环境变量(Secrets)都已正确设置
|
||||||
|
3. 验证你的 API Token 是否有足够的权限
|
||||||
|
4. 检查你的账户是否启用了 Workers AI 服务
|
||||||
|
|
||||||
|
## 安全注意事项
|
||||||
|
|
||||||
|
- 定期轮换你的 API 密钥和令牌
|
||||||
|
- 为 Worker API 密钥使用强密码,因为这是客户端用来访问你的 Worker 的凭证
|
||||||
|
- 考虑添加速率限制或其他安全措施来防止滥用
|
||||||
|
|
||||||
|
## 资源链接
|
||||||
|
|
||||||
|
- [Cloudflare Workers 文档](https://developers.cloudflare.com/workers/)
|
||||||
|
- [Workers AI 文档](https://developers.cloudflare.com/workers-ai/)
|
|
@ -0,0 +1,77 @@
|
||||||
|
interface Env {
|
||||||
|
WORKER_API_KEY: string;
|
||||||
|
CLOUDFLARE_API_TOKEN: string;
|
||||||
|
CLOUDFLARE_ACCOUNT_ID: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
|
||||||
|
if (request.method !== 'POST') {
|
||||||
|
return new Response('Expected POST', { status: 405 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 认证客户端 (使用 X-Api-Key 请求头)
|
||||||
|
const clientApiKey = request.headers.get('X-Api-Key');
|
||||||
|
// 'WORKER_API_KEY' 是你在 Cloudflare Secrets 中设置的变量名
|
||||||
|
if (!clientApiKey || clientApiKey !== env.WORKER_API_KEY) {
|
||||||
|
return new Response('Unauthorized: Missing or invalid API Key', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 2. 解析客户端请求体 (只需要 prompt)
|
||||||
|
const clientData = await request.json() as { prompt?: string, steps?: unknown };
|
||||||
|
const prompt = clientData.prompt;
|
||||||
|
const steps = clientData.steps;
|
||||||
|
|
||||||
|
if (!prompt) {
|
||||||
|
return new Response('Missing "prompt" in request body', { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 从环境变量(Secrets)获取 Worker 自身的凭证
|
||||||
|
const apiToken = env.CLOUDFLARE_API_TOKEN;
|
||||||
|
const accountId = env.CLOUDFLARE_ACCOUNT_ID;
|
||||||
|
|
||||||
|
if (!apiToken || !accountId) {
|
||||||
|
console.error('ERROR: Missing Cloudflare credentials in Worker secrets. Ensure CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID secrets are set.');
|
||||||
|
return new Response('Internal Server Error - Configuration Missing', { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 构造发往 Cloudflare AI 的请求 (使用 Worker 的凭证)
|
||||||
|
const aiApiUrl = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/@cf/black-forest-labs/flux-1-schnell`;
|
||||||
|
|
||||||
|
const aiRequest = new Request(aiApiUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${apiToken}`, // 使用 Worker 的 Token
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ prompt: prompt, steps: steps || 4 }), // 使用客户端的 Prompt
|
||||||
|
});
|
||||||
|
|
||||||
|
// 5. 发送请求到 AI API 并获取响应
|
||||||
|
console.log(`Forwarding request to AI API for prompt: "${prompt}"`);
|
||||||
|
const aiResponse = await fetch(aiRequest);
|
||||||
|
console.log(`Received response from AI API with status: ${aiResponse.status}`);
|
||||||
|
|
||||||
|
|
||||||
|
// 6. 将 AI 的响应直接返回给客户端
|
||||||
|
// 创建一个新的 Response 对象以避免潜在的 header 问题或 immutability 问题
|
||||||
|
const responseHeaders = new Headers(aiResponse.headers);
|
||||||
|
//responseHeaders.set('X-Proxied-By', 'my-ai-proxy-worker'); // 添加一个自定义头(可选)
|
||||||
|
|
||||||
|
return new Response(aiResponse.body, {
|
||||||
|
status: aiResponse.status,
|
||||||
|
statusText: aiResponse.statusText,
|
||||||
|
headers: responseHeaders // 返回 AI 的响应头,可以按需修改
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error: unknown) {
|
||||||
|
console.error('Error processing request:', error);
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
return new Response('Invalid JSON in request body', { status: 400 });
|
||||||
|
}
|
||||||
|
// 避免将详细错误暴露给客户端
|
||||||
|
return new Response(`Internal Server Error: ${error instanceof Error ? error.message : 'Unknown error'}`, { status: 500 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} satisfies ExportedHandler<Env>;
|
Loading…
Reference in New Issue