qwenproxy-cli 1.0.0

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.
Files changed (109) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +907 -0
  3. package/bin/qwenproxy.js +141 -0
  4. package/package.json +78 -0
  5. package/src/api/error-classifier.ts +159 -0
  6. package/src/api/error-helpers.ts +118 -0
  7. package/src/api/models.ts +261 -0
  8. package/src/api/server.ts +859 -0
  9. package/src/cache/memory-cache.ts +385 -0
  10. package/src/clean-cache.ts +204 -0
  11. package/src/core/account-concurrency.ts +671 -0
  12. package/src/core/account-manager.ts +297 -0
  13. package/src/core/account-priority.ts +163 -0
  14. package/src/core/accounts.ts +186 -0
  15. package/src/core/config.ts +383 -0
  16. package/src/core/crypto-utils.ts +79 -0
  17. package/src/core/database.ts +276 -0
  18. package/src/core/errors.ts +118 -0
  19. package/src/core/logger.ts +269 -0
  20. package/src/core/memory-usage.ts +84 -0
  21. package/src/core/metrics.ts +291 -0
  22. package/src/core/model-alias.ts +77 -0
  23. package/src/core/model-registry.ts +544 -0
  24. package/src/core/mutex.ts +119 -0
  25. package/src/core/paths.ts +199 -0
  26. package/src/core/prompt-limits.ts +214 -0
  27. package/src/core/reasoning-effort.ts +102 -0
  28. package/src/core/stream-registry.ts +96 -0
  29. package/src/core/waf-isolation.ts +117 -0
  30. package/src/core/watchdog.ts +195 -0
  31. package/src/delete-chats.ts +23 -0
  32. package/src/index.ts +64 -0
  33. package/src/login.ts +147 -0
  34. package/src/reset-cooldowns.ts +11 -0
  35. package/src/routes/anthropic/index.ts +355 -0
  36. package/src/routes/anthropic/translate.ts +522 -0
  37. package/src/routes/anthropic/types.ts +154 -0
  38. package/src/routes/anthropic/validation.ts +144 -0
  39. package/src/routes/chat/account.ts +1817 -0
  40. package/src/routes/chat/context.ts +241 -0
  41. package/src/routes/chat/errors.ts +85 -0
  42. package/src/routes/chat/helpers.ts +268 -0
  43. package/src/routes/chat/index.ts +618 -0
  44. package/src/routes/chat/media.ts +285 -0
  45. package/src/routes/chat/retry-policy.ts +754 -0
  46. package/src/routes/chat/stop.ts +98 -0
  47. package/src/routes/chat/streaming.ts +2710 -0
  48. package/src/routes/chat/validation.ts +526 -0
  49. package/src/routes/chat.ts +2 -0
  50. package/src/routes/completions.ts +290 -0
  51. package/src/routes/images.ts +139 -0
  52. package/src/routes/responses/adapter.ts +503 -0
  53. package/src/routes/responses/index.ts +405 -0
  54. package/src/routes/responses/state.ts +230 -0
  55. package/src/routes/responses/streaming.ts +528 -0
  56. package/src/routes/responses/types.ts +285 -0
  57. package/src/routes/responses/validation.ts +202 -0
  58. package/src/routes/upload.ts +731 -0
  59. package/src/routes/videos.ts +214 -0
  60. package/src/services/auth-playwright.ts +173 -0
  61. package/src/services/captcha-coordinator.ts +161 -0
  62. package/src/services/captcha-solver.ts +553 -0
  63. package/src/services/chat-cleanup.ts +80 -0
  64. package/src/services/context-meter.ts +317 -0
  65. package/src/services/fingerprint.ts +242 -0
  66. package/src/services/human-behavior.ts +173 -0
  67. package/src/services/media-generation.ts +1748 -0
  68. package/src/services/playwright.ts +2800 -0
  69. package/src/services/qwen-chat-pool.ts +345 -0
  70. package/src/services/qwen-errors.ts +133 -0
  71. package/src/services/qwen-headers.ts +79 -0
  72. package/src/services/qwen-thread-state.ts +393 -0
  73. package/src/services/qwen-url.ts +19 -0
  74. package/src/services/qwen.ts +3126 -0
  75. package/src/services/session-keeper.ts +88 -0
  76. package/src/services/token-estimation-metrics.ts +118 -0
  77. package/src/sync/claude-code.ts +75 -0
  78. package/src/sync/codex.ts +123 -0
  79. package/src/sync/index.ts +362 -0
  80. package/src/sync/omp.ts +105 -0
  81. package/src/sync/opencode.ts +214 -0
  82. package/src/sync/types.ts +53 -0
  83. package/src/sync/utils.ts +27 -0
  84. package/src/sync-clients.ts +189 -0
  85. package/src/tools/instructions.ts +137 -0
  86. package/src/tools/manifest.ts +81 -0
  87. package/src/tools/parser.ts +2989 -0
  88. package/src/tools/toolcall-tags.ts +142 -0
  89. package/src/tools/types.ts +53 -0
  90. package/src/tui/app.ts +264 -0
  91. package/src/tui/index.ts +61 -0
  92. package/src/tui/markdown.ts +258 -0
  93. package/src/tui/proxy-client.ts +326 -0
  94. package/src/tui/screen.ts +278 -0
  95. package/src/tui/server-manager.ts +270 -0
  96. package/src/tui/theme.ts +432 -0
  97. package/src/tui/types.ts +33 -0
  98. package/src/tui/views/accounts-view.ts +656 -0
  99. package/src/tui/views/chat-view.ts +823 -0
  100. package/src/tui/views/logs-view.ts +413 -0
  101. package/src/tui/views/status-view.ts +204 -0
  102. package/src/tui/views/storage-view.ts +291 -0
  103. package/src/tui/views/sync-view.ts +409 -0
  104. package/src/types/ali-oss.d.ts +32 -0
  105. package/src/utils/context-truncation.ts +84 -0
  106. package/src/utils/json.ts +380 -0
  107. package/src/utils/session-id.ts +37 -0
  108. package/src/utils/tool-call-guard.ts +85 -0
  109. package/src/utils/types.ts +109 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Handler for aborting an in-flight chat completion via the upstream
