opencode-translate 0.0.9 → 0.0.11

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/translator.ts +40 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-translate",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "OpenCode plugin that lets the user chat in a configured source language while the main chat loop only sees English.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/translator.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { createHash, randomUUID } from "node:crypto"
1
+ import { createHash, randomBytes } from "node:crypto"
2
2
  import { setTimeout as sleep } from "node:timers/promises"
3
3
  import { generateText } from "ai"
4
4
  import { createCredentialResolver } from "./auth"
@@ -30,8 +30,10 @@ interface TranslateTextInput {
30
30
  }
31
31
 
32
32
  // Hard timeout for a single generateText call. Without this, a stalled
33
- // provider request can block the chat.message hook indefinitely.
34
- const DEFAULT_TRANSLATE_TIMEOUT_MS = 60_000
33
+ // provider request can block the chat.message hook indefinitely. Long
34
+ // assistant responses can require well over a minute to translate, so
35
+ // the budget here is generous; retries will still bound the worst case.
36
+ const DEFAULT_TRANSLATE_TIMEOUT_MS = 180_000
35
37
 
36
38
  function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T> {
37
39
  return new Promise<T>((resolve, reject) => {
@@ -51,8 +53,29 @@ function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string):
51
53
 
52
54
  const providerFactoryCache = new Map<string, unknown>()
53
55
 
56
+ const PART_ID_LENGTH = 26
57
+ const PART_ID_PREFIX = "prt"
58
+ const BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
59
+ let partLastTimestamp = 0
60
+ let partCounter = 0
61
+
54
62
  export function __resetTranslatorCachesForTest() {
55
63
  providerFactoryCache.clear()
64
+ __resetSyntheticPartIDForTest()
65
+ }
66
+
67
+ export function __resetSyntheticPartIDForTest() {
68
+ partLastTimestamp = 0
69
+ partCounter = 0
70
+ }
71
+
72
+ function randomBase62(length: number): string {
73
+ const bytes = randomBytes(length)
74
+ let result = ""
75
+ for (let index = 0; index < length; index += 1) {
76
+ result += BASE62_CHARS[bytes[index] % BASE62_CHARS.length]
77
+ }
78
+ return result
56
79
  }
57
80
 
58
81
  function getStatus(error: unknown): number | undefined {
@@ -201,7 +224,20 @@ export function hashText(text: string): string {
201
224
  }
202
225
 
203
226
  export function createSyntheticPartID(): string {
204
- return `prt_${randomUUID().replaceAll("-", "")}`
227
+ const currentTimestamp = Date.now()
228
+ if (currentTimestamp !== partLastTimestamp) {
229
+ partLastTimestamp = currentTimestamp
230
+ partCounter = 0
231
+ }
232
+ partCounter += 1
233
+
234
+ const encoded = BigInt(currentTimestamp) * BigInt(0x1000) + BigInt(partCounter)
235
+ const timeBytes = Buffer.alloc(6)
236
+ for (let index = 0; index < 6; index += 1) {
237
+ timeBytes[index] = Number((encoded >> BigInt(40 - 8 * index)) & BigInt(0xff))
238
+ }
239
+
240
+ return `${PART_ID_PREFIX}_${timeBytes.toString("hex")}${randomBase62(PART_ID_LENGTH - 12)}`
205
241
  }
206
242
 
207
243
  export function createTranslator(