Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 22s
CI / Detect changes (pull_request) Successful in 24s
E2E API Smoke Test / detect-changes (pull_request) Successful in 20s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 21s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 44s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 38s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 35s
Harness Replays / detect-changes (pull_request) Successful in 44s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 27s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 56s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Failing after 2m1s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Failing after 2m34s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Failing after 2m34s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 23s
Harness Replays / Harness Replays (pull_request) Failing after 1m12s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2m51s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 5m37s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6m15s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6m34s
CI / Python Lint & Test (pull_request) Successful in 8m20s
CI / Canvas (Next.js) (pull_request) Successful in 9m46s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Failing after 13m23s
The GitHub org Molecule-AI was suspended on 2026-05-06; canonical SCM is now Gitea at https://git.moleculesai.app/molecule-ai/. Stale github.com/Molecule-AI/... URLs return 404 and break tooling that clones / pip-installs / curls them. This bundles all non-Go-module URL fixes for this repo into a single PR. Go module path references (in *.go, go.mod, go.sum) are out of scope here -- tracked separately under Task #140. Token-auth clone URLs also flip ${GITHUB_TOKEN} -> ${GITEA_TOKEN} since the GitHub token does not auth against Gitea. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
151 lines
6.8 KiB
Bash
Executable File
151 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# VENDORED COPY — DO NOT EDIT THIS FILE BY HAND.
|
|
#
|
|
# Source of truth:
|
|
# git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-hermes
|
|
# scripts/derive-provider.sh
|
|
#
|
|
# This snapshot is read by derive_provider_drift_test.go so the AST
|
|
# drift gate stays hermetic (no network, no submodule, no path-walk).
|
|
# When upstream changes, refresh via:
|
|
#
|
|
# cp ~/path/to/molecule-ai-workspace-template-hermes/scripts/derive-provider.sh \
|
|
# workspace-server/internal/handlers/testdata/derive-provider.sh
|
|
#
|
|
# (and re-add the VENDORED COPY header below.) The drift test will
|
|
# fail loudly if upstream adds prefixes that deriveProviderFromModelSlug
|
|
# doesn't handle — fix it by adding the missing case to the Go function,
|
|
# not by silently widening acceptedDivergences.
|
|
#
|
|
# derive-provider.sh — map a hermes-agent model slug to its provider
|
|
# name. Sourced by both install.sh (SaaS bare-host path) and start.sh
|
|
# (Docker path) so the two entry-points stay consistent.
|
|
#
|
|
# Contract:
|
|
# Reads: $HERMES_INFERENCE_PROVIDER (if already set, we respect it)
|
|
# $HERMES_INFERENCE_MODEL (preferred — matches upstream env name)
|
|
# $HERMES_DEFAULT_MODEL (legacy fallback — name we invented before
|
|
# 2026-05; workspace-server still writes
|
|
# it during the migration window)
|
|
# $HERMES_API_KEY / $NOUS_API_KEY (affect the nousresearch/* branch)
|
|
# Writes: $PROVIDER — the derived provider name, or "auto" if unknown.
|
|
#
|
|
# Upstream's actual env var is $HERMES_INFERENCE_MODEL (see
|
|
# website/docs/reference/environment-variables.md in NousResearch/hermes-agent).
|
|
# We accept both for one release cycle so workspaces booting under the legacy
|
|
# control-plane don't break — drop $HERMES_DEFAULT_MODEL once workspace-server
|
|
# is updated to write the upstream name.
|
|
#
|
|
# Why the per-template sub-script (vs doing this in CP): every runtime
|
|
# has its own provider taxonomy. Keeping the logic inside the template
|
|
# repo means CP stays runtime-agnostic and adding a new runtime with
|
|
# different provider semantics doesn't require a CP edit.
|
|
#
|
|
# Hermes-specific quirks encoded here:
|
|
# - `openai/...` routes through `openrouter` (hermes has no direct
|
|
# openai provider; openai-codex is OAuth-only for Codex models)
|
|
# - `nousresearch/...` prefers direct `nous` if HERMES_API_KEY is
|
|
# set, else falls back to `openrouter` (which also serves Hermes 3)
|
|
# - chinese-region variants (minimax-cn, kimi-coding-cn) keep their
|
|
# full prefix as the provider name
|
|
#
|
|
# See molecule-controlplane/docs/canary-tenants.md and the hermes-agent
|
|
# providers.md docs for the full taxonomy.
|
|
|
|
# Honour an explicit override.
|
|
if [ -n "${HERMES_INFERENCE_PROVIDER:-}" ]; then
|
|
PROVIDER="${HERMES_INFERENCE_PROVIDER}"
|
|
return 0 2>/dev/null || exit 0
|
|
fi
|
|
|
|
# Resolve the model slug — prefer the upstream env name, fall back to legacy.
|
|
_HERMES_MODEL="${HERMES_INFERENCE_MODEL:-${HERMES_DEFAULT_MODEL:-}}"
|
|
|
|
if [ -z "${_HERMES_MODEL}" ]; then
|
|
PROVIDER="auto"
|
|
return 0 2>/dev/null || exit 0
|
|
fi
|
|
|
|
case "${_HERMES_MODEL}" in
|
|
# Keep full CN-suffix as provider so chinese-region keys route right
|
|
minimax-cn/*) PROVIDER="minimax-cn" ;;
|
|
kimi-coding-cn/*) PROVIDER="kimi-coding-cn" ;;
|
|
|
|
# Direct-SDK providers (clean 1:1 prefix→provider mapping)
|
|
minimax/*) PROVIDER="minimax" ;;
|
|
anthropic/*) PROVIDER="anthropic" ;;
|
|
gemini/*) PROVIDER="gemini" ;;
|
|
deepseek/*) PROVIDER="deepseek" ;;
|
|
zai/*) PROVIDER="zai" ;;
|
|
kimi-coding/*) PROVIDER="kimi-coding" ;;
|
|
alibaba/*|dashscope/*|qwen/*) PROVIDER="alibaba" ;;
|
|
xiaomi/*|mimo/*) PROVIDER="xiaomi" ;;
|
|
arcee/*|arcee-ai/*) PROVIDER="arcee" ;;
|
|
nvidia/*|nim/*) PROVIDER="nvidia" ;;
|
|
ollama-cloud/*) PROVIDER="ollama-cloud" ;;
|
|
huggingface/*|hf/*) PROVIDER="huggingface" ;;
|
|
ai-gateway/*|aigateway/*) PROVIDER="ai-gateway" ;;
|
|
kilocode/*) PROVIDER="kilocode" ;;
|
|
opencode-zen/*) PROVIDER="opencode-zen" ;;
|
|
opencode-go/*) PROVIDER="opencode-go" ;;
|
|
|
|
# Hermes-specific routing quirks. `openai/*` has two valid targets:
|
|
# 1. hermes's "custom" provider pointed at api.openai.com — requires
|
|
# OPENAI_API_KEY. install.sh sees this case and auto-populates
|
|
# HERMES_CUSTOM_{BASE_URL,API_KEY} so the direct-OpenAI path works
|
|
# without the user having to set HERMES_CUSTOM_* explicitly.
|
|
# 2. OpenRouter (hermes's built-in path — requires OPENROUTER_API_KEY).
|
|
#
|
|
# Priority: prefer **custom** (direct OpenAI) when OPENAI_API_KEY is set.
|
|
# The operator supplying OPENAI_API_KEY for an openai/* model is an
|
|
# explicit intent signal to hit OpenAI directly. The previous "prefer
|
|
# OR if any OR key exists" rule silently hijacked that intent whenever
|
|
# a tenant-global OPENROUTER_API_KEY was present (even if stale/empty
|
|
# enough to 401), which is exactly what bit the 2026-04-23 E2E (surfaced
|
|
# as OpenRouter's `401 Missing Authentication header` in the agent reply).
|
|
#
|
|
# To explicitly route openai/* through OR, set HERMES_INFERENCE_PROVIDER=openrouter
|
|
# (handled at the top of this file) or use an openrouter/* model slug.
|
|
openai/*)
|
|
if [ -n "${OPENAI_API_KEY:-}" ]; then
|
|
PROVIDER="custom"
|
|
elif [ -n "${OPENROUTER_API_KEY:-}" ]; then
|
|
PROVIDER="openrouter"
|
|
else
|
|
PROVIDER="openrouter" # no-key fallback — hermes will error clearly
|
|
fi
|
|
;;
|
|
nousresearch/*)
|
|
# Prefer direct Nous Portal if Nous credentials present, else OR.
|
|
if [ -n "${HERMES_API_KEY:-}" ] || [ -n "${NOUS_API_KEY:-}" ]; then
|
|
PROVIDER="nous"
|
|
else
|
|
PROVIDER="openrouter"
|
|
fi
|
|
;;
|
|
|
|
# Explicit catch-alls
|
|
openrouter/*) PROVIDER="openrouter" ;;
|
|
custom/*) PROVIDER="custom" ;;
|
|
|
|
# Additional 1:1 prefix→provider mappings — kept aligned with upstream's
|
|
# HERMES_INFERENCE_PROVIDER list (website/docs/reference/environment-variables.md
|
|
# in NousResearch/hermes-agent, v0.12.0 / 2026-04-30). Place these BEFORE the
|
|
# catch-all so they win.
|
|
xai/*|grok/*) PROVIDER="xai" ;;
|
|
bedrock/*|aws/*) PROVIDER="bedrock" ;;
|
|
tencent/*|tencent-tokenhub/*) PROVIDER="tencent-tokenhub" ;;
|
|
gmi/*) PROVIDER="gmi" ;;
|
|
qwen-oauth/*) PROVIDER="qwen-oauth" ;;
|
|
lmstudio/*|lm-studio/*) PROVIDER="lmstudio" ;;
|
|
minimax-oauth/*) PROVIDER="minimax-oauth" ;;
|
|
alibaba-coding-plan/*) PROVIDER="alibaba-coding-plan" ;;
|
|
google-gemini-cli/*) PROVIDER="google-gemini-cli" ;;
|
|
openai-codex/*) PROVIDER="openai-codex" ;;
|
|
copilot-acp/*) PROVIDER="copilot-acp" ;;
|
|
copilot/*) PROVIDER="copilot" ;;
|
|
|
|
# Unknown prefix → let hermes auto-detect
|
|
*) PROVIDER="auto" ;;
|
|
esac
|