agentsw 0.6.0 → 0.6.1
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/targets/dsh.js +2 -2
- package/dist/targets/hermes.js +14 -5
- package/dist/targets/omp.js +4 -4
- package/dist/targets/opencode.js +12 -10
- package/dist/targets/pistyle.js +4 -4
- package/dist/targets/wire.js +7 -4
- package/package.json +1 -1
package/dist/targets/dsh.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import YAML from "yaml";
|
|
4
4
|
import { backupFile, expandHome, home, localAppDataDir, readTextIfExists, writeFileAtomic } from "../fsutil.js";
|
|
5
|
-
import { apiValue, classifyApi, mergeModels,
|
|
5
|
+
import { apiValue, classifyApi, mergeModels, sdkBaseUrl } from "./wire.js";
|
|
6
6
|
/** `$DSH_HOME`, or `~/.dsh` (packages/util/home-paths `resolveDshHome`). */
|
|
7
7
|
function dshHome() {
|
|
8
8
|
const env = process.env.DSH_HOME?.trim();
|
|
@@ -91,7 +91,7 @@ export const dsh = {
|
|
|
91
91
|
displayName: provider.name,
|
|
92
92
|
apiKeyEnv: ref, // credential reference, never the secret
|
|
93
93
|
api: apiValue(provider.protocol, provider.openaiApi, prev?.api),
|
|
94
|
-
baseURL:
|
|
94
|
+
baseURL: sdkBaseUrl(provider.protocol, provider.baseUrl),
|
|
95
95
|
models: mergeModels(prev?.models, provider.models.map(modelEntry), OWNED_MODEL_KEYS),
|
|
96
96
|
};
|
|
97
97
|
if (YAML.isMap(doc.getIn(at))) {
|
package/dist/targets/hermes.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import YAML from "yaml";
|
|
4
4
|
import { backupFile, home, localAppDataDir, readTextIfExists, writeFileAtomic } from "../fsutil.js";
|
|
5
|
-
import {
|
|
5
|
+
import { sdkBaseUrl } from "./wire.js";
|
|
6
6
|
function hermesHome() {
|
|
7
7
|
const env = process.env.HERMES_HOME?.trim();
|
|
8
8
|
if (env)
|
|
@@ -47,9 +47,13 @@ export const hermes = {
|
|
|
47
47
|
}
|
|
48
48
|
const entry = {
|
|
49
49
|
name: provider.name,
|
|
50
|
-
api:
|
|
50
|
+
api: sdkBaseUrl(provider.protocol, provider.baseUrl),
|
|
51
51
|
key_env: keyVar,
|
|
52
|
-
transport: provider.protocol === "anthropic"
|
|
52
|
+
transport: provider.protocol === "anthropic"
|
|
53
|
+
? "anthropic_messages"
|
|
54
|
+
: provider.openaiApi === "responses"
|
|
55
|
+
? "codex_responses"
|
|
56
|
+
: "chat_completions",
|
|
53
57
|
default_model: provider.defaultModel,
|
|
54
58
|
models,
|
|
55
59
|
};
|
|
@@ -158,9 +162,14 @@ export const hermes = {
|
|
|
158
162
|
return Object.entries(parsed.providers).flatMap(([id, entry]) => {
|
|
159
163
|
if (!entry || typeof entry.api !== "string" || !entry.api)
|
|
160
164
|
return [];
|
|
161
|
-
const protocol = entry.transport === "anthropic_messages"
|
|
165
|
+
const protocol = entry.transport === "anthropic_messages"
|
|
166
|
+
? "anthropic"
|
|
167
|
+
: ["chat_completions", "codex_responses"].includes(entry.transport ?? "")
|
|
168
|
+
? "openai"
|
|
169
|
+
: undefined;
|
|
162
170
|
if (!protocol)
|
|
163
171
|
return [];
|
|
172
|
+
const openaiApi = protocol === "openai" ? (entry.transport === "codex_responses" ? "responses" : "completions") : undefined;
|
|
164
173
|
const keyEnv = typeof entry.key_env === "string" && entry.key_env ? entry.key_env : undefined;
|
|
165
174
|
const apiKey = keyEnv ? readEnv(keyEnv) : undefined;
|
|
166
175
|
const models = Object.keys(entry.models ?? {});
|
|
@@ -168,7 +177,7 @@ export const hermes = {
|
|
|
168
177
|
const defaultModel = entry.default_model ?? active;
|
|
169
178
|
if (defaultModel && !models.includes(defaultModel))
|
|
170
179
|
models.unshift(defaultModel);
|
|
171
|
-
return [{ id, name: entry.name ?? id, protocol, baseUrl: entry.api, apiKey, keyEnv, models, defaultModel, source: self }];
|
|
180
|
+
return [{ id, name: entry.name ?? id, protocol, openaiApi, baseUrl: entry.api, apiKey, keyEnv, models, defaultModel, source: self }];
|
|
172
181
|
});
|
|
173
182
|
},
|
|
174
183
|
};
|
package/dist/targets/omp.js
CHANGED
|
@@ -3,8 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import YAML from "yaml";
|
|
4
4
|
import { backupFile, home, readTextIfExists, writeFileAtomic } from "../fsutil.js";
|
|
5
5
|
import { looksLikeEnvName } from "../slug.js";
|
|
6
|
-
import {
|
|
7
|
-
import { apiValue, classifyApi, entryApi, mergeModels, stripConflictingOverrides } from "./wire.js";
|
|
6
|
+
import { apiValue, classifyApi, entryApi, mergeModels, sdkBaseUrl, stripConflictingOverrides } from "./wire.js";
|
|
8
7
|
/** Per-model keys this adapter writes; one that stops being emitted is cleared, not inherited. */
|
|
9
8
|
const OWNED_MODEL_KEYS = ["id", "name", "reasoning", "input", "contextWindow", "maxTokens", "cost"];
|
|
10
9
|
const agentDir = path.join(home, ".omp", "agent");
|
|
@@ -34,6 +33,7 @@ export const omp = {
|
|
|
34
33
|
const prev = doc.getIn(["providers", provider.id])?.toJSON?.();
|
|
35
34
|
const anthropic = provider.protocol === "anthropic";
|
|
36
35
|
const api = apiValue(provider.protocol, provider.openaiApi, entryApi(prev ?? {}));
|
|
36
|
+
const baseUrl = sdkBaseUrl(provider.protocol, provider.baseUrl);
|
|
37
37
|
const models = mergeModels(prev?.models, provider.models.map((m) => ({
|
|
38
38
|
id: m.id,
|
|
39
39
|
...(m.name ? { name: m.name } : {}),
|
|
@@ -52,11 +52,11 @@ export const omp = {
|
|
|
52
52
|
}
|
|
53
53
|
: {}),
|
|
54
54
|
})), OWNED_MODEL_KEYS);
|
|
55
|
-
const conflicts = stripConflictingOverrides(models, api,
|
|
55
|
+
const conflicts = stripConflictingOverrides(models, api, baseUrl);
|
|
56
56
|
if (conflicts.length)
|
|
57
57
|
notes.push(`dropped model overrides pointing elsewhere: ${conflicts.join(", ")}`);
|
|
58
58
|
const entry = {
|
|
59
|
-
baseUrl
|
|
59
|
+
baseUrl,
|
|
60
60
|
apiKey: provider.apiKey, // omp treats value as env-var name first, then literal
|
|
61
61
|
api,
|
|
62
62
|
models,
|
package/dist/targets/opencode.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { appDataDir, backupFile, readJsonIfExists, writeFileAtomic } from "../fsutil.js";
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
3
|
+
import { appDataDir, backupFile, expandHome, readJsonIfExists, writeFileAtomic } from "../fsutil.js";
|
|
4
|
+
const customDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
5
|
+
const configFile = customDir
|
|
6
|
+
? path.join(expandHome(customDir), "opencode.json")
|
|
7
|
+
: path.join(appDataDir("opencode"), "opencode.json");
|
|
7
8
|
/**
|
|
8
9
|
* opencode: custom providers in ~/.config/opencode/opencode.json "provider" map,
|
|
9
10
|
* backed by @ai-sdk/openai-compatible or @ai-sdk/anthropic npm loaders.
|
|
@@ -48,11 +49,11 @@ export const opencode = {
|
|
|
48
49
|
},
|
|
49
50
|
}
|
|
50
51
|
: {}),
|
|
51
|
-
...(m.contextWindow
|
|
52
|
+
...(m.contextWindow && m.maxOutput
|
|
52
53
|
? {
|
|
53
54
|
limit: {
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
context: m.contextWindow,
|
|
56
|
+
output: m.maxOutput,
|
|
56
57
|
},
|
|
57
58
|
}
|
|
58
59
|
: {}),
|
|
@@ -60,11 +61,11 @@ export const opencode = {
|
|
|
60
61
|
}
|
|
61
62
|
providerMap[provider.id] = {
|
|
62
63
|
...prev,
|
|
63
|
-
npm: anthropic ? "@ai-sdk/anthropic" : "@ai-sdk/openai-compatible",
|
|
64
|
+
npm: anthropic ? "@ai-sdk/anthropic" : provider.openaiApi === "responses" ? "@ai-sdk/openai" : "@ai-sdk/openai-compatible",
|
|
64
65
|
name: provider.name,
|
|
65
66
|
options: {
|
|
66
67
|
...prev.options,
|
|
67
|
-
baseURL:
|
|
68
|
+
baseURL: provider.baseUrl.replace(/\/+$/, ""),
|
|
68
69
|
apiKey: provider.apiKey,
|
|
69
70
|
},
|
|
70
71
|
models,
|
|
@@ -120,6 +121,7 @@ export const opencode = {
|
|
|
120
121
|
if (!entry.npm)
|
|
121
122
|
return []; // built-in provider without a custom npm loader
|
|
122
123
|
const protocol = entry.npm.includes("anthropic") ? "anthropic" : "openai";
|
|
124
|
+
const openaiApi = protocol === "openai" ? (entry.npm === "@ai-sdk/openai" ? "responses" : "completions") : undefined;
|
|
123
125
|
let apiKey = entry.options?.apiKey;
|
|
124
126
|
let keyEnv;
|
|
125
127
|
const ref = apiKey?.match(/^\{env:([A-Za-z0-9_]+)\}$/);
|
|
@@ -131,7 +133,7 @@ export const opencode = {
|
|
|
131
133
|
const defaultModel = activeProvider === id ? activeModel : undefined;
|
|
132
134
|
if (defaultModel && !models.includes(defaultModel))
|
|
133
135
|
models.unshift(defaultModel);
|
|
134
|
-
return [{ id, name: entry.name ?? id, protocol, baseUrl, apiKey, keyEnv, models, defaultModel, source: self }];
|
|
136
|
+
return [{ id, name: entry.name ?? id, protocol, openaiApi, baseUrl, apiKey, keyEnv, models, defaultModel, source: self }];
|
|
135
137
|
});
|
|
136
138
|
},
|
|
137
139
|
};
|
package/dist/targets/pistyle.js
CHANGED
|
@@ -2,8 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { backupFile, home, readJsonIfExists, writeFileAtomic } from "../fsutil.js";
|
|
4
4
|
import { looksLikeEnvName } from "../slug.js";
|
|
5
|
-
import {
|
|
6
|
-
import { apiValue, classifyApi, entryApi, mergeModels, stripConflictingOverrides } from "./wire.js";
|
|
5
|
+
import { apiValue, classifyApi, entryApi, mergeModels, sdkBaseUrl, stripConflictingOverrides } from "./wire.js";
|
|
7
6
|
/** Per-model keys this adapter writes; one that stops being emitted is cleared, not inherited. */
|
|
8
7
|
const OWNED_MODEL_KEYS = [
|
|
9
8
|
"id",
|
|
@@ -60,6 +59,7 @@ export function piStyleTarget(opts) {
|
|
|
60
59
|
? existing
|
|
61
60
|
: {});
|
|
62
61
|
const api = apiValue(provider.protocol, provider.openaiApi, entryApi(prev));
|
|
62
|
+
const baseUrl = sdkBaseUrl(provider.protocol, provider.baseUrl);
|
|
63
63
|
const models = mergeModels(prev.models, provider.models.map((m) => ({
|
|
64
64
|
id: m.id,
|
|
65
65
|
...(m.name ? { name: m.name } : {}),
|
|
@@ -81,13 +81,13 @@ export function piStyleTarget(opts) {
|
|
|
81
81
|
}
|
|
82
82
|
: {}),
|
|
83
83
|
})), OWNED_MODEL_KEYS);
|
|
84
|
-
const conflicts = stripConflictingOverrides(models, api,
|
|
84
|
+
const conflicts = stripConflictingOverrides(models, api, baseUrl);
|
|
85
85
|
if (conflicts.length)
|
|
86
86
|
notes.push(`dropped model overrides pointing elsewhere: ${conflicts.join(", ")}`);
|
|
87
87
|
providers[provider.id] = {
|
|
88
88
|
...prev,
|
|
89
89
|
name: provider.name,
|
|
90
|
-
baseUrl
|
|
90
|
+
baseUrl,
|
|
91
91
|
apiKey: provider.apiKey, // literal key; pi treats "$VAR"/"!cmd" as indirection, prime also accepts bare env names
|
|
92
92
|
api,
|
|
93
93
|
models,
|
package/dist/targets/wire.js
CHANGED
|
@@ -108,11 +108,14 @@ export function stripConflictingOverrides(models, api, baseUrl) {
|
|
|
108
108
|
return dropped;
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* (
|
|
114
|
-
* it appends `/responses` directly, so it keeps the `/v1` segment.
|
|
111
|
+
* Return the base URL expected by SDK-backed clients. Anthropic SDK methods
|
|
112
|
+
* append `/v1/...`, while OpenAI-compatible clients append only the operation
|
|
113
|
+
* path (`/responses` or `/chat/completions`) and therefore keep `/v1`.
|
|
115
114
|
*/
|
|
115
|
+
export function sdkBaseUrl(protocol, baseUrl) {
|
|
116
|
+
return protocol === "anthropic" ? stripApiVersion(baseUrl) : baseUrl.replace(/\/+$/, "");
|
|
117
|
+
}
|
|
118
|
+
/** Strip a trailing API version segment (e.g. `/v1`, `/v2beta`). */
|
|
116
119
|
export function stripApiVersion(baseUrl) {
|
|
117
120
|
return baseUrl.replace(/\/v\d+(?:beta\d*)?\/?$/i, "");
|
|
118
121
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentsw",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "CLI provider switcher for coding agents: manage OpenAI/Anthropic-protocol providers in one place and sync them, with models.dev metadata, into Claude Code, Codex, omp, pi, prime-agent, opencode, Hermes, WorkBuddy and DeepSeek Harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|