@kenkaiiii/gg-core 5.91.2 → 5.93.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/NOTICE +1 -1
- package/README.md +52 -36
- package/dist/{chunk-YXPGQIOD.js → chunk-SDUIKPGO.js} +20 -2
- package/dist/chunk-SDUIKPGO.js.map +1 -0
- package/dist/index.cjs +19 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/model-registry.cjs.map +1 -1
- package/dist/model-registry.js +1 -1
- package/package.json +17 -4
- package/dist/chunk-YXPGQIOD.js.map +0 -1
package/NOTICE
CHANGED
package/README.md
CHANGED
|
@@ -1,68 +1,84 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">@kenkaiiii/gg-core</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<strong>Model
|
|
4
|
+
<strong>Model list, sign-in and local model discovery for apps built on gg-ai.</strong>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<a href="https://www.npmjs.com/package/@kenkaiiii/gg-core"><img src="https://img.shields.io/npm/v/@kenkaiiii/gg-core?style=for-the-badge" alt="npm version"></a>
|
|
9
|
-
<a href="
|
|
8
|
+
<a href="https://www.npmjs.com/package/@kenkaiiii/gg-core"><img src="https://img.shields.io/npm/v/@kenkaiiii/gg-core?style=for-the-badge&color=blue" alt="npm version"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@kenkaiiii/gg-core"><img src="https://img.shields.io/npm/dm/@kenkaiiii/gg-core?style=for-the-badge&color=2ecc71" alt="npm downloads per month"></a>
|
|
10
|
+
<a href="https://github.com/KenKaiii/gg-framework/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-AGPL--3.0-blue.svg?style=for-the-badge" alt="AGPL-3.0 License"></a>
|
|
10
11
|
</p>
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
gg-core is the shared base under [GG Coder](https://github.com/KenKaiii/gg-framework)'s desktop app and CLI. It knows every supported model (context window, image and video support, thinking levels), signs users in to their AI subscriptions, keeps those credentials fresh, and finds models running on the user's machine.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
---
|
|
15
|
+
It has no UI and no agent loop. Its only framework dependency is [`@kenkaiiii/gg-ai`](https://www.npmjs.com/package/@kenkaiiii/gg-ai).
|
|
17
16
|
|
|
18
17
|
## Install
|
|
19
18
|
|
|
20
19
|
```bash
|
|
21
|
-
npm
|
|
20
|
+
npm install @kenkaiiii/gg-core
|
|
22
21
|
```
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## What's inside
|
|
27
|
-
|
|
28
|
-
| Area | Main exports |
|
|
29
|
-
| --------------- | ----------------------------------------------------------------------------------------- |
|
|
30
|
-
| Model registry | `getModel`, `getAllModels`, `getModelsForProvider`, `getDefaultModel`, `getContextWindow` |
|
|
31
|
-
| Thinking levels | `getSupportedThinkingLevels`, `getMaxThinkingLevel`, `getDefaultThinkingLevel` |
|
|
32
|
-
| Auth storage | `AuthStorage` (reads and writes `~/.gg/auth.json`, refreshes OAuth tokens) |
|
|
33
|
-
| OAuth | Anthropic, OpenAI, Gemini, Kimi and xAI login flows |
|
|
34
|
-
| Local models | `discoverLocalModels` (Ollama, LM Studio, llama.cpp, vLLM, custom endpoints) |
|
|
35
|
-
| Paths | `getAppPaths` (every file under `~/.gg/`) |
|
|
36
|
-
| Other | Logger, file lock, usage limits, Telegram, voice transcription, auto-update |
|
|
23
|
+
Needs Node.js 22 or newer. Ships ESM and CommonJS builds with TypeScript types.
|
|
37
24
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import { getModel } from "@kenkaiiii/gg-core/models";
|
|
42
|
-
import { getAppPaths } from "@kenkaiiii/gg-core/paths";
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Example
|
|
25
|
+
## Quick start
|
|
48
26
|
|
|
49
27
|
```ts
|
|
50
28
|
import { AuthStorage, discoverLocalModels, getModel } from "@kenkaiiii/gg-core";
|
|
51
29
|
|
|
52
30
|
const model = getModel("claude-sonnet-5-5");
|
|
53
|
-
console.log(model?.contextWindow);
|
|
31
|
+
console.log(model?.contextWindow, model?.supportsImages); // 1000000 true
|
|
54
32
|
|
|
33
|
+
// Credentials saved by `ggcoder login` or the GG Coder app, refreshed when they expire.
|
|
55
34
|
const auth = new AuthStorage();
|
|
56
35
|
const token = await auth.resolveToken("anthropic");
|
|
57
36
|
|
|
37
|
+
// Models on a running Ollama server.
|
|
58
38
|
const { models } = await discoverLocalModels();
|
|
59
39
|
console.log(models.map((m) => m.id));
|
|
60
40
|
```
|
|
61
41
|
|
|
62
|
-
`
|
|
42
|
+
`resolveToken()` throws `NotLoggedInError` when the provider has no saved credentials.
|
|
43
|
+
|
|
44
|
+
## What's inside
|
|
45
|
+
|
|
46
|
+
| Area | Main exports |
|
|
47
|
+
| --------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
48
|
+
| Models | `getModel`, `getAllModels`, `getModelsForProvider`, `getDefaultModel`, `getContextWindow`, `MODELS` |
|
|
49
|
+
| Thinking levels | `getSupportedThinkingLevels`, `getMaxThinkingLevel`, `getDefaultThinkingLevel`, `getNextThinkingLevel` |
|
|
50
|
+
| Credentials | `AuthStorage`: reads and writes `~/.gg/auth.json`, refreshes sign-in tokens, safe across processes |
|
|
51
|
+
| Sign-in | `loginAnthropic`, `loginOpenAI`, `loginKimi`, `loginXai`, `loginGemini` and matching `refresh…Token` functions |
|
|
52
|
+
| Provider list | `AUTH_PROVIDERS`: each provider's name, models and sign-in methods, ready for a login screen |
|
|
53
|
+
| Local models | `discoverLocalModels`, `probeEndpoint`: Ollama by default, plus LM Studio, llama.cpp, vLLM or any custom URL |
|
|
54
|
+
| Plan usage | `fetchSubscriptionUsage`: remaining Claude, ChatGPT and Kimi plan usage |
|
|
55
|
+
| Paths | `getAppPaths`: every file GG Coder keeps under `~/.gg/` |
|
|
56
|
+
| Other | Logger, file lock, Telegram bot, voice transcription, auto-update |
|
|
57
|
+
|
|
58
|
+
`AuthStorage` shares `~/.gg/auth.json` with GG Coder, so a user who has signed in there is already signed in to your tool. Pass a different file path to the constructor to keep your own.
|
|
59
|
+
|
|
60
|
+
## Lighter imports
|
|
61
|
+
|
|
62
|
+
Two subpaths load only what they need, which keeps startup fast:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { getModel } from "@kenkaiiii/gg-core/models";
|
|
66
|
+
import { getAppPaths } from "@kenkaiiii/gg-core/paths";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Voice transcription uses two optional dependencies (`@huggingface/transformers`, `ogg-opus-decoder`). Everything else works without them.
|
|
70
|
+
|
|
71
|
+
## The GG Framework
|
|
72
|
+
|
|
73
|
+
| Package | What it does |
|
|
74
|
+
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
|
|
75
|
+
| [@kenkaiiii/gg-ai](https://www.npmjs.com/package/@kenkaiiii/gg-ai) | One streaming API for every provider |
|
|
76
|
+
| [@kenkaiiii/gg-agent](https://www.npmjs.com/package/@kenkaiiii/gg-agent) | The agent loop: runs tools and feeds results back to the model |
|
|
77
|
+
| **@kenkaiiii/gg-core** | Model list, sign-in and stored credentials, local model discovery (this package) |
|
|
78
|
+
| [@kenkaiiii/ggcoder](https://www.npmjs.com/package/@kenkaiiii/ggcoder) | The GG Coder coding agent: CLI, tools and sessions |
|
|
63
79
|
|
|
64
|
-
|
|
80
|
+
Source, issues and the desktop app: [github.com/KenKaiii/gg-framework](https://github.com/KenKaiii/gg-framework).
|
|
65
81
|
|
|
66
82
|
## License
|
|
67
83
|
|
|
68
|
-
AGPL-3.0-only
|
|
84
|
+
[AGPL-3.0-only](https://github.com/KenKaiii/gg-framework/blob/main/LICENSE). You can build on it; if you distribute your changes or run them as a network service, share their source under the same license.
|
|
@@ -1148,6 +1148,7 @@ import { setTimeout as setTimeout2 } from "timers/promises";
|
|
|
1148
1148
|
var STALE_TIMEOUT_MS = 1e4;
|
|
1149
1149
|
var RETRY_INTERVAL_MS = 50;
|
|
1150
1150
|
var MAX_WAIT_MS = 5e3;
|
|
1151
|
+
var PENDING_DELETE_CODES = /* @__PURE__ */ new Set(["EACCES", "EBUSY", "EPERM"]);
|
|
1151
1152
|
async function withFileLock(filePath, fn) {
|
|
1152
1153
|
const lockPath = filePath + ".lock";
|
|
1153
1154
|
await acquireLock(lockPath);
|
|
@@ -1159,13 +1160,22 @@ async function withFileLock(filePath, fn) {
|
|
|
1159
1160
|
}
|
|
1160
1161
|
async function acquireLock(lockPath) {
|
|
1161
1162
|
const startTime = Date.now();
|
|
1163
|
+
let refusedWithoutLock = 0;
|
|
1162
1164
|
while (true) {
|
|
1163
1165
|
try {
|
|
1164
1166
|
const info = { pid: process.pid, timestamp: Date.now() };
|
|
1165
1167
|
await fs.writeFile(lockPath, JSON.stringify(info), { flag: "wx" });
|
|
1166
1168
|
return;
|
|
1167
1169
|
} catch (err) {
|
|
1168
|
-
|
|
1170
|
+
const code = err.code;
|
|
1171
|
+
if (code !== "EEXIST") {
|
|
1172
|
+
if (process.platform !== "win32" || !code || !PENDING_DELETE_CODES.has(code)) throw err;
|
|
1173
|
+
const lockPresent = await lockFileExists(lockPath);
|
|
1174
|
+
if (!lockPresent && ++refusedWithoutLock > 3) throw err;
|
|
1175
|
+
if (Date.now() - startTime > MAX_WAIT_MS) throw err;
|
|
1176
|
+
await setTimeout2(RETRY_INTERVAL_MS);
|
|
1177
|
+
continue;
|
|
1178
|
+
}
|
|
1169
1179
|
try {
|
|
1170
1180
|
const content = await fs.readFile(lockPath, "utf-8");
|
|
1171
1181
|
const info = JSON.parse(content);
|
|
@@ -1194,6 +1204,14 @@ async function acquireLock(lockPath) {
|
|
|
1194
1204
|
}
|
|
1195
1205
|
}
|
|
1196
1206
|
}
|
|
1207
|
+
async function lockFileExists(lockPath) {
|
|
1208
|
+
try {
|
|
1209
|
+
await fs.stat(lockPath);
|
|
1210
|
+
return true;
|
|
1211
|
+
} catch (err) {
|
|
1212
|
+
return err.code !== "ENOENT";
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1197
1215
|
async function releaseLock(lockPath) {
|
|
1198
1216
|
await fs.unlink(lockPath).catch(() => {
|
|
1199
1217
|
});
|
|
@@ -3021,4 +3039,4 @@ export {
|
|
|
3021
3039
|
getDefaultThinkingLevel,
|
|
3022
3040
|
getSummaryModel
|
|
3023
3041
|
};
|
|
3024
|
-
//# sourceMappingURL=chunk-
|
|
3042
|
+
//# sourceMappingURL=chunk-SDUIKPGO.js.map
|