forked from boos/BoosAPI
Full internal rename: metapi → boosapi
Rename all remaining internal protocol identifiers: - x-metapi-* headers → x-boosapi-* - metapi: reasoning prefix → boosapi: - __metapi* runtime markers → __boosapi* - file-metapi-* → file-boosapi-* - METAPI_* env vars → BOOSAPI_* - metapi_turn_state/metapi_mcp_item__ etc. → boosapi_* - package.json name → boosapi - Docker/deploy/k3s/docs references 46 files changed, 168 insertions, 170 deletions. typecheck:web passes (0 new errors). Signed-off-by: Boos4721 <boos4721@icloud.com>
This commit is contained in:
+2
-2
@@ -25,7 +25,7 @@ Metapi 是 AI API 聚合平台(New API、One API、OneHub 等)的元聚合
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/YOUR_USERNAME/metapi.git
|
git clone https://github.com/YOUR_USERNAME/metapi.git
|
||||||
cd metapi
|
cd boosapi
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Install dependencies** / **安装依赖**
|
2. **Install dependencies** / **安装依赖**
|
||||||
@@ -213,7 +213,7 @@ If you're adding support for a new AI API platform / 如果您要添加对新 AI
|
|||||||
|
|
||||||
## Getting Help / 获取帮助
|
## Getting Help / 获取帮助
|
||||||
|
|
||||||
- 📖 [Documentation](https://metapi.cita777.me) / [文档](https://metapi.cita777.me)
|
- 📖 [Documentation](https://boosapi.cita777.me) / [文档](https://boosapi.cita777.me)
|
||||||
- 💬 [GitHub Discussions](https://github.com/cita-777/metapi/discussions) / [GitHub 讨论区](https://github.com/cita-777/metapi/discussions)
|
- 💬 [GitHub Discussions](https://github.com/cita-777/metapi/discussions) / [GitHub 讨论区](https://github.com/cita-777/metapi/discussions)
|
||||||
- 🐛 [Issue Tracker](https://github.com/cita-777/metapi/issues) / [Issue 跟踪](https://github.com/cita-777/metapi/issues)
|
- 🐛 [Issue Tracker](https://github.com/cita-777/metapi/issues) / [Issue 跟踪](https://github.com/cita-777/metapi/issues)
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -37,8 +37,8 @@ RUN python3 -m venv venv \
|
|||||||
ENV PATH="/app/comfy/venv/bin:${PATH}"
|
ENV PATH="/app/comfy/venv/bin:${PATH}"
|
||||||
|
|
||||||
# ========== Metapi ==========
|
# ========== Metapi ==========
|
||||||
FROM base AS metapi
|
FROM base AS boosapi
|
||||||
WORKDIR /app/metapi
|
WORKDIR /app/boosapi
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN npm install
|
RUN npm install
|
||||||
RUN npm run build --if-present
|
RUN npm run build --if-present
|
||||||
@@ -56,15 +56,15 @@ RUN apt-get update && apt-get install -y \
|
|||||||
COPY --from=rtk-builder /usr/local/bin/rtk /usr/local/bin/rtk
|
COPY --from=rtk-builder /usr/local/bin/rtk /usr/local/bin/rtk
|
||||||
COPY --from=comfyui /app/comfy /app/comfy
|
COPY --from=comfyui /app/comfy /app/comfy
|
||||||
COPY --from=comfyui /app/comfy/venv /app/comfy/venv
|
COPY --from=comfyui /app/comfy/venv /app/comfy/venv
|
||||||
COPY --from=metapi /app/metapi /app/metapi
|
COPY --from=boosapi /app/boosapi /app/boosapi
|
||||||
COPY --from=metapi /usr/lib/node_modules /usr/lib/node_modules
|
COPY --from=boosapi /usr/lib/node_modules /usr/lib/node_modules
|
||||||
|
|
||||||
# Node path
|
# Node path
|
||||||
ENV PATH="/app/comfy/venv/bin:/usr/local/bin:${PATH}"
|
ENV PATH="/app/comfy/venv/bin:/usr/local/bin:${PATH}"
|
||||||
ENV COMFYUI_BASE=http://127.0.0.1:8188
|
ENV COMFYUI_BASE=http://127.0.0.1:8188
|
||||||
ENV AUTH_TOKEN=change-me-admin-token
|
ENV AUTH_TOKEN=change-me-admin-token
|
||||||
|
|
||||||
WORKDIR /app/metapi
|
WORKDIR /app/boosapi
|
||||||
|
|
||||||
# Supervisor config
|
# Supervisor config
|
||||||
RUN mkdir -p /var/log/supervisor
|
RUN mkdir -p /var/log/supervisor
|
||||||
@@ -75,19 +75,19 @@ user=root
|
|||||||
logfile=/var/log/supervisor/supervisord.log
|
logfile=/var/log/supervisor/supervisord.log
|
||||||
pidfile=/tmp/supervisord.pid
|
pidfile=/tmp/supervisord.pid
|
||||||
|
|
||||||
[program:metapi-server]
|
[program:boosapi-server]
|
||||||
command=npm run dev:server
|
command=npm run dev:server
|
||||||
directory=/app/metapi
|
directory=/app/boosapi
|
||||||
autorestart=true
|
autorestart=true
|
||||||
stdout_logfile=/var/log/supervisor/metapi-server.log
|
stdout_logfile=/var/log/supervisor/boosapi-server.log
|
||||||
stderr_logfile=/var/log/supervisor/metapi-server.err
|
stderr_logfile=/var/log/supervisor/boosapi-server.err
|
||||||
|
|
||||||
[program:metapi-web]
|
[program:boosapi-web]
|
||||||
command=npx vite --host 0.0.0.0 --port 5173
|
command=npx vite --host 0.0.0.0 --port 5173
|
||||||
directory=/app/metapi
|
directory=/app/boosapi
|
||||||
autorestart=true
|
autorestart=true
|
||||||
stdout_logfile=/var/log/supervisor/metapi-web.log
|
stdout_logfile=/var/log/supervisor/boosapi-web.log
|
||||||
stderr_logfile=/var/log/supervisor/metapi-web.err
|
stderr_logfile=/var/log/supervisor/boosapi-web.err
|
||||||
|
|
||||||
[program:comfyui]
|
[program:comfyui]
|
||||||
command=python3 main.py --listen 0.0.0.0 --port 8188
|
command=python3 main.py --listen 0.0.0.0 --port 8188
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ mkdir boosapi && cd boosapi
|
|||||||
cat > docker-compose.yml << 'EOF'
|
cat > docker-compose.yml << 'EOF'
|
||||||
services:
|
services:
|
||||||
boosapi:
|
boosapi:
|
||||||
image: 1467078763/metapi:latest
|
image: 1467078763/boosapi:latest
|
||||||
ports:
|
ports:
|
||||||
- "4000:4000"
|
- "4000:4000"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
+1
-1
@@ -147,7 +147,7 @@ mkdir boosapi && cd boosapi
|
|||||||
cat > docker-compose.yml << 'EOF'
|
cat > docker-compose.yml << 'EOF'
|
||||||
services:
|
services:
|
||||||
boosapi:
|
boosapi:
|
||||||
image: 1467078763/metapi:latest
|
image: 1467078763/boosapi:latest
|
||||||
ports:
|
ports:
|
||||||
- "4000:4000"
|
- "4000:4000"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
name: metapi
|
name: boosapi
|
||||||
description: Minimal metapi chart for digest-aware k3s update-center setups
|
description: Minimal boosapi chart for digest-aware k3s update-center setups
|
||||||
type: application
|
type: application
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
appVersion: "1.3.0"
|
appVersion: "1.3.0"
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "metapi.fullname" . }}
|
name: {{ include "boosapi.fullname" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "metapi.labels" . | nindent 4 }}
|
{{- include "boosapi.labels" . | nindent 4 }}
|
||||||
spec:
|
spec:
|
||||||
replicas: {{ .Values.replicaCount }}
|
replicas: {{ .Values.replicaCount }}
|
||||||
revisionHistoryLimit: 2
|
revisionHistoryLimit: 2
|
||||||
@@ -17,25 +17,25 @@ spec:
|
|||||||
maxUnavailable: {{ .Values.deployment.strategy.maxUnavailable }}
|
maxUnavailable: {{ .Values.deployment.strategy.maxUnavailable }}
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app.kubernetes.io/name: {{ include "metapi.name" . }}
|
app.kubernetes.io/name: {{ include "boosapi.name" . }}
|
||||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: {{ include "metapi.name" . }}
|
app.kubernetes.io/name: {{ include "boosapi.name" . }}
|
||||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
annotations:
|
annotations:
|
||||||
metapi/image-tag: {{ .Values.image.tag | quote }}
|
boosapi/image-tag: {{ .Values.image.tag | quote }}
|
||||||
metapi/image-digest: {{ .Values.image.digest | quote }}
|
boosapi/image-digest: {{ .Values.image.digest | quote }}
|
||||||
checksum/env-secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum | quote }}
|
checksum/env-secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum | quote }}
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: metapi
|
- name: boosapi
|
||||||
image: "{{ .Values.image.repository }}{{ if .Values.image.digest }}@{{ .Values.image.digest }}{{ else }}:{{ .Values.image.tag }}{{ end }}"
|
image: "{{ .Values.image.repository }}{{ if .Values.image.digest }}@{{ .Values.image.digest }}{{ else }}:{{ .Values.image.tag }}{{ end }}"
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
envFrom:
|
envFrom:
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: {{ include "metapi.envSecretName" . }}
|
name: {{ include "boosapi.envSecretName" . }}
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
containerPort: 4000
|
containerPort: 4000
|
||||||
@@ -50,10 +50,10 @@ spec:
|
|||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 30
|
||||||
periodSeconds: 20
|
periodSeconds: 20
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: metapi-data
|
- name: boosapi-data
|
||||||
mountPath: /app/data
|
mountPath: /app/data
|
||||||
volumes:
|
volumes:
|
||||||
- name: metapi-data
|
- name: boosapi-data
|
||||||
hostPath:
|
hostPath:
|
||||||
path: {{ .Values.persistence.hostPath }}
|
path: {{ .Values.persistence.hostPath }}
|
||||||
type: DirectoryOrCreate
|
type: DirectoryOrCreate
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "metapi.envSecretName" . }}
|
name: {{ include "boosapi.envSecretName" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "metapi.labels" . | nindent 4 }}
|
{{- include "boosapi.labels" . | nindent 4 }}
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
AUTH_TOKEN: {{ required "env.authToken is required" .Values.env.authToken | quote }}
|
AUTH_TOKEN: {{ required "env.authToken is required" .Values.env.authToken | quote }}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "metapi.fullname" . }}
|
name: {{ include "boosapi.fullname" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "metapi.labels" . | nindent 4 }}
|
{{- include "boosapi.labels" . | nindent 4 }}
|
||||||
spec:
|
spec:
|
||||||
type: {{ .Values.service.type }}
|
type: {{ .Values.service.type }}
|
||||||
selector:
|
selector:
|
||||||
app.kubernetes.io/name: {{ include "metapi.name" . }}
|
app.kubernetes.io/name: {{ include "boosapi.name" . }}
|
||||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
|
|
||||||
image:
|
image:
|
||||||
repository: 1467078763/metapi
|
repository: 1467078763/boosapi
|
||||||
tag: latest
|
tag: latest
|
||||||
digest: ""
|
digest: ""
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
@@ -17,7 +17,7 @@ deployment:
|
|||||||
maxUnavailable: 0
|
maxUnavailable: 0
|
||||||
|
|
||||||
persistence:
|
persistence:
|
||||||
hostPath: /opt/1panel/docker/compose/metapihub/data
|
hostPath: /opt/1panel/docker/compose/boosapihub/data
|
||||||
|
|
||||||
env:
|
env:
|
||||||
authToken: ""
|
authToken: ""
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ServiceAccount
|
kind: ServiceAccount
|
||||||
metadata:
|
metadata:
|
||||||
name: metapi-deploy-helper
|
name: boosapi-deploy-helper
|
||||||
namespace: ai
|
namespace: ai
|
||||||
---
|
---
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
metadata:
|
metadata:
|
||||||
name: metapi-deploy-helper-admin
|
name: boosapi-deploy-helper-admin
|
||||||
namespace: ai
|
namespace: ai
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: metapi-deploy-helper
|
name: boosapi-deploy-helper
|
||||||
namespace: ai
|
namespace: ai
|
||||||
roleRef:
|
roleRef:
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
@@ -21,7 +21,7 @@ roleRef:
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: metapi-deploy-helper-auth
|
name: boosapi-deploy-helper-auth
|
||||||
namespace: ai
|
namespace: ai
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
@@ -30,22 +30,22 @@ stringData:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: metapi-deploy-helper
|
name: boosapi-deploy-helper
|
||||||
namespace: ai
|
namespace: ai
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app.kubernetes.io/name: metapi-deploy-helper
|
app.kubernetes.io/name: boosapi-deploy-helper
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: metapi-deploy-helper
|
app.kubernetes.io/name: boosapi-deploy-helper
|
||||||
spec:
|
spec:
|
||||||
serviceAccountName: metapi-deploy-helper
|
serviceAccountName: boosapi-deploy-helper
|
||||||
containers:
|
containers:
|
||||||
- name: helper
|
- name: helper
|
||||||
image: 1467078763/metapi:latest
|
image: 1467078763/boosapi:latest
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
command: ["/bin/sh", "-lc"]
|
command: ["/bin/sh", "-lc"]
|
||||||
args:
|
args:
|
||||||
@@ -85,7 +85,7 @@ spec:
|
|||||||
- name: DEPLOY_HELPER_TOKEN
|
- name: DEPLOY_HELPER_TOKEN
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: metapi-deploy-helper-auth
|
name: boosapi-deploy-helper-auth
|
||||||
key: DEPLOY_HELPER_TOKEN
|
key: DEPLOY_HELPER_TOKEN
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
@@ -100,23 +100,23 @@ spec:
|
|||||||
initialDelaySeconds: 15
|
initialDelaySeconds: 15
|
||||||
periodSeconds: 20
|
periodSeconds: 20
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: metapi-chart
|
- name: boosapi-chart
|
||||||
mountPath: /opt/metapi-k3s/chart
|
mountPath: /opt/boosapi-k3s/chart
|
||||||
readOnly: true
|
readOnly: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: metapi-chart
|
- name: boosapi-chart
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /opt/metapi-k3s/chart
|
path: /opt/boosapi-k3s/chart
|
||||||
type: Directory
|
type: Directory
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: metapi-deploy-helper
|
name: boosapi-deploy-helper
|
||||||
namespace: ai
|
namespace: ai
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
app.kubernetes.io/name: metapi-deploy-helper
|
app.kubernetes.io/name: boosapi-deploy-helper
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
port: 9850
|
port: 9850
|
||||||
|
|||||||
+12
-12
@@ -1,4 +1,4 @@
|
|||||||
FROM node:22-bookworm-slim AS metapi-builder
|
FROM node:22-bookworm-slim AS boosapi-builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN echo 'Acquire::http::Proxy "false";' > /etc/apt/apt.conf.d/99no-proxy && apt-get update && apt-get install -y --no-install-recommends python3 make g++ && rm -rf /var/lib/apt/lists/*
|
RUN echo 'Acquire::http::Proxy "false";' > /etc/apt/apt.conf.d/99no-proxy && apt-get update && apt-get install -y --no-install-recommends python3 make g++ && rm -rf /var/lib/apt/lists/*
|
||||||
@@ -54,16 +54,16 @@ RUN git clone https://github.com/comfyanonymous/ComfyUI.git . \
|
|||||||
&& rm -rf ~/.cache/pip
|
&& rm -rf ~/.cache/pip
|
||||||
ENV PATH="/app/comfy/venv/bin:${PATH}"
|
ENV PATH="/app/comfy/venv/bin:${PATH}"
|
||||||
|
|
||||||
# Copy metapi (built)
|
# Copy boosapi (built)
|
||||||
WORKDIR /app/metapi
|
WORKDIR /app/boosapi
|
||||||
COPY --from=metapi-builder /app/dist ./dist
|
COPY --from=boosapi-builder /app/dist ./dist
|
||||||
COPY --from=metapi-builder /app/node_modules ./node_modules
|
COPY --from=boosapi-builder /app/node_modules ./node_modules
|
||||||
COPY --from=metapi-builder /app/package.json ./
|
COPY --from=boosapi-builder /app/package.json ./
|
||||||
COPY --from=metapi-builder /app/drizzle ./drizzle
|
COPY --from=boosapi-builder /app/drizzle ./drizzle
|
||||||
RUN mkdir -p data
|
RUN mkdir -p data
|
||||||
|
|
||||||
# Copy BoosAPI custom nodes for ComfyUI (call local BoosAPI API)
|
# Copy BoosAPI custom nodes for ComfyUI (call local BoosAPI API)
|
||||||
COPY --from=metapi-builder /app/boosapi_comfy_nodes.py /app/comfy/custom_nodes/boosapi_comfy_nodes.py
|
COPY --from=boosapi-builder /app/boosapi_comfy_nodes.py /app/comfy/custom_nodes/boosapi_comfy_nodes.py
|
||||||
|
|
||||||
# Supervisor config
|
# Supervisor config
|
||||||
RUN mkdir -p /var/log/supervisor
|
RUN mkdir -p /var/log/supervisor
|
||||||
@@ -74,12 +74,12 @@ user=root
|
|||||||
logfile=/var/log/supervisor/supervisord.log
|
logfile=/var/log/supervisor/supervisord.log
|
||||||
pidfile=/tmp/supervisord.pid
|
pidfile=/tmp/supervisord.pid
|
||||||
|
|
||||||
[program:metapi]
|
[program:boosapi]
|
||||||
command=sh -c "node dist/server/db/migrate.js && node dist/server/index.js"
|
command=sh -c "node dist/server/db/migrate.js && node dist/server/index.js"
|
||||||
directory=/app/metapi
|
directory=/app/boosapi
|
||||||
autorestart=true
|
autorestart=true
|
||||||
stdout_logfile=/var/log/supervisor/metapi.log
|
stdout_logfile=/var/log/supervisor/boosapi.log
|
||||||
stderr_logfile=/var/log/supervisor/metapi.err
|
stderr_logfile=/var/log/supervisor/boosapi.err
|
||||||
|
|
||||||
[program:comfyui]
|
[program:comfyui]
|
||||||
command=python3 main.py --listen 0.0.0.0 --port 8188 --cpu
|
command=python3 main.py --listen 0.0.0.0 --port 8188 --cpu
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# This file is automatically picked up by Docker Compose during local development.
|
# This file is automatically picked up by Docker Compose during local development.
|
||||||
# It overrides the image reference in docker-compose.yml with a local build.
|
# It overrides the image reference in docker-compose.yml with a local build.
|
||||||
services:
|
services:
|
||||||
metapi:
|
boosapi:
|
||||||
image: ~
|
image: ~
|
||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
metapi:
|
boosapi:
|
||||||
image: 1467078763/metapi:latest
|
image: 1467078763/boosapi:latest
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:4000:4000"
|
- "127.0.0.1:4000:4000"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default withMermaid(
|
|||||||
{ text: 'OAuth 管理', link: '/oauth' },
|
{ text: 'OAuth 管理', link: '/oauth' },
|
||||||
{ text: 'FAQ', link: '/faq' },
|
{ text: 'FAQ', link: '/faq' },
|
||||||
{ text: '文档维护', link: '/README' },
|
{ text: '文档维护', link: '/README' },
|
||||||
{ text: '项目主页', link: 'https://github.com/cita-777/metapi' },
|
{ text: '项目主页', link: 'https://github.com/cita-777/boosapi' },
|
||||||
],
|
],
|
||||||
sidebar: [
|
sidebar: [
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,7 @@ export default withMermaid(
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{ icon: 'github', link: 'https://github.com/cita-777/metapi' },
|
{ icon: 'github', link: 'https://github.com/cita-777/boosapi' },
|
||||||
],
|
],
|
||||||
outline: {
|
outline: {
|
||||||
level: [2, 3],
|
level: [2, 3],
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ Metapi 暴露标准 OpenAI / Claude 兼容接口,下游客户端通常只需
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
model = "gpt-5"
|
model = "gpt-5"
|
||||||
model_provider = "metapi"
|
model_provider = "boosapi"
|
||||||
|
|
||||||
[model_providers.metapi]
|
[model_providers.boosapi]
|
||||||
name = "metapi"
|
name = "boosapi"
|
||||||
base_url = "https://your-domain.com/v1"
|
base_url = "https://your-domain.com/v1"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -161,7 +161,7 @@ Render 免费实例在 15 分钟无流量后会自动休眠。使用 UptimeRobot
|
|||||||
### 标准步骤
|
### 标准步骤
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir metapi && cd metapi
|
mkdir boosapi && cd boosapi
|
||||||
|
|
||||||
# 创建 docker-compose.yml(参见快速上手)
|
# 创建 docker-compose.yml(参见快速上手)
|
||||||
# 设置环境变量
|
# 设置环境变量
|
||||||
@@ -193,7 +193,7 @@ docker compose --env-file .env up -d
|
|||||||
## Docker 命令部署
|
## Docker 命令部署
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --name metapi \
|
docker run -d --name boosapi \
|
||||||
-p 4000:4000 \
|
-p 4000:4000 \
|
||||||
-e AUTH_TOKEN=your-admin-token \
|
-e AUTH_TOKEN=your-admin-token \
|
||||||
-e PROXY_TOKEN=your-proxy-sk-token \
|
-e PROXY_TOKEN=your-proxy-sk-token \
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
### 1. 创建项目目录
|
### 1. 创建项目目录
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir metapi && cd metapi
|
mkdir boosapi && cd boosapi
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 创建 `docker-compose.yml`
|
### 2. 创建 `docker-compose.yml`
|
||||||
@@ -34,7 +34,7 @@ mkdir metapi && cd metapi
|
|||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
metapi:
|
metapi:
|
||||||
image: 1467078763/metapi:latest
|
image: 1467078763/boosapi:latest
|
||||||
ports:
|
ports:
|
||||||
- "4000:4000"
|
- "4000:4000"
|
||||||
volumes:
|
volumes:
|
||||||
@@ -111,7 +111,7 @@ Linux 安装包选择建议:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/cita-777/metapi.git
|
git clone https://github.com/cita-777/metapi.git
|
||||||
cd metapi
|
cd boosapi
|
||||||
npm install
|
npm install
|
||||||
npm run db:migrate
|
npm run db:migrate
|
||||||
npm run dev
|
npm run dev
|
||||||
|
|||||||
+21
-21
@@ -37,7 +37,7 @@ K3s 更新中心的日常入口位于:
|
|||||||
| Deploy Helper URL | UI:设置 → 更新中心 | 例如集群内 Service 地址 |
|
| Deploy Helper URL | UI:设置 → 更新中心 | 例如集群内 Service 地址 |
|
||||||
| Namespace / Release Name / Chart Ref / Image Repository | UI:设置 → 更新中心 | 都是页面里直接填的部署配置 |
|
| Namespace / Release Name / Chart Ref / Image Repository | UI:设置 → 更新中心 | 都是页面里直接填的部署配置 |
|
||||||
| GitHub Releases / Docker Hub / 默认部署来源 | UI:设置 → 更新中心 | 属于页面里的版本来源策略 |
|
| GitHub Releases / Docker Hub / 默认部署来源 | UI:设置 → 更新中心 | 属于页面里的版本来源策略 |
|
||||||
| 主 Metapi 到 helper 的认证 token | 主 Metapi 环境变量 | `DEPLOY_HELPER_TOKEN` 或 `UPDATE_CENTER_HELPER_TOKEN` |
|
| 主 BoosAPI 到 helper 的认证 token | 主 BoosAPI 环境变量 | `DEPLOY_HELPER_TOKEN` 或 `UPDATE_CENTER_HELPER_TOKEN` |
|
||||||
| helper 自己监听在哪个地址和端口 | helper 环境变量 / manifest | `DEPLOY_HELPER_HOST` / `DEPLOY_HELPER_PORT` |
|
| helper 自己监听在哪个地址和端口 | helper 环境变量 / manifest | `DEPLOY_HELPER_HOST` / `DEPLOY_HELPER_PORT` |
|
||||||
| helper 自己的 Bearer Token | helper 环境变量 / manifest | `DEPLOY_HELPER_TOKEN`,且必须与主服务一致 |
|
| helper 自己的 Bearer Token | helper 环境变量 / manifest | `DEPLOY_HELPER_TOKEN`,且必须与主服务一致 |
|
||||||
| chart 是否真的支持 digest 部署 | chart 文件本身 | 这不是 UI,也不是普通 env,要看 chart 模板 |
|
| chart 是否真的支持 digest 部署 | chart 文件本身 | 这不是 UI,也不是普通 env,要看 chart 模板 |
|
||||||
@@ -151,7 +151,7 @@ docker compose up -d
|
|||||||
- `image.tag`
|
- `image.tag`
|
||||||
- `image.digest`
|
- `image.digest`
|
||||||
- 目标 Deployment 带有 `app.kubernetes.io/instance=<releaseName>` 标签
|
- 目标 Deployment 带有 `app.kubernetes.io/instance=<releaseName>` 标签
|
||||||
- 主 Metapi 服务可以访问:
|
- 主 BoosAPI 服务可以访问:
|
||||||
- GitHub API
|
- GitHub API
|
||||||
- Docker Hub API
|
- Docker Hub API
|
||||||
- Deploy Helper 的集群内地址
|
- Deploy Helper 的集群内地址
|
||||||
@@ -160,7 +160,7 @@ docker compose up -d
|
|||||||
|
|
||||||
## helper 是什么
|
## helper 是什么
|
||||||
|
|
||||||
Deploy Helper 是一个跑在集群里的小服务。它不负责对外提供 Metapi 功能,只负责接受主 Metapi 发来的部署请求,然后在集群里执行:
|
Deploy Helper 是一个跑在集群里的小服务。它不负责对外提供 Metapi 功能,只负责接受主 BoosAPI 发来的部署请求,然后在集群里执行:
|
||||||
|
|
||||||
- `helm history`
|
- `helm history`
|
||||||
- `helm get values`
|
- `helm get values`
|
||||||
@@ -202,7 +202,7 @@ Deploy Helper 是一个跑在集群里的小服务。它不负责对外提供 Me
|
|||||||
|
|
||||||
仓库里带了一个最小示例清单:
|
仓库里带了一个最小示例清单:
|
||||||
|
|
||||||
- `deploy/k3s/metapi-deploy-helper.yaml`
|
- `deploy/k3s/boosapi-deploy-helper.yaml`
|
||||||
- `deploy/k3s/chart`
|
- `deploy/k3s/chart`
|
||||||
|
|
||||||
使用前至少要改这些值:
|
使用前至少要改这些值:
|
||||||
@@ -213,8 +213,8 @@ Deploy Helper 是一个跑在集群里的小服务。它不负责对外提供 Me
|
|||||||
|
|
||||||
如果你准备直接按仓库示例接入,推荐把它们放到这两个路径:
|
如果你准备直接按仓库示例接入,推荐把它们放到这两个路径:
|
||||||
|
|
||||||
- `/opt/metapi-k3s/metapi-deploy-helper.yaml`
|
- `/opt/boosapi-k3s/boosapi-deploy-helper.yaml`
|
||||||
- `/opt/metapi-k3s/chart`
|
- `/opt/boosapi-k3s/chart`
|
||||||
|
|
||||||
这里有一个很容易漏掉、但会直接决定更新中心是否真的可靠的约束:
|
这里有一个很容易漏掉、但会直接决定更新中心是否真的可靠的约束:
|
||||||
|
|
||||||
@@ -223,16 +223,16 @@ Deploy Helper 是一个跑在集群里的小服务。它不负责对外提供 Me
|
|||||||
|
|
||||||
这两个值必须指向同一份 chart。
|
这两个值必须指向同一份 chart。
|
||||||
|
|
||||||
如果你在设置页把 `Chart Ref` 填成 `/opt/metapi-k3s/chart`,但 helper Pod 里根本没有把那份 chart 挂进去,那么更新中心即使能看到版本,也无法稳定把 digest 部署到真正运行中的 Pod。
|
如果你在设置页把 `Chart Ref` 填成 `/opt/boosapi-k3s/chart`,但 helper Pod 里根本没有把那份 chart 挂进去,那么更新中心即使能看到版本,也无法稳定把 digest 部署到真正运行中的 Pod。
|
||||||
|
|
||||||
最小部署命令示例:
|
最小部署命令示例:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl create namespace ai
|
kubectl create namespace ai
|
||||||
mkdir -p /opt/metapi-k3s/chart
|
mkdir -p /opt/boosapi-k3s/chart
|
||||||
cp -R deploy/k3s/chart/. /opt/metapi-k3s/chart/
|
cp -R deploy/k3s/chart/. /opt/boosapi-k3s/chart/
|
||||||
cp deploy/k3s/metapi-deploy-helper.yaml /opt/metapi-k3s/metapi-deploy-helper.yaml
|
cp deploy/k3s/boosapi-deploy-helper.yaml /opt/boosapi-k3s/boosapi-deploy-helper.yaml
|
||||||
kubectl apply -f /opt/metapi-k3s/metapi-deploy-helper.yaml
|
kubectl apply -f /opt/boosapi-k3s/boosapi-deploy-helper.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.1 首次接入前一定要做的自检
|
### 1.1 首次接入前一定要做的自检
|
||||||
@@ -255,8 +255,8 @@ kubectl apply -f /opt/metapi-k3s/metapi-deploy-helper.yaml
|
|||||||
你可以在接入前先跑一次自检:
|
你可以在接入前先跑一次自检:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
helm template metapi /opt/metapi-k3s/chart \
|
helm template boosapi /opt/boosapi-k3s/chart \
|
||||||
--set image.repository=1467078763/metapi \
|
--set image.repository=1467078763/boosapi \
|
||||||
--set image.tag=latest \
|
--set image.tag=latest \
|
||||||
--set-string image.digest=sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
|
--set-string image.digest=sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
|
||||||
| grep -n 'image:'
|
| grep -n 'image:'
|
||||||
@@ -264,17 +264,17 @@ helm template metapi /opt/metapi-k3s/chart \
|
|||||||
|
|
||||||
你期望看到的是:
|
你期望看到的是:
|
||||||
|
|
||||||
- `image: "1467078763/metapi@sha256:..."`
|
- `image: "1467078763/boosapi@sha256:..."`
|
||||||
|
|
||||||
如果输出仍然是:
|
如果输出仍然是:
|
||||||
|
|
||||||
- `image: "1467078763/metapi:latest"`
|
- `image: "1467078763/boosapi:latest"`
|
||||||
|
|
||||||
那说明这份 chart 还是 tag 语义,先不要继续配置更新中心。
|
那说明这份 chart 还是 tag 语义,先不要继续配置更新中心。
|
||||||
|
|
||||||
### 2. 让主 Metapi 和 helper 用同一个 token
|
### 2. 让主 BoosAPI 和 helper 用同一个 token
|
||||||
|
|
||||||
主 Metapi 端支持这两个环境变量,设置一个即可:
|
主 BoosAPI 端支持这两个环境变量,设置一个即可:
|
||||||
|
|
||||||
- `DEPLOY_HELPER_TOKEN`
|
- `DEPLOY_HELPER_TOKEN`
|
||||||
- `UPDATE_CENTER_HELPER_TOKEN`
|
- `UPDATE_CENTER_HELPER_TOKEN`
|
||||||
@@ -295,11 +295,11 @@ helper 端使用:
|
|||||||
|
|
||||||
| 字段 | 怎么理解 | 典型示例 |
|
| 字段 | 怎么理解 | 典型示例 |
|
||||||
|------|--------|----------|
|
|------|--------|----------|
|
||||||
| `Deploy Helper URL` | 主 Metapi 访问 helper 的地址 | `http://metapi-deploy-helper.ai.svc.cluster.local:9850` |
|
| `Deploy Helper URL` | 主 BoosAPI 访问 helper 的地址 | `http://boosapi-deploy-helper.ai.svc.cluster.local:9850` |
|
||||||
| `Namespace` | 目标 release 所在命名空间 | `ai` |
|
| `Namespace` | 目标 release 所在命名空间 | `ai` |
|
||||||
| `Release Name` | Helm release 名 | `metapi` |
|
| `Release Name` | Helm release 名 | `metapi` |
|
||||||
| `Chart Ref` | helper Pod 能访问到的 chart 引用 | `/opt/metapi-k3s/chart` |
|
| `Chart Ref` | helper Pod 能访问到的 chart 引用 | `/opt/boosapi-k3s/chart` |
|
||||||
| `Image Repository` | 升级时写入 chart 的镜像仓库 | `1467078763/metapi` |
|
| `Image Repository` | 升级时写入 chart 的镜像仓库 | `1467078763/boosapi` |
|
||||||
| `默认部署来源` | 默认从 GitHub 还是 Docker Hub 取版本 | `GitHub Releases` |
|
| `默认部署来源` | 默认从 GitHub 还是 Docker Hub 取版本 | `GitHub Releases` |
|
||||||
|
|
||||||
另外还有 3 个开关:
|
另外还有 3 个开关:
|
||||||
@@ -395,7 +395,7 @@ About 页里的“更新提醒”更像一个轻量入口:
|
|||||||
如果你是第一次接入,最稳妥的方式就是直接从仓库自带的:
|
如果你是第一次接入,最稳妥的方式就是直接从仓库自带的:
|
||||||
|
|
||||||
- `deploy/k3s/chart`
|
- `deploy/k3s/chart`
|
||||||
- `deploy/k3s/metapi-deploy-helper.yaml`
|
- `deploy/k3s/boosapi-deploy-helper.yaml`
|
||||||
|
|
||||||
开始,不要自己先抄一份简化版再改。
|
开始,不要自己先抄一份简化版再改。
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
appId: me.cita777.metapi.desktop
|
appId: me.cita777.boosapi.desktop
|
||||||
productName: Metapi
|
productName: Metapi
|
||||||
artifactName: ${name}-${version}-${os}-${arch}.${ext}
|
artifactName: ${name}-${version}-${os}-${arch}.${ext}
|
||||||
directories:
|
directories:
|
||||||
@@ -31,7 +31,7 @@ linux:
|
|||||||
publish:
|
publish:
|
||||||
provider: github
|
provider: github
|
||||||
owner: cita-777
|
owner: cita-777
|
||||||
repo: metapi
|
repo: boosapi
|
||||||
releaseType: release
|
releaseType: release
|
||||||
publishAutoUpdate: true
|
publishAutoUpdate: true
|
||||||
nsis:
|
nsis:
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "metapi",
|
"name": "boosapi",
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "metapi",
|
"name": "boosapi",
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "metapi",
|
"name": "boosapi",
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"description": "Meta-layer management and unified proxy for AI API aggregation platforms",
|
"description": "Meta-layer management and unified proxy for AI API aggregation platforms",
|
||||||
"main": "dist/desktop/main.js",
|
"main": "dist/desktop/main.js",
|
||||||
|
|||||||
@@ -17,25 +17,23 @@
|
|||||||
| 后端通知 | `notifyService.ts` 通知前缀 `[metapi]` → `[BoosAPI]` |
|
| 后端通知 | `notifyService.ts` 通知前缀 `[metapi]` → `[BoosAPI]` |
|
||||||
| 桌面元数据 | Electron/Docker 描述信息 |
|
| 桌面元数据 | Electron/Docker 描述信息 |
|
||||||
|
|
||||||
### 保留不变的
|
### 已全部改完的(此表仅作历史记录)
|
||||||
|
|
||||||
| 项 | 原因 |
|
| 项 | 说明 |
|
||||||
|---|------|
|
|---|------|
|
||||||
| `x-metapi-*` HTTP 头 | 有线协议,向后兼容 |
|
| `x-metapi-*` HTTP 头 | 已改 `x-boosapi-*`,注意有外部依赖的需同步更新 |
|
||||||
| `metapi:` 推理签名前缀 | 内部协议标识 |
|
| `metapi:` 推理签名前缀 | 已改 `boosapi:` |
|
||||||
| `__metapiTruncated` 等运行时属性 | 内部运行时标记 |
|
| `__metapiTruncated` 等运行时属性 | 已改 `__boosapi*` |
|
||||||
| `METAPI_*` 环境变量 | 外部契约,改了就断 |
|
| `METAPI_*` 环境变量 | 已改 `BOOSAPI_*`,部署配置需要同步 |
|
||||||
| localStorage key | 改了丢用户数据 |
|
| `package.json` name | 已改 `boosapi` |
|
||||||
| DB schema 列名 | 影响持久化数据 |
|
|
||||||
| `package.json` name | npm 包名 |
|
|
||||||
|
|
||||||
### 验证
|
### 验证
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 确认没有遗漏的用户可见"Metapi"
|
# 确认没有遗漏的 metapi
|
||||||
grep -rn 'Metapi\|metapi' src/ --include='*.ts' --include='*.tsx' --include='*.html' \
|
grep -rn 'mM]etapi' src/ --include='*.ts' --include='*.tsx' --include='*.html' \
|
||||||
| grep -v '.test.' | grep -v node_modules | grep -iv 'boosapi'
|
| grep -v '.test.' | grep -v node_modules | grep -iv 'boosapi'
|
||||||
# 剩余应只有 x-metapi、metapi:、__metapi 等内部标识
|
# 应无输出
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
services:
|
services:
|
||||||
- type: web
|
- type: web
|
||||||
name: metapi
|
name: boosapi
|
||||||
runtime: docker
|
runtime: docker
|
||||||
repo: https://github.com/cita-777/metapi
|
repo: https://github.com/cita-777/boosapi
|
||||||
dockerfilePath: ./docker/Dockerfile
|
dockerfilePath: ./docker/Dockerfile
|
||||||
dockerContext: .
|
dockerContext: .
|
||||||
plan: free
|
plan: free
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ async function ensureBetterSqliteCompatible() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rebuild = buildBetterSqliteRebuildCommand();
|
const rebuild = buildBetterSqliteRebuildCommand();
|
||||||
console.log('[metapi] Detected better-sqlite3 ABI mismatch. Rebuilding for the current Node.js runtime...');
|
console.log('[boosapi] Detected better-sqlite3 ABI mismatch. Rebuilding for the current Node.js runtime...');
|
||||||
await run(rebuild.command, rebuild.args);
|
await run(rebuild.command, rebuild.args);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { readFileSync, writeFileSync } from 'node:fs';
|
|||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
const REPO = 'cita-777/metapi';
|
const REPO = 'cita-777/boosapi';
|
||||||
const README_FILES = ['README.md', 'README_EN.md'] as const;
|
const README_FILES = ['README.md', 'README_EN.md'] as const;
|
||||||
const START_MARKER = '<!-- metapi-contributors:start -->';
|
const START_MARKER = '<!-- boosapi-contributors:start -->';
|
||||||
const END_MARKER = '<!-- metapi-contributors:end -->';
|
const END_MARKER = '<!-- boosapi-contributors:end -->';
|
||||||
const PER_LINE = 10;
|
const PER_LINE = 10;
|
||||||
const EXCLUDED_LOGINS = new Set(['dependabot[bot]']);
|
const EXCLUDED_LOGINS = new Set(['dependabot[bot]']);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -61,13 +61,13 @@ function getWindowIconPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveFrontendUrl() {
|
function resolveFrontendUrl() {
|
||||||
const devUrl = (process.env.METAPI_DESKTOP_DEV_SERVER_URL || '').trim();
|
const devUrl = (process.env.BOOSAPI_DESKTOP_DEV_SERVER_URL || '').trim();
|
||||||
if (devUrl) return devUrl;
|
if (devUrl) return devUrl;
|
||||||
return serverUrl;
|
return serverUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveExternalServerUrl() {
|
function resolveExternalServerUrl() {
|
||||||
return (process.env.METAPI_DESKTOP_EXTERNAL_SERVER_URL || '').trim();
|
return (process.env.BOOSAPI_DESKTOP_EXTERNAL_SERVER_URL || '').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMainWindow() {
|
function showMainWindow() {
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ export function buildDesktopServerEnv(input: DesktopServerEnvInput): NodeJS.Proc
|
|||||||
HOST: host,
|
HOST: host,
|
||||||
PORT: String(input.port),
|
PORT: String(input.port),
|
||||||
DATA_DIR: input.userDataDir,
|
DATA_DIR: input.userDataDir,
|
||||||
METAPI_DESKTOP: '1',
|
BOOSAPI_DESKTOP: '1',
|
||||||
METAPI_LOG_DIR: input.logsDir,
|
BOOSAPI_LOG_DIR: input.logsDir,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ export function createDesktopHealthUrl(port: number): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function resolveDesktopServerPort(env?: NodeJS.ProcessEnv): number {
|
export function resolveDesktopServerPort(env?: NodeJS.ProcessEnv): number {
|
||||||
const forcedPort = Number.parseInt(env?.METAPI_DESKTOP_SERVER_PORT || '', 10);
|
const forcedPort = Number.parseInt(env?.BOOSAPI_DESKTOP_SERVER_PORT || '', 10);
|
||||||
if (Number.isFinite(forcedPort) && forcedPort > 0) return forcedPort;
|
if (Number.isFinite(forcedPort) && forcedPort > 0) return forcedPort;
|
||||||
return DEFAULT_DESKTOP_SERVER_PORT;
|
return DEFAULT_DESKTOP_SERVER_PORT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { tokenRouter } from '../services/tokenRouter.js';
|
|||||||
|
|
||||||
type SelectedChannel = Awaited<ReturnType<typeof tokenRouter.selectChannel>>;
|
type SelectedChannel = Awaited<ReturnType<typeof tokenRouter.selectChannel>>;
|
||||||
|
|
||||||
export const TESTER_FORCED_CHANNEL_HEADER = 'x-metapi-tester-forced-channel-id';
|
export const TESTER_FORCED_CHANNEL_HEADER = 'x-boosapi-tester-forced-channel-id';
|
||||||
export const TESTER_REQUEST_HEADER = 'x-metapi-tester-request';
|
export const TESTER_REQUEST_HEADER = 'x-boosapi-tester-request';
|
||||||
|
|
||||||
function headerValueEquals(
|
function headerValueEquals(
|
||||||
headers: Record<string, unknown> | undefined,
|
headers: Record<string, unknown> | undefined,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function normalizeLowerCaseHeaderMap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function uuidFromSeed(seed: string): string {
|
export function uuidFromSeed(seed: string): string {
|
||||||
const derived = pbkdf2Sync(seed, 'metapi-runtime-header-seed', 10_000, 16, 'sha256');
|
const derived = pbkdf2Sync(seed, 'boosapi-runtime-header-seed', 10_000, 16, 'sha256');
|
||||||
const bytes = new Uint8Array(derived);
|
const bytes = new Uint8Array(derived);
|
||||||
bytes[6] = (bytes[6]! & 0x0f) | 0x50;
|
bytes[6] = (bytes[6]! & 0x0f) | 0x50;
|
||||||
bytes[8] = (bytes[8]! & 0x3f) | 0x80;
|
bytes[8] = (bytes[8]! & 0x3f) | 0x80;
|
||||||
@@ -159,7 +159,7 @@ export function buildCodexRuntimeHeaders(input: {
|
|||||||
getInputHeader(input.baseHeaders, 'session_id')
|
getInputHeader(input.baseHeaders, 'session_id')
|
||||||
|| getInputHeader(input.baseHeaders, 'session-id')
|
|| getInputHeader(input.baseHeaders, 'session-id')
|
||||||
|| explicitSessionId
|
|| explicitSessionId
|
||||||
|| (continuityKey ? uuidFromSeed(`metapi:codex:${continuityKey}`) : null)
|
|| (continuityKey ? uuidFromSeed(`boosapi:codex:${continuityKey}`) : null)
|
||||||
|| randomUUID()
|
|| randomUUID()
|
||||||
);
|
);
|
||||||
const conversationId = (
|
const conversationId = (
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ function getCodexSessionHeaderValue(headers: Record<string, string>): string {
|
|||||||
}
|
}
|
||||||
function isResponsesWebsocketTransportRequest(headers: Record<string, unknown>): boolean {
|
function isResponsesWebsocketTransportRequest(headers: Record<string, unknown>): boolean {
|
||||||
return Object.entries(headers)
|
return Object.entries(headers)
|
||||||
.some(([rawKey, rawValue]) => rawKey.trim().toLowerCase() === 'x-metapi-responses-websocket-transport'
|
.some(([rawKey, rawValue]) => rawKey.trim().toLowerCase() === 'x-boosapi-responses-websocket-transport'
|
||||||
&& String(rawValue).trim() === '1');
|
&& String(rawValue).trim() === '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FastifyInstance } from 'fastify';
|
import { FastifyInstance } from 'fastify';
|
||||||
import { fetch } from 'undici';
|
import { fetch } from 'undici';
|
||||||
|
|
||||||
const METAPI_BASE = `http://127.0.0.1:${process.env.PORT || 3000}`;
|
const BOOSAPI_BASE = `http://127.0.0.1:${process.env.PORT || 3000}`;
|
||||||
|
|
||||||
interface AgentRequest {
|
interface AgentRequest {
|
||||||
script: string;
|
script: string;
|
||||||
@@ -72,7 +72,7 @@ const SCENE_PROMPT_GEN = `根据场景描述生成图像生成提示词,用于
|
|||||||
只返回 JSON。`;
|
只返回 JSON。`;
|
||||||
|
|
||||||
async function callLLM(prompt: string, system: string): Promise<string> {
|
async function callLLM(prompt: string, system: string): Promise<string> {
|
||||||
const resp = await fetch(`${METAPI_BASE}/v1/chat/completions`, {
|
const resp = await fetch(`${BOOSAPI_BASE}/v1/chat/completions`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -92,7 +92,7 @@ async function callLLM(prompt: string, system: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function callImageGen(prompt: string): Promise<string> {
|
async function callImageGen(prompt: string): Promise<string> {
|
||||||
const resp = await fetch(`${METAPI_BASE}/v1/images/generations`, {
|
const resp = await fetch(`${BOOSAPI_BASE}/v1/images/generations`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -110,7 +110,7 @@ async function callImageGen(prompt: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function callTTS(text: string, voice = 'alloy'): Promise<Buffer | null> {
|
async function callTTS(text: string, voice = 'alloy'): Promise<Buffer | null> {
|
||||||
const resp = await fetch(`${METAPI_BASE}/v1/audio/speech`, {
|
const resp = await fetch(`${BOOSAPI_BASE}/v1/audio/speech`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
||||||
|
|
||||||
type MultipartAwareFastify = FastifyInstance & {
|
type MultipartAwareFastify = FastifyInstance & {
|
||||||
__metapiMultipartParserRegistered?: boolean;
|
__boosapiMultipartParserRegistered?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getContentType(request: FastifyRequest): string {
|
function getContentType(request: FastifyRequest): string {
|
||||||
@@ -12,13 +12,13 @@ function getContentType(request: FastifyRequest): string {
|
|||||||
|
|
||||||
export function ensureMultipartBufferParser(app: FastifyInstance): void {
|
export function ensureMultipartBufferParser(app: FastifyInstance): void {
|
||||||
const target = app as MultipartAwareFastify;
|
const target = app as MultipartAwareFastify;
|
||||||
if (target.__metapiMultipartParserRegistered) return;
|
if (target.__boosapiMultipartParserRegistered) return;
|
||||||
|
|
||||||
app.addContentTypeParser(/^multipart\/form-data(?:;.*)?$/i, { parseAs: 'buffer' }, (_request, body, done) => {
|
app.addContentTypeParser(/^multipart\/form-data(?:;.*)?$/i, { parseAs: 'buffer' }, (_request, body, done) => {
|
||||||
done(null, body);
|
done(null, body);
|
||||||
});
|
});
|
||||||
|
|
||||||
target.__metapiMultipartParserRegistered = true;
|
target.__boosapiMultipartParserRegistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isMultipartRequest(request: FastifyRequest): boolean {
|
export function isMultipartRequest(request: FastifyRequest): boolean {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import { applyOpenAiServiceTierPolicy } from '../../proxy-core/serviceTierPolicy
|
|||||||
|
|
||||||
const installedApps = new WeakSet<FastifyInstance>();
|
const installedApps = new WeakSet<FastifyInstance>();
|
||||||
const WS_TURN_STATE_HEADER = 'x-codex-turn-state';
|
const WS_TURN_STATE_HEADER = 'x-codex-turn-state';
|
||||||
const RESPONSES_WEBSOCKET_MODE_HEADER = 'x-metapi-responses-websocket-mode';
|
const RESPONSES_WEBSOCKET_MODE_HEADER = 'x-boosapi-responses-websocket-mode';
|
||||||
const RESPONSES_WEBSOCKET_TRANSPORT_HEADER = 'x-metapi-responses-websocket-transport';
|
const RESPONSES_WEBSOCKET_TRANSPORT_HEADER = 'x-boosapi-responses-websocket-transport';
|
||||||
const codexWebsocketRuntime = createCodexWebsocketRuntime();
|
const codexWebsocketRuntime = createCodexWebsocketRuntime();
|
||||||
|
|
||||||
type SelectedChannel = NonNullable<Awaited<ReturnType<typeof tokenRouter.selectChannel>>>;
|
type SelectedChannel = NonNullable<Awaited<ReturnType<typeof tokenRouter.selectChannel>>>;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ let lastPruneAtMs = 0;
|
|||||||
const PRUNE_INTERVAL_MS = 5 * 60 * 1000;
|
const PRUNE_INTERVAL_MS = 5 * 60 * 1000;
|
||||||
|
|
||||||
type TruncatedDebugPreview = {
|
type TruncatedDebugPreview = {
|
||||||
__metapiTruncated: true;
|
__boosapiTruncated: true;
|
||||||
preview: string;
|
preview: string;
|
||||||
originalBytes: number;
|
originalBytes: number;
|
||||||
storedBytes: number;
|
storedBytes: number;
|
||||||
@@ -36,7 +36,7 @@ type TruncatedDebugPreview = {
|
|||||||
function buildTruncatedDebugPreview(text: string, maxBytes: number, originalBytes: number): string {
|
function buildTruncatedDebugPreview(text: string, maxBytes: number, originalBytes: number): string {
|
||||||
const truncated = Buffer.from(text, 'utf8').subarray(0, Math.max(0, maxBytes)).toString('utf8');
|
const truncated = Buffer.from(text, 'utf8').subarray(0, Math.max(0, maxBytes)).toString('utf8');
|
||||||
const payload: TruncatedDebugPreview = {
|
const payload: TruncatedDebugPreview = {
|
||||||
__metapiTruncated: true,
|
__boosapiTruncated: true,
|
||||||
preview: truncated,
|
preview: truncated,
|
||||||
originalBytes,
|
originalBytes,
|
||||||
storedBytes: maxBytes,
|
storedBytes: maxBytes,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { db, schema } from '../db/index.js';
|
|||||||
import type { ProxyResourceOwner } from '../middleware/auth.js';
|
import type { ProxyResourceOwner } from '../middleware/auth.js';
|
||||||
import { formatUtcSqlDateTime } from './localTimeService.js';
|
import { formatUtcSqlDateTime } from './localTimeService.js';
|
||||||
|
|
||||||
export const LOCAL_PROXY_FILE_ID_PREFIX = 'file-metapi-';
|
export const LOCAL_PROXY_FILE_ID_PREFIX = 'file-boosapi-';
|
||||||
|
|
||||||
export type ProxyFileRecord = {
|
export type ProxyFileRecord = {
|
||||||
publicId: string;
|
publicId: string;
|
||||||
|
|||||||
@@ -85,19 +85,19 @@ const GENERIC_PASSTHROUGH_ALLOWED_HEADERS = new Set([
|
|||||||
'x-codex-turn-metadata',
|
'x-codex-turn-metadata',
|
||||||
'x-codex-turn-state',
|
'x-codex-turn-state',
|
||||||
]);
|
]);
|
||||||
const METAPI_INTERNAL_HEADER_BLOCKLIST = new Set([
|
const BOOSAPI_INTERNAL_HEADER_BLOCKLIST = new Set([
|
||||||
'x-metapi-tester-request',
|
'x-boosapi-tester-request',
|
||||||
'x-metapi-tester-forced-channel-id',
|
'x-boosapi-tester-forced-channel-id',
|
||||||
'x-metapi-responses-websocket-mode',
|
'x-boosapi-responses-websocket-mode',
|
||||||
'x-metapi-responses-websocket-transport',
|
'x-boosapi-responses-websocket-transport',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ANTIGRAVITY_RUNTIME_USER_AGENT = 'antigravity/1.19.6 darwin/arm64';
|
const ANTIGRAVITY_RUNTIME_USER_AGENT = 'antigravity/1.19.6 darwin/arm64';
|
||||||
|
|
||||||
function shouldSkipPassthroughHeader(key: string): boolean {
|
function shouldSkipPassthroughHeader(key: string): boolean {
|
||||||
if (HOP_BY_HOP_HEADERS.has(key) || BLOCKED_PASSTHROUGH_HEADERS.has(key)) return true;
|
if (HOP_BY_HOP_HEADERS.has(key) || BLOCKED_PASSTHROUGH_HEADERS.has(key)) return true;
|
||||||
if (METAPI_INTERNAL_HEADER_BLOCKLIST.has(key)) return true;
|
if (BOOSAPI_INTERNAL_HEADER_BLOCKLIST.has(key)) return true;
|
||||||
if (key.startsWith('x-metapi-')) return true;
|
if (key.startsWith('x-boosapi-')) return true;
|
||||||
if (!GENERIC_PASSTHROUGH_ALLOWED_HEADERS.has(key)) return true;
|
if (!GENERIC_PASSTHROUGH_ALLOWED_HEADERS.has(key)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -645,9 +645,9 @@ export function buildUpstreamEndpointRequest(input: {
|
|||||||
if (input.endpoint === 'responses') {
|
if (input.endpoint === 'responses') {
|
||||||
const responsesWebsocketTransport = getInputHeader(
|
const responsesWebsocketTransport = getInputHeader(
|
||||||
input.downstreamHeaders,
|
input.downstreamHeaders,
|
||||||
'x-metapi-responses-websocket-transport',
|
'x-boosapi-responses-websocket-transport',
|
||||||
) === '1';
|
) === '1';
|
||||||
const websocketMode = Object.entries(input.downstreamHeaders || {}).find(([rawKey]) => rawKey.trim().toLowerCase() === 'x-metapi-responses-websocket-mode');
|
const websocketMode = Object.entries(input.downstreamHeaders || {}).find(([rawKey]) => rawKey.trim().toLowerCase() === 'x-boosapi-responses-websocket-mode');
|
||||||
const preserveWebsocketIncrementalMode = asTrimmedString(websocketMode?.[1]).toLowerCase() === 'incremental';
|
const preserveWebsocketIncrementalMode = asTrimmedString(websocketMode?.[1]).toLowerCase() === 'incremental';
|
||||||
const responsesHeaders = input.downstreamFormat === 'responses'
|
const responsesHeaders = input.downstreamFormat === 'responses'
|
||||||
? extractResponsesPassthroughHeaders(input.downstreamHeaders)
|
? extractResponsesPassthroughHeaders(input.downstreamHeaders)
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ function resolveAnthropicThinkingSignature(item: Record<string, unknown>): strin
|
|||||||
if (decodedTaggedSignature !== null) {
|
if (decodedTaggedSignature !== null) {
|
||||||
return decodedTaggedSignature;
|
return decodedTaggedSignature;
|
||||||
}
|
}
|
||||||
if (item.reasoning_signature !== undefined || rawSignature.startsWith('metapi:')) {
|
if (item.reasoning_signature !== undefined || rawSignature.startsWith('boosapi:')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return rawSignature;
|
return rawSignature;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ function cleanAnthropicReasoningSignature(value: unknown): string | null {
|
|||||||
if (!raw) return null;
|
if (!raw) return null;
|
||||||
const decoded = decodeAnthropicReasoningSignature(raw);
|
const decoded = decodeAnthropicReasoningSignature(raw);
|
||||||
if (decoded) return decoded;
|
if (decoded) return decoded;
|
||||||
if (raw.startsWith('metapi:')) return null;
|
if (raw.startsWith('boosapi:')) return null;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function cleanAnthropicReasoningSignature(value: unknown): string | null {
|
|||||||
if (!raw) return null;
|
if (!raw) return null;
|
||||||
const decoded = decodeAnthropicReasoningSignature(raw);
|
const decoded = decodeAnthropicReasoningSignature(raw);
|
||||||
if (decoded) return decoded;
|
if (decoded) return decoded;
|
||||||
if (raw.startsWith('metapi:')) return null;
|
if (raw.startsWith('boosapi:')) return null;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { CanonicalContinuation } from './types.js';
|
import type { CanonicalContinuation } from './types.js';
|
||||||
|
|
||||||
export const OPENAI_CONTINUATION_TURN_STATE_METADATA_KEY = 'metapi_turn_state';
|
export const OPENAI_CONTINUATION_TURN_STATE_METADATA_KEY = 'boosapi_turn_state';
|
||||||
|
|
||||||
function asTrimmedString(value: unknown): string {
|
function asTrimmedString(value: unknown): string {
|
||||||
return typeof value === 'string' ? value.trim() : '';
|
return typeof value === 'string' ? value.trim() : '';
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ function cloneJsonValue<T>(value: T): T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RESPONSES_MCP_COMPAT_MARKER = 'responses_mcp_item';
|
const RESPONSES_MCP_COMPAT_MARKER = 'responses_mcp_item';
|
||||||
const RESPONSES_MCP_COMPAT_PREFIX = 'metapi_mcp_item__';
|
const RESPONSES_MCP_COMPAT_PREFIX = 'boosapi_mcp_item__';
|
||||||
|
|
||||||
type ResponsesMcpCompatEnvelope = {
|
type ResponsesMcpCompatEnvelope = {
|
||||||
metapi_compat: typeof RESPONSES_MCP_COMPAT_MARKER;
|
boosapi_compat: typeof RESPONSES_MCP_COMPAT_MARKER;
|
||||||
itemType: string;
|
itemType: string;
|
||||||
item: Record<string, unknown>;
|
item: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
@@ -38,7 +38,7 @@ function createResponsesMcpCompatEnvelope(
|
|||||||
if (!itemType.startsWith('mcp_')) return null;
|
if (!itemType.startsWith('mcp_')) return null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
metapi_compat: RESPONSES_MCP_COMPAT_MARKER,
|
boosapi_compat: RESPONSES_MCP_COMPAT_MARKER,
|
||||||
itemType,
|
itemType,
|
||||||
item: cloneJsonValue(item),
|
item: cloneJsonValue(item),
|
||||||
};
|
};
|
||||||
@@ -81,14 +81,14 @@ function parseCompatEnvelope(rawArguments: unknown): ResponsesMcpCompatEnvelope
|
|||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(trimmed) as unknown;
|
const parsed = JSON.parse(trimmed) as unknown;
|
||||||
if (!isRecord(parsed)) return null;
|
if (!isRecord(parsed)) return null;
|
||||||
if (asTrimmedString(parsed.metapi_compat) !== RESPONSES_MCP_COMPAT_MARKER) return null;
|
if (asTrimmedString(parsed.boosapi_compat) !== RESPONSES_MCP_COMPAT_MARKER) return null;
|
||||||
|
|
||||||
const itemType = asTrimmedString(parsed.itemType).toLowerCase();
|
const itemType = asTrimmedString(parsed.itemType).toLowerCase();
|
||||||
if (!itemType.startsWith('mcp_')) return null;
|
if (!itemType.startsWith('mcp_')) return null;
|
||||||
if (!isRecord(parsed.item)) return null;
|
if (!isRecord(parsed.item)) return null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
metapi_compat: RESPONSES_MCP_COMPAT_MARKER,
|
boosapi_compat: RESPONSES_MCP_COMPAT_MARKER,
|
||||||
itemType,
|
itemType,
|
||||||
item: cloneJsonValue(parsed.item),
|
item: cloneJsonValue(parsed.item),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ export function buildNormalizedFinalToOpenAiResponsesPayload(input: {
|
|||||||
? normalized.reasoningSignature.trim()
|
? normalized.reasoningSignature.trim()
|
||||||
: '';
|
: '';
|
||||||
const encryptedReasoning = decodeOpenAiEncryptedReasoning(rawReasoningSignature)
|
const encryptedReasoning = decodeOpenAiEncryptedReasoning(rawReasoningSignature)
|
||||||
?? (rawReasoningSignature && !rawReasoningSignature.startsWith('metapi:') ? rawReasoningSignature : null);
|
?? (rawReasoningSignature && !rawReasoningSignature.startsWith('boosapi:') ? rawReasoningSignature : null);
|
||||||
const annotations = extractAnnotationsFromUpstream(upstreamPayload);
|
const annotations = extractAnnotationsFromUpstream(upstreamPayload);
|
||||||
|
|
||||||
const output: Array<Record<string, unknown>> = syntheticOutput.map((item) => cloneJson(item));
|
const output: Array<Record<string, unknown>> = syntheticOutput.map((item) => cloneJson(item));
|
||||||
|
|||||||
@@ -2251,7 +2251,7 @@ export function serializeFinalResponse(
|
|||||||
const rawReasoningSignature = typeof normalized.reasoningSignature === 'string'
|
const rawReasoningSignature = typeof normalized.reasoningSignature === 'string'
|
||||||
? normalized.reasoningSignature.trim()
|
? normalized.reasoningSignature.trim()
|
||||||
: '';
|
: '';
|
||||||
const taggedReasoningSignature = rawReasoningSignature.startsWith('metapi:');
|
const taggedReasoningSignature = rawReasoningSignature.startsWith('boosapi:');
|
||||||
const claudeReasoningSignature = decodeAnthropicReasoningSignature(rawReasoningSignature)
|
const claudeReasoningSignature = decodeAnthropicReasoningSignature(rawReasoningSignature)
|
||||||
?? (rawReasoningSignature && !taggedReasoningSignature ? rawReasoningSignature : null);
|
?? (rawReasoningSignature && !taggedReasoningSignature ? rawReasoningSignature : null);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const PROVIDER_PREFIX = 'metapi';
|
const PROVIDER_PREFIX = 'boosapi';
|
||||||
|
|
||||||
export const ANTHROPIC_REASONING_SIGNATURE_PREFIX = `${PROVIDER_PREFIX}:anthropic-signature:`;
|
export const ANTHROPIC_REASONING_SIGNATURE_PREFIX = `${PROVIDER_PREFIX}:anthropic-signature:`;
|
||||||
export const GEMINI_THOUGHT_SIGNATURE_PREFIX = `${PROVIDER_PREFIX}:gemini-thought-signature:`;
|
export const GEMINI_THOUGHT_SIGNATURE_PREFIX = `${PROVIDER_PREFIX}:gemini-thought-signature:`;
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ export const zhToEnSupplemental: Record<string, string> = {
|
|||||||
'拉取分组失败': 'Failed to pull group',
|
'拉取分组失败': 'Failed to pull group',
|
||||||
'拉取分组失败,已回退 default': 'Failed to pull the group and has fallen back to default',
|
'拉取分组失败,已回退 default': 'Failed to pull the group and has fallen back to default',
|
||||||
'冷却中': 'Cooling down',
|
'冷却中': 'Cooling down',
|
||||||
'例如 BoosAPI': 'For example metapi',
|
'例如 BoosAPI': 'For example BoosAPI',
|
||||||
'例如: admin@example.com': 'For example: admin@example.com',
|
'例如: admin@example.com': 'For example: admin@example.com',
|
||||||
'例如: smtp.qq.com': 'For example: smtp.qq.com',
|
'例如: smtp.qq.com': 'For example: smtp.qq.com',
|
||||||
'例如: target@example.com': 'For example: target@example.com',
|
'例如: target@example.com': 'For example: target@example.com',
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ metadata:
|
|||||||
name: Metapi
|
name: Metapi
|
||||||
spec:
|
spec:
|
||||||
description: Meta-layer management and unified proxy for AI API aggregation platforms.
|
description: Meta-layer management and unified proxy for AI API aggregation platforms.
|
||||||
icon: https://raw.githubusercontent.com/cita-777/metapi/main/docs/logos/logo-icon-512.png
|
icon: https://raw.githubusercontent.com/cita-777/boosapi/main/docs/logos/logo-icon-512.png
|
||||||
coverImage: https://raw.githubusercontent.com/cita-777/metapi/main/docs/logos/logo-banner.png
|
coverImage: https://raw.githubusercontent.com/cita-777/boosapi/main/docs/logos/logo-banner.png
|
||||||
tags:
|
tags:
|
||||||
- AI
|
- AI
|
||||||
- Tool
|
- Tool
|
||||||
@@ -41,12 +41,12 @@ spec:
|
|||||||
name: Service Port
|
name: Service Port
|
||||||
description: Internal HTTP port (default 4000).
|
description: Internal HTTP port (default 4000).
|
||||||
services:
|
services:
|
||||||
- name: metapi
|
- name: boosapi
|
||||||
icon: https://raw.githubusercontent.com/cita-777/metapi/main/docs/logos/logo-icon-512.png
|
icon: https://raw.githubusercontent.com/cita-777/boosapi/main/docs/logos/logo-icon-512.png
|
||||||
template: PREBUILT
|
template: PREBUILT
|
||||||
spec:
|
spec:
|
||||||
source:
|
source:
|
||||||
image: 1467078763/metapi:latest
|
image: 1467078763/boosapi:latest
|
||||||
ports:
|
ports:
|
||||||
- id: web
|
- id: web
|
||||||
port: 4000
|
port: 4000
|
||||||
|
|||||||
Reference in New Issue
Block a user