@kenkaiiii/ggcoder 4.3.243 → 4.4.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.
- package/dist/config.d.ts +3 -14
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -17
- package/dist/config.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -40
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -200
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/auto-update.d.ts +4 -26
- package/dist/core/auto-update.d.ts.map +1 -1
- package/dist/core/auto-update.js +12 -237
- package/dist/core/auto-update.js.map +1 -1
- package/dist/core/claude-code-version.d.ts +1 -9
- package/dist/core/claude-code-version.d.ts.map +1 -1
- package/dist/core/claude-code-version.js +2 -105
- package/dist/core/claude-code-version.js.map +1 -1
- package/dist/core/file-lock.d.ts +1 -5
- package/dist/core/file-lock.d.ts.map +1 -1
- package/dist/core/file-lock.js +2 -75
- package/dist/core/file-lock.js.map +1 -1
- package/dist/core/logger.d.ts +4 -17
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +21 -110
- package/dist/core/logger.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -54
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +4 -296
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/oauth/anthropic.d.ts +1 -3
- package/dist/core/oauth/anthropic.d.ts.map +1 -1
- package/dist/core/oauth/anthropic.js +2 -96
- package/dist/core/oauth/anthropic.js.map +1 -1
- package/dist/core/oauth/gemini.d.ts +1 -3
- package/dist/core/oauth/gemini.d.ts.map +1 -1
- package/dist/core/oauth/gemini.js +2 -379
- package/dist/core/oauth/gemini.js.map +1 -1
- package/dist/core/oauth/openai.d.ts +1 -3
- package/dist/core/oauth/openai.d.ts.map +1 -1
- package/dist/core/oauth/openai.js +2 -187
- package/dist/core/oauth/openai.js.map +1 -1
- package/dist/core/oauth/pkce.d.ts +1 -4
- package/dist/core/oauth/pkce.d.ts.map +1 -1
- package/dist/core/oauth/pkce.js +2 -16
- package/dist/core/oauth/pkce.js.map +1 -1
- package/dist/core/oauth/types.d.ts +1 -13
- package/dist/core/oauth/types.d.ts.map +1 -1
- package/dist/core/telegram.d.ts +1 -112
- package/dist/core/telegram.d.ts.map +1 -1
- package/dist/core/telegram.js +2 -251
- package/dist/core/telegram.js.map +1 -1
- package/dist/core/thinking-level.d.ts +1 -4
- package/dist/core/thinking-level.d.ts.map +1 -1
- package/dist/core/thinking-level.js +3 -58
- package/dist/core/thinking-level.js.map +1 -1
- package/dist/core/voice-transcriber.d.ts +1 -32
- package/dist/core/voice-transcriber.d.ts.map +1 -1
- package/dist/core/voice-transcriber.js +3 -112
- package/dist/core/voice-transcriber.js.map +1 -1
- package/package.json +5 -4
- package/dist/core/model-registry.test.d.ts +0 -2
- package/dist/core/model-registry.test.d.ts.map +0 -1
- package/dist/core/model-registry.test.js +0 -95
- package/dist/core/model-registry.test.js.map +0 -1
- package/dist/core/oauth/gemini.test.d.ts +0 -2
- package/dist/core/oauth/gemini.test.d.ts.map +0 -1
- package/dist/core/oauth/gemini.test.js +0 -154
- package/dist/core/oauth/gemini.test.js.map +0 -1
- package/dist/core/thinking-level.test.d.ts +0 -2
- package/dist/core/thinking-level.test.d.ts.map +0 -1
- package/dist/core/thinking-level.test.js +0 -38
- package/dist/core/thinking-level.test.js.map +0 -1
- package/dist/core/voice-transcriber.test.d.ts +0 -2
- package/dist/core/voice-transcriber.test.d.ts.map +0 -1
- package/dist/core/voice-transcriber.test.js +0 -88
- package/dist/core/voice-transcriber.test.js.map +0 -1
|
@@ -1,113 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Model (~75MB) is downloaded on first use and cached locally.
|
|
5
|
-
*/
|
|
6
|
-
const TARGET_SAMPLE_RATE = 16000;
|
|
7
|
-
const MODEL_ID = "Xenova/whisper-tiny.en";
|
|
8
|
-
let transcriber = null;
|
|
9
|
-
let loadPromise = null;
|
|
10
|
-
let onProgress = null;
|
|
11
|
-
/** Set a callback to receive model download progress updates. */
|
|
12
|
-
export function setProgressCallback(cb) {
|
|
13
|
-
onProgress = cb;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Resample audio from one sample rate to another using linear interpolation.
|
|
17
|
-
*/
|
|
18
|
-
export function resample(audio, fromRate, toRate) {
|
|
19
|
-
if (fromRate === toRate)
|
|
20
|
-
return audio;
|
|
21
|
-
const ratio = fromRate / toRate;
|
|
22
|
-
const newLength = Math.round(audio.length / ratio);
|
|
23
|
-
const result = new Float32Array(newLength);
|
|
24
|
-
for (let i = 0; i < newLength; i++) {
|
|
25
|
-
const srcIndex = i * ratio;
|
|
26
|
-
const low = Math.floor(srcIndex);
|
|
27
|
-
const high = Math.min(low + 1, audio.length - 1);
|
|
28
|
-
const frac = srcIndex - low;
|
|
29
|
-
result[i] = audio[low] * (1 - frac) + audio[high] * frac;
|
|
30
|
-
}
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Downmix multi-channel audio to mono by averaging all channels.
|
|
35
|
-
*/
|
|
36
|
-
export function downmixToMono(channelData) {
|
|
37
|
-
if (channelData.length === 0)
|
|
38
|
-
return new Float32Array();
|
|
39
|
-
if (channelData.length === 1)
|
|
40
|
-
return channelData[0];
|
|
41
|
-
const samples = channelData[0].length;
|
|
42
|
-
const out = new Float32Array(samples);
|
|
43
|
-
const scale = 1 / channelData.length;
|
|
44
|
-
for (let i = 0; i < samples; i++) {
|
|
45
|
-
let mixed = 0;
|
|
46
|
-
for (const channel of channelData)
|
|
47
|
-
mixed += channel[i] ?? 0;
|
|
48
|
-
out[i] = mixed * scale;
|
|
49
|
-
}
|
|
50
|
-
return out;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Decode OGG Opus audio buffer to 16kHz mono PCM Float32Array.
|
|
54
|
-
*/
|
|
55
|
-
export async function decodeOggOpus(buffer) {
|
|
56
|
-
const { OggOpusDecoder } = await import("ogg-opus-decoder");
|
|
57
|
-
const decoder = new OggOpusDecoder();
|
|
58
|
-
await decoder.ready;
|
|
59
|
-
try {
|
|
60
|
-
const decoded = await decoder.decodeFile(buffer);
|
|
61
|
-
if (!decoded.channelData?.length || !decoded.channelData[0]?.length) {
|
|
62
|
-
throw new Error("Decoded audio is empty");
|
|
63
|
-
}
|
|
64
|
-
const mono = downmixToMono(decoded.channelData);
|
|
65
|
-
return resample(mono, decoded.sampleRate, TARGET_SAMPLE_RATE);
|
|
66
|
-
}
|
|
67
|
-
finally {
|
|
68
|
-
decoder.free();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Get or initialize the Whisper transcription pipeline.
|
|
73
|
-
* Model is downloaded on first use and cached by transformers.js.
|
|
74
|
-
*/
|
|
75
|
-
async function getTranscriber() {
|
|
76
|
-
if (transcriber)
|
|
77
|
-
return transcriber;
|
|
78
|
-
if (!loadPromise) {
|
|
79
|
-
loadPromise = (async () => {
|
|
80
|
-
const { pipeline } = await import("@huggingface/transformers");
|
|
81
|
-
const instance = await pipeline("automatic-speech-recognition", MODEL_ID, {
|
|
82
|
-
dtype: "fp32",
|
|
83
|
-
progress_callback: onProgress ?? undefined,
|
|
84
|
-
});
|
|
85
|
-
transcriber = instance;
|
|
86
|
-
return instance;
|
|
87
|
-
})();
|
|
88
|
-
}
|
|
89
|
-
return loadPromise;
|
|
90
|
-
}
|
|
91
|
-
/** Whether the model has been loaded already. */
|
|
92
|
-
export function isModelLoaded() {
|
|
93
|
-
return transcriber !== null;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Transcribe a voice message from its Telegram file URL.
|
|
97
|
-
* Downloads the OGG Opus file, decodes to PCM, and runs Whisper locally.
|
|
98
|
-
*/
|
|
99
|
-
export async function transcribeVoice(fileUrl) {
|
|
100
|
-
// Download the audio file
|
|
101
|
-
const response = await fetch(fileUrl);
|
|
102
|
-
if (!response.ok)
|
|
103
|
-
throw new Error(`Failed to download voice file: ${response.status}`);
|
|
104
|
-
const buffer = new Uint8Array(await response.arrayBuffer());
|
|
105
|
-
// Decode OGG Opus → 16kHz mono PCM
|
|
106
|
-
const pcm = await decodeOggOpus(buffer);
|
|
107
|
-
// Transcribe with Whisper
|
|
108
|
-
const asr = await getTranscriber();
|
|
109
|
-
const result = await asr(pcm);
|
|
110
|
-
const text = Array.isArray(result) ? result[0]?.text : result.text;
|
|
111
|
-
return (text ?? "").trim();
|
|
112
|
-
}
|
|
1
|
+
// Moved to @kenkaiiii/gg-core. Shim keeps `../core/voice-transcriber.js`
|
|
2
|
+
// imports working.
|
|
3
|
+
export { setProgressCallback, resample, downmixToMono, decodeOggOpus, isModelLoaded, transcribeVoice, } from "@kenkaiiii/gg-core";
|
|
113
4
|
//# sourceMappingURL=voice-transcriber.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-transcriber.js","sourceRoot":"","sources":["../../src/core/voice-transcriber.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"voice-transcriber.js","sourceRoot":"","sources":["../../src/core/voice-transcriber.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,mBAAmB;AACnB,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,GAEhB,MAAM,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kenkaiiii/ggcoder",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI coding agent with OAuth authentication for Anthropic, OpenAI, and Gemini",
|
|
6
6
|
"license": "MIT",
|
|
@@ -110,9 +110,10 @@
|
|
|
110
110
|
"strip-ansi": "^7.2.0",
|
|
111
111
|
"wrap-ansi": "^10.0.0",
|
|
112
112
|
"zod": "^4.4.3",
|
|
113
|
-
"@kenkaiiii/gg-agent": "4.
|
|
114
|
-
"@kenkaiiii/gg-ai": "4.
|
|
115
|
-
"@kenkaiiii/gg-pixel": "4.3.101"
|
|
113
|
+
"@kenkaiiii/gg-agent": "4.4.0",
|
|
114
|
+
"@kenkaiiii/gg-ai": "4.4.0",
|
|
115
|
+
"@kenkaiiii/gg-pixel": "4.3.101",
|
|
116
|
+
"@kenkaiiii/gg-core": "4.4.0"
|
|
116
117
|
},
|
|
117
118
|
"optionalDependencies": {
|
|
118
119
|
"@huggingface/transformers": "^3.6.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-registry.test.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { MODELS, getContextWindow, getDefaultModel, getModelsForProvider, usesOpenAICodexTransport, } from "./model-registry.js";
|
|
3
|
-
const PROVIDERS = [
|
|
4
|
-
"anthropic",
|
|
5
|
-
"openai",
|
|
6
|
-
"gemini",
|
|
7
|
-
"moonshot",
|
|
8
|
-
"glm",
|
|
9
|
-
"minimax",
|
|
10
|
-
"xiaomi",
|
|
11
|
-
"deepseek",
|
|
12
|
-
"openrouter",
|
|
13
|
-
];
|
|
14
|
-
const THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
15
|
-
const COST_TIERS = ["low", "medium", "high"];
|
|
16
|
-
describe("model registry invariants", () => {
|
|
17
|
-
it("has unique ids and coherent required metadata for every entry", () => {
|
|
18
|
-
const ids = new Set();
|
|
19
|
-
for (const model of MODELS) {
|
|
20
|
-
expect(ids.has(model.id), `${model.id} is duplicated`).toBe(false);
|
|
21
|
-
ids.add(model.id);
|
|
22
|
-
expect(model.id, `${model.id} id`).toEqual(expect.any(String));
|
|
23
|
-
expect(model.name, `${model.id} name`).toEqual(expect.any(String));
|
|
24
|
-
expect(PROVIDERS, `${model.id} provider`).toContain(model.provider);
|
|
25
|
-
expect(model.contextWindow, `${model.id} contextWindow`).toBeGreaterThan(0);
|
|
26
|
-
expect(Number.isInteger(model.contextWindow), `${model.id} contextWindow integer`).toBe(true);
|
|
27
|
-
expect(model.maxOutputTokens, `${model.id} maxOutputTokens`).toBeGreaterThan(0);
|
|
28
|
-
expect(Number.isInteger(model.maxOutputTokens), `${model.id} maxOutputTokens integer`).toBe(true);
|
|
29
|
-
expect(model.maxOutputTokens, `${model.id} maxOutputTokens <= contextWindow`).toBeLessThanOrEqual(model.contextWindow);
|
|
30
|
-
expect(typeof model.supportsThinking, `${model.id} supportsThinking`).toBe("boolean");
|
|
31
|
-
expect(typeof model.supportsImages, `${model.id} supportsImages`).toBe("boolean");
|
|
32
|
-
expect(typeof model.supportsVideo, `${model.id} supportsVideo`).toBe("boolean");
|
|
33
|
-
expect(COST_TIERS, `${model.id} costTier`).toContain(model.costTier);
|
|
34
|
-
expect(THINKING_LEVELS, `${model.id} maxThinkingLevel`).toContain(model.maxThinkingLevel);
|
|
35
|
-
if (!model.supportsThinking) {
|
|
36
|
-
expect(model.maxThinkingLevel, `${model.id} non-thinking max level`).toBe("low");
|
|
37
|
-
}
|
|
38
|
-
if (model.codexContextWindow !== undefined) {
|
|
39
|
-
expect(model.provider, `${model.id} codexContextWindow provider`).toBe("openai");
|
|
40
|
-
expect(model.codexContextWindow, `${model.id} codexContextWindow`).toBeGreaterThan(0);
|
|
41
|
-
expect(Number.isInteger(model.codexContextWindow), `${model.id} codexContextWindow integer`).toBe(true);
|
|
42
|
-
expect(model.codexContextWindow, `${model.id} codexContextWindow <= contextWindow`).toBeLessThanOrEqual(model.contextWindow);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
it("returns a registered default model for every provider", () => {
|
|
47
|
-
for (const provider of PROVIDERS) {
|
|
48
|
-
const defaultModel = getDefaultModel(provider);
|
|
49
|
-
expect(defaultModel.provider, `${provider} default provider`).toBe(provider);
|
|
50
|
-
expect(MODELS, `${provider} default registered`).toContain(defaultModel);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
describe("model registry context windows", () => {
|
|
55
|
-
it("uses the public API context window for OpenAI API-key requests", () => {
|
|
56
|
-
expect(getContextWindow("gpt-5.5", { provider: "openai" })).toBe(1_050_000);
|
|
57
|
-
expect(getContextWindow("gpt-5.4", { provider: "openai" })).toBe(1_050_000);
|
|
58
|
-
});
|
|
59
|
-
it("uses the Codex product context window for OpenAI OAuth requests", () => {
|
|
60
|
-
const options = { provider: "openai", accountId: "acct_123" };
|
|
61
|
-
expect(usesOpenAICodexTransport(options)).toBe(true);
|
|
62
|
-
expect(getContextWindow("gpt-5.5", options)).toBe(272_000);
|
|
63
|
-
expect(getContextWindow("gpt-5.4", options)).toBe(272_000);
|
|
64
|
-
});
|
|
65
|
-
it("keeps non-OpenAI providers on their model context windows", () => {
|
|
66
|
-
expect(usesOpenAICodexTransport({ provider: "anthropic", accountId: "acct_123" })).toBe(false);
|
|
67
|
-
expect(getContextWindow("claude-sonnet-4-6", { provider: "anthropic", accountId: "acct_123" })).toBe(1_000_000);
|
|
68
|
-
});
|
|
69
|
-
it("defaults MiniMax to the multimodal M3 with a 1M context window", () => {
|
|
70
|
-
expect(getDefaultModel("minimax")).toMatchObject({
|
|
71
|
-
id: "MiniMax-M3",
|
|
72
|
-
name: "MiniMax M3",
|
|
73
|
-
provider: "minimax",
|
|
74
|
-
contextWindow: 1_000_000,
|
|
75
|
-
supportsImages: true,
|
|
76
|
-
supportsVideo: true,
|
|
77
|
-
});
|
|
78
|
-
expect(getModelsForProvider("minimax").map((model) => model.id)).toEqual(["MiniMax-M3"]);
|
|
79
|
-
expect(getContextWindow("MiniMax-M3", { provider: "minimax" })).toBe(1_000_000);
|
|
80
|
-
});
|
|
81
|
-
it("registers a Code Assist-supported Gemini default", () => {
|
|
82
|
-
expect(getDefaultModel("gemini")).toMatchObject({
|
|
83
|
-
id: "gemini-3.1-flash-lite-preview",
|
|
84
|
-
name: "Gemini 3.1 Flash Lite Preview",
|
|
85
|
-
provider: "gemini",
|
|
86
|
-
});
|
|
87
|
-
expect(getModelsForProvider("gemini").map((model) => model.id)).toEqual([
|
|
88
|
-
"gemini-3.1-flash-lite-preview",
|
|
89
|
-
"gemini-3.5-flash",
|
|
90
|
-
]);
|
|
91
|
-
expect(getContextWindow("gemini-3.1-flash-lite-preview", { provider: "gemini" })).toBe(1_048_576);
|
|
92
|
-
expect(getContextWindow("gemini-3.5-flash", { provider: "gemini" })).toBe(1_048_576);
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
//# sourceMappingURL=model-registry.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-registry.test.js","sourceRoot":"","sources":["../../src/core/model-registry.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.test.d.ts","sourceRoot":"","sources":["../../../src/core/oauth/gemini.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import http from "node:http";
|
|
2
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { loginGemini } from "./gemini.js";
|
|
4
|
-
const originalFetch = globalThis.fetch;
|
|
5
|
-
const originalCodeAssistEndpoint = process.env.CODE_ASSIST_ENDPOINT;
|
|
6
|
-
const originalCodeAssistApiVersion = process.env.CODE_ASSIST_API_VERSION;
|
|
7
|
-
const originalGoogleCloudProject = process.env.GOOGLE_CLOUD_PROJECT;
|
|
8
|
-
const originalGoogleCloudProjectId = process.env.GOOGLE_CLOUD_PROJECT_ID;
|
|
9
|
-
const originalGeminiClientId = process.env.GGCODER_GEMINI_OAUTH_CLIENT_ID;
|
|
10
|
-
const originalGeminiClientSecret = process.env.GGCODER_GEMINI_OAUTH_CLIENT_SECRET;
|
|
11
|
-
function tokenResponse() {
|
|
12
|
-
return new Response(JSON.stringify({
|
|
13
|
-
access_token: "access-token",
|
|
14
|
-
refresh_token: "refresh-token",
|
|
15
|
-
expires_in: 3_600,
|
|
16
|
-
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
17
|
-
}
|
|
18
|
-
function completeLoopbackLogin(authUrl) {
|
|
19
|
-
const loginUrl = new URL(authUrl);
|
|
20
|
-
if (loginUrl.hostname !== "accounts.google.com")
|
|
21
|
-
return;
|
|
22
|
-
const redirectUri = loginUrl.searchParams.get("redirect_uri");
|
|
23
|
-
const state = loginUrl.searchParams.get("state");
|
|
24
|
-
if (!redirectUri || !state)
|
|
25
|
-
return;
|
|
26
|
-
const callbackUrl = new URL(redirectUri);
|
|
27
|
-
callbackUrl.searchParams.set("code", "oauth-code");
|
|
28
|
-
callbackUrl.searchParams.set("state", state);
|
|
29
|
-
const req = http.get(callbackUrl, (res) => {
|
|
30
|
-
res.resume();
|
|
31
|
-
});
|
|
32
|
-
req.on("error", () => undefined);
|
|
33
|
-
}
|
|
34
|
-
describe("loginGemini", () => {
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
delete process.env.GOOGLE_CLOUD_PROJECT;
|
|
37
|
-
delete process.env.GOOGLE_CLOUD_PROJECT_ID;
|
|
38
|
-
process.env.GGCODER_GEMINI_OAUTH_CLIENT_ID = "test-client-id";
|
|
39
|
-
process.env.GGCODER_GEMINI_OAUTH_CLIENT_SECRET = "test-client-secret";
|
|
40
|
-
});
|
|
41
|
-
afterEach(() => {
|
|
42
|
-
globalThis.fetch = originalFetch;
|
|
43
|
-
if (originalCodeAssistEndpoint === undefined) {
|
|
44
|
-
delete process.env.CODE_ASSIST_ENDPOINT;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
process.env.CODE_ASSIST_ENDPOINT = originalCodeAssistEndpoint;
|
|
48
|
-
}
|
|
49
|
-
if (originalCodeAssistApiVersion === undefined) {
|
|
50
|
-
delete process.env.CODE_ASSIST_API_VERSION;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
process.env.CODE_ASSIST_API_VERSION = originalCodeAssistApiVersion;
|
|
54
|
-
}
|
|
55
|
-
if (originalGoogleCloudProject === undefined) {
|
|
56
|
-
delete process.env.GOOGLE_CLOUD_PROJECT;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
process.env.GOOGLE_CLOUD_PROJECT = originalGoogleCloudProject;
|
|
60
|
-
}
|
|
61
|
-
if (originalGoogleCloudProjectId === undefined) {
|
|
62
|
-
delete process.env.GOOGLE_CLOUD_PROJECT_ID;
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
process.env.GOOGLE_CLOUD_PROJECT_ID = originalGoogleCloudProjectId;
|
|
66
|
-
}
|
|
67
|
-
if (originalGeminiClientId === undefined) {
|
|
68
|
-
delete process.env.GGCODER_GEMINI_OAUTH_CLIENT_ID;
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
process.env.GGCODER_GEMINI_OAUTH_CLIENT_ID = originalGeminiClientId;
|
|
72
|
-
}
|
|
73
|
-
if (originalGeminiClientSecret === undefined) {
|
|
74
|
-
delete process.env.GGCODER_GEMINI_OAUTH_CLIENT_SECRET;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
process.env.GGCODER_GEMINI_OAUTH_CLIENT_SECRET = originalGeminiClientSecret;
|
|
78
|
-
}
|
|
79
|
-
vi.restoreAllMocks();
|
|
80
|
-
});
|
|
81
|
-
it("opens validation URLs and retries Code Assist setup", async () => {
|
|
82
|
-
process.env.CODE_ASSIST_ENDPOINT = "https://code-assist.example.test";
|
|
83
|
-
process.env.CODE_ASSIST_API_VERSION = "v2test";
|
|
84
|
-
const fetchMock = vi
|
|
85
|
-
.fn()
|
|
86
|
-
.mockResolvedValueOnce(tokenResponse())
|
|
87
|
-
.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
88
|
-
ineligibleTiers: [
|
|
89
|
-
{
|
|
90
|
-
reasonCode: "VALIDATION_REQUIRED",
|
|
91
|
-
reasonMessage: "verify account",
|
|
92
|
-
validationUrl: "https://validation.example.test",
|
|
93
|
-
},
|
|
94
|
-
],
|
|
95
|
-
}), { status: 200, headers: { "content-type": "application/json" } }))
|
|
96
|
-
.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
97
|
-
currentTier: { id: "standard-tier" },
|
|
98
|
-
cloudaicompanionProject: "validated-project",
|
|
99
|
-
}), { status: 200, headers: { "content-type": "application/json" } }));
|
|
100
|
-
globalThis.fetch = fetchMock;
|
|
101
|
-
const openedUrls = [];
|
|
102
|
-
const creds = await loginGemini({
|
|
103
|
-
onOpenUrl: (url) => {
|
|
104
|
-
openedUrls.push(url);
|
|
105
|
-
completeLoopbackLogin(url);
|
|
106
|
-
},
|
|
107
|
-
onPromptCode: async (message) => {
|
|
108
|
-
if (message.includes("validation"))
|
|
109
|
-
return "";
|
|
110
|
-
throw new Error(`Unexpected Gemini prompt: ${message}`);
|
|
111
|
-
},
|
|
112
|
-
onStatus: vi.fn(),
|
|
113
|
-
});
|
|
114
|
-
expect(creds.projectId).toBe("validated-project");
|
|
115
|
-
expect(openedUrls).toContain("https://validation.example.test");
|
|
116
|
-
expect(fetchMock).toHaveBeenNthCalledWith(2, "https://code-assist.example.test/v2test:loadCodeAssist", expect.objectContaining({ method: "POST" }));
|
|
117
|
-
expect(fetchMock).toHaveBeenNthCalledWith(3, "https://code-assist.example.test/v2test:loadCodeAssist", expect.objectContaining({ method: "POST" }));
|
|
118
|
-
});
|
|
119
|
-
it("uses free-tier onboarding metadata without a project", async () => {
|
|
120
|
-
const fetchMock = vi
|
|
121
|
-
.fn()
|
|
122
|
-
.mockResolvedValueOnce(tokenResponse())
|
|
123
|
-
.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
124
|
-
allowedTiers: [{ id: "free-tier", isDefault: true }],
|
|
125
|
-
}), { status: 200, headers: { "content-type": "application/json" } }))
|
|
126
|
-
.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
127
|
-
done: true,
|
|
128
|
-
response: { cloudaicompanionProject: { id: "managed-project" } },
|
|
129
|
-
}), { status: 200, headers: { "content-type": "application/json" } }));
|
|
130
|
-
globalThis.fetch = fetchMock;
|
|
131
|
-
const openedUrls = [];
|
|
132
|
-
const creds = await loginGemini({
|
|
133
|
-
onOpenUrl: (url) => {
|
|
134
|
-
openedUrls.push(url);
|
|
135
|
-
completeLoopbackLogin(url);
|
|
136
|
-
},
|
|
137
|
-
onPromptCode: async (message) => {
|
|
138
|
-
throw new Error(`Unexpected Gemini prompt: ${message}`);
|
|
139
|
-
},
|
|
140
|
-
onStatus: vi.fn(),
|
|
141
|
-
});
|
|
142
|
-
expect(creds.projectId).toBe("managed-project");
|
|
143
|
-
const [, onboardInit] = fetchMock.mock.calls[2];
|
|
144
|
-
expect(JSON.parse(onboardInit.body)).toEqual({
|
|
145
|
-
tierId: "free-tier",
|
|
146
|
-
metadata: {
|
|
147
|
-
ideType: "IDE_UNSPECIFIED",
|
|
148
|
-
platform: "PLATFORM_UNSPECIFIED",
|
|
149
|
-
pluginType: "GEMINI",
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
//# sourceMappingURL=gemini.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.test.js","sourceRoot":"","sources":["../../../src/core/oauth/gemini.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"thinking-level.test.d.ts","sourceRoot":"","sources":["../../src/core/thinking-level.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { getNextThinkingLevel, getSupportedThinkingLevels, isThinkingLevelSupported, } from "./thinking-level.js";
|
|
3
|
-
describe("thinking-level helpers", () => {
|
|
4
|
-
it("cycles OpenAI GPT models through supported reasoning efforts", () => {
|
|
5
|
-
expect(getSupportedThinkingLevels("openai", "gpt-5.5")).toEqual(["medium", "high", "xhigh"]);
|
|
6
|
-
expect(getNextThinkingLevel("openai", "gpt-5.5", undefined)).toBe("medium");
|
|
7
|
-
expect(getNextThinkingLevel("openai", "gpt-5.5", "medium")).toBe("high");
|
|
8
|
-
expect(getNextThinkingLevel("openai", "gpt-5.5", "high")).toBe("xhigh");
|
|
9
|
-
expect(getNextThinkingLevel("openai", "gpt-5.5", "xhigh")).toBeUndefined();
|
|
10
|
-
});
|
|
11
|
-
it("cycles Anthropic adaptive Opus models through max, including xhigh", () => {
|
|
12
|
-
expect(getSupportedThinkingLevels("anthropic", "claude-opus-4-8")).toEqual([
|
|
13
|
-
"low",
|
|
14
|
-
"medium",
|
|
15
|
-
"high",
|
|
16
|
-
"xhigh",
|
|
17
|
-
"max",
|
|
18
|
-
]);
|
|
19
|
-
expect(getNextThinkingLevel("anthropic", "claude-opus-4-8", "xhigh")).toBe("max");
|
|
20
|
-
expect(getNextThinkingLevel("anthropic", "claude-opus-4-8", "max")).toBeUndefined();
|
|
21
|
-
});
|
|
22
|
-
it("cycles Anthropic adaptive Sonnet models without xhigh", () => {
|
|
23
|
-
expect(getSupportedThinkingLevels("anthropic", "claude-sonnet-4-6")).toEqual([
|
|
24
|
-
"low",
|
|
25
|
-
"medium",
|
|
26
|
-
"high",
|
|
27
|
-
"max",
|
|
28
|
-
]);
|
|
29
|
-
expect(getNextThinkingLevel("anthropic", "claude-sonnet-4-6", "high")).toBe("max");
|
|
30
|
-
expect(isThinkingLevelSupported("anthropic", "claude-sonnet-4-6", "xhigh")).toBe(false);
|
|
31
|
-
});
|
|
32
|
-
it("keeps non-cycling providers binary at their model max", () => {
|
|
33
|
-
expect(getSupportedThinkingLevels("moonshot", "kimi-k2.6")).toEqual(["high"]);
|
|
34
|
-
expect(getNextThinkingLevel("moonshot", "kimi-k2.6", undefined)).toBe("high");
|
|
35
|
-
expect(getNextThinkingLevel("moonshot", "kimi-k2.6", "high")).toBeUndefined();
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
//# sourceMappingURL=thinking-level.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"thinking-level.test.js","sourceRoot":"","sources":["../../src/core/thinking-level.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7F,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5E,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzE,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxE,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,CAAC,0BAA0B,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;YACzE,KAAK;YACL,QAAQ;YACR,MAAM;YACN,OAAO;YACP,KAAK;SACN,CAAC,CAAC;QACH,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClF,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,0BAA0B,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC;YAC3E,KAAK;YACL,QAAQ;YACR,MAAM;YACN,KAAK;SACN,CAAC,CAAC;QACH,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnF,MAAM,CAAC,wBAAwB,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,0BAA0B,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,oBAAoB,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9E,MAAM,CAAC,oBAAoB,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"voice-transcriber.test.d.ts","sourceRoot":"","sources":["../../src/core/voice-transcriber.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { resample, downmixToMono, decodeOggOpus } from "./voice-transcriber.js";
|
|
3
|
-
// ── resample ────────────────────────────────────────────────
|
|
4
|
-
describe("resample", () => {
|
|
5
|
-
it("returns the same array when rates match", () => {
|
|
6
|
-
const input = new Float32Array([0.1, 0.2, 0.3]);
|
|
7
|
-
const result = resample(input, 16000, 16000);
|
|
8
|
-
expect(result).toBe(input); // same reference
|
|
9
|
-
});
|
|
10
|
-
it("downsamples 48kHz → 16kHz (3:1 ratio)", () => {
|
|
11
|
-
// 9 samples at 48kHz → 3 samples at 16kHz
|
|
12
|
-
const input = new Float32Array([0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]);
|
|
13
|
-
const result = resample(input, 48000, 16000);
|
|
14
|
-
expect(result.length).toBe(3);
|
|
15
|
-
expect(result[0]).toBeCloseTo(0.0, 5);
|
|
16
|
-
expect(result[1]).toBeCloseTo(0.3, 5);
|
|
17
|
-
expect(result[2]).toBeCloseTo(0.6, 5);
|
|
18
|
-
});
|
|
19
|
-
it("upsamples 16kHz → 48kHz (1:3 ratio)", () => {
|
|
20
|
-
const input = new Float32Array([0.0, 0.6, 1.2]);
|
|
21
|
-
const result = resample(input, 16000, 48000);
|
|
22
|
-
expect(result.length).toBe(9);
|
|
23
|
-
expect(result[0]).toBeCloseTo(0.0, 5);
|
|
24
|
-
expect(result[1]).toBeCloseTo(0.2, 1);
|
|
25
|
-
expect(result[2]).toBeCloseTo(0.4, 1);
|
|
26
|
-
expect(result[3]).toBeCloseTo(0.6, 1);
|
|
27
|
-
});
|
|
28
|
-
it("handles single sample", () => {
|
|
29
|
-
const input = new Float32Array([0.5]);
|
|
30
|
-
const result = resample(input, 48000, 16000);
|
|
31
|
-
expect(result.length).toBeLessThanOrEqual(1);
|
|
32
|
-
});
|
|
33
|
-
it("handles empty array", () => {
|
|
34
|
-
const input = new Float32Array([]);
|
|
35
|
-
const result = resample(input, 48000, 16000);
|
|
36
|
-
expect(result.length).toBe(0);
|
|
37
|
-
});
|
|
38
|
-
it("preserves signal energy approximately", () => {
|
|
39
|
-
const numSamples = 4800; // 100ms at 48kHz
|
|
40
|
-
const freq = 440;
|
|
41
|
-
const input = new Float32Array(numSamples);
|
|
42
|
-
for (let i = 0; i < numSamples; i++) {
|
|
43
|
-
input[i] = Math.sin((2 * Math.PI * freq * i) / 48000);
|
|
44
|
-
}
|
|
45
|
-
const output = resample(input, 48000, 16000);
|
|
46
|
-
expect(output.length).toBe(1600);
|
|
47
|
-
const rmsIn = Math.sqrt(input.reduce((sum, v) => sum + v * v, 0) / input.length);
|
|
48
|
-
const rmsOut = Math.sqrt(output.reduce((sum, v) => sum + v * v, 0) / output.length);
|
|
49
|
-
expect(rmsOut).toBeCloseTo(rmsIn, 1);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
// ── downmixToMono ───────────────────────────────────────────
|
|
53
|
-
describe("downmixToMono", () => {
|
|
54
|
-
it("returns empty array for no channels", () => {
|
|
55
|
-
const result = downmixToMono([]);
|
|
56
|
-
expect(result.length).toBe(0);
|
|
57
|
-
});
|
|
58
|
-
it("returns the channel directly for mono input", () => {
|
|
59
|
-
const mono = new Float32Array([0.1, 0.2, 0.3]);
|
|
60
|
-
const result = downmixToMono([mono]);
|
|
61
|
-
expect(result).toBe(mono); // same reference
|
|
62
|
-
});
|
|
63
|
-
it("averages two channels for stereo input", () => {
|
|
64
|
-
const left = new Float32Array([0.0, 0.4, 0.8]);
|
|
65
|
-
const right = new Float32Array([1.0, 0.6, 0.2]);
|
|
66
|
-
const result = downmixToMono([left, right]);
|
|
67
|
-
expect(result.length).toBe(3);
|
|
68
|
-
expect(result[0]).toBeCloseTo(0.5, 5);
|
|
69
|
-
expect(result[1]).toBeCloseTo(0.5, 5);
|
|
70
|
-
expect(result[2]).toBeCloseTo(0.5, 5);
|
|
71
|
-
});
|
|
72
|
-
it("handles multi-channel (5.1 surround)", () => {
|
|
73
|
-
const channels = Array.from({ length: 6 }, () => new Float32Array([0.6]));
|
|
74
|
-
const result = downmixToMono(channels);
|
|
75
|
-
expect(result.length).toBe(1);
|
|
76
|
-
expect(result[0]).toBeCloseTo(0.6, 5);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
// ── decodeOggOpus ───────────────────────────────────────────
|
|
80
|
-
describe("decodeOggOpus", () => {
|
|
81
|
-
it("rejects invalid data", async () => {
|
|
82
|
-
const garbage = new Uint8Array([0, 1, 2, 3, 4, 5]);
|
|
83
|
-
await expect(decodeOggOpus(garbage)).rejects.toThrow();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
// Integration tests for transcribeVoice require network access and ~75MB model download.
|
|
87
|
-
// Run the standalone e2e test instead: node test-voice.mjs
|
|
88
|
-
//# sourceMappingURL=voice-transcriber.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"voice-transcriber.test.js","sourceRoot":"","sources":["../../src/core/voice-transcriber.test.ts"],"names":[],"mappings":"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"}
|