Compare commits
No commits in common. "8a51997fae99b9158164958a786a7c4ffa92cb0b" and "d09b0a13e63f661ac79f4bb31bd1105d747acc3a" have entirely different histories.
8a51997fae
...
d09b0a13e6
|
@ -0,0 +1,45 @@
|
||||||
|
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.
|
|
@ -0,0 +1,21 @@
|
||||||
|
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.
|
|
@ -0,0 +1,15 @@
|
||||||
|
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.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
name: '📝 其他 Other'
|
||||||
|
about: '其他问题 | Other issues'
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
---
|
|
@ -0,0 +1,18 @@
|
||||||
|
#### 💻 变更类型 | 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. -->
|
|
@ -0,0 +1,72 @@
|
||||||
|
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'
|
|
@ -0,0 +1,23 @@
|
||||||
|
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
|
|
@ -0,0 +1,52 @@
|
||||||
|
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,若有任何问题,可评论回复。
|
|
@ -0,0 +1,33 @@
|
||||||
|
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 }}
|
|
@ -0,0 +1,27 @@
|
||||||
|
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
|
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
||||||
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.
|
|
66
README.md
66
README.md
|
@ -1,66 +0,0 @@
|
||||||
# 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)`
|
|
66
README_CN.md
66
README_CN.md
|
@ -1,66 +0,0 @@
|
||||||
# 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,20 +1,18 @@
|
||||||
{
|
{
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://raw.githubusercontent.com/foryoung365/lobechat-plugin-workers-schnell/main/public/openapi.json",
|
"url": "https://raw.githubusercontent.com/GithuBarry/chat-plugin-search-engine/main/public/openapi.json",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "service_http",
|
"type": "none"
|
||||||
"authorization_type": "custom",
|
|
||||||
"custom_auth_header": "X-Api-Key: ${WORKER_API_KEY}"
|
|
||||||
},
|
},
|
||||||
"contact_email": "1758359+foryoung365@users.noreply.github.com",
|
"contact_email": "33831597+GithuBarry@users.noreply.github.com",
|
||||||
"description_for_human": "Generate images with Cloudflare Workers AI's flux-1-schnell model",
|
"description_for_human": "Google search engine via Serper.dev free API (2500x🆓/month)",
|
||||||
"description_for_model": "This plugin uses the Cloudflare Workers AI's flux-1-schnell model to generate beautiful images.",
|
"description_for_model": "Plugin for performing web searches using the Serper.dev API to access Google search results.",
|
||||||
"legal_info_url": "https://developers.cloudflare.com/ai/",
|
"legal_info_url": "https://serper.dev/terms",
|
||||||
"logo_url": "https://developers.cloudflare.com/favicon.ico",
|
"logo_url": "https://serper.dev/favicon.ico",
|
||||||
"name_for_human": "AI Image Generator (Flux-1-Schnell)",
|
"name_for_human": "Search Google via Serper",
|
||||||
"name_for_model": "ai-image-generator-flux-schnell",
|
"name_for_model": "search-engine-serper",
|
||||||
"schema_version": "v1"
|
"schema_version": "v1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
{
|
{
|
||||||
"components": {
|
"components": {
|
||||||
"securitySchemes": {
|
"securitySchemes": {
|
||||||
"apiKeyAuth": {
|
"apiAuth": {
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"in": "header",
|
"name": "X-API-KEY",
|
||||||
"name": "X-Api-Key",
|
"in": "header"
|
||||||
"description": "API Key for authentication"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"title": "AI Image Generator",
|
"title": "Web Search",
|
||||||
"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": "Generate Image",
|
"summary": "Search Google and return top 10 results",
|
||||||
"operationId": "generateImage",
|
"operationId": "searchGoogle",
|
||||||
"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": ["prompt"],
|
"required": [
|
||||||
|
"q"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"prompt": {
|
"q": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Text description of the image you want to generate(English only)",
|
"example": "今天吃什么"
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 2048
|
|
||||||
},
|
},
|
||||||
"steps": {
|
"gl": {
|
||||||
"type": "integer",
|
"type": "string",
|
||||||
"description": "The number of diffusion steps; higher values can improve quality but take longer",
|
"description": "Google Geo location parameter",
|
||||||
"default": 4,
|
"example": "cn"
|
||||||
"minimum": 1,
|
},
|
||||||
"maximum": 8
|
"hl": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Google Geo locale parameter",
|
||||||
|
"example": "zh-cn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,30 +49,29 @@
|
||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successfully generated image",
|
"description": "Successful search results",
|
||||||
"content": {
|
"content": {
|
||||||
"image/png": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"result"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"result": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "binary",
|
"description": "Top 10 search results",
|
||||||
"description": "Generated image data"
|
"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": [
|
||||||
{
|
{
|
||||||
"apiKeyAuth": []
|
"apiAuth": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -80,13 +79,12 @@
|
||||||
},
|
},
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"apiKeyAuth": []
|
"apiAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "https://schnell-worker.foryoung365.workers.dev",
|
"url": "https://google.serper.dev"
|
||||||
"description": "Cloudflare Worker for Image Generation"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"author": "foryoung365",
|
"author": "Barry",
|
||||||
"homepage": "https://github.com/foryoung365/lobechat-plugin-workers-schnell",
|
"homepage": "https://github.com/GithuBarry/chat-plugin-search-engine",
|
||||||
"identifier": "ai-image-generator-flux-schnell",
|
"identifier": "search-engine-serper",
|
||||||
"manifest": "https://raw.githubusercontent.com/foryoung365/lobechat-plugin-workers-schnell/main/public/manifest.json",
|
"manifest": "https://raw.githubusercontent.com/GithuBarry/chat-plugin-search-engine/main/public/openapi.json",
|
||||||
"meta": {
|
"meta": {
|
||||||
"avatar": "🖼️",
|
"avatar": "🔍",
|
||||||
"description": "Generate images with Cloudflare Workers AI's flux-1-schnell model",
|
"description": "Google search engine via Serper.dev free API (2500x🆓/month)",
|
||||||
"tags": ["image", "ai", "generation"],
|
"tags": ["web", "search"],
|
||||||
"title": "AI Image Generator (Flux-1-Schnell)"
|
"title": "Search Google via Serper"
|
||||||
},
|
},
|
||||||
"schemaVersion": 1
|
"schemaVersion": 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
# 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/)
|
|
|
@ -1,77 +0,0 @@
|
||||||
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