3
+ * Qwen stop endpoint. Looks up the active stream in the registry,
4
+ * forwards the stop request, then aborts the local AbortController.
5
+ */
6
+
7
+ import type { Context } from "hono";
8
+ import { buildQwenRequestHeaders } from "../../services/qwen-headers.ts";
9
+ import { qwenUrl } from "../../services/qwen-url.ts";
10
+ import {
11
+ getStream,
12
+ getStreamKeyBySessionAndResponse,
13
+ getStreamKeysBySessionId,
14
+ removeStream,
15
+ } from "../../core/stream-registry.ts";
16
+ import { requestQwenTextInBrowser } from "../../services/qwen.ts";
17
+ import { sendOpenAIError, createError } from "../../api/error-helpers.js";
18
+
19
+ export async function chatCompletionsStop(c: Context) {
20
+ try {
21
+ const body = await c.req.json();
22
+ const { chat_id, response_id } = body;
23
+
24
+ if (!chat_id || !response_id) {
25
+ return sendOpenAIError(
26
+ c,
27
+ createError(400, "chat_id and response_id are required", "chat_id"),
28
+ );
29
+ }
30
+
31
+ // Resolve the stream key with the minimum number of registry scans:
32
+ // exact (session, response) match first, then a single session scan.
33
+ const exactStreamKey = getStreamKeyBySessionAndResponse(
34
+ chat_id,
35
+ response_id,
36
+ );
37
+ let streamKey = exactStreamKey ?? chat_id;
38
+ if (!exactStreamKey) {
39
+ const matchingSessionStreamKeys = getStreamKeysBySessionId(chat_id);
40
+ if (matchingSessionStreamKeys.length > 1) {
41
+ return sendOpenAIError(
42
+ c,
43
+ createError(
44
+ 400,
45
+ "Multiple active streams for this chat_id; wait for response_id registration and retry",
46
+ "chat_id",
47
+ ),
48
+ );
49
+ }
50
+ streamKey = matchingSessionStreamKeys[0] ?? chat_id;
51
+ }
52
+ const stream = getStream(streamKey);
53
+ if (!stream) {
54
+ return sendOpenAIError(c, createError(404, "Stream not found"));
55
+ }
56
+
57
+ if (stream.targetResponseId && stream.targetResponseId !== response_id) {
58
+ return sendOpenAIError(
59
+ c,
60
+ createError(400, "response_id mismatch", "response_id"),
61
+ );
62
+ }
63
+
64
+ const stopResponse = await requestQwenTextInBrowser(
65
+ stream.accountId,
66
+ "POST",
67
+ `/api/v2/chat/completions/stop?chat_id=${encodeURIComponent(chat_id)}`,
68
+ buildQwenRequestHeaders({
69
+ cookie: stream.headers.cookie,
70
+ userAgent: stream.headers["user-agent"],
71
+ bxUa: stream.headers["bx-ua"],
72
+ bxUmidtoken: stream.headers["bx-umidtoken"],
73
+ bxV: stream.headers["bx-v"],
74
+ chatSessionId: chat_id,
75
+ }),
76
+ JSON.stringify({ chat_id, response_id }),
77
+ { referrer: qwenUrl(`/c/${encodeURIComponent(chat_id)}`) },
78
+ );
79
+
80
+ if (!stopResponse.ok) {
81
+ const errorText = await stopResponse.text();
82
+ console.error(
83
+ `[Stop] Failed to stop generation for chat_id=${chat_id}: ${stopResponse.status} ${errorText}`,
84
+ );
85
+ return sendOpenAIError(c, createError(502, "Failed to stop generation"));
86
+ }
87
+
88
+ stream.abortController.abort();
89
+ removeStream(streamKey);
90
+
91
+ console.log(`🛑 [Stop] Generation stopped for chat_id=${chat_id}`);
92
+ return c.json({ success: true });
93
+ } catch (err: unknown) {
94
+ const message = err instanceof Error ? err.message : String(err);
95
+ console.error(`❌ [Stop] Error | ${message}`);
96
+ return sendOpenAIError(c, err, 500);
97
+ }
98
+ }