mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-15 20:16:02 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 37214c27e8 |
@@ -1,75 +0,0 @@
|
||||
name: Release CLI
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Tag name for the release (e.g. v0.1.0)'
|
||||
required: true
|
||||
default: 'v0.0.0'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.target }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
# skip pre-release tags (containing '-') on auto-trigger; always run on workflow_dispatch
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || !contains(github.ref_name, '-') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: lobe-linux-x64
|
||||
- os: macos-latest
|
||||
target: lobe-macos-arm64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build binary
|
||||
run: |
|
||||
mkdir -p dist
|
||||
bun build ./apps/cli/src/index.ts --compile --minify --outfile ./dist/${{ matrix.target }}
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.target }}
|
||||
path: ./dist/${{ matrix.target }}
|
||||
|
||||
release:
|
||||
name: Upload to Release
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: ./dist
|
||||
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
|
||||
files: |
|
||||
./dist/lobe-linux-x64/lobe-linux-x64
|
||||
./dist/lobe-macos-arm64/lobe-macos-arm64
|
||||
./apps/cli/install.sh
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
REPO="lobehub/lobe-chat"
|
||||
BIN_NAME="lh"
|
||||
|
||||
# Detect OS
|
||||
case "$(uname -s)" in
|
||||
Linux) OS="linux" ;;
|
||||
Darwin) OS="macos" ;;
|
||||
*)
|
||||
printf 'Error: Unsupported OS: %s\n' "$(uname -s)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Detect architecture
|
||||
case "$(uname -m)" in
|
||||
x86_64) ARCH="x64" ;;
|
||||
aarch64|arm64) ARCH="arm64" ;;
|
||||
*)
|
||||
printf 'Error: Unsupported architecture: %s\n' "$(uname -m)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
BINARY="lobe-${OS}-${ARCH}"
|
||||
URL="https://github.com/${REPO}/releases/latest/download/${BINARY}"
|
||||
|
||||
printf 'Detected: %s/%s\n' "$OS" "$ARCH"
|
||||
printf 'Downloading %s...\n' "$BINARY"
|
||||
|
||||
TMP="$(mktemp)"
|
||||
trap 'rm -f "$TMP"' EXIT
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$URL" -o "$TMP"
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -qO "$TMP" "$URL"
|
||||
else
|
||||
printf 'Error: curl or wget is required\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod +x "$TMP"
|
||||
|
||||
# Choose install directory: prefer /usr/local/bin, fall back to ~/.local/bin
|
||||
USE_SUDO=0
|
||||
if [ -w "/usr/local/bin" ]; then
|
||||
INSTALL_DIR="/usr/local/bin"
|
||||
elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
|
||||
INSTALL_DIR="/usr/local/bin"
|
||||
USE_SUDO=1
|
||||
else
|
||||
INSTALL_DIR="${HOME}/.local/bin"
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
printf 'Note: No sudo access. Installing to %s\n' "$INSTALL_DIR"
|
||||
printf 'Add the following to your shell profile if needed:\n'
|
||||
printf ' export PATH="%s:$PATH"\n' "$INSTALL_DIR"
|
||||
fi
|
||||
|
||||
# Install binary and create symlinks
|
||||
if [ "$USE_SUDO" = "1" ]; then
|
||||
sudo cp "$TMP" "${INSTALL_DIR}/${BIN_NAME}"
|
||||
sudo chmod +x "${INSTALL_DIR}/${BIN_NAME}"
|
||||
sudo ln -sf "${INSTALL_DIR}/${BIN_NAME}" "${INSTALL_DIR}/lobe"
|
||||
sudo ln -sf "${INSTALL_DIR}/${BIN_NAME}" "${INSTALL_DIR}/lobehub"
|
||||
else
|
||||
cp "$TMP" "${INSTALL_DIR}/${BIN_NAME}"
|
||||
chmod +x "${INSTALL_DIR}/${BIN_NAME}"
|
||||
ln -sf "${INSTALL_DIR}/${BIN_NAME}" "${INSTALL_DIR}/lobe"
|
||||
ln -sf "${INSTALL_DIR}/${BIN_NAME}" "${INSTALL_DIR}/lobehub"
|
||||
fi
|
||||
|
||||
printf '\nInstalled successfully!\n'
|
||||
printf ' Binary: %s/%s\n' "$INSTALL_DIR" "$BIN_NAME"
|
||||
printf ' Symlinks: lobe, lobehub -> lh\n\n'
|
||||
"${INSTALL_DIR}/${BIN_NAME}" --version
|
||||
@@ -125,7 +125,6 @@
|
||||
"node-mac-permissions"
|
||||
],
|
||||
"overrides": {
|
||||
"node-gyp": "^12.4.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"vitest": "3.2.4"
|
||||
|
||||
@@ -16,7 +16,6 @@ import type {
|
||||
InitWorkspaceParams,
|
||||
KillCommandParams,
|
||||
ListLocalFileParams,
|
||||
ListProjectSkillsParams,
|
||||
LocalReadFileParams,
|
||||
LocalReadFilesParams,
|
||||
LocalSearchFilesParams,
|
||||
@@ -408,10 +407,6 @@ export default class GatewayConnectionCtr extends ControllerModule {
|
||||
return this.localFileCtr.getProjectFileIndex(params as { scope?: string });
|
||||
}
|
||||
|
||||
case 'listProjectSkills': {
|
||||
return this.workspaceCtr.listProjectSkills(params as ListProjectSkillsParams);
|
||||
}
|
||||
|
||||
case 'getGitBranchDiff': {
|
||||
return this.gitCtr.getGitBranchDiff(params as { baseRef?: string; path: string });
|
||||
}
|
||||
|
||||
@@ -440,14 +440,8 @@ describe('HeterogeneousAgentCtr', () => {
|
||||
expect(command).toBe('codex');
|
||||
expect(cliArgs).not.toContain(prompt);
|
||||
expect(cliArgs).toEqual(
|
||||
expect.arrayContaining([
|
||||
'exec',
|
||||
'--json',
|
||||
'--skip-git-repo-check',
|
||||
'--dangerously-bypass-approvals-and-sandbox',
|
||||
]),
|
||||
expect.arrayContaining(['exec', '--json', '--skip-git-repo-check', '--full-auto']),
|
||||
);
|
||||
expect(cliArgs).not.toContain('--full-auto');
|
||||
expect(cliArgs).not.toContain('-');
|
||||
expect(writes).toEqual([prompt]);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {
|
||||
CODEX_DEFAULT_EXECUTION_ARGS,
|
||||
CODEX_EXECUTION_MODE_FLAGS,
|
||||
CODEX_REQUIRED_ARGS,
|
||||
} from '@lobechat/heterogeneous-agents/spawn';
|
||||
|
||||
import type { HeterogeneousAgentBuildPlanParams, HeterogeneousAgentDriver } from '../types';
|
||||
|
||||
const CODEX_REQUIRED_ARGS = ['--json', '--skip-git-repo-check'] as const;
|
||||
const CODEX_AUTO_EXECUTION_FLAGS = [
|
||||
'--full-auto',
|
||||
'--dangerously-bypass-approvals-and-sandbox',
|
||||
'--sandbox',
|
||||
'-s',
|
||||
] as const;
|
||||
|
||||
const hasAnyFlag = (args: string[], flags: readonly string[]) =>
|
||||
args.some((arg) => flags.includes(arg as (typeof flags)[number]));
|
||||
|
||||
@@ -16,11 +18,9 @@ const buildCodexOptionArgs = async ({
|
||||
}: Pick<HeterogeneousAgentBuildPlanParams, 'args' | 'helpers' | 'imageList'>) => {
|
||||
const imagePaths = await helpers.resolveCliImagePaths(imageList);
|
||||
const imageArgs = imagePaths.flatMap((filePath) => ['--image', filePath]);
|
||||
const executionModeArgs = hasAnyFlag(args, CODEX_EXECUTION_MODE_FLAGS)
|
||||
? []
|
||||
: [...CODEX_DEFAULT_EXECUTION_ARGS];
|
||||
const autoExecutionArgs = hasAnyFlag(args, CODEX_AUTO_EXECUTION_FLAGS) ? [] : ['--full-auto'];
|
||||
|
||||
return [...CODEX_REQUIRED_ARGS, ...executionModeArgs, ...args, ...imageArgs];
|
||||
return [...CODEX_REQUIRED_ARGS, ...autoExecutionArgs, ...args, ...imageArgs];
|
||||
};
|
||||
|
||||
export const codexDriver: HeterogeneousAgentDriver = {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@lobechat/server",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"type-check": "tsc --noEmit"
|
||||
}
|
||||
}
|
||||
-18
@@ -790,23 +790,6 @@ export const createRuntimeExecutors = (
|
||||
// {{sandbox_enabled}} — mirrors client-side check for lobe-cloud-sandbox.
|
||||
const sandboxEnabled = String(resolved.enabledToolIds.includes('lobe-cloud-sandbox'));
|
||||
|
||||
// {{sandbox_uploaded_files}} — lists the topic/session files that are
|
||||
// synced into the sandbox upload dir, so the agent knows they exist.
|
||||
// Mirrors the bootstrap query in SandboxMiddlewareService.
|
||||
let sandboxUploadedFiles = '';
|
||||
if (sandboxEnabled === 'true' && ctx.serverDB && ctx.userId && lobehubSkillTopicId) {
|
||||
try {
|
||||
const { FileModel } = await import('@/database/models/file');
|
||||
const { formatUploadedFilesPrompt } =
|
||||
await import('@lobechat/builtin-tool-cloud-sandbox');
|
||||
const fileModel = new FileModel(ctx.serverDB, ctx.userId);
|
||||
const uploadedFiles = await fileModel.findFilesToInitInSandbox(lobehubSkillTopicId);
|
||||
sandboxUploadedFiles = formatUploadedFilesPrompt(uploadedFiles);
|
||||
} catch (error) {
|
||||
log('Failed to resolve files for {{sandbox_uploaded_files}} substitution: %O', error);
|
||||
}
|
||||
}
|
||||
|
||||
// {{session_date}} — current date formatted for user's timezone.
|
||||
const sessionDate = new Intl.DateTimeFormat('en-US', {
|
||||
day: 'numeric',
|
||||
@@ -896,7 +879,6 @@ export const createRuntimeExecutors = (
|
||||
session_date: sessionDate,
|
||||
// Creds tool variables
|
||||
sandbox_enabled: sandboxEnabled,
|
||||
sandbox_uploaded_files: sandboxUploadedFiles,
|
||||
CREDS_LIST: credsListStr,
|
||||
KLAVIS_SERVICES_LIST: klavisServicesListStr,
|
||||
// Memory tool variables
|
||||
+2
-2
@@ -3763,9 +3763,9 @@ describe('RuntimeExecutors', () => {
|
||||
|
||||
// Import real implementations directly from source (bypassing the @lobechat/model-runtime mock)
|
||||
const { consumeStreamUntilDone: realConsume } =
|
||||
await import('../../../../../packages/model-runtime/src/utils/consumeStream');
|
||||
await import('../../../../../../packages/model-runtime/src/utils/consumeStream');
|
||||
const { createCallbacksTransformer } =
|
||||
await import('../../../../../packages/model-runtime/src/core/streams/protocol');
|
||||
await import('../../../../../../packages/model-runtime/src/core/streams/protocol');
|
||||
|
||||
// Use real consumeStreamUntilDone so the stream is actually consumed
|
||||
vi.mocked(consumeStreamUntilDone).mockImplementation(realConsume);
|
||||
-1
@@ -188,7 +188,6 @@ describe('AssistantStore', () => {
|
||||
global.fetch = vi.fn().mockRejectedValue(new Error('something else'));
|
||||
const store = new AssistantStore();
|
||||
|
||||
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
await expect(store.getAgentIndex()).rejects.toThrow('something else');
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user