feat: update claude client gateway configuration
- Simplify model display names (remove verbose descriptions) - Add use-model.sh for quick profile switching (dev-corp/ornith/fable/sonnet/opus) - Change default gateway port from 18443 to 18444 - Remove deprecated ANTHROPIC_CUSTOM_MODEL_OPTION env vars - Support system/developer role messages in OpenAI conversion - Remove gateway-models.json cache (no longer needed) - Add environment variables for gateway port and PATH in launchd plist
This commit is contained in:
parent
5cd7aea826
commit
217930f9b0
3 changed files with 144 additions and 77 deletions
|
|
@ -1,13 +1,11 @@
|
||||||
# Claude Agent Client
|
# Claude Agent Client
|
||||||
|
|
||||||
기존 Seulgivibe Claude 설정이 되어 있는 macOS 환경에서 Claude TUI `/model`에 아래 모델을 함께 노출한다.
|
기존 Seulgivibe Claude 설정이 되어 있는 macOS 환경에서 Claude 기본 모델은 그대로 두고, Claude TUI `/model`에 아래 gateway 모델만 추가로 노출한다.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
claude-seulgivibe-sonnet-4-5 Claude Sonnet 4.5 - coding agents
|
claude-seulgivibe-mythos-5 Claude Fable 5
|
||||||
claude-seulgivibe-opus-4-8 Claude Opus 4.8 - browser agents
|
claude-dev-corp-gemma4-26b Gemma 4 26B A4B IT NVFP4
|
||||||
claude-seulgivibe-mythos-5 Claude Fable 5 - autonomous work
|
claude-dev-corp-ornith35b Ornith 1.0 35B 8-bit
|
||||||
claude-dev-corp-gemma4-26b Gemma4 26B - gemma4:26b
|
|
||||||
claude-dev-corp-ornith35b Ornith 35B - ornith35b
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 설치
|
## 설치
|
||||||
|
|
@ -27,6 +25,8 @@ cd agent-client/claude
|
||||||
- `~/.claude/dev-corp-openai-api-key`
|
- `~/.claude/dev-corp-openai-api-key`
|
||||||
- `~/.pi/agent/dev-corp-openai-api-key`
|
- `~/.pi/agent/dev-corp-openai-api-key`
|
||||||
- 없으면 `~/.claude/anthropic_key.sh` 출력값을 fallback으로 사용한다.
|
- 없으면 `~/.claude/anthropic_key.sh` 출력값을 fallback으로 사용한다.
|
||||||
|
- 기본 Claude 모델은 gateway 모델로 재등록하지 않고 Claude Code 기본 표시를 사용한다.
|
||||||
|
- `~/.claude/use-model.sh dev-corp|ornith|fable|sonnet|opus`로 로컬 모델 프로필을 전환할 수 있다.
|
||||||
- `claude-dev-corp-gemma4-26b`는 Claude 표시용 alias이며 upstream 호출 모델은 `gemma4:26b`다.
|
- `claude-dev-corp-gemma4-26b`는 Claude 표시용 alias이며 upstream 호출 모델은 `gemma4:26b`다.
|
||||||
- `claude-dev-corp-ornith35b`는 Claude 표시용 alias이며 upstream 호출 모델은 `ornith:35b`다.
|
- `claude-dev-corp-ornith35b`는 Claude 표시용 alias이며 upstream 호출 모델은 `ornith:35b`다.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@ CLAUDE_DIR="$HOME/.claude"
|
||||||
SETTINGS="$CLAUDE_DIR/settings.json"
|
SETTINGS="$CLAUDE_DIR/settings.json"
|
||||||
GATEWAY="$CLAUDE_DIR/iop-claude-gateway.py"
|
GATEWAY="$CLAUDE_DIR/iop-claude-gateway.py"
|
||||||
DEV_CORP_KEY_HELPER="$CLAUDE_DIR/dev-corp-openai-key.sh"
|
DEV_CORP_KEY_HELPER="$CLAUDE_DIR/dev-corp-openai-key.sh"
|
||||||
|
USE_MODEL="$CLAUDE_DIR/use-model.sh"
|
||||||
LABEL="com.iop.agent-client.claude"
|
LABEL="com.iop.agent-client.claude"
|
||||||
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
|
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
|
||||||
PYTHON_BIN="/usr/bin/python3"
|
PYTHON_BIN="/usr/bin/python3"
|
||||||
UID_VALUE="$(id -u)"
|
UID_VALUE="$(id -u)"
|
||||||
|
GATEWAY_PORT="${IOP_CLAUDE_GATEWAY_PORT:-18444}"
|
||||||
|
|
||||||
if [[ ! -x "$PYTHON_BIN" ]]; then
|
if [[ ! -x "$PYTHON_BIN" ]]; then
|
||||||
PYTHON_BIN="$(command -v python3 || true)"
|
PYTHON_BIN="$(command -v python3 || true)"
|
||||||
|
|
@ -29,6 +31,7 @@ mkdir -p "$CLAUDE_DIR/cache" "$HOME/Library/LaunchAgents"
|
||||||
|
|
||||||
OLD_LABELS=(
|
OLD_LABELS=(
|
||||||
"$LABEL"
|
"$LABEL"
|
||||||
|
"com.leedongmyung.dev-corp-claude-gateway"
|
||||||
"com.seulgivibe.claude.models"
|
"com.seulgivibe.claude.models"
|
||||||
"com.seulgivibe.claude.anthropic-proxy"
|
"com.seulgivibe.claude.anthropic-proxy"
|
||||||
"com.leedongmyung.claude.seulgivibe-anthropic-proxy"
|
"com.leedongmyung.claude.seulgivibe-anthropic-proxy"
|
||||||
|
|
@ -40,6 +43,7 @@ done
|
||||||
|
|
||||||
OLD_PLISTS=(
|
OLD_PLISTS=(
|
||||||
"$PLIST"
|
"$PLIST"
|
||||||
|
"$HOME/Library/LaunchAgents/com.leedongmyung.dev-corp-claude-gateway.plist"
|
||||||
"$HOME/Library/LaunchAgents/com.seulgivibe.claude.models.plist"
|
"$HOME/Library/LaunchAgents/com.seulgivibe.claude.models.plist"
|
||||||
"$HOME/Library/LaunchAgents/com.seulgivibe.claude.anthropic-proxy.plist"
|
"$HOME/Library/LaunchAgents/com.seulgivibe.claude.anthropic-proxy.plist"
|
||||||
"$HOME/Library/LaunchAgents/com.leedongmyung.claude.seulgivibe-anthropic-proxy.plist"
|
"$HOME/Library/LaunchAgents/com.leedongmyung.claude.seulgivibe-anthropic-proxy.plist"
|
||||||
|
|
@ -86,69 +90,136 @@ EOF
|
||||||
chmod 755 "$DEV_CORP_KEY_HELPER"
|
chmod 755 "$DEV_CORP_KEY_HELPER"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
"$PYTHON_BIN" - "$SETTINGS" "$CLAUDE_DIR/cache/gateway-models.json" <<'PY'
|
"$PYTHON_BIN" - "$SETTINGS" "$CLAUDE_DIR" "$GATEWAY_PORT" <<'PY'
|
||||||
import json
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
settings_path = pathlib.Path(sys.argv[1])
|
settings_path = pathlib.Path(sys.argv[1])
|
||||||
cache_path = pathlib.Path(sys.argv[2])
|
claude_dir = pathlib.Path(sys.argv[2])
|
||||||
|
gateway_port = sys.argv[3]
|
||||||
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
cache_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
settings = {}
|
settings = {}
|
||||||
if settings_path.exists():
|
if settings_path.exists():
|
||||||
backup = settings_path.with_name(f"{settings_path.name}.bak-{time.strftime('%Y%m%d%H%M%S')}")
|
backup = settings_path.with_name(f"{settings_path.name}.bak-{time.strftime('%Y%m%d%H%M%S')}")
|
||||||
backup.write_bytes(settings_path.read_bytes())
|
backup.write_bytes(settings_path.read_bytes())
|
||||||
settings = json.loads(settings_path.read_text() or "{}")
|
try:
|
||||||
|
settings = json.loads(settings_path.read_text() or "{}")
|
||||||
|
except Exception:
|
||||||
|
settings = {}
|
||||||
|
|
||||||
models = [
|
base_url = f"http://127.0.0.1:{gateway_port}/anthropic"
|
||||||
"claude-seulgivibe-sonnet-4-5",
|
common_env = {
|
||||||
"claude-seulgivibe-opus-4-8",
|
"ANTHROPIC_BASE_URL": base_url,
|
||||||
"claude-seulgivibe-mythos-5",
|
"NODE_TLS_REJECT_UNAUTHORIZED": "0",
|
||||||
"gemma4:26b",
|
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1",
|
||||||
]
|
}
|
||||||
|
removed_env_keys = [
|
||||||
settings["apiKeyHelper"] = settings.get("apiKeyHelper") or "~/.claude/anthropic_key.sh"
|
|
||||||
env = settings.setdefault("env", {})
|
|
||||||
env["ANTHROPIC_BASE_URL"] = "http://127.0.0.1:18443/anthropic"
|
|
||||||
env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
||||||
env["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] = "1"
|
|
||||||
for key in [
|
|
||||||
"ANTHROPIC_CUSTOM_MODEL_OPTION",
|
"ANTHROPIC_CUSTOM_MODEL_OPTION",
|
||||||
"ANTHROPIC_CUSTOM_MODEL_OPTION_NAME",
|
"ANTHROPIC_CUSTOM_MODEL_OPTION_NAME",
|
||||||
"ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION",
|
"ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION",
|
||||||
|
"ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES",
|
||||||
"ANTHROPIC_DEFAULT_FABLE_MODEL",
|
"ANTHROPIC_DEFAULT_FABLE_MODEL",
|
||||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME",
|
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME",
|
||||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_DESCRIPTION",
|
"ANTHROPIC_DEFAULT_FABLE_MODEL_DESCRIPTION",
|
||||||
]:
|
]
|
||||||
env.pop(key, None)
|
model_aliases = {
|
||||||
|
"claude-seulgivibe-sonnet-4-5": "sonnet",
|
||||||
|
"claude-seulgivibe-opus-4-8": "opus",
|
||||||
|
"gemma4:26b": "claude-dev-corp-gemma4-26b",
|
||||||
|
"ornith35b": "claude-dev-corp-ornith35b",
|
||||||
|
"ornith:35b": "claude-dev-corp-ornith35b",
|
||||||
|
}
|
||||||
|
|
||||||
if settings.get("model") == "claude-dev-corp-gemma4-26b":
|
def normalize_settings(value, model=None):
|
||||||
settings["model"] = "gemma4:26b"
|
output = dict(value or {})
|
||||||
if settings.get("model") not in models:
|
output["apiKeyHelper"] = output.get("apiKeyHelper") or "~/.claude/anthropic_key.sh"
|
||||||
settings["model"] = "claude-seulgivibe-mythos-5"
|
env = dict(output.get("env") or {})
|
||||||
settings["availableModels"] = models
|
for key in removed_env_keys:
|
||||||
settings["enforceAvailableModels"] = True
|
env.pop(key, None)
|
||||||
settings.setdefault("effortLevel", "xhigh")
|
env.update(common_env)
|
||||||
settings.setdefault("alwaysThinkingEnabled", True)
|
output["env"] = env
|
||||||
|
output.pop("availableModels", None)
|
||||||
|
output.pop("enforceAvailableModels", None)
|
||||||
|
if model is not None:
|
||||||
|
output["model"] = model
|
||||||
|
elif output.get("model") in model_aliases:
|
||||||
|
output["model"] = model_aliases[output["model"]]
|
||||||
|
output.setdefault("permissions", {})
|
||||||
|
output["permissions"].setdefault("defaultMode", "bypassPermissions")
|
||||||
|
output["permissions"].setdefault("skipDangerousModePermissionPrompt", True)
|
||||||
|
output.setdefault("effortLevel", "xhigh")
|
||||||
|
output.setdefault("alwaysThinkingEnabled", True)
|
||||||
|
output.setdefault("skipDangerousModePermissionPrompt", True)
|
||||||
|
return output
|
||||||
|
|
||||||
|
settings = normalize_settings(settings)
|
||||||
settings_path.write_text(json.dumps(settings, indent=2, ensure_ascii=False) + "\n")
|
settings_path.write_text(json.dumps(settings, indent=2, ensure_ascii=False) + "\n")
|
||||||
|
|
||||||
cache = {
|
profiles = {
|
||||||
"baseUrl": "http://127.0.0.1:18443/anthropic",
|
"settings.dev-corp.json": "claude-dev-corp-gemma4-26b",
|
||||||
"fetchedAt": int(time.time() * 1000),
|
"settings.ornith35b.json": "claude-dev-corp-ornith35b",
|
||||||
"models": [
|
"settings.fable.json": "claude-seulgivibe-mythos-5",
|
||||||
{"id": "claude-seulgivibe-sonnet-4-5", "display_name": "Seulgivibe Sonnet 4.5"},
|
"settings.sonnet-4-5.json": "sonnet",
|
||||||
{"id": "claude-seulgivibe-opus-4-8", "display_name": "Seulgivibe Opus 4.8"},
|
"settings.opus-4-8.json": "opus",
|
||||||
{"id": "claude-seulgivibe-mythos-5", "display_name": "Seulgivibe Fable 5"},
|
|
||||||
{"id": "gemma4:26b", "display_name": "dev-corp gemma4:26b"},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
cache_path.write_text(json.dumps(cache, ensure_ascii=False, separators=(",", ":")) + "\n")
|
for filename, model in profiles.items():
|
||||||
|
profile_path = claude_dir / filename
|
||||||
|
profile = {}
|
||||||
|
if profile_path.exists():
|
||||||
|
try:
|
||||||
|
profile = json.loads(profile_path.read_text() or "{}")
|
||||||
|
except Exception:
|
||||||
|
profile = {}
|
||||||
|
profile = normalize_settings(profile, model=model)
|
||||||
|
profile_path.write_text(json.dumps(profile, indent=2, ensure_ascii=False) + "\n")
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
cat > "$USE_MODEL" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
profile="${1:-}"
|
||||||
|
case "$profile" in
|
||||||
|
dev-corp|devcorp|gemma|gemma4)
|
||||||
|
source_file="$HOME/.claude/settings.dev-corp.json"
|
||||||
|
;;
|
||||||
|
ornith|ornith35b)
|
||||||
|
source_file="$HOME/.claude/settings.ornith35b.json"
|
||||||
|
;;
|
||||||
|
fable)
|
||||||
|
source_file="$HOME/.claude/settings.fable.json"
|
||||||
|
;;
|
||||||
|
sonnet|sonnet-4-5)
|
||||||
|
source_file="$HOME/.claude/settings.sonnet-4-5.json"
|
||||||
|
;;
|
||||||
|
opus|opus-4-8)
|
||||||
|
source_file="$HOME/.claude/settings.opus-4-8.json"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 dev-corp|ornith|fable|sonnet|opus" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
mkdir -p "$HOME/.claude/backups"
|
||||||
|
if [ -f "$HOME/.claude/settings.json" ]; then
|
||||||
|
cp "$HOME/.claude/settings.json" "$HOME/.claude/backups/settings.json.$(date +%Y%m%d-%H%M%S)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "$source_file" "$HOME/.claude/settings.json"
|
||||||
|
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
jq -r '"Claude Code model set to " + .model + " / effort=" + (.effortLevel // "default")' "$HOME/.claude/settings.json"
|
||||||
|
else
|
||||||
|
echo "Claude Code model profile applied: $profile"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
chmod 755 "$USE_MODEL"
|
||||||
|
rm -f "$CLAUDE_DIR/cache/gateway-models.json"
|
||||||
|
|
||||||
cat > "$PLIST" <<EOF
|
cat > "$PLIST" <<EOF
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
|
@ -161,6 +232,13 @@ cat > "$PLIST" <<EOF
|
||||||
<string>$PYTHON_BIN</string>
|
<string>$PYTHON_BIN</string>
|
||||||
<string>$GATEWAY</string>
|
<string>$GATEWAY</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>EnvironmentVariables</key>
|
||||||
|
<dict>
|
||||||
|
<key>IOP_CLAUDE_GATEWAY_PORT</key>
|
||||||
|
<string>$GATEWAY_PORT</string>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
||||||
|
</dict>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>KeepAlive</key>
|
<key>KeepAlive</key>
|
||||||
|
|
@ -177,9 +255,9 @@ launchctl bootstrap "gui/$UID_VALUE" "$PLIST"
|
||||||
launchctl kickstart -k "gui/$UID_VALUE/$LABEL"
|
launchctl kickstart -k "gui/$UID_VALUE/$LABEL"
|
||||||
|
|
||||||
for _ in 1 2 3 4 5; do
|
for _ in 1 2 3 4 5; do
|
||||||
curl -fsS "http://127.0.0.1:18443/health" >/dev/null 2>&1 && break
|
curl -fsS "http://127.0.0.1:$GATEWAY_PORT/health" >/dev/null 2>&1 && break
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
curl -fsS "http://127.0.0.1:18443/anthropic/v1/models" >/dev/null
|
curl -fsS "http://127.0.0.1:$GATEWAY_PORT/anthropic/v1/models" >/dev/null
|
||||||
echo "완료: Claude TUI를 새로 열고 /model 에서 모델을 선택하세요."
|
echo "완료: Claude TUI를 새로 열고 /model 에서 모델을 선택하세요."
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from urllib.parse import urlsplit
|
||||||
|
|
||||||
|
|
||||||
HOST = "127.0.0.1"
|
HOST = "127.0.0.1"
|
||||||
PORT = int(os.environ.get("IOP_CLAUDE_GATEWAY_PORT", "18443"))
|
PORT = int(os.environ.get("IOP_CLAUDE_GATEWAY_PORT", "18444"))
|
||||||
|
|
||||||
SEULGIVIBE_HOST = os.environ.get("SEULGIVIBE_HOST", "seulgivibe.lgudax.cool")
|
SEULGIVIBE_HOST = os.environ.get("SEULGIVIBE_HOST", "seulgivibe.lgudax.cool")
|
||||||
SEULGIVIBE_PREFIX = os.environ.get("SEULGIVIBE_ANTHROPIC_PREFIX", "/anthropic")
|
SEULGIVIBE_PREFIX = os.environ.get("SEULGIVIBE_ANTHROPIC_PREFIX", "/anthropic")
|
||||||
|
|
@ -37,7 +37,7 @@ GEMMA_OPENAI_BASE_URL = os.environ.get(
|
||||||
).rstrip("/")
|
).rstrip("/")
|
||||||
ORNITH_OPENAI_BASE_URL = os.environ.get(
|
ORNITH_OPENAI_BASE_URL = os.environ.get(
|
||||||
"DEV_CORP_ORNITH_OPENAI_BASE_URL",
|
"DEV_CORP_ORNITH_OPENAI_BASE_URL",
|
||||||
"http://172.24.63.178:18003/v1",
|
DEFAULT_DEV_CORP_OPENAI_BASE_URL,
|
||||||
).rstrip("/")
|
).rstrip("/")
|
||||||
DEV_CORP_MODEL_CONFIGS = {
|
DEV_CORP_MODEL_CONFIGS = {
|
||||||
GEMMA_MODEL: {
|
GEMMA_MODEL: {
|
||||||
|
|
@ -59,45 +59,29 @@ DEV_CORP_MODEL_CONFIGS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
SEULGIVIBE_ALIASES = {
|
SEULGIVIBE_ALIASES = {
|
||||||
"claude-seulgivibe-sonnet-4-5": "claude-sonnet-4-5-20250929",
|
|
||||||
"claude-seulgivibe-opus-4-8": "claude-opus-4-8",
|
|
||||||
"claude-seulgivibe-mythos-5": "claude-fable-5",
|
"claude-seulgivibe-mythos-5": "claude-fable-5",
|
||||||
}
|
}
|
||||||
|
|
||||||
MODELS = [
|
MODELS = [
|
||||||
{
|
|
||||||
"id": "claude-seulgivibe-sonnet-4-5",
|
|
||||||
"type": "model",
|
|
||||||
"display_name": "Claude Sonnet 4.5 - coding agents",
|
|
||||||
"description": "Seulgivibe Claude Sonnet 4.5 for coding, complex agents, computer use, and long-horizon tasks.",
|
|
||||||
"created_at": "2026-05-13T00:00:00Z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "claude-seulgivibe-opus-4-8",
|
|
||||||
"type": "model",
|
|
||||||
"display_name": "Claude Opus 4.8 - browser agents",
|
|
||||||
"description": "Seulgivibe Claude Opus 4.8 for deeper agent work, browser and computer-use tasks, and long-session collaboration.",
|
|
||||||
"created_at": "2026-05-13T00:00:00Z",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "claude-seulgivibe-mythos-5",
|
"id": "claude-seulgivibe-mythos-5",
|
||||||
"type": "model",
|
"type": "model",
|
||||||
"display_name": "Claude Fable 5 - autonomous work",
|
"display_name": "Claude Fable 5",
|
||||||
"description": "Seulgivibe Claude Fable 5 for complex knowledge work, coding, multi-day autonomous tasks, staged planning, delegation, and self-verification.",
|
"description": "Official: next-generation model for complex knowledge work, coding, and sustained multi-day autonomous tasks.",
|
||||||
"created_at": "2026-05-13T00:00:00Z",
|
"created_at": "2026-05-13T00:00:00Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": CLAUDE_GEMMA_MODEL,
|
"id": CLAUDE_GEMMA_MODEL,
|
||||||
"type": "model",
|
"type": "model",
|
||||||
"display_name": "Gemma4 26B - gemma4:26b",
|
"display_name": "Gemma 4 26B A4B IT NVFP4",
|
||||||
"description": "dev-corp Gemma 4 26B A4B IT NVFP4 via MLX/OpenAI-compatible, tuned here for image-text and local code workflows.",
|
"description": "Model card: MLX Image-Text-to-Text Gemma 4 26B A4B IT NVFP4 model, served here as gemma4:26b.",
|
||||||
"created_at": "2026-07-10T00:00:00Z",
|
"created_at": "2026-07-10T00:00:00Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": CLAUDE_ORNITH_MODEL,
|
"id": CLAUDE_ORNITH_MODEL,
|
||||||
"type": "model",
|
"type": "model",
|
||||||
"display_name": "Ornith 35B - ornith35b",
|
"display_name": "Ornith 1.0 35B 8-bit",
|
||||||
"description": "dev-corp Ornith 1.0 35B 8-bit MLX open coding agent, routed to upstream ornith:35b.",
|
"description": "Model card: MLX 8-bit Ornith 1.0 35B from the open-source self-improving agentic coding family.",
|
||||||
"created_at": "2026-07-10T00:00:00Z",
|
"created_at": "2026-07-10T00:00:00Z",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
@ -222,6 +206,7 @@ def seulgivibe_path(raw_path):
|
||||||
|
|
||||||
def call_seulgivibe(method, raw_path, payload, inbound_headers):
|
def call_seulgivibe(method, raw_path, payload, inbound_headers):
|
||||||
outbound_payload = dict(payload)
|
outbound_payload = dict(payload)
|
||||||
|
outbound_payload.pop("context_management", None)
|
||||||
model = outbound_payload.get("model")
|
model = outbound_payload.get("model")
|
||||||
if model in SEULGIVIBE_ALIASES:
|
if model in SEULGIVIBE_ALIASES:
|
||||||
normalize_system_messages(outbound_payload)
|
normalize_system_messages(outbound_payload)
|
||||||
|
|
@ -265,10 +250,10 @@ def unwrap_json_string_body(body):
|
||||||
|
|
||||||
def anthropic_messages_to_openai(payload):
|
def anthropic_messages_to_openai(payload):
|
||||||
messages = []
|
messages = []
|
||||||
system_text = normalize_system(payload.get("system"))
|
system_parts = []
|
||||||
if system_text:
|
initial_system_text = normalize_system(payload.get("system"))
|
||||||
messages.append({"role": "system", "content": system_text})
|
if initial_system_text:
|
||||||
|
system_parts.append(initial_system_text)
|
||||||
tool_names = {}
|
tool_names = {}
|
||||||
for message in payload.get("messages") or []:
|
for message in payload.get("messages") or []:
|
||||||
if not is_record(message):
|
if not is_record(message):
|
||||||
|
|
@ -276,6 +261,12 @@ def anthropic_messages_to_openai(payload):
|
||||||
role = message.get("role")
|
role = message.get("role")
|
||||||
content = message.get("content")
|
content = message.get("content")
|
||||||
|
|
||||||
|
if role in ("system", "developer"):
|
||||||
|
text = content_to_text(content)
|
||||||
|
if text:
|
||||||
|
system_parts.append(text)
|
||||||
|
continue
|
||||||
|
|
||||||
if role == "assistant":
|
if role == "assistant":
|
||||||
text_parts = []
|
text_parts = []
|
||||||
tool_calls = []
|
tool_calls = []
|
||||||
|
|
@ -331,10 +322,8 @@ def anthropic_messages_to_openai(payload):
|
||||||
messages.append({"role": "user", "content": "\n".join(text_parts)})
|
messages.append({"role": "user", "content": "\n".join(text_parts)})
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if role in ("system", "developer"):
|
if system_parts:
|
||||||
text = content_to_text(content)
|
messages.insert(0, {"role": "system", "content": "\n\n".join(system_parts)})
|
||||||
if text:
|
|
||||||
messages.append({"role": "system", "content": text})
|
|
||||||
|
|
||||||
return messages
|
return messages
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue