noiton 2.0.0 → 2.0.2

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.
@@ -1,128 +0,0 @@
1
- /**
2
- * Cline Agent Adapter
3
- *
4
- * Config: VS Code settings.json with cline config block.
5
- * Format (under `cline` key):
6
- * "cline.provider": "openai",
7
- * "cline.openAiBaseUrl": "<BASE_URL>",
8
- * "cline.openAiApiKey": "<key>",
9
- * "cline.openAiModelId": "<model>"
10
- *
11
- * VS Code stores multiple providers via cline.provider entries.
12
- */
13
-
14
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
15
- import { join, dirname } from "node:path";
16
- import { homedir } from "node:os";
17
- import JSON5 from "json5";
18
- import { BASE_URL, PROVIDER_ID } from "../../constants.js";
19
-
20
- const HOME = homedir();
21
- const XDG = process.env.XDG_CONFIG_HOME || join(HOME, ".config");
22
- const CONFIG_PATH = join(XDG, "Code", "User", "settings.json");
23
-
24
- function readConfig() {
25
- if (!existsSync(CONFIG_PATH)) return { config: {}, path: CONFIG_PATH };
26
- try {
27
- // VS Code settings support JSON with comments (JSONC)
28
- const raw = readFileSync(CONFIG_PATH, "utf8");
29
- const cleaned = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
30
- return { config: JSON5.parse(cleaned), path: CONFIG_PATH };
31
- } catch {
32
- return { config: {}, path: CONFIG_PATH };
33
- }
34
- }
35
-
36
- function writeConfig(config) {
37
- if (!existsSync(dirname(CONFIG_PATH))) {
38
- mkdirSync(dirname(dirname(CONFIG_PATH)), { recursive: true });
39
- }
40
- writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf8");
41
- }
42
-
43
- // ============= ADAPTER INTERFACE =============
44
-
45
- export const clineAgent = {
46
- id: "cline",
47
- name: "Cline",
48
- supportsMultipleModels: true,
49
-
50
- detect() {
51
- return existsSync(CONFIG_PATH);
52
- },
53
-
54
- isConfigured() {
55
- const { config } = readConfig();
56
- const result = Boolean(
57
- config?.["cline.openAiBaseUrl"] === BASE_URL ||
58
- config?.["cline.apiProvider"] === "openai" && config?.["cline.openAiApiKey"]
59
- );
60
- return result;
61
- },
62
-
63
- getStatus() {
64
- const { config, path } = readConfig();
65
- const baseUrl = config?.["cline.openAiBaseUrl"];
66
- const apiKey = config?.["cline.openAiApiKey"];
67
- const modelId = config?.["cline.openAiModelId"];
68
- const configured = Boolean(baseUrl === BASE_URL || (apiKey && baseUrl));
69
-
70
- const models = modelId ? [modelId] : [];
71
-
72
- return {
73
- configured,
74
- path,
75
- models,
76
- apiKey: apiKey ? `${apiKey.slice(0, 6)}...${apiKey.slice(-4)}` : null,
77
- };
78
- },
79
-
80
- configure({ apiKey, models, primaryModel }) {
81
- const { config } = readConfig();
82
- config["cline.apiProvider"] = "openai";
83
- config["cline.openAiBaseUrl"] = `${BASE_URL}/v1`;
84
- config["cline.openAiApiKey"] = apiKey;
85
- config["cline.openAiModelId"] = primaryModel || models[0]?.id;
86
- // Save list of available models as a JSON array string
87
- config["cline.noitonModels"] = JSON.stringify(models.map((m) => m.id));
88
- writeConfig(config);
89
- return { path: CONFIG_PATH, modelsCount: 1 };
90
- },
91
-
92
- changeKey(apiKey) {
93
- const { config } = readConfig();
94
- if (!config?.["cline.openAiApiKey"]) {
95
- throw new Error("NOITON não está configurado no Cline");
96
- }
97
- config["cline.openAiApiKey"] = apiKey;
98
- writeConfig(config);
99
- return { path: CONFIG_PATH };
100
- },
101
-
102
- refresh(models) {
103
- const { config } = readConfig();
104
- if (!config?.["cline.openAiBaseUrl"]) {
105
- throw new Error("NOITON não está configurado no Cline");
106
- }
107
- config["cline.openAiModelId"] = models[0]?.id || config["cline.openAiModelId"];
108
- config["cline.noitonModels"] = JSON.stringify(models.map((m) => m.id));
109
- writeConfig(config);
110
- return { path: CONFIG_PATH, modelsCount: 1 };
111
- },
112
-
113
- remove() {
114
- const { config } = readConfig();
115
- let removed = false;
116
- if (config?.["cline.openAiBaseUrl"] === BASE_URL ||
117
- config?.["cline.openAiApiKey"]) {
118
- delete config["cline.apiProvider"];
119
- delete config["cline.openAiBaseUrl"];
120
- delete config["cline.openAiApiKey"];
121
- delete config["cline.openAiModelId"];
122
- delete config["cline.noitonModels"];
123
- removed = true;
124
- }
125
- if (removed) writeConfig(config);
126
- return { path: CONFIG_PATH, removed };
127
- },
128
- };
@@ -1,140 +0,0 @@
1
- /**
2
- * Kilo Code Agent Adapter
3
- *
4
- * Config: ~/.config/kilo/kilo.jsonc (JSONC)
5
- * Format (under `provider.openai-compatible`):
6
- * model: openai-compatible/<model-id>
7
- * provider.openai-compatible.options.apiKey
8
- * provider.openai-compatible.options.baseURL
9
- * provider.openai-compatible.models.<id>.limit.context/output
10
- */
11
-
12
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
13
- import { join, dirname } from "node:path";
14
- import { homedir } from "node:os";
15
- import JSON5 from "json5";
16
- import { BASE_URL } from "../../constants.js";
17
-
18
- const HOME = homedir();
19
- const XDG = process.env.XDG_CONFIG_HOME || join(HOME, ".config");
20
- const CONFIG_PATH = join(XDG, "kilo", "kilo.jsonc");
21
- const PROVIDER_ID = "openai-compatible";
22
-
23
- function readConfig() {
24
- if (!existsSync(CONFIG_PATH)) return { config: {}, path: CONFIG_PATH };
25
- try {
26
- const raw = readFileSync(CONFIG_PATH, "utf8");
27
- // Strip comments (JSONC)
28
- const cleaned = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
29
- return { config: JSON5.parse(cleaned), path: CONFIG_PATH };
30
- } catch {
31
- return { config: {}, path: CONFIG_PATH };
32
- }
33
- }
34
-
35
- function writeConfig(config) {
36
- if (!existsSync(dirname(CONFIG_PATH))) {
37
- mkdirSync(dirname(CONFIG_PATH), { recursive: true });
38
- }
39
- writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf8");
40
- }
41
-
42
- function buildModels(models) {
43
- const obj = {};
44
- for (const m of models) {
45
- if (!m.id) continue;
46
- obj[m.id] = {
47
- name: prettifyName(m.id),
48
- tool_call: true,
49
- limit: { context: m.context_window || 32768, output: 4096 },
50
- };
51
- }
52
- return obj;
53
- }
54
-
55
- function prettifyName(id) {
56
- return id
57
- .replace(/[@/]/g, " ")
58
- .split(/[-_]/)
59
- .filter(Boolean)
60
- .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
61
- .join(" ");
62
- }
63
-
64
- // ============= ADAPTER INTERFACE =============
65
-
66
- export const kiloAgent = {
67
- id: "kilo",
68
- name: "Kilo Code",
69
- supportsMultipleModels: true,
70
-
71
- detect() {
72
- return existsSync(CONFIG_PATH);
73
- },
74
-
75
- isConfigured() {
76
- const { config } = readConfig();
77
- return Boolean(config?.provider?.[PROVIDER_ID]?.options?.baseURL === BASE_URL);
78
- },
79
-
80
- getStatus() {
81
- const { config, path } = readConfig();
82
- const provider = config?.provider?.[PROVIDER_ID];
83
- if (!provider) return { configured: false, path, models: [], apiKey: null };
84
- const apiKey = provider.options?.apiKey;
85
- const models = provider.models ? Object.keys(provider.models) : [];
86
- return {
87
- configured: provider.options?.baseURL === BASE_URL,
88
- path,
89
- models,
90
- apiKey: apiKey ? (apiKey.startsWith("{env:") ? "(env var)" : `${apiKey.slice(0, 6)}...${apiKey.slice(-4)}`) : null,
91
- };
92
- },
93
-
94
- configure({ apiKey, models, primaryModel }) {
95
- const { config } = readConfig();
96
- config.model = `${PROVIDER_ID}/${primaryModel || models[0]?.id}`;
97
- config.provider = config.provider || {};
98
- config.provider[PROVIDER_ID] = {
99
- options: {
100
- apiKey,
101
- baseURL: `${BASE_URL}/v1`,
102
- },
103
- models: buildModels(models),
104
- };
105
- writeConfig(config);
106
- return { path: CONFIG_PATH, modelsCount: models.length };
107
- },
108
-
109
- changeKey(apiKey) {
110
- const { config } = readConfig();
111
- if (!config?.provider?.[PROVIDER_ID]) {
112
- throw new Error("NOITON não está configurado no Kilo Code");
113
- }
114
- config.provider[PROVIDER_ID].options.apiKey = apiKey;
115
- writeConfig(config);
116
- return { path: CONFIG_PATH };
117
- },
118
-
119
- refresh(models) {
120
- const { config } = readConfig();
121
- if (!config?.provider?.[PROVIDER_ID]) {
122
- throw new Error("NOITON não está configurado no Kilo Code");
123
- }
124
- config.provider[PROVIDER_ID].models = buildModels(models);
125
- writeConfig(config);
126
- return { path: CONFIG_PATH, modelsCount: models.length };
127
- },
128
-
129
- remove() {
130
- const { config } = readConfig();
131
- let removed = false;
132
- if (config?.provider?.[PROVIDER_ID]) {
133
- delete config.provider[PROVIDER_ID];
134
- delete config.model;
135
- removed = true;
136
- writeConfig(config);
137
- }
138
- return { path: CONFIG_PATH, removed };
139
- },
140
- };
@@ -1,149 +0,0 @@
1
- /**
2
- * Kimi Code Agent Adapter
3
- *
4
- * Config: ~/.kimi-code/config.toml (TOML)
5
- * Format:
6
- * [providers.noiton]
7
- * type = "openai"
8
- * base_url = "<BASE_URL>/v1"
9
- * api_key = "<key>"
10
- *
11
- * [models."<id>"]
12
- * provider = "noiton"
13
- * model = "<id>"
14
- * max_context_size = <ctx>
15
- */
16
-
17
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
18
- import { join, dirname } from "node:path";
19
- import { homedir } from "node:os";
20
- import * as TOML from "@iarna/toml";
21
- import { BASE_URL, PROVIDER_ID } from "../../constants.js";
22
-
23
- const HOME = homedir();
24
- const CONFIG_PATH = join(HOME, ".kimi-code", "config.toml");
25
-
26
- function readConfig() {
27
- if (!existsSync(CONFIG_PATH)) return { config: {}, path: CONFIG_PATH };
28
- try {
29
- const raw = readFileSync(CONFIG_PATH, "utf8");
30
- return { config: TOML.parse(raw), path: CONFIG_PATH };
31
- } catch {
32
- return { config: {}, path: CONFIG_PATH };
33
- }
34
- }
35
-
36
- function writeConfig(config) {
37
- if (!existsSync(dirname(CONFIG_PATH))) {
38
- mkdirSync(dirname(CONFIG_PATH), { recursive: true });
39
- }
40
- writeFileSync(CONFIG_PATH, TOML.stringify(config), "utf8");
41
- }
42
-
43
- // ============= ADAPTER INTERFACE =============
44
-
45
- export const kimiAgent = {
46
- id: "kimi",
47
- name: "Kimi Code",
48
- supportsMultipleModels: false,
49
-
50
- detect() {
51
- return existsSync(CONFIG_PATH);
52
- },
53
-
54
- isConfigured() {
55
- const { config } = readConfig();
56
- return Boolean(config?.providers?.[PROVIDER_ID]);
57
- },
58
-
59
- getStatus() {
60
- const { config, path } = readConfig();
61
- const provider = config?.providers?.[PROVIDER_ID];
62
- if (!provider) return { configured: false, path, models: [], apiKey: null };
63
- const apiKey = provider.api_key;
64
- const models = config.models
65
- ? Object.entries(config.models)
66
- .filter(([, v]) => v.provider === PROVIDER_ID)
67
- .map(([k]) => k)
68
- : [];
69
- return {
70
- configured: true,
71
- path,
72
- models,
73
- apiKey: apiKey ? `${apiKey.slice(0, 6)}...${apiKey.slice(-4)}` : null,
74
- };
75
- },
76
-
77
- configure({ apiKey, models, primaryModel }) {
78
- const { config } = readConfig();
79
- config.providers = config.providers || {};
80
- config.providers[PROVIDER_ID] = {
81
- type: "openai",
82
- base_url: `${BASE_URL}/v1`,
83
- api_key: apiKey,
84
- };
85
-
86
- config.models = config.models || {};
87
- const modelId = primaryModel || models[0]?.id || "glm-5.2";
88
- config.models[modelId] = {
89
- provider: PROVIDER_ID,
90
- model: modelId,
91
- max_context_size: models[0]?.context_window || 32768,
92
- };
93
-
94
- writeConfig(config);
95
- return { path: CONFIG_PATH, modelsCount: 1 };
96
- },
97
-
98
- changeKey(apiKey) {
99
- const { config } = readConfig();
100
- if (!config?.providers?.[PROVIDER_ID]) {
101
- throw new Error("NOITON não está configurado no Kimi Code");
102
- }
103
- config.providers[PROVIDER_ID].api_key = apiKey;
104
- writeConfig(config);
105
- return { path: CONFIG_PATH };
106
- },
107
-
108
- refresh(models) {
109
- const { config } = readConfig();
110
- if (!config?.providers?.[PROVIDER_ID]) {
111
- throw new Error("NOITON não está configurado no Kimi Code");
112
- }
113
- // Update context size if model exists
114
- const modelId = Object.keys(config.models || {}).find(
115
- (k) => config.models[k]?.provider === PROVIDER_ID
116
- );
117
- if (modelId && models[0]?.context_window) {
118
- config.models[modelId].max_context_size = models[0].context_window;
119
- }
120
- writeConfig(config);
121
- return { path: CONFIG_PATH, modelsCount: 1 };
122
- },
123
-
124
- remove() {
125
- const { config } = readConfig();
126
- let removed = false;
127
- if (config?.providers?.[PROVIDER_ID]) {
128
- delete config.providers[PROVIDER_ID];
129
- removed = true;
130
- }
131
- if (config?.models) {
132
- for (const [k, v] of Object.entries(config.models)) {
133
- if (v.provider === PROVIDER_ID) {
134
- delete config.models[k];
135
- removed = true;
136
- }
137
- }
138
- }
139
- // Clean up empty top-level tables
140
- if (config.providers && Object.keys(config.providers).length === 0) {
141
- delete config.providers;
142
- }
143
- if (config.models && Object.keys(config.models).length === 0) {
144
- delete config.models;
145
- }
146
- if (removed) writeConfig(config);
147
- return { path: CONFIG_PATH, removed };
148
- },
149
- };
@@ -1,155 +0,0 @@
1
- /**
2
- * OpenClaw Agent Adapter
3
- *
4
- * Config: ~/.openclaw/openclaw.json (JSON5)
5
- * Format:
6
- * models.providers.noiton = {
7
- * baseUrl, apiKey, api: "openai-completions", models: [...]
8
- * }
9
- */
10
-
11
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
12
- import { join, dirname } from "node:path";
13
- import { homedir } from "node:os";
14
- import JSON5 from "json5";
15
- import { BASE_URL, PROVIDER_ID, PROVIDER_NAME } from "../../constants.js";
16
-
17
- const HOME = homedir();
18
- const CONFIG_PATH = join(HOME, ".openclaw", "openclaw.json");
19
-
20
- function readConfig() {
21
- if (!existsSync(CONFIG_PATH)) return { config: {}, path: CONFIG_PATH };
22
- try {
23
- const raw = readFileSync(CONFIG_PATH, "utf8");
24
- return { config: JSON5.parse(raw), path: CONFIG_PATH };
25
- } catch {
26
- return { config: {}, path: CONFIG_PATH };
27
- }
28
- }
29
-
30
- function writeConfig(config) {
31
- if (!existsSync(dirname(CONFIG_PATH))) {
32
- mkdirSync(dirname(CONFIG_PATH), { recursive: true });
33
- }
34
- // Write as standard JSON (OpenClaw accepts JSON5 which is a superset)
35
- writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf8");
36
- }
37
-
38
- // ============= ADAPTER INTERFACE =============
39
-
40
- export const openclawAgent = {
41
- id: "openclaw",
42
- name: "OpenClaw",
43
- supportsMultipleModels: true,
44
-
45
- detect() {
46
- return existsSync(CONFIG_PATH);
47
- },
48
-
49
- isConfigured() {
50
- const { config } = readConfig();
51
- return Boolean(config?.models?.providers?.[PROVIDER_ID]);
52
- },
53
-
54
- getStatus() {
55
- const { config, path } = readConfig();
56
- const provider = config?.models?.providers?.[PROVIDER_ID];
57
- if (!provider) return { configured: false, path, models: [], apiKey: null };
58
- const models = (provider.models || []).map((m) => m.id);
59
- return {
60
- configured: true,
61
- path,
62
- models,
63
- apiKey: provider.apiKey,
64
- };
65
- },
66
-
67
- configure({ apiKey, models, primaryModel }) {
68
- const { config } = readConfig();
69
- config.models = config.models || {};
70
- config.models.mode = config.models.mode || "merge";
71
- config.models.providers = config.models.providers || {};
72
-
73
- config.models.providers[PROVIDER_ID] = {
74
- baseUrl: `${BASE_URL}/v1`,
75
- apiKey: `\${NOITON_API_KEY}`,
76
- api: "openai-completions",
77
- models: models.map((m) => ({
78
- id: m.id,
79
- name: prettifyName(m.id),
80
- reasoning: false,
81
- input: ["text"],
82
- contextWindow: m.context_window || 32768,
83
- maxTokens: 4096,
84
- })),
85
- };
86
-
87
- // Set env for apiKey substitution
88
- config.env = config.env || {};
89
- config.env.NOITON_API_KEY = apiKey;
90
-
91
- // Set default model if missing
92
- if (!config.agents) config.agents = {};
93
- if (!config.agents.defaults) config.agents.defaults = {};
94
- if (!config.agents.defaults.model) {
95
- config.agents.defaults.model = {
96
- primary: `${PROVIDER_ID}/${primaryModel || models[0]?.id}`,
97
- };
98
- }
99
-
100
- writeConfig(config);
101
- return { path: CONFIG_PATH, modelsCount: models.length };
102
- },
103
-
104
- changeKey(apiKey) {
105
- const { config } = readConfig();
106
- if (!config?.models?.providers?.[PROVIDER_ID]) {
107
- throw new Error("NOITON não está configurado no OpenClaw");
108
- }
109
- config.env = config.env || {};
110
- config.env.NOITON_API_KEY = apiKey;
111
- writeConfig(config);
112
- return { path: CONFIG_PATH };
113
- },
114
-
115
- refresh(models) {
116
- const { config } = readConfig();
117
- if (!config?.models?.providers?.[PROVIDER_ID]) {
118
- throw new Error("NOITON não está configurado no OpenClaw");
119
- }
120
- config.models.providers[PROVIDER_ID].models = models.map((m) => ({
121
- id: m.id,
122
- name: prettifyName(m.id),
123
- reasoning: false,
124
- input: ["text"],
125
- contextWindow: m.context_window || 32768,
126
- maxTokens: 4096,
127
- }));
128
- writeConfig(config);
129
- return { path: CONFIG_PATH, modelsCount: models.length };
130
- },
131
-
132
- remove() {
133
- const { config } = readConfig();
134
- let removed = false;
135
- if (config?.models?.providers?.[PROVIDER_ID]) {
136
- delete config.models.providers[PROVIDER_ID];
137
- removed = true;
138
- }
139
- if (config?.env?.NOITON_API_KEY) {
140
- delete config.env.NOITON_API_KEY;
141
- removed = true;
142
- }
143
- if (removed) writeConfig(config);
144
- return { path: CONFIG_PATH, removed };
145
- },
146
- };
147
-
148
- function prettifyName(id) {
149
- return id
150
- .replace(/[@/]/g, " ")
151
- .split(/[-_]/)
152
- .filter(Boolean)
153
- .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
154
- .join(" ");
155
- }