@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-launcher",
3
- "version": "0.2.150",
4
- "description": "OpenAgents Launcher — install, configure, and run AI coding agents from your terminal",
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
  ]
@@ -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
  };
@@ -370,12 +370,31 @@ class BaseAdapter {
370
370
  }
371
371
 
372
372
  try {
373
- const result = installer.installSkill({
374
- skill,
375
- agentType: this.agentType,
376
- workingDir: this.workingDir,
377
- log: (m) => this._log(`skill.install: ${m}`),
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;