mirror of
https://github.com/wisdgod/cursor-api.git
synced 2025-10-16 11:40:38 +08:00
修复arm的问题
This commit is contained in:
29
.github/workflows/build-darwin.yml
vendored
29
.github/workflows/build-darwin.yml
vendored
@@ -25,33 +25,26 @@ jobs:
|
||||
run: |
|
||||
RUSTFLAGS="-C link-arg=-s -C target-cpu=x86-64-v3" \
|
||||
cargo build --release --target x86_64-apple-darwin
|
||||
mv target/x86_64-apple-darwin/release/cursor-api cursor-api-x86_64-apple-darwin
|
||||
|
||||
- name: Build arm64 binary
|
||||
run: |
|
||||
RUSTFLAGS="-C link-arg=-s -C target-cpu=apple-m1" \
|
||||
cargo build --release --target aarch64-apple-darwin
|
||||
mv target/aarch64-apple-darwin/release/cursor-api cursor-api-aarch64-apple-darwin
|
||||
|
||||
- name: Create universal binary
|
||||
run: |
|
||||
lipo -create \
|
||||
target/x86_64-apple-darwin/release/cursor-api \
|
||||
target/aarch64-apple-darwin/release/cursor-api \
|
||||
-output target/cursor-api-universal
|
||||
cursor-api-x86_64-apple-darwin \
|
||||
cursor-api-aarch64-apple-darwin \
|
||||
-output cursor-api-universal-apple-darwin
|
||||
|
||||
- name: Upload x86_64 artifact
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4.6.0
|
||||
with:
|
||||
name: cursor-api-x86_64-apple-darwin
|
||||
path: target/x86_64-apple-darwin/release/cursor-api
|
||||
|
||||
- name: Upload arm64 artifact
|
||||
uses: actions/upload-artifact@v4.6.0
|
||||
with:
|
||||
name: cursor-api-aarch64-apple-darwin
|
||||
path: target/aarch64-apple-darwin/release/cursor-api
|
||||
|
||||
- name: Upload universal artifact
|
||||
uses: actions/upload-artifact@v4.6.0
|
||||
with:
|
||||
name: cursor-api-universal-apple-darwin
|
||||
path: target/cursor-api-universal
|
||||
name: cursor-api-darwin
|
||||
path: |
|
||||
cursor-api-x86_64-apple-darwin
|
||||
cursor-api-aarch64-apple-darwin
|
||||
cursor-api-universal-apple-darwin
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -23,3 +23,4 @@ node_modules
|
||||
/build*
|
||||
/*.bin
|
||||
/result.txt
|
||||
tools/tokenizer/
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -361,7 +361,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cursor-api"
|
||||
version = "0.1.3-rc.4.2"
|
||||
version = "0.1.3-rc.4.3"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"base64",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cursor-api"
|
||||
version = "0.1.3-rc.4.2"
|
||||
version = "0.1.3-rc.4.3"
|
||||
edition = "2021"
|
||||
authors = ["wisdgod <nav@wisdgod.com>"]
|
||||
description = "OpenAI format compatibility layer for the Cursor API"
|
||||
|
45
Dockerfile
45
Dockerfile
@@ -1,49 +1,36 @@
|
||||
# AMD64 构建阶段
|
||||
FROM --platform=linux/amd64 rust:1.84.0-slim-bookworm as builder-amd64
|
||||
ARG TARGETARCH
|
||||
FROM --platform=linux/${TARGETARCH} rust:1.84.0-slim-bookworm as builder
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
WORKDIR /app
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential protobuf-compiler pkg-config libssl-dev nodejs npm openssl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY . .
|
||||
ENV RUSTFLAGS="-C link-arg=-s -C target-cpu=x86-64-v3"
|
||||
RUN cargo build --release && \
|
||||
RUN case "$TARGETARCH" in \
|
||||
amd64) TARGET_CPU="x86-64-v3" ;; \
|
||||
arm64) TARGET_CPU="neoverse-n1" ;; \
|
||||
*) echo "Unsupported architecture: $TARGETARCH" && exit 1 ;; \
|
||||
esac && \
|
||||
RUSTFLAGS="-C link-arg=-s -C target-cpu=$TARGET_CPU" cargo build --release && \
|
||||
cp target/release/cursor-api /app/cursor-api
|
||||
|
||||
# ARM64 构建阶段
|
||||
FROM --platform=linux/arm64 rust:1.84.0-slim-bookworm as builder-arm64
|
||||
WORKDIR /app
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential protobuf-compiler pkg-config libssl-dev nodejs npm openssl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY . .
|
||||
ENV RUSTFLAGS="-C link-arg=-s -C target-cpu=apple-m1"
|
||||
RUN cargo build --release && \
|
||||
cp target/release/cursor-api /app/cursor-api
|
||||
# 运行阶段
|
||||
FROM --platform=linux/${TARGETARCH} debian:bookworm-slim
|
||||
|
||||
# AMD64 运行阶段
|
||||
FROM --platform=linux/amd64 debian:bookworm-slim as run-amd64
|
||||
WORKDIR /app
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates tzdata openssl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder-amd64 /app/cursor-api .
|
||||
|
||||
# ARM64 运行阶段
|
||||
FROM --platform=linux/arm64 debian:bookworm-slim as run-arm64
|
||||
WORKDIR /app
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates tzdata openssl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder-arm64 /app/cursor-api .
|
||||
COPY --from=builder /app/cursor-api .
|
||||
|
||||
# 通用配置
|
||||
FROM run-${TARGETARCH}
|
||||
ENV PORT=3000
|
||||
EXPOSE ${PORT}
|
||||
CMD ["./cursor-api"]
|
@@ -730,7 +730,7 @@ pub async fn handle_chat(
|
||||
index: 0,
|
||||
message: Some(Message {
|
||||
role: Role::Assistant,
|
||||
content: MessageContent::Text(full_text),
|
||||
content: MessageContent::Text(full_text.trim_leading_newlines()),
|
||||
}),
|
||||
delta: None,
|
||||
finish_reason: Some(FINISH_REASON_STOP.to_string()),
|
||||
|
@@ -55,11 +55,13 @@ pub trait TrimNewlines {
|
||||
impl TrimNewlines for String {
|
||||
#[inline(always)]
|
||||
fn trim_leading_newlines(mut self) -> Self {
|
||||
if self.as_bytes().get(..2) == Some(b"\n\n".as_slice()) {
|
||||
let bytes = self.as_bytes();
|
||||
if bytes.len() >= 2 && bytes[0] == b'\n' && bytes[1] == b'\n' {
|
||||
unsafe {
|
||||
let vec = self.as_mut_vec();
|
||||
vec.copy_within(2.., 0);
|
||||
vec.truncate(vec.len() - 2);
|
||||
let start_ptr = self.as_mut_ptr();
|
||||
let new_len = self.len() - 2;
|
||||
std::ptr::copy(start_ptr.add(2), start_ptr, new_len);
|
||||
self.as_mut_vec().set_len(new_len);
|
||||
}
|
||||
}
|
||||
self
|
||||
|
@@ -91,7 +91,8 @@
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.action-cell {
|
||||
width: 100px;
|
||||
width: 160px;
|
||||
/* 增加宽度以容纳两个按钮 */
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
@@ -99,6 +100,8 @@
|
||||
padding: 2px 8px;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
margin: 0 2px;
|
||||
/* 添加按钮间距 */
|
||||
}
|
||||
|
||||
/* 提示框样式 */
|
||||
@@ -256,6 +259,21 @@
|
||||
.model-item input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* 确认对话框的额外样式 */
|
||||
#confirmModal {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
#confirmModal .modal-content {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#confirmModal .modal-footer button {
|
||||
min-width: 80px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -368,6 +386,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加确认对话框 -->
|
||||
<div class="modal-backdrop" id="confirmModal-backdrop"></div>
|
||||
<div class="modal" id="confirmModal">
|
||||
<div class="modal-header">
|
||||
<h3>确认删除</h3>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<p>确定要删除这个token吗?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button onclick="closeConfirmModal()" class="secondary">取消</button>
|
||||
<button onclick="confirmDelete()" class="danger">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function getTokenInfo() {
|
||||
const data = await makeAuthenticatedRequest('/tokens/get');
|
||||
@@ -380,7 +413,7 @@
|
||||
const usage = profile.usage || {};
|
||||
const premium = usage.premium || {};
|
||||
|
||||
return `<tr><td title="${t.token}">${t.token}</td><td title="${t.checksum}">${t.checksum}</td><td>${user.email || '-'}</td><td>${formatMembershipType(stripe.membership_type)}</td><td>${premium.requests || 0}/${premium.max_requests || '∞'}</td><td>${stripe.days_remaining_on_trial > 0 ? `${stripe.days_remaining_on_trial}天` : '-'}</td><td class="action-cell"><button onclick="showKeyModal('${t.token}','${t.checksum}')" class="secondary">生成Key</button></td></tr>`;
|
||||
return `<tr><td title="${t.token}">${t.token}</td><td title="${t.checksum}">${t.checksum}</td><td>${user.email || '-'}</td><td>${formatMembershipType(stripe.membership_type)}</td><td>${premium.requests || 0}/${premium.max_requests || '∞'}</td><td>${stripe.days_remaining_on_trial > 0 ? `${stripe.days_remaining_on_trial}天` : '-'}</td><td class="action-cell"><button onclick="showKeyModal('${t.token}','${t.checksum}')" class="secondary">生成Key</button><button onclick="deleteToken('${t.token}')" class="danger">删除</button></td></tr>`;
|
||||
}).join('');
|
||||
showGlobalMessage('配置获取成功');
|
||||
}
|
||||
@@ -477,6 +510,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 添加删除单个token的函数
|
||||
let tokenToDelete = null;
|
||||
|
||||
function showConfirmModal(token) {
|
||||
tokenToDelete = token;
|
||||
const modal = document.getElementById('confirmModal');
|
||||
const backdrop = document.getElementById('confirmModal-backdrop');
|
||||
modal.style.display = 'block';
|
||||
backdrop.style.display = 'block';
|
||||
}
|
||||
|
||||
function closeConfirmModal() {
|
||||
const modal = document.getElementById('confirmModal');
|
||||
const backdrop = document.getElementById('confirmModal-backdrop');
|
||||
modal.style.display = 'none';
|
||||
backdrop.style.display = 'none';
|
||||
tokenToDelete = null;
|
||||
}
|
||||
|
||||
async function confirmDelete() {
|
||||
if (!tokenToDelete) return;
|
||||
|
||||
const data = await makeAuthenticatedRequest('/tokens/delete', {
|
||||
body: JSON.stringify({
|
||||
tokens: [tokenToDelete],
|
||||
expectation: 'detailed'
|
||||
})
|
||||
});
|
||||
|
||||
if (data) {
|
||||
showGlobalMessage('Token删除成功');
|
||||
getTokenInfo();
|
||||
}
|
||||
|
||||
closeConfirmModal();
|
||||
}
|
||||
|
||||
// 修改deleteToken函数
|
||||
function deleteToken(token) {
|
||||
showConfirmModal(token);
|
||||
}
|
||||
|
||||
// 动态key相关函数
|
||||
let availableModels = [];
|
||||
let currentToken = '';
|
||||
|
Reference in New Issue
Block a user