feat: dynamic provider config — pos config ai auto-discovers provider keys
gates / consistency-and-conventions (push) Successful in 1m30s
gates / consistency-and-conventions (push) Successful in 1m30s
- lib/ai-providers/*.sh declare # PROVIDER_CONFIG: headers - lib/config-ui.sh: _cfg_provider_keys() scans providers at runtime - bin/pos-ai: POS_CONFIG uses *providers marker (no hardcoded keys) - Adding a new provider auto-populates config UI — no main tool edits needed
This commit is contained in:
@@ -633,7 +633,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
|
||||
| `bin/pos-system-health` | 209 | Host health dashboard (disk, RAM, services, backup age, fail2ban, docker); exit 1 if any FAIL |
|
||||
| `bin/pos-system-schedule` | 151 | Scheduled jobs: run a command on a timer; notify on threshold/change/error/always or silently |
|
||||
| `bin/pos-system-uninstall` | 415 | Remove pos toolkit binaries, services, shell integration, config, and data |
|
||||
| `bin/pos-ai` | 645 | AI assistant: ask, chat, sessions, capture, models, providers |
|
||||
| `bin/pos-ai` | 632 | AI assistant: ask, chat, sessions, capture, models, providers |
|
||||
| `bin/pos-config` | 80 | Interactive editor for the tools' runtime config (reads # POS_CONFIG: registry) |
|
||||
| `bin/pos-tree` | 112 | Show the pos CLI command tree: categories, commands, and subcommands |
|
||||
| `completions/pos.bash` | 306 | Dynamic bash completion |
|
||||
|
||||
+3
-5
@@ -3,7 +3,7 @@ set -euo pipefail
|
||||
# POS: ai ask — AI assistant: ask, chat, sessions, capture, models, providers
|
||||
# POS_SUBCMDS: ask chat sessions capture models providers
|
||||
# POS_FLAGS: --provider --model --session --system --full --last
|
||||
# POS_CONFIG: ai | ai.env | AI_PROVIDER=:Provider (gemini or openrouter, default gemini) | AI_GEMINI_API_KEY=secret:Gemini API key from aistudio.google.com | OPENROUTER_API_KEY=secret:OpenRouter API key from openrouter.ai | AI_MODEL=:Model id (default per provider) | AI_SYSTEM_PROMPT=:Custom system prompt (overrides built-in, empty to reset)
|
||||
# POS_CONFIG: ai | ai.env | AI_PROVIDER=:Provider (gemini or openrouter, default gemini) | *providers | AI_SYSTEM_PROMPT=:Custom system prompt (overrides built-in, empty to reset)
|
||||
|
||||
source "$(dirname "$0")/../lib/common.sh" 2>/dev/null || source "$(dirname "$0")/common.sh"
|
||||
|
||||
@@ -76,11 +76,9 @@ Options:
|
||||
|
||||
Config: $CONFIG_FILE (edit with 'pos config ai')
|
||||
AI_PROVIDER Provider to use (gemini|openrouter, default gemini)
|
||||
AI_GEMINI_API_KEY Gemini API key from aistudio.google.com
|
||||
OPENROUTER_API_KEY OpenRouter API key from openrouter.ai
|
||||
AI_MODEL Model id (default depends on provider)
|
||||
AI_SYSTEM_PROMPT Custom system prompt (overrides built-in; empty to reset)
|
||||
OPENROUTER_MODEL Legacy: OpenRouter model fallback
|
||||
Provider keys: auto-discovered from lib/ai-providers/*.sh
|
||||
(AI_GEMINI_API_KEY, OPENROUTER_API_KEY, etc.)
|
||||
|
||||
Notes:
|
||||
ask is terse by default: a built-in system instruction tells the model to
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
# Provider-specific: API call, auth, response parsing, models list
|
||||
# Part of the R8 provider-agnostic architecture (lib/ai-providers/).
|
||||
|
||||
# Provider-specific config variables (auto-discovered by pos config ai):
|
||||
# PROVIDER_CONFIG: AI_GEMINI_API_KEY=secret:Gemini API key from aistudio.google.com
|
||||
# PROVIDER_CONFIG: AI_GEMINI_MODEL=:Gemini model id (default: gemini-2.5-flash)
|
||||
|
||||
provider_name() { printf 'Google Gemini'; }
|
||||
provider_default_model() { printf 'gemini-2.5-flash'; }
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
# Provider-specific: API call, auth, response parsing, models list
|
||||
# Part of the R8 provider-agnostic architecture (lib/ai-providers/).
|
||||
|
||||
# Provider-specific config variables (auto-discovered by pos config ai):
|
||||
# PROVIDER_CONFIG: OPENROUTER_API_KEY=secret:OpenRouter API key from openrouter.ai
|
||||
# PROVIDER_CONFIG: OPENROUTER_MODEL=:OpenRouter model id (default: openrouter/auto)
|
||||
|
||||
provider_name() { printf 'OpenRouter'; }
|
||||
provider_default_model() { printf 'openrouter/auto'; }
|
||||
|
||||
|
||||
+29
-1
@@ -136,6 +136,33 @@ _cfg_plugin_keys() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# "*providers" expansion: keys declared by the installed AI provider
|
||||
# adapters' "# PROVIDER_CONFIG:" headers (lib/ai-providers/*.sh).
|
||||
_cfg_provider_keys() {
|
||||
local pdir line key desc flags
|
||||
# Find lib/ai-providers/ relative to config-ui.sh
|
||||
pdir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../lib/ai-providers" 2>/dev/null && pwd)"
|
||||
[ -d "$pdir" ] || return 0
|
||||
while IFS= read -r line; do
|
||||
[ -n "$line" ] || continue
|
||||
# Format: KEY=flags:description (same as POS_CONFIG key fields)
|
||||
key="${line%%=*}"
|
||||
[ -n "$key" ] || continue
|
||||
[ -n "${_cfg_seen[$key]:-}" ] && continue
|
||||
_cfg_seen[$key]=1
|
||||
# Parse flags and description from the rest
|
||||
local rest="${line#*=}" flags="" desc=""
|
||||
if [[ "$rest" == *":"* ]]; then
|
||||
flags="${rest%%:*}"
|
||||
desc="${rest#*:}"
|
||||
else
|
||||
flags="$rest"
|
||||
fi
|
||||
printf '%s|%s|%s|\n' "$key" "$flags" "$desc"
|
||||
done < <(grep '^# PROVIDER_CONFIG:' "$pdir"/*.sh 2>/dev/null | sed 's/^.*# PROVIDER_CONFIG:[[:space:]]*//' || true)
|
||||
return 0
|
||||
}
|
||||
|
||||
# Declared keys for a scope: "KEY|flags|description" lines, deduped.
|
||||
cfg_scope_keys() {
|
||||
local scope="$1" dir line s keystring field
|
||||
@@ -155,7 +182,8 @@ cfg_scope_keys() {
|
||||
if [ -n "$field" ]; then
|
||||
if [[ "$field" == "*"* ]]; then
|
||||
case "$field" in
|
||||
*plugins*) _cfg_plugin_keys ;;
|
||||
*plugins*) _cfg_plugin_keys ;;
|
||||
*providers*) _cfg_provider_keys ;;
|
||||
esac
|
||||
else
|
||||
_cfg_key_line "$field"
|
||||
|
||||
Reference in New Issue
Block a user