Compare commits

..

19 Commits

Author SHA1 Message Date
github-actions[bot]
1f25451927 chore(release): v0.0.6-nightly.2 2025-08-14 00:09:43 +00:00
pomelo
6516d0d136 Merge pull request #313 from QwenLM/chore/log_api_request
chore: add api request logger
2025-08-13 18:54:02 +08:00
tanzhenxin
5369af61d2 chore: add api request logger 2025-08-13 18:51:40 +08:00
pomelo
6a4005cace Merge pull request #262 from nguu0123/main
feat(sandbox): add GHA to build sandbox image
2025-08-13 18:37:39 +08:00
tanzhenxin
0bc45aeefe chore: build issue, fallback to 0.0.5 version 2025-08-12 21:58:12 +08:00
tanzhenxin
7856f52afb Merge pull request #298 from QwenLM/chore/pkg_version
Chore/pkg version
2025-08-12 21:12:07 +08:00
tanzhenxin
e986476fe0 chore: pump version to 0.0.6 2025-08-12 21:03:25 +08:00
tanzhenxin
cfc1aebee6 chore: use correct CLI_VERSION for logging 2025-08-12 21:00:17 +08:00
pomelo
ef1c8a4bfe Merge pull request #293 from Clarence-pan/main
fix: 🐛 fix EPERM error when run `qwen --sandbox` in macOS
2025-08-12 19:53:59 +08:00
tanzhenxin
484292b2ac Merge pull request #297 from QwenLM/chore/pr-review-action
chore: adjust workflow to run PR review
2025-08-12 19:35:07 +08:00
mingholy.lmh
f9659184d4 chore: adjust workflow to run PR review 2025-08-12 18:05:52 +08:00
Clarence-pan
16ea8560b7 fix: 🐛 fix EPERM error when run qwen --sandbox in macOS 2025-08-12 15:04:01 +08:00
nguu0123
a37423bf7f Update name of the workflow 2025-08-10 13:40:24 +03:00
nguu0123
bfcb3e7f1d Remove redundant Node.js setup and build steps from Docker workflow 2025-08-10 13:23:49 +03:00
nguu0123
1a581ed191 Limit docker image workflow to tags and manual triggers 2025-08-10 13:17:34 +03:00
nguu0123
5c94913643 Refactor Dockerfile with multi-stage build for smaller image size 2025-08-10 13:00:46 +03:00
nguu0123
e221b077e5 Fix gha version 2025-08-10 12:26:51 +03:00
nguu0123
0f58b3fd32 fix qemu gha version 2025-08-10 12:24:18 +03:00
nguu0123
32d06b2fc1 Add publish image gha 2025-08-10 12:20:22 +03:00
25 changed files with 175 additions and 56 deletions

View File

@@ -0,0 +1,65 @@
name: Build and Publish Docker Image
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
publish:
description: 'Publish to GHCR (only works on main branch)'
type: boolean
default: false
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-to-ghcr:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=sha-,format=short
- name: Log in to the Container registry
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || github.event.inputs.publish == 'true') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
CLI_VERSION_ARG=${{ github.sha }}

View File

@@ -24,7 +24,7 @@ jobs:
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
with:
version: 0.0.4
version: 0.0.5
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
settings_json: |
{

View File

@@ -42,7 +42,7 @@ jobs:
ISSUES_TO_TRIAGE: ${{ steps.find_issues.outputs.issues_to_triage }}
REPOSITORY: ${{ github.repository }}
with:
version: 0.0.4
version: 0.0.5
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
OPENAI_MODEL: ${{ secrets.OPENAI_MODEL }}

View File

@@ -1,7 +1,7 @@
name: 🧐 Qwen Pull Request Review
on:
pull_request:
pull_request_target:
types: [opened]
pull_request_review_comment:
types: [created]

View File

@@ -1,3 +1,31 @@
# Build stage
FROM docker.io/library/node:20-slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
make \
g++ \
git \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Set up npm global package folder
RUN mkdir -p /usr/local/share/npm-global
ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
ENV PATH=$PATH:/usr/local/share/npm-global/bin
# Copy source code
COPY . /home/node/app
WORKDIR /home/node/app
# Install dependencies and build packages
RUN npm ci \
&& npm run build --workspaces \
&& npm pack -w @qwen-code/qwen-code --pack-destination ./packages/cli/dist \
&& npm pack -w @qwen-code/qwen-code-core --pack-destination ./packages/core/dist
# Runtime stage
FROM docker.io/library/node:20-slim
ARG SANDBOX_NAME="qwen-code-sandbox"
@@ -5,11 +33,9 @@ ARG CLI_VERSION_ARG
ENV SANDBOX="$SANDBOX_NAME"
ENV CLI_VERSION=$CLI_VERSION_ARG
# install minimal set of packages, then clean up
# Install runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
make \
g++ \
man-db \
curl \
dnsutils \
@@ -29,22 +55,19 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# set up npm global package folder under /usr/local/share
# give it to non-root user node, already set up in base image
RUN mkdir -p /usr/local/share/npm-global \
&& chown -R node:node /usr/local/share/npm-global
# Set up npm global package folder
RUN mkdir -p /usr/local/share/npm-global
ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
ENV PATH=$PATH:/usr/local/share/npm-global/bin
# switch to non-root user node
USER node
# Copy built packages from builder stage
COPY --from=builder /home/node/app/packages/cli/dist/*.tgz /tmp/
COPY --from=builder /home/node/app/packages/core/dist/*.tgz /tmp/
# install qwen-code and clean up
COPY packages/cli/dist/qwen-code-*.tgz /usr/local/share/npm-global/qwen-code.tgz
COPY packages/core/dist/qwen-code-qwen-code-core-*.tgz /usr/local/share/npm-global/qwen-code-core.tgz
RUN npm install -g /usr/local/share/npm-global/qwen-code.tgz /usr/local/share/npm-global/qwen-code-core.tgz \
# Install built packages globally
RUN npm install -g /tmp/*.tgz \
&& npm cache clean --force \
&& rm -f /usr/local/share/npm-global/qwen-{code,code-core}.tgz
&& rm -rf /tmp/*.tgz
# default entrypoint when none specified
CMD ["qwen"]
# Default entrypoint when none specified
CMD ["qwen"]

10
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@qwen-code/qwen-code",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@qwen-code/qwen-code",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"workspaces": [
"packages/*"
],
@@ -11817,7 +11817,7 @@
},
"packages/cli": {
"name": "@qwen-code/qwen-code",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"dependencies": {
"@google/genai": "1.9.0",
"@iarna/toml": "^2.2.5",
@@ -11894,7 +11894,7 @@
},
"packages/core": {
"name": "@qwen-code/qwen-code-core",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"dependencies": {
"@google/genai": "1.9.0",
"@modelcontextprotocol/sdk": "^1.11.0",
@@ -11962,7 +11962,7 @@
},
"packages/vscode-ide-companion": {
"name": "qwen-code-vscode-ide-companion",
"version": "0.0.4",
"version": "0.0.5",
"license": "LICENSE",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.15.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@qwen-code/qwen-code",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"engines": {
"node": ">=20.0.0"
},
@@ -13,7 +13,7 @@
"url": "git+https://github.com/QwenLM/qwen-code.git"
},
"config": {
"sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.0.5-nightly.12"
"sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.0.6-nightly.2"
},
"scripts": {
"start": "node scripts/start.js",

View File

@@ -1,6 +1,6 @@
{
"name": "@qwen-code/qwen-code",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"description": "Qwen Code",
"repository": {
"type": "git",
@@ -25,7 +25,7 @@
"dist"
],
"config": {
"sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.0.5-nightly.12"
"sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.0.6-nightly.2"
},
"dependencies": {
"@google/genai": "1.9.0",

View File

@@ -412,6 +412,7 @@ export async function loadCliConfig(
}
const sandboxConfig = await loadSandboxConfig(settings, argv);
const cliVersion = await getCliVersion();
return new Config({
sessionId,
@@ -497,6 +498,7 @@ export async function loadCliConfig(
},
],
contentGenerator: settings.contentGenerator,
cliVersion,
});
}

View File

@@ -9,7 +9,7 @@
(subpath (param "TARGET_DIR"))
(subpath (param "TMP_DIR"))
(subpath (param "CACHE_DIR"))
(subpath (string-append (param "HOME_DIR") "/.gemini"))
(subpath (string-append (param "HOME_DIR") "/.qwen"))
(subpath (string-append (param "HOME_DIR") "/.npm"))
(subpath (string-append (param "HOME_DIR") "/.cache"))
(subpath (string-append (param "HOME_DIR") "/.gitconfig"))

View File

@@ -9,7 +9,7 @@
(subpath (param "TARGET_DIR"))
(subpath (param "TMP_DIR"))
(subpath (param "CACHE_DIR"))
(subpath (string-append (param "HOME_DIR") "/.gemini"))
(subpath (string-append (param "HOME_DIR") "/.qwen"))
(subpath (string-append (param "HOME_DIR") "/.npm"))
(subpath (string-append (param "HOME_DIR") "/.cache"))
(subpath (string-append (param "HOME_DIR") "/.gitconfig"))

View File

@@ -9,7 +9,7 @@
(subpath (param "TARGET_DIR"))
(subpath (param "TMP_DIR"))
(subpath (param "CACHE_DIR"))
(subpath (string-append (param "HOME_DIR") "/.gemini"))
(subpath (string-append (param "HOME_DIR") "/.qwen"))
(subpath (string-append (param "HOME_DIR") "/.npm"))
(subpath (string-append (param "HOME_DIR") "/.cache"))
(subpath (string-append (param "HOME_DIR") "/.gitconfig"))

View File

@@ -67,7 +67,7 @@
(subpath (param "TARGET_DIR"))
(subpath (param "TMP_DIR"))
(subpath (param "CACHE_DIR"))
(subpath (string-append (param "HOME_DIR") "/.gemini"))
(subpath (string-append (param "HOME_DIR") "/.qwen"))
(subpath (string-append (param "HOME_DIR") "/.npm"))
(subpath (string-append (param "HOME_DIR") "/.cache"))
(subpath (string-append (param "HOME_DIR") "/.gitconfig"))

View File

@@ -67,7 +67,7 @@
(subpath (param "TARGET_DIR"))
(subpath (param "TMP_DIR"))
(subpath (param "CACHE_DIR"))
(subpath (string-append (param "HOME_DIR") "/.gemini"))
(subpath (string-append (param "HOME_DIR") "/.qwen"))
(subpath (string-append (param "HOME_DIR") "/.npm"))
(subpath (string-append (param "HOME_DIR") "/.cache"))
(subpath (string-append (param "HOME_DIR") "/.gitconfig"))

View File

@@ -67,7 +67,7 @@
(subpath (param "TARGET_DIR"))
(subpath (param "TMP_DIR"))
(subpath (param "CACHE_DIR"))
(subpath (string-append (param "HOME_DIR") "/.gemini"))
(subpath (string-append (param "HOME_DIR") "/.qwen"))
(subpath (string-append (param "HOME_DIR") "/.npm"))
(subpath (string-append (param "HOME_DIR") "/.cache"))
(subpath (string-append (param "HOME_DIR") "/.gitconfig"))

View File

@@ -1,6 +1,6 @@
{
"name": "@qwen-code/qwen-code-core",
"version": "0.0.5-nightly.12",
"version": "0.0.6-nightly.2",
"description": "Qwen Code Core",
"repository": {
"type": "git",

View File

@@ -208,6 +208,7 @@ export interface ConfigParameters {
timeout?: number;
maxRetries?: number;
};
cliVersion?: string;
}
export class Config {
@@ -281,6 +282,7 @@ export class Config {
timeout?: number;
maxRetries?: number;
};
private readonly cliVersion?: string;
constructor(params: ConfigParameters) {
this.sessionId = params.sessionId;
this.embeddingModel =
@@ -350,6 +352,7 @@ export class Config {
this.enableOpenAILogging = params.enableOpenAILogging ?? false;
this.sampling_params = params.sampling_params;
this.contentGenerator = params.contentGenerator;
this.cliVersion = params.cliVersion;
if (params.contextFileName) {
setGeminiMdFilename(params.contextFileName);
@@ -719,6 +722,10 @@ export class Config {
return this.contentGenerator?.maxRetries;
}
getCliVersion(): string | undefined {
return this.cliVersion;
}
getSystemPromptMappings():
| Array<{
baseUrls?: string[];

View File

@@ -45,6 +45,7 @@ describe('OpenAIContentGenerator Timeout Handling', () => {
timeout: 120000,
maxRetries: 3,
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
// Mock OpenAI client
@@ -256,6 +257,7 @@ describe('OpenAIContentGenerator Timeout Handling', () => {
timeout: 300000, // 5 minutes
maxRetries: 5,
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
new OpenAIContentGenerator('test-key', 'gpt-4', customConfig);
@@ -274,6 +276,7 @@ describe('OpenAIContentGenerator Timeout Handling', () => {
it('should handle missing timeout config gracefully', () => {
const noTimeoutConfig = {
getContentGeneratorConfig: vi.fn().mockReturnValue({}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
new OpenAIContentGenerator('test-key', 'gpt-4', noTimeoutConfig);

View File

@@ -228,6 +228,7 @@ describe('Gemini Client (client.ts)', () => {
getGeminiClient: vi.fn(),
setFallbackMode: vi.fn(),
getDebugMode: vi.fn().mockReturnValue(false),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
};
const MockedConfig = vi.mocked(Config, true);
MockedConfig.mockImplementation(

View File

@@ -17,7 +17,9 @@ import { Config } from '../config/config.js';
vi.mock('../code_assist/codeAssist.js');
vi.mock('@google/genai');
const mockConfig = {} as unknown as Config;
const mockConfig = {
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
describe('createContentGenerator', () => {
it('should create a CodeAssistContentGenerator', async () => {
@@ -73,6 +75,7 @@ describe('createContentGeneratorConfig', () => {
getSamplingParams: vi.fn().mockReturnValue(undefined),
getContentGeneratorTimeout: vi.fn().mockReturnValue(undefined),
getContentGeneratorMaxRetries: vi.fn().mockReturnValue(undefined),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
beforeEach(() => {

View File

@@ -151,7 +151,7 @@ export async function createContentGenerator(
gcConfig: Config,
sessionId?: string,
): Promise<ContentGenerator> {
const version = process.env.CLI_VERSION || process.version;
const version = gcConfig.getCliVersion() || 'unknown';
const httpOptions = {
headers: {
'User-Agent': `GeminiCLI/${version} (${process.platform}; ${process.arch})`,

View File

@@ -66,6 +66,7 @@ describe('OpenAIContentGenerator', () => {
top_p: 0.9,
},
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
// Mock OpenAI client
@@ -143,6 +144,7 @@ describe('OpenAIContentGenerator', () => {
timeout: 300000,
maxRetries: 5,
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
new OpenAIContentGenerator('test-key', 'gpt-4', customConfig);
@@ -901,6 +903,7 @@ describe('OpenAIContentGenerator', () => {
getContentGeneratorConfig: vi.fn().mockReturnValue({
enableOpenAILogging: true,
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const loggingGenerator = new OpenAIContentGenerator(
@@ -1023,6 +1026,7 @@ describe('OpenAIContentGenerator', () => {
getContentGeneratorConfig: vi.fn().mockReturnValue({
enableOpenAILogging: true,
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const loggingGenerator = new OpenAIContentGenerator(
@@ -1817,6 +1821,7 @@ describe('OpenAIContentGenerator', () => {
max_tokens: 500,
},
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const loggingGenerator = new OpenAIContentGenerator(
@@ -2001,6 +2006,7 @@ describe('OpenAIContentGenerator', () => {
getContentGeneratorConfig: vi.fn().mockReturnValue({
enableOpenAILogging: true,
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const loggingGenerator = new OpenAIContentGenerator(
@@ -2257,6 +2263,7 @@ describe('OpenAIContentGenerator', () => {
top_p: undefined,
},
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const testGenerator = new OpenAIContentGenerator(
@@ -2314,6 +2321,7 @@ describe('OpenAIContentGenerator', () => {
frequency_penalty: 0.3,
},
}),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const testGenerator = new OpenAIContentGenerator(
@@ -2394,6 +2402,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const qwenGenerator = new OpenAIContentGenerator(
@@ -2447,6 +2456,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('dashscope-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const dashscopeGenerator = new OpenAIContentGenerator(
@@ -2507,6 +2517,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('regular-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const regularGenerator = new OpenAIContentGenerator(
@@ -2552,6 +2563,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('other-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const otherGenerator = new OpenAIContentGenerator(
@@ -2600,6 +2612,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('other-base-url-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const otherBaseUrlGenerator = new OpenAIContentGenerator(
@@ -2648,6 +2661,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('streaming-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const qwenGenerator = new OpenAIContentGenerator(
@@ -2726,6 +2740,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('regular-streaming-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const regularGenerator = new OpenAIContentGenerator(
@@ -2799,6 +2814,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue(undefined), // Undefined session ID
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const qwenGenerator = new OpenAIContentGenerator(
@@ -2852,6 +2868,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('no-base-url-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const noBaseUrlGenerator = new OpenAIContentGenerator(
@@ -2900,6 +2917,7 @@ describe('OpenAIContentGenerator', () => {
enableOpenAILogging: false,
}),
getSessionId: vi.fn().mockReturnValue('undefined-auth-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const undefinedAuthGenerator = new OpenAIContentGenerator(
@@ -2945,6 +2963,7 @@ describe('OpenAIContentGenerator', () => {
const undefinedConfig = {
getContentGeneratorConfig: vi.fn().mockReturnValue(undefined), // Undefined config
getSessionId: vi.fn().mockReturnValue('undefined-config-session-id'),
getCliVersion: vi.fn().mockReturnValue('1.0.0'),
} as unknown as Config;
const undefinedConfigGenerator = new OpenAIContentGenerator(

View File

@@ -114,8 +114,7 @@ export class OpenAIContentGenerator implements ContentGenerator {
timeoutConfig.maxRetries = contentGeneratorConfig.maxRetries;
}
// Set up User-Agent header (same format as contentGenerator.ts)
const version = process.env.CLI_VERSION || process.version;
const version = config.getCliVersion() || 'unknown';
const userAgent = `QwenCode/${version} (${process.platform}; ${process.arch})`;
// Check if using OpenRouter and add required headers

View File

@@ -140,14 +140,14 @@ export class QwenLogger {
return this.createRumEvent('exception', type, name, properties);
}
createRumPayload(): RumPayload {
const version = process.env.CLI_VERSION || process.version;
async createRumPayload(): Promise<RumPayload> {
const version = this.config?.getCliVersion() || 'unknown';
return {
app: {
id: RUN_APP_ID,
env: process.env.DEBUG ? 'dev' : 'prod',
version,
version: version || 'unknown',
type: 'cli',
},
user: {
@@ -190,7 +190,7 @@ export class QwenLogger {
this.isFlushInProgress = true;
const rumPayload = this.createRumPayload();
const rumPayload = await this.createRumPayload();
const flushFn = () =>
new Promise<Buffer>((resolve, reject) => {
const body = safeJsonStringify(rumPayload);
@@ -322,19 +322,16 @@ export class QwenLogger {
this.flushIfNeeded();
}
logApiRequestEvent(_event: ApiRequestEvent): void {
// ignore for now
return;
logApiRequestEvent(event: ApiRequestEvent): void {
const rumEvent = this.createResourceEvent('api', 'api_request', {
properties: {
model: event.model,
prompt_id: event.prompt_id,
},
});
// const rumEvent = this.createResourceEvent('api', 'api_request', {
// properties: {
// model: event.model,
// prompt_id: event.prompt_id,
// },
// });
// this.enqueueLogEvent(rumEvent);
// this.flushIfNeeded();
this.enqueueLogEvent(rumEvent);
this.flushIfNeeded();
}
logApiResponseEvent(event: ApiResponseEvent): void {

View File

@@ -2,7 +2,7 @@
"name": "qwen-code-vscode-ide-companion",
"displayName": "Qwen Code Companion",
"description": "Enable Qwen Code with direct access to your VS Code workspace.",
"version": "0.0.4",
"version": "0.0.5",
"publisher": "qwenlm",
"icon": "assets/icon.png",
"repository": {