@pedrofariasx/qwenproxy 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pedrofariasx/qwenproxy",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Local OpenAI-compatible proxy API that routes requests to Qwen (chat.qwen.ai) via Playwright browser automation.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -74,9 +74,8 @@ export function listAccounts(): QwenAccount[] {
74
74
  }
75
75
 
76
76
  export function getAccountCredentials(id: string): QwenAccount | undefined {
77
- const db = getDatabase()
78
- const row = db.prepare('SELECT id, email, password, cooldown_until, cooldown_reason FROM accounts WHERE id = ?').get(id)
79
- return row as QwenAccount | undefined
77
+ const cached = getCachedAccounts()
78
+ return cached.find(a => a.id === id)
80
79
  }
81
80
 
82
81
  export function updateAccountCooldown(id: string, cooldownUntil: number, reason: string | null): void {
@@ -566,12 +566,12 @@ export async function chatCompletions(c: Context) {
566
566
  const createdTimestamp = Math.floor(Date.now() / 1000);
567
567
 
568
568
  const fastWriteContent = (content: string) => {
569
- const escaped = content.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t');
569
+ const escaped = JSON.stringify(content).slice(1, -1);
570
570
  streamWriter.write(`data: {"id":"${completionId}","object":"chat.completion.chunk","created":${createdTimestamp},"model":"${body.model}","choices":[{"index":0,"delta":{"content":"${escaped}"},"logprobs":null,"finish_reason":null}]}\n\n`);
571
571
  };
572
572
 
573
573
  const fastWriteReasoning = (content: string) => {
574
- const escaped = content.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t');
574
+ const escaped = JSON.stringify(content).slice(1, -1);
575
575
  streamWriter.write(`data: {"id":"${completionId}","object":"chat.completion.chunk","created":${createdTimestamp},"model":"${body.model}","choices":[{"index":0,"delta":{"reasoning_content":"${escaped}"},"logprobs":null,"finish_reason":null}]}\n\n`);
576
576
  };
577
577
 
@@ -827,9 +827,9 @@ async function _getQwenHeadersInternal(forceNew = false, accountId?: string): Pr
827
827
 
828
828
  await page.focus(inputSelector);
829
829
  await page.fill(inputSelector, '');
830
- await page.type(inputSelector, 'a', { delay: 100 });
830
+ await page.type(inputSelector, 'a', { delay: 20 });
831
831
  console.log(`[Playwright] Typed char for ${cacheKey}, waiting for UI to update...`);
832
- await sleep(2000);
832
+ await sleep(800);
833
833
 
834
834
  const selectors = [
835
835
  '.message-input-right-button-send .send-button',
@@ -86,6 +86,7 @@ const refillPromises: Map<string, Promise<void>> = new Map();
86
86
 
87
87
  const WARM_POOL_SIZE = 10;
88
88
  const WARM_POOL_TTL_MS = 10 * 60 * 1000;
89
+ const WARM_POOL_LOW_WATER = 3;
89
90
 
90
91
  function cleanupStalePool(accountId: string) {
91
92
  const pool = warmPool.get(accountId);
@@ -243,6 +244,11 @@ export async function getWarmedChat(accountId?: string) {
243
244
  let pool = warmPool.get(key);
244
245
  if (!pool) { pool = []; warmPool.set(key, pool); }
245
246
  cleanupStalePool(key);
247
+
248
+ if (pool.length < WARM_POOL_LOW_WATER && !refillPromises.has(key)) {
249
+ refillPromises.set(key, refillPoolForAccount(key).finally(() => refillPromises.delete(key)));
250
+ }
251
+
246
252
  if (pool.length === 0) {
247
253
  if (!refillPromises.has(key)) {
248
254
  refillPromises.set(key, refillPoolForAccount(key).finally(() => refillPromises.delete(key)));