@openagents-org/agent-launcher 0.2.150 → 0.2.152
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/package.json +2 -2
- package/registry.json +95 -0
- package/src/adapters/aider.js +5 -3
- package/src/adapters/base.js +34 -6
- package/src/adapters/claude.js +358 -158
- package/src/adapters/codex.js +58 -4
- package/src/adapters/cursor.js +21 -3
- package/src/adapters/decision-log.js +181 -0
- package/src/adapters/index.js +4 -1
- package/src/adapters/mini.js +572 -0
- package/src/adapters/openclaw.js +39 -2
- package/src/adapters/opencode.js +58 -10
- package/src/adapters/workspace-prompt.js +255 -29
- package/src/mcp-server.js +112 -0
- package/src/skill-installer.js +218 -0
- package/src/workspace-client.js +59 -14
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openagents-org/agent-launcher",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "OpenAgents Launcher
|
|
3
|
+
"version": "0.2.152",
|
|
4
|
+
"description": "OpenAgents Launcher \u2014 install, configure, and run AI coding agents from your terminal",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"agn": "bin/agent-connector.js",
|
package/registry.json
CHANGED
|
@@ -835,5 +835,100 @@
|
|
|
835
835
|
"login_command": "hermes setup",
|
|
836
836
|
"not_ready_message": "Hermes not configured — run: hermes setup"
|
|
837
837
|
}
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
"name": "mini-swe-agent",
|
|
841
|
+
"label": "mini-SWE-agent",
|
|
842
|
+
"description": "A minimal shell-based coding agent for fixing issues and modifying code in a workspace.",
|
|
843
|
+
"homepage": "https://mini-swe-agent.com",
|
|
844
|
+
"tags": [
|
|
845
|
+
"coding",
|
|
846
|
+
"cli",
|
|
847
|
+
"shell",
|
|
848
|
+
"autonomous"
|
|
849
|
+
],
|
|
850
|
+
"builtin": true,
|
|
851
|
+
"support": {
|
|
852
|
+
"install": true,
|
|
853
|
+
"workspace": true,
|
|
854
|
+
"collaboration": true
|
|
855
|
+
},
|
|
856
|
+
"install": {
|
|
857
|
+
"binary": "mini",
|
|
858
|
+
"verify": "mini --help",
|
|
859
|
+
"verify_win": "mini --help",
|
|
860
|
+
"macos": "pip install mini-swe-agent",
|
|
861
|
+
"linux": "pip install mini-swe-agent",
|
|
862
|
+
"windows": "pip install mini-swe-agent"
|
|
863
|
+
},
|
|
864
|
+
"launch": {
|
|
865
|
+
"args": []
|
|
866
|
+
},
|
|
867
|
+
"env_config": [
|
|
868
|
+
{
|
|
869
|
+
"name": "MSWEA_MODEL_NAME",
|
|
870
|
+
"description": "Model to use (routed through LiteLLM), e.g. anthropic/claude-sonnet-4-5 or gpt-4o. Optional when a model is already configured via a config file or `mini-extra config setup`. Passed as --model.",
|
|
871
|
+
"required": false,
|
|
872
|
+
"placeholder": "anthropic/claude-sonnet-4-5"
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
"name": "MSWEA_MINI_CONFIG_PATH",
|
|
876
|
+
"description": "Path to a FULL mini config file (YAML). Optional. This REPLACES mini's built-in default config (agent prompt templates, step/environment settings) — it does not merge — so provide a complete file (a good starting point is the output of `mini-extra config setup`). Leave blank to use mini's default config.",
|
|
877
|
+
"required": false,
|
|
878
|
+
"placeholder": "/path/to/mini.yaml"
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
"name": "MSWEA_COST_LIMIT",
|
|
882
|
+
"description": "Optional per-run cost limit in USD, passed as --cost-limit. Leave blank for mini's default.",
|
|
883
|
+
"required": false,
|
|
884
|
+
"placeholder": "3.0"
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
"name": "ANTHROPIC_API_KEY",
|
|
888
|
+
"description": "Anthropic API key — used when the model is an Anthropic model. Leave blank if using another provider or a key already in your environment.",
|
|
889
|
+
"required": false,
|
|
890
|
+
"password": true
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
"name": "ANTHROPIC_BASE_URL",
|
|
894
|
+
"description": "Custom endpoint for native `anthropic/…` models (an enterprise gateway or Anthropic-protocol relay). Leave blank for hosted Anthropic. Note: most third-party relays are OpenAI-compatible — for those use an `openai/…` model + OPENAI_BASE_URL instead.",
|
|
895
|
+
"required": false,
|
|
896
|
+
"placeholder": "https://your-anthropic-gateway.example"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
"name": "OPENAI_API_KEY",
|
|
900
|
+
"description": "OpenAI API key — used when the model is an OpenAI model. Leave blank if using another provider or a key already in your environment.",
|
|
901
|
+
"required": false,
|
|
902
|
+
"password": true
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
"name": "OPENAI_BASE_URL",
|
|
906
|
+
"description": "Custom endpoint for OpenAI-compatible models (a relay/proxy or self-hosted gateway) — applies only to `openai/…` models. Leave blank for hosted OpenAI, or for native providers like `deepseek/…` / `anthropic/…`.",
|
|
907
|
+
"required": false,
|
|
908
|
+
"placeholder": "https://your-relay.example/v1"
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
"name": "DEEPSEEK_API_KEY",
|
|
912
|
+
"description": "DeepSeek API key — used when the model is a `deepseek/…` model (e.g. deepseek/deepseek-chat or deepseek/deepseek-reasoner). Connects directly to api.deepseek.com; no base URL needed.",
|
|
913
|
+
"required": false,
|
|
914
|
+
"password": true
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
"name": "DEEPSEEK_API_BASE",
|
|
918
|
+
"description": "Custom endpoint for native `deepseek/…` models. Leave blank to use DeepSeek's default (api.deepseek.com).",
|
|
919
|
+
"required": false,
|
|
920
|
+
"placeholder": "https://api.deepseek.com"
|
|
921
|
+
}
|
|
922
|
+
],
|
|
923
|
+
"check_ready": {
|
|
924
|
+
"env_vars": [
|
|
925
|
+
"MSWEA_MODEL_NAME",
|
|
926
|
+
"MSWEA_MINI_CONFIG_PATH",
|
|
927
|
+
"ANTHROPIC_API_KEY",
|
|
928
|
+
"OPENAI_API_KEY",
|
|
929
|
+
"DEEPSEEK_API_KEY"
|
|
930
|
+
],
|
|
931
|
+
"not_ready_message": "mini-SWE-agent CLI detected. Configure a model through environment variables (MSWEA_MODEL_NAME + a provider key), a full config file (MSWEA_MINI_CONFIG_PATH), or the Model field before running a task."
|
|
932
|
+
}
|
|
838
933
|
}
|
|
839
934
|
]
|
package/src/adapters/aider.js
CHANGED
|
@@ -107,13 +107,14 @@ function classifyError(stderr, stdout) {
|
|
|
107
107
|
// ---------------------------------------------------------------------------
|
|
108
108
|
|
|
109
109
|
const VALID_PROVIDERS = [
|
|
110
|
-
'auto', 'openai', 'anthropic', 'openrouter', 'gemini', 'deepseek',
|
|
110
|
+
'auto', 'openai', 'anthropic', 'openrouter', 'requesty', 'gemini', 'deepseek',
|
|
111
111
|
'openai-compatible',
|
|
112
112
|
];
|
|
113
113
|
const PROVIDER_KEY_VAR = {
|
|
114
114
|
openai: 'OPENAI_API_KEY',
|
|
115
115
|
anthropic: 'ANTHROPIC_API_KEY',
|
|
116
116
|
openrouter: 'OPENROUTER_API_KEY',
|
|
117
|
+
requesty: 'REQUESTY_API_KEY',
|
|
117
118
|
gemini: 'GEMINI_API_KEY',
|
|
118
119
|
deepseek: 'DEEPSEEK_API_KEY',
|
|
119
120
|
'openai-compatible': 'OPENAI_API_KEY',
|
|
@@ -122,6 +123,7 @@ const PROVIDER_KEY_VAR = {
|
|
|
122
123
|
function explicitPrefixProvider(model) {
|
|
123
124
|
const m = String(model || '').trim().toLowerCase();
|
|
124
125
|
if (m.startsWith('openrouter/')) return 'openrouter';
|
|
126
|
+
if (m.startsWith('requesty/')) return 'requesty';
|
|
125
127
|
if (m.startsWith('anthropic/')) return 'anthropic';
|
|
126
128
|
if (m.startsWith('openai/')) return 'openai';
|
|
127
129
|
if (m.startsWith('gemini/') || m.startsWith('google/')) return 'gemini';
|
|
@@ -167,7 +169,7 @@ function resolveAiderProvider(provider, model, apiKey, baseUrl) {
|
|
|
167
169
|
return {
|
|
168
170
|
env: {}, model,
|
|
169
171
|
error: `Unknown AIDER_PROVIDER '${provider}'. Valid values: auto, openai, `
|
|
170
|
-
+ 'anthropic, openrouter, gemini, deepseek, openai-compatible.',
|
|
172
|
+
+ 'anthropic, openrouter, requesty, gemini, deepseek, openai-compatible.',
|
|
171
173
|
};
|
|
172
174
|
}
|
|
173
175
|
if (!provider) provider = 'auto';
|
|
@@ -191,7 +193,7 @@ function resolveAiderProvider(provider, model, apiKey, baseUrl) {
|
|
|
191
193
|
return {
|
|
192
194
|
env: {}, model,
|
|
193
195
|
error: 'Could not determine the model provider for LLM_API_KEY. Set '
|
|
194
|
-
+ 'AIDER_PROVIDER (openai, anthropic, openrouter, gemini, deepseek, or '
|
|
196
|
+
+ 'AIDER_PROVIDER (openai, anthropic, openrouter, requesty, gemini, deepseek, or '
|
|
195
197
|
+ 'openai-compatible), use an AIDER_MODEL whose name identifies the '
|
|
196
198
|
+ 'provider, or set the native provider key directly.',
|
|
197
199
|
};
|
package/src/adapters/base.js
CHANGED
|
@@ -370,12 +370,31 @@ class BaseAdapter {
|
|
|
370
370
|
}
|
|
371
371
|
|
|
372
372
|
try {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
373
|
+
// Custom (uploaded) skills carry source_type=workspace_file + a file_id.
|
|
374
|
+
// Download the package bytes here (async), then hand them to the sync
|
|
375
|
+
// installer. Catalog skills keep their existing fetch-by-source path.
|
|
376
|
+
const sourceType = skill && (skill.source_type || skill.sourceType);
|
|
377
|
+
let result;
|
|
378
|
+
if (sourceType === 'workspace_file') {
|
|
379
|
+
const fileId = skill.file_id || skill.fileId;
|
|
380
|
+
if (!fileId) throw new Error('workspace_file skill is missing file_id');
|
|
381
|
+
this._log(`skill.install: downloading uploaded package (file_id=${fileId})`);
|
|
382
|
+
const buffer = await this.client.readFile(this.workspaceId, this.token, fileId);
|
|
383
|
+
if (!buffer || buffer.length === 0) throw new Error('uploaded skill file is empty');
|
|
384
|
+
result = installer.installUploadedSkill({
|
|
385
|
+
skill, buffer,
|
|
386
|
+
agentType: this.agentType,
|
|
387
|
+
workingDir: this.workingDir,
|
|
388
|
+
log: (m) => this._log(`skill.install: ${m}`),
|
|
389
|
+
});
|
|
390
|
+
} else {
|
|
391
|
+
result = installer.installSkill({
|
|
392
|
+
skill,
|
|
393
|
+
agentType: this.agentType,
|
|
394
|
+
workingDir: this.workingDir,
|
|
395
|
+
log: (m) => this._log(`skill.install: ${m}`),
|
|
396
|
+
});
|
|
397
|
+
}
|
|
379
398
|
try {
|
|
380
399
|
await this.client.reportSkillStatus(this.workspaceId, this.agentName, this.token, {
|
|
381
400
|
skillId, state: 'installed', path: result.path, partial: result.partial === true,
|
|
@@ -688,6 +707,15 @@ class BaseAdapter {
|
|
|
688
707
|
}
|
|
689
708
|
|
|
690
709
|
if (this._channelBusy.has(channel)) {
|
|
710
|
+
// A routine that's already running must not stack up. Routine fires are
|
|
711
|
+
// periodic, so a fire that arrives while the previous run is still going
|
|
712
|
+
// is simply dropped — the next scheduled tick re-fires once the agent is
|
|
713
|
+
// free. (The backend guard normally prevents this from even being sent;
|
|
714
|
+
// this is the last line of defense against a queue backlog.)
|
|
715
|
+
if (msg.senderName === 'system:routine') {
|
|
716
|
+
this._log(`Skipping routine fire in ${channel} — previous run still in progress`);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
691
719
|
if (!this._channelQueues[channel]) this._channelQueues[channel] = [];
|
|
692
720
|
const queueId = `q-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
693
721
|
msg._queueId = queueId;
|