修复arm的问题

This commit is contained in:
wisdgod
2025-01-29 14:47:59 +08:00
parent 6c982483d5
commit fb0de13712
8 changed files with 114 additions and 56 deletions

View File

@@ -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
View File

@@ -23,3 +23,4 @@ node_modules
/build*
/*.bin
/result.txt
tools/tokenizer/

2
Cargo.lock generated
View File

@@ -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",

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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()),

View File

@@ -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

View File

@@ -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 = '';