docs(03-tier-3-9-providers): create phase plan
This commit is contained in:
@@ -79,7 +79,17 @@ Plans:
|
|||||||
2. Chinese/regional provider keys (DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, etc.) are detected using keyword-based matching since they use generic key formats
|
2. Chinese/regional provider keys (DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, etc.) are detected using keyword-based matching since they use generic key formats
|
||||||
3. Self-hosted provider definitions (Ollama, vLLM, LocalAI, etc.) include patterns for API key authentication when applicable
|
3. Self-hosted provider definitions (Ollama, vLLM, LocalAI, etc.) include patterns for API key authentication when applicable
|
||||||
4. `keyhunter providers list --tier=enterprise` returns Salesforce, ServiceNow, SAP, Palantir, Databricks, Snowflake, Oracle, HPE providers
|
4. `keyhunter providers list --tier=enterprise` returns Salesforce, ServiceNow, SAP, Palantir, Databricks, Snowflake, Oracle, HPE providers
|
||||||
**Plans**: TBD
|
**Plans**: 8 plans
|
||||||
|
|
||||||
|
Plans:
|
||||||
|
- [ ] 03-01-PLAN.md — Tier 4 Chinese/regional providers (DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, 01.AI, MiniMax, Baichuan, StepFun, SenseTime, iFlytek, Tencent, SiliconFlow, 360 AI, Kuaishou)
|
||||||
|
- [ ] 03-02-PLAN.md — Tier 3 Specialized (Perplexity, You.com, Voyage, Jina, Unstructured, AssemblyAI, Deepgram, ElevenLabs, Stability, Runway, Midjourney)
|
||||||
|
- [ ] 03-03-PLAN.md — Tier 5 Infrastructure/Gateway (OpenRouter, LiteLLM, Cloudflare AI, Vercel AI, Portkey, Helicone, Martian, Kong, BricksAI, Aether, Not Diamond)
|
||||||
|
- [ ] 03-04-PLAN.md — Tier 7 Code/Dev Tools (GitHub Copilot, Cursor, Tabnine, Codeium, Sourcegraph, CodeWhisperer, Replit AI, Codestral, watsonx, Oracle AI)
|
||||||
|
- [ ] 03-05-PLAN.md — Tier 8 Self-Hosted runtimes (Ollama, vLLM, LocalAI, LM Studio, llama.cpp, GPT4All, text-gen-webui, TensorRT-LLM, Triton, Jan)
|
||||||
|
- [ ] 03-06-PLAN.md — Tier 9 Enterprise (Salesforce Einstein, ServiceNow, SAP AI Core, Palantir, Databricks, Snowflake, Oracle GenAI, HPE GreenLake)
|
||||||
|
- [ ] 03-07-PLAN.md — Tier 6 Emerging/Niche (Reka, Aleph Alpha, Lamini, Writer, Jasper, Typeface, Comet, W&B, LangSmith, Pinecone, Weaviate, Qdrant, Chroma, Milvus, Neon)
|
||||||
|
- [ ] 03-08-PLAN.md — Tier 3-9 guardrail test: lock 108 total providers, per-tier counts, and name sets
|
||||||
|
|
||||||
### Phase 4: Input Sources
|
### Phase 4: Input Sources
|
||||||
**Goal**: Users can point KeyHunter at any content source — local files, git history across all branches, piped content, remote URLs, and the clipboard — and all are scanned through the same detection pipeline
|
**Goal**: Users can point KeyHunter at any content source — local files, git history across all branches, piped content, remote URLs, and the clipboard — and all are scanned through the same detection pipeline
|
||||||
|
|||||||
544
.planning/phases/03-tier-3-9-providers/03-01-PLAN.md
Normal file
544
.planning/phases/03-tier-3-9-providers/03-01-PLAN.md
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/deepseek.yaml
|
||||||
|
- providers/zhipu.yaml
|
||||||
|
- providers/moonshot.yaml
|
||||||
|
- providers/qwen.yaml
|
||||||
|
- providers/baidu.yaml
|
||||||
|
- providers/bytedance.yaml
|
||||||
|
- providers/01ai.yaml
|
||||||
|
- providers/minimax.yaml
|
||||||
|
- providers/baichuan.yaml
|
||||||
|
- providers/stepfun.yaml
|
||||||
|
- providers/sensetime.yaml
|
||||||
|
- providers/iflytek.yaml
|
||||||
|
- providers/tencent.yaml
|
||||||
|
- providers/siliconflow.yaml
|
||||||
|
- providers/360ai.yaml
|
||||||
|
- providers/kuaishou.yaml
|
||||||
|
- pkg/providers/definitions/deepseek.yaml
|
||||||
|
- pkg/providers/definitions/zhipu.yaml
|
||||||
|
- pkg/providers/definitions/moonshot.yaml
|
||||||
|
- pkg/providers/definitions/qwen.yaml
|
||||||
|
- pkg/providers/definitions/baidu.yaml
|
||||||
|
- pkg/providers/definitions/bytedance.yaml
|
||||||
|
- pkg/providers/definitions/01ai.yaml
|
||||||
|
- pkg/providers/definitions/minimax.yaml
|
||||||
|
- pkg/providers/definitions/baichuan.yaml
|
||||||
|
- pkg/providers/definitions/stepfun.yaml
|
||||||
|
- pkg/providers/definitions/sensetime.yaml
|
||||||
|
- pkg/providers/definitions/iflytek.yaml
|
||||||
|
- pkg/providers/definitions/tencent.yaml
|
||||||
|
- pkg/providers/definitions/siliconflow.yaml
|
||||||
|
- pkg/providers/definitions/360ai.yaml
|
||||||
|
- pkg/providers/definitions/kuaishou.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-04]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "Registry loads 16 Tier 4 Chinese/regional provider YAMLs"
|
||||||
|
- "Providers without documented key formats use keyword-only detection (no patterns entry)"
|
||||||
|
- "DeepSeek uses documented sk- prefix pattern"
|
||||||
|
- "All YAMLs are dual-located and diff-clean"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/deepseek.yaml"
|
||||||
|
provides: "DeepSeek sk- prefix pattern + keywords"
|
||||||
|
contains: "deepseek"
|
||||||
|
- path: "providers/qwen.yaml"
|
||||||
|
provides: "Alibaba Qwen/DashScope keyword-only detection"
|
||||||
|
contains: "dashscope"
|
||||||
|
- path: "providers/baidu.yaml"
|
||||||
|
provides: "Baidu ERNIE/Wenxin keyword detection"
|
||||||
|
contains: "wenxin"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 16 Tier 4 Chinese/regional LLM provider YAML definitions. These providers mostly lack documented key formats, so detection relies on strong keyword lists anchored to their SDK envs, domains, and API hostnames — not on generic regex (which caused false positives in Phase 2).
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-04 (16 Tier 4 providers). Chinese/regional providers are high-value targets but low-signal for regex detection — keyword-only matching is the correct mitigation.
|
||||||
|
|
||||||
|
Output: 32 YAML files (16 providers × 2 locations).
|
||||||
|
|
||||||
|
Addresses PROV-04.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
@providers/mistral.yaml
|
||||||
|
@providers/cohere.yaml
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Provider schema (pkg/providers/schema.go): FormatVersion, Name, DisplayName, Tier, LastVerified, Keywords, Patterns, Verify. NO `category` field. Confidence values: high|medium|low.
|
||||||
|
|
||||||
|
Patterns array MAY be empty/omitted — registry allows keyword-only providers. Keywords list MUST have ≥3 entries (Aho-Corasick pre-filter requirement).
|
||||||
|
|
||||||
|
Files must be dual-located: providers/X.yaml AND pkg/providers/definitions/X.yaml (Go embed cannot use '..' paths).
|
||||||
|
|
||||||
|
Phase 2 lesson: generic regex like `[A-Za-z0-9]{32,64}` causes false positives. For providers without distinctive prefixes, OMIT the patterns field entirely (keyword-only detection).
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, 01.AI, MiniMax YAMLs</name>
|
||||||
|
<files>providers/deepseek.yaml, providers/zhipu.yaml, providers/moonshot.yaml, providers/qwen.yaml, providers/baidu.yaml, providers/bytedance.yaml, providers/01ai.yaml, providers/minimax.yaml, pkg/providers/definitions/deepseek.yaml, pkg/providers/definitions/zhipu.yaml, pkg/providers/definitions/moonshot.yaml, pkg/providers/definitions/qwen.yaml, pkg/providers/definitions/baidu.yaml, pkg/providers/definitions/bytedance.yaml, pkg/providers/definitions/01ai.yaml, pkg/providers/definitions/minimax.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
- providers/mistral.yaml (reference: keyword-anchored generic pattern)
|
||||||
|
- .planning/phases/03-tier-3-9-providers/03-CONTEXT.md (lessons from Phase 2)
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
Create each file in providers/ AND pkg/providers/definitions/ (verbatim copy). DeepSeek has a documented sk- prefix so it gets a pattern; all others are keyword-only (omit patterns entirely).
|
||||||
|
|
||||||
|
providers/deepseek.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: deepseek
|
||||||
|
display_name: DeepSeek
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "deepseek"
|
||||||
|
- "DEEPSEEK_API_KEY"
|
||||||
|
- "api.deepseek.com"
|
||||||
|
- "deepseek-chat"
|
||||||
|
- "deepseek-coder"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-[a-f0-9]{32}'
|
||||||
|
entropy_min: 3.5
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.deepseek.com/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/zhipu.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: zhipu
|
||||||
|
display_name: Zhipu AI (GLM)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "zhipu"
|
||||||
|
- "ZHIPU_API_KEY"
|
||||||
|
- "ZHIPUAI_API_KEY"
|
||||||
|
- "bigmodel.cn"
|
||||||
|
- "open.bigmodel.cn"
|
||||||
|
- "glm-4"
|
||||||
|
- "chatglm"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://open.bigmodel.cn/api/paas/v4/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/moonshot.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: moonshot
|
||||||
|
display_name: Moonshot AI (Kimi)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "moonshot"
|
||||||
|
- "MOONSHOT_API_KEY"
|
||||||
|
- "api.moonshot.cn"
|
||||||
|
- "kimi"
|
||||||
|
- "moonshot-v1"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-[A-Za-z0-9]{48}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.moonshot.cn/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/qwen.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: qwen
|
||||||
|
display_name: Alibaba Qwen (DashScope)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "dashscope"
|
||||||
|
- "DASHSCOPE_API_KEY"
|
||||||
|
- "qwen"
|
||||||
|
- "qwen-turbo"
|
||||||
|
- "qwen-max"
|
||||||
|
- "dashscope.aliyuncs.com"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-[a-f0-9]{32}'
|
||||||
|
entropy_min: 3.5
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/baidu.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: baidu
|
||||||
|
display_name: Baidu ERNIE (Wenxin)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "wenxin"
|
||||||
|
- "ernie"
|
||||||
|
- "BAIDU_API_KEY"
|
||||||
|
- "QIANFAN_AK"
|
||||||
|
- "QIANFAN_SK"
|
||||||
|
- "aip.baidubce.com"
|
||||||
|
- "qianfan"
|
||||||
|
verify:
|
||||||
|
method: POST
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/bytedance.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: bytedance
|
||||||
|
display_name: ByteDance Doubao (Volcengine)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "doubao"
|
||||||
|
- "volcengine"
|
||||||
|
- "VOLC_ACCESSKEY"
|
||||||
|
- "VOLC_SECRETKEY"
|
||||||
|
- "ARK_API_KEY"
|
||||||
|
- "ark.cn-beijing.volces.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/01ai.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: 01ai
|
||||||
|
display_name: 01.AI (Yi)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "01.ai"
|
||||||
|
- "yi-large"
|
||||||
|
- "yi-34b"
|
||||||
|
- "YI_API_KEY"
|
||||||
|
- "api.lingyiwanwu.com"
|
||||||
|
- "lingyiwanwu"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.lingyiwanwu.com/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/minimax.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: minimax
|
||||||
|
display_name: MiniMax
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "minimax"
|
||||||
|
- "MINIMAX_API_KEY"
|
||||||
|
- "MINIMAX_GROUP_ID"
|
||||||
|
- "api.minimax.chat"
|
||||||
|
- "abab6"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.minimax.chat/v1/text/chatcompletion_v2
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy each file VERBATIM to pkg/providers/definitions/ with the same basename.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in deepseek zhipu moonshot qwen baidu bytedance 01ai minimax; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 16 files exist (8 providers × 2 locations)
|
||||||
|
- `grep -q 'DEEPSEEK_API_KEY' providers/deepseek.yaml`
|
||||||
|
- `grep -q 'dashscope' providers/qwen.yaml`
|
||||||
|
- `grep -q 'wenxin' providers/baidu.yaml`
|
||||||
|
- `grep -q 'lingyiwanwu' providers/01ai.yaml`
|
||||||
|
- `grep -L 'patterns:' providers/zhipu.yaml providers/baidu.yaml providers/bytedance.yaml` returns all three (keyword-only, no patterns field)
|
||||||
|
- `diff providers/deepseek.yaml pkg/providers/definitions/deepseek.yaml` returns no diff
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes (no regression from new providers)
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>8 Chinese/regional providers dual-located, registry loads them, engine tests pass.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Baichuan, StepFun, SenseTime, iFlytek, Tencent, SiliconFlow, 360 AI, Kuaishou YAMLs</name>
|
||||||
|
<files>providers/baichuan.yaml, providers/stepfun.yaml, providers/sensetime.yaml, providers/iflytek.yaml, providers/tencent.yaml, providers/siliconflow.yaml, providers/360ai.yaml, providers/kuaishou.yaml, pkg/providers/definitions/baichuan.yaml, pkg/providers/definitions/stepfun.yaml, pkg/providers/definitions/sensetime.yaml, pkg/providers/definitions/iflytek.yaml, pkg/providers/definitions/tencent.yaml, pkg/providers/definitions/siliconflow.yaml, pkg/providers/definitions/360ai.yaml, pkg/providers/definitions/kuaishou.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
- providers/deepseek.yaml (created in Task 1, reference for format)
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
All 8 of these providers lack publicly documented key formats. Use KEYWORD-ONLY detection — omit the patterns field entirely.
|
||||||
|
|
||||||
|
providers/baichuan.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: baichuan
|
||||||
|
display_name: Baichuan AI
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "baichuan"
|
||||||
|
- "BAICHUAN_API_KEY"
|
||||||
|
- "api.baichuan-ai.com"
|
||||||
|
- "baichuan2"
|
||||||
|
- "baichuan-turbo"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.baichuan-ai.com/v1/chat/completions
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/stepfun.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: stepfun
|
||||||
|
display_name: StepFun (阶跃星辰)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "stepfun"
|
||||||
|
- "STEP_API_KEY"
|
||||||
|
- "STEPFUN_API_KEY"
|
||||||
|
- "api.stepfun.com"
|
||||||
|
- "step-1v"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.stepfun.com/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/sensetime.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: sensetime
|
||||||
|
display_name: SenseTime SenseNova
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "sensetime"
|
||||||
|
- "sensenova"
|
||||||
|
- "SENSETIME_API_KEY"
|
||||||
|
- "SENSENOVA_API_KEY"
|
||||||
|
- "api.sensenova.cn"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/iflytek.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: iflytek
|
||||||
|
display_name: iFlytek Spark (讯飞星火)
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "iflytek"
|
||||||
|
- "xf_yun"
|
||||||
|
- "spark_desk"
|
||||||
|
- "XFYUN_API_KEY"
|
||||||
|
- "XFYUN_API_SECRET"
|
||||||
|
- "XFYUN_APPID"
|
||||||
|
- "spark-api.xf-yun.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/tencent.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: tencent
|
||||||
|
display_name: Tencent Hunyuan
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "hunyuan"
|
||||||
|
- "TENCENTCLOUD_SECRET_ID"
|
||||||
|
- "TENCENTCLOUD_SECRET_KEY"
|
||||||
|
- "hunyuan.tencentcloudapi.com"
|
||||||
|
- "tencent-hunyuan"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/siliconflow.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: siliconflow
|
||||||
|
display_name: SiliconFlow
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "siliconflow"
|
||||||
|
- "SILICONFLOW_API_KEY"
|
||||||
|
- "api.siliconflow.cn"
|
||||||
|
- "siliconflow.cn"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-[a-z]{20,}'
|
||||||
|
entropy_min: 3.5
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.siliconflow.cn/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/360ai.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: 360ai
|
||||||
|
display_name: 360 AI Brain
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "360gpt"
|
||||||
|
- "QIHOO_API_KEY"
|
||||||
|
- "api.360.cn"
|
||||||
|
- "ai.360.com"
|
||||||
|
- "360-ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/kuaishou.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: kuaishou
|
||||||
|
display_name: Kuaishou KwaiYii
|
||||||
|
tier: 4
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "kuaishou"
|
||||||
|
- "kwaiyii"
|
||||||
|
- "KUAISHOU_API_KEY"
|
||||||
|
- "KWAI_API_KEY"
|
||||||
|
- "kwai-ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy each file VERBATIM to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in baichuan stepfun sensetime iflytek tencent siliconflow 360ai kuaishou; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 16 files exist (8 providers × 2 locations)
|
||||||
|
- `grep -q 'baichuan-ai.com' providers/baichuan.yaml`
|
||||||
|
- `grep -q 'hunyuan' providers/tencent.yaml`
|
||||||
|
- `grep -q 'spark_desk' providers/iflytek.yaml`
|
||||||
|
- 7 of 8 files have NO patterns field: `grep -L 'patterns:' providers/{baichuan,stepfun,sensetime,iflytek,tencent,360ai,kuaishou}.yaml` returns all 7
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes
|
||||||
|
- Total Tier 4 provider count = 16: `grep -l 'tier: 4' providers/*.yaml | wc -l` → 16
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 16 Tier 4 Chinese/regional providers exist dual-located. PROV-04 satisfied.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 4' providers/*.yaml | wc -l` returns 16.
|
||||||
|
`go test ./pkg/providers/... ./pkg/engine/... -count=1` passes.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 16 Tier 4 providers dual-located
|
||||||
|
- 13 use keyword-only detection (no patterns field)
|
||||||
|
- 3 use documented prefix patterns (deepseek, moonshot, qwen, siliconflow — note: 4 with patterns, adjust count)
|
||||||
|
- Registry loads all without validation errors
|
||||||
|
- No engine test regressions
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
418
.planning/phases/03-tier-3-9-providers/03-02-PLAN.md
Normal file
418
.planning/phases/03-tier-3-9-providers/03-02-PLAN.md
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 02
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/perplexity.yaml
|
||||||
|
- providers/you.yaml
|
||||||
|
- providers/voyage.yaml
|
||||||
|
- providers/jina.yaml
|
||||||
|
- providers/unstructured.yaml
|
||||||
|
- providers/assemblyai.yaml
|
||||||
|
- providers/deepgram.yaml
|
||||||
|
- providers/elevenlabs.yaml
|
||||||
|
- providers/stability.yaml
|
||||||
|
- providers/runway.yaml
|
||||||
|
- providers/midjourney.yaml
|
||||||
|
- pkg/providers/definitions/perplexity.yaml
|
||||||
|
- pkg/providers/definitions/you.yaml
|
||||||
|
- pkg/providers/definitions/voyage.yaml
|
||||||
|
- pkg/providers/definitions/jina.yaml
|
||||||
|
- pkg/providers/definitions/unstructured.yaml
|
||||||
|
- pkg/providers/definitions/assemblyai.yaml
|
||||||
|
- pkg/providers/definitions/deepgram.yaml
|
||||||
|
- pkg/providers/definitions/elevenlabs.yaml
|
||||||
|
- pkg/providers/definitions/stability.yaml
|
||||||
|
- pkg/providers/definitions/runway.yaml
|
||||||
|
- pkg/providers/definitions/midjourney.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-03]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "11 new Tier 3 Specialized provider YAMLs load (huggingface already exists → 12 total)"
|
||||||
|
- "Providers with documented prefixes (pplx-, xai-voyage, sk-, jina_) use tight regex"
|
||||||
|
- "Voice/image providers without documented prefixes use keyword-only"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/perplexity.yaml"
|
||||||
|
provides: "Perplexity pplx- prefix pattern"
|
||||||
|
contains: "pplx-"
|
||||||
|
- path: "providers/elevenlabs.yaml"
|
||||||
|
provides: "ElevenLabs API key keyword detection"
|
||||||
|
contains: "elevenlabs"
|
||||||
|
- path: "providers/assemblyai.yaml"
|
||||||
|
provides: "AssemblyAI keyword detection"
|
||||||
|
contains: "assemblyai"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 11 Tier 3 Specialized LLM/AI provider YAMLs — search (Perplexity, You.com), embeddings (Voyage, Jina, Unstructured), voice (AssemblyAI, Deepgram, ElevenLabs), and image/video (Stability, Runway, Midjourney). Huggingface is pre-existing from Phase 2 and must NOT be recreated. Total Tier 3 = 12 after this plan.
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-03 (12 Tier 3 Specialized providers).
|
||||||
|
|
||||||
|
Output: 22 YAML files (11 providers × 2 locations).
|
||||||
|
|
||||||
|
Addresses PROV-03.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
@providers/huggingface.yaml
|
||||||
|
@providers/cohere.yaml
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Schema: pkg/providers/schema.go. No `category` field. Confidence: high|medium|low.
|
||||||
|
Patterns field may be omitted for keyword-only providers. Keywords ≥3 required.
|
||||||
|
Dual-location required (providers/ + pkg/providers/definitions/).
|
||||||
|
RE2 regex only.
|
||||||
|
|
||||||
|
IMPORTANT: providers/huggingface.yaml ALREADY EXISTS (tier: 3). Do NOT modify or recreate it.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Search + embeddings providers (Perplexity, You.com, Voyage, Jina, Unstructured, AssemblyAI)</name>
|
||||||
|
<files>providers/perplexity.yaml, providers/you.yaml, providers/voyage.yaml, providers/jina.yaml, providers/unstructured.yaml, providers/assemblyai.yaml, pkg/providers/definitions/perplexity.yaml, pkg/providers/definitions/you.yaml, pkg/providers/definitions/voyage.yaml, pkg/providers/definitions/jina.yaml, pkg/providers/definitions/unstructured.yaml, pkg/providers/definitions/assemblyai.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
- providers/huggingface.yaml (existing tier 3 reference — DO NOT MODIFY)
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
Create each file in providers/ AND copy verbatim to pkg/providers/definitions/.
|
||||||
|
|
||||||
|
providers/perplexity.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: perplexity
|
||||||
|
display_name: Perplexity AI
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "perplexity"
|
||||||
|
- "PERPLEXITY_API_KEY"
|
||||||
|
- "pplx-"
|
||||||
|
- "api.perplexity.ai"
|
||||||
|
patterns:
|
||||||
|
- regex: 'pplx-[A-Za-z0-9]{48,}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: high
|
||||||
|
verify:
|
||||||
|
method: POST
|
||||||
|
url: https://api.perplexity.ai/chat/completions
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/you.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: you
|
||||||
|
display_name: You.com
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "you.com"
|
||||||
|
- "YDC_API_KEY"
|
||||||
|
- "YOU_API_KEY"
|
||||||
|
- "api.ydc-index.io"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.ydc-index.io/search
|
||||||
|
headers:
|
||||||
|
X-API-Key: "{KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/voyage.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: voyage
|
||||||
|
display_name: Voyage AI
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "voyage"
|
||||||
|
- "VOYAGE_API_KEY"
|
||||||
|
- "voyageai"
|
||||||
|
- "api.voyageai.com"
|
||||||
|
patterns:
|
||||||
|
- regex: 'pa-[A-Za-z0-9_\-]{40,}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: POST
|
||||||
|
url: https://api.voyageai.com/v1/embeddings
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/jina.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: jina
|
||||||
|
display_name: Jina AI
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "jina"
|
||||||
|
- "JINA_API_KEY"
|
||||||
|
- "api.jina.ai"
|
||||||
|
- "jinaai"
|
||||||
|
patterns:
|
||||||
|
- regex: 'jina_[A-Za-z0-9]{40,}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: high
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.jina.ai/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/unstructured.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: unstructured
|
||||||
|
display_name: Unstructured.io
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "unstructured"
|
||||||
|
- "UNSTRUCTURED_API_KEY"
|
||||||
|
- "api.unstructured.io"
|
||||||
|
- "unstructuredio"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.unstructured.io/general/v0/general
|
||||||
|
headers:
|
||||||
|
unstructured-api-key: "{KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/assemblyai.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: assemblyai
|
||||||
|
display_name: AssemblyAI
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "assemblyai"
|
||||||
|
- "ASSEMBLYAI_API_KEY"
|
||||||
|
- "api.assemblyai.com"
|
||||||
|
- "assembly.ai"
|
||||||
|
patterns:
|
||||||
|
- regex: '[a-f0-9]{32}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.assemblyai.com/v2/transcript
|
||||||
|
headers:
|
||||||
|
authorization: "{KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 6 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in perplexity you voyage jina unstructured assemblyai; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 12 files exist (6 providers × 2 locations)
|
||||||
|
- `grep -q 'pplx-' providers/perplexity.yaml`
|
||||||
|
- `grep -q 'jina_' providers/jina.yaml`
|
||||||
|
- `grep -q 'api.voyageai.com' providers/voyage.yaml`
|
||||||
|
- `diff providers/perplexity.yaml pkg/providers/definitions/perplexity.yaml` returns no diff
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>6 search/embeddings providers dual-located.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Voice + image/video providers (Deepgram, ElevenLabs, Stability, Runway, Midjourney)</name>
|
||||||
|
<files>providers/deepgram.yaml, providers/elevenlabs.yaml, providers/stability.yaml, providers/runway.yaml, providers/midjourney.yaml, pkg/providers/definitions/deepgram.yaml, pkg/providers/definitions/elevenlabs.yaml, pkg/providers/definitions/stability.yaml, pkg/providers/definitions/runway.yaml, pkg/providers/definitions/midjourney.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/deepgram.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: deepgram
|
||||||
|
display_name: Deepgram
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "deepgram"
|
||||||
|
- "DEEPGRAM_API_KEY"
|
||||||
|
- "api.deepgram.com"
|
||||||
|
- "dg-api"
|
||||||
|
patterns:
|
||||||
|
- regex: '[a-f0-9]{40}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.deepgram.com/v1/projects
|
||||||
|
headers:
|
||||||
|
Authorization: "Token {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/elevenlabs.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: elevenlabs
|
||||||
|
display_name: ElevenLabs
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "elevenlabs"
|
||||||
|
- "ELEVENLABS_API_KEY"
|
||||||
|
- "ELEVEN_API_KEY"
|
||||||
|
- "XI_API_KEY"
|
||||||
|
- "api.elevenlabs.io"
|
||||||
|
patterns:
|
||||||
|
- regex: '[a-f0-9]{32}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.elevenlabs.io/v1/user
|
||||||
|
headers:
|
||||||
|
xi-api-key: "{KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/stability.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: stability
|
||||||
|
display_name: Stability AI
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "stability"
|
||||||
|
- "STABILITY_API_KEY"
|
||||||
|
- "STABILITY_KEY"
|
||||||
|
- "api.stability.ai"
|
||||||
|
- "stable-diffusion"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-[A-Za-z0-9]{48}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.stability.ai/v1/user/account
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/runway.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: runway
|
||||||
|
display_name: Runway
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "runway"
|
||||||
|
- "runwayml"
|
||||||
|
- "RUNWAY_API_KEY"
|
||||||
|
- "RUNWAYML_API_SECRET"
|
||||||
|
- "api.runwayml.com"
|
||||||
|
- "dev.runwayml.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.dev.runwayml.com/v1/tasks
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/midjourney.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: midjourney
|
||||||
|
display_name: Midjourney
|
||||||
|
tier: 3
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "midjourney"
|
||||||
|
- "MIDJOURNEY_API_KEY"
|
||||||
|
- "MJ_API_KEY"
|
||||||
|
- "midjourney.com"
|
||||||
|
- "useapi.net"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 5 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in deepgram elevenlabs stability runway midjourney; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 10 files exist
|
||||||
|
- `grep -q 'XI_API_KEY' providers/elevenlabs.yaml`
|
||||||
|
- `grep -q 'stable-diffusion' providers/stability.yaml`
|
||||||
|
- `grep -q 'runwayml' providers/runway.yaml`
|
||||||
|
- `grep -L 'patterns:' providers/runway.yaml providers/midjourney.yaml` returns both (keyword-only)
|
||||||
|
- Total Tier 3 count: `grep -l 'tier: 3' providers/*.yaml | wc -l` → 12 (11 new + pre-existing huggingface)
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 11 new Tier 3 Specialized providers dual-located. PROV-03 satisfied (12 total with pre-existing huggingface).</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 3' providers/*.yaml | wc -l` returns 12.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 11 new Tier 3 providers added (huggingface pre-existing, total 12)
|
||||||
|
- All dual-located
|
||||||
|
- Documented prefixes use tight regex; undocumented use keyword-only
|
||||||
|
- No engine regression
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-02-SUMMARY.md`
|
||||||
|
</output>
|
||||||
393
.planning/phases/03-tier-3-9-providers/03-03-PLAN.md
Normal file
393
.planning/phases/03-tier-3-9-providers/03-03-PLAN.md
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 03
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/openrouter.yaml
|
||||||
|
- providers/litellm.yaml
|
||||||
|
- providers/cloudflare-ai.yaml
|
||||||
|
- providers/vercel-ai.yaml
|
||||||
|
- providers/portkey.yaml
|
||||||
|
- providers/helicone.yaml
|
||||||
|
- providers/martian.yaml
|
||||||
|
- providers/kong.yaml
|
||||||
|
- providers/bricksai.yaml
|
||||||
|
- providers/aether.yaml
|
||||||
|
- providers/notdiamond.yaml
|
||||||
|
- pkg/providers/definitions/openrouter.yaml
|
||||||
|
- pkg/providers/definitions/litellm.yaml
|
||||||
|
- pkg/providers/definitions/cloudflare-ai.yaml
|
||||||
|
- pkg/providers/definitions/vercel-ai.yaml
|
||||||
|
- pkg/providers/definitions/portkey.yaml
|
||||||
|
- pkg/providers/definitions/helicone.yaml
|
||||||
|
- pkg/providers/definitions/martian.yaml
|
||||||
|
- pkg/providers/definitions/kong.yaml
|
||||||
|
- pkg/providers/definitions/bricksai.yaml
|
||||||
|
- pkg/providers/definitions/aether.yaml
|
||||||
|
- pkg/providers/definitions/notdiamond.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-05]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "11 Tier 5 infrastructure/gateway provider YAMLs load"
|
||||||
|
- "OpenRouter sk-or- and Helicone sk-helicone- prefixes use high-confidence regex"
|
||||||
|
- "Gateway providers have strong keyword anchors to their SDK envs"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/openrouter.yaml"
|
||||||
|
provides: "OpenRouter sk-or- prefix pattern"
|
||||||
|
contains: "sk-or-"
|
||||||
|
- path: "providers/helicone.yaml"
|
||||||
|
provides: "Helicone sk-helicone- prefix pattern"
|
||||||
|
contains: "helicone"
|
||||||
|
- path: "providers/litellm.yaml"
|
||||||
|
provides: "LiteLLM proxy keyword detection"
|
||||||
|
contains: "litellm"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 11 Tier 5 Infrastructure/Gateway provider YAMLs — LLM routers, proxies, and observability gateways (OpenRouter, LiteLLM, Cloudflare AI, Vercel AI, Portkey, Helicone, Martian, Kong, BricksAI, Aether, Not Diamond).
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-05 (11 Tier 5 Infrastructure/Gateway providers). Several of these have documented key prefixes (sk-or-, sk-helicone-) that support high-confidence detection.
|
||||||
|
|
||||||
|
Output: 22 YAML files.
|
||||||
|
|
||||||
|
Addresses PROV-05.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
@providers/groq.yaml
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Schema per pkg/providers/schema.go. No category field. Dual-location required. RE2 regex only.
|
||||||
|
Keyword-only detection for providers without documented key formats.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: OpenRouter, LiteLLM, Cloudflare, Vercel, Portkey, Helicone YAMLs</name>
|
||||||
|
<files>providers/openrouter.yaml, providers/litellm.yaml, providers/cloudflare-ai.yaml, providers/vercel-ai.yaml, providers/portkey.yaml, providers/helicone.yaml, pkg/providers/definitions/openrouter.yaml, pkg/providers/definitions/litellm.yaml, pkg/providers/definitions/cloudflare-ai.yaml, pkg/providers/definitions/vercel-ai.yaml, pkg/providers/definitions/portkey.yaml, pkg/providers/definitions/helicone.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/openrouter.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: openrouter
|
||||||
|
display_name: OpenRouter
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "openrouter"
|
||||||
|
- "OPENROUTER_API_KEY"
|
||||||
|
- "openrouter.ai"
|
||||||
|
- "sk-or-"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-or-v1-[a-f0-9]{64}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: high
|
||||||
|
- regex: 'sk-or-[A-Za-z0-9]{40,}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://openrouter.ai/api/v1/auth/key
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/litellm.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: litellm
|
||||||
|
display_name: LiteLLM Proxy
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "litellm"
|
||||||
|
- "LITELLM_API_KEY"
|
||||||
|
- "LITELLM_MASTER_KEY"
|
||||||
|
- "LITELLM_PROXY_API_KEY"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-[A-Za-z0-9_\-]{20,}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/cloudflare-ai.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: cloudflare-ai
|
||||||
|
display_name: Cloudflare Workers AI
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "cloudflare"
|
||||||
|
- "workers-ai"
|
||||||
|
- "CLOUDFLARE_API_TOKEN"
|
||||||
|
- "CLOUDFLARE_ACCOUNT_ID"
|
||||||
|
- "CF_API_TOKEN"
|
||||||
|
- "api.cloudflare.com"
|
||||||
|
patterns:
|
||||||
|
- regex: '[A-Za-z0-9_\-]{40}'
|
||||||
|
entropy_min: 4.5
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.cloudflare.com/client/v4/user/tokens/verify
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/vercel-ai.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: vercel-ai
|
||||||
|
display_name: Vercel AI Gateway
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "vercel"
|
||||||
|
- "VERCEL_AI_GATEWAY"
|
||||||
|
- "AI_GATEWAY_API_KEY"
|
||||||
|
- "vercel.ai"
|
||||||
|
- "ai-sdk"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/portkey.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: portkey
|
||||||
|
display_name: Portkey
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "portkey"
|
||||||
|
- "PORTKEY_API_KEY"
|
||||||
|
- "api.portkey.ai"
|
||||||
|
- "portkey-ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.portkey.ai/v1/feedback
|
||||||
|
headers:
|
||||||
|
x-portkey-api-key: "{KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/helicone.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: helicone
|
||||||
|
display_name: Helicone
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "helicone"
|
||||||
|
- "HELICONE_API_KEY"
|
||||||
|
- "sk-helicone-"
|
||||||
|
- "api.helicone.ai"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sk-helicone-[a-z0-9]{7}-[a-z0-9]{7}-[a-z0-9]{7}-[a-z0-9]{7}'
|
||||||
|
entropy_min: 3.5
|
||||||
|
confidence: high
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.helicone.ai/v1/key/verify
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 6 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in openrouter litellm cloudflare-ai vercel-ai portkey helicone; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 12 files exist
|
||||||
|
- `grep -q 'sk-or-v1-' providers/openrouter.yaml`
|
||||||
|
- `grep -q 'sk-helicone-' providers/helicone.yaml`
|
||||||
|
- `grep -q 'LITELLM_MASTER_KEY' providers/litellm.yaml`
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>6 major gateway providers dual-located.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Martian, Kong, BricksAI, Aether, Not Diamond YAMLs</name>
|
||||||
|
<files>providers/martian.yaml, providers/kong.yaml, providers/bricksai.yaml, providers/aether.yaml, providers/notdiamond.yaml, pkg/providers/definitions/martian.yaml, pkg/providers/definitions/kong.yaml, pkg/providers/definitions/bricksai.yaml, pkg/providers/definitions/aether.yaml, pkg/providers/definitions/notdiamond.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
All 5 use keyword-only detection (no documented public key formats). Omit patterns field.
|
||||||
|
|
||||||
|
providers/martian.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: martian
|
||||||
|
display_name: Martian (Model Router)
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "withmartian"
|
||||||
|
- "MARTIAN_API_KEY"
|
||||||
|
- "withmartian.com"
|
||||||
|
- "martian-router"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/kong.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: kong
|
||||||
|
display_name: Kong AI Gateway
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "kong"
|
||||||
|
- "KONG_API_KEY"
|
||||||
|
- "kong-ai-gateway"
|
||||||
|
- "konghq.com"
|
||||||
|
- "ai-proxy"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/bricksai.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: bricksai
|
||||||
|
display_name: BricksAI
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "bricksai"
|
||||||
|
- "BRICKS_API_KEY"
|
||||||
|
- "trybricks.ai"
|
||||||
|
- "bricksllm"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/aether.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: aether
|
||||||
|
display_name: Aether AI
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "aether"
|
||||||
|
- "AETHER_API_KEY"
|
||||||
|
- "aether.ai"
|
||||||
|
- "aetherplatform"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/notdiamond.yaml:
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: notdiamond
|
||||||
|
display_name: Not Diamond
|
||||||
|
tier: 5
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "notdiamond"
|
||||||
|
- "NOTDIAMOND_API_KEY"
|
||||||
|
- "not-diamond"
|
||||||
|
- "notdiamond.ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 5 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in martian kong bricksai aether notdiamond; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1 && test "$(grep -l 'tier: 5' providers/*.yaml | wc -l)" = "11"</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 10 files exist
|
||||||
|
- `grep -q 'withmartian' providers/martian.yaml`
|
||||||
|
- `grep -q 'konghq.com' providers/kong.yaml`
|
||||||
|
- All 5 omit patterns field: `grep -L 'patterns:' providers/{martian,kong,bricksai,aether,notdiamond}.yaml` returns all 5
|
||||||
|
- Total Tier 5 count = 11: `grep -l 'tier: 5' providers/*.yaml | wc -l` → 11
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 11 Tier 5 gateway providers dual-located. PROV-05 satisfied.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 5' providers/*.yaml | wc -l` returns 11.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 11 Tier 5 gateway providers created
|
||||||
|
- Documented prefixes use tight high-confidence regex (openrouter, helicone)
|
||||||
|
- Undocumented providers use keyword-only detection
|
||||||
|
- No engine test regressions
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-03-SUMMARY.md`
|
||||||
|
</output>
|
||||||
382
.planning/phases/03-tier-3-9-providers/03-04-PLAN.md
Normal file
382
.planning/phases/03-tier-3-9-providers/03-04-PLAN.md
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 04
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/github-copilot.yaml
|
||||||
|
- providers/cursor.yaml
|
||||||
|
- providers/tabnine.yaml
|
||||||
|
- providers/codeium.yaml
|
||||||
|
- providers/sourcegraph.yaml
|
||||||
|
- providers/codewhisperer.yaml
|
||||||
|
- providers/replit-ai.yaml
|
||||||
|
- providers/codestral.yaml
|
||||||
|
- providers/watsonx.yaml
|
||||||
|
- providers/oracle-ai.yaml
|
||||||
|
- pkg/providers/definitions/github-copilot.yaml
|
||||||
|
- pkg/providers/definitions/cursor.yaml
|
||||||
|
- pkg/providers/definitions/tabnine.yaml
|
||||||
|
- pkg/providers/definitions/codeium.yaml
|
||||||
|
- pkg/providers/definitions/sourcegraph.yaml
|
||||||
|
- pkg/providers/definitions/codewhisperer.yaml
|
||||||
|
- pkg/providers/definitions/replit-ai.yaml
|
||||||
|
- pkg/providers/definitions/codestral.yaml
|
||||||
|
- pkg/providers/definitions/watsonx.yaml
|
||||||
|
- pkg/providers/definitions/oracle-ai.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-07]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "10 Tier 7 Code/Dev Tools provider YAMLs load"
|
||||||
|
- "Sourcegraph Cody uses documented sgp_ prefix pattern"
|
||||||
|
- "GitHub Copilot uses ghu_/gho_ token patterns"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/github-copilot.yaml"
|
||||||
|
provides: "GitHub Copilot token pattern"
|
||||||
|
contains: "copilot"
|
||||||
|
- path: "providers/sourcegraph.yaml"
|
||||||
|
provides: "Sourcegraph Cody sgp_ pattern"
|
||||||
|
contains: "sgp_"
|
||||||
|
- path: "providers/codestral.yaml"
|
||||||
|
provides: "Codestral (Mistral) keyword detection"
|
||||||
|
contains: "codestral"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 10 Tier 7 Code/Dev Tools provider YAMLs — AI coding assistants and IDE plugins (GitHub Copilot, Cursor, Tabnine, Codeium, Sourcegraph Cody, Amazon CodeWhisperer, Replit AI, Codestral, IBM watsonx, Oracle AI).
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-07 (10 Tier 7 Code/Dev Tools providers).
|
||||||
|
|
||||||
|
Output: 20 YAML files.
|
||||||
|
|
||||||
|
Addresses PROV-07.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Schema per pkg/providers/schema.go. Dual-location required. RE2 regex only.
|
||||||
|
GitHub Copilot uses standard GitHub token formats (ghu_, gho_) — keyword anchoring to "copilot" disambiguates from generic GitHub tokens.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: GitHub Copilot, Cursor, Tabnine, Codeium, Sourcegraph YAMLs</name>
|
||||||
|
<files>providers/github-copilot.yaml, providers/cursor.yaml, providers/tabnine.yaml, providers/codeium.yaml, providers/sourcegraph.yaml, pkg/providers/definitions/github-copilot.yaml, pkg/providers/definitions/cursor.yaml, pkg/providers/definitions/tabnine.yaml, pkg/providers/definitions/codeium.yaml, pkg/providers/definitions/sourcegraph.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/github-copilot.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: github-copilot
|
||||||
|
display_name: GitHub Copilot
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "copilot"
|
||||||
|
- "github-copilot"
|
||||||
|
- "GITHUB_COPILOT_TOKEN"
|
||||||
|
- "api.githubcopilot.com"
|
||||||
|
- "copilot-internal"
|
||||||
|
patterns:
|
||||||
|
- regex: 'ghu_[A-Za-z0-9]{36}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
- regex: 'gho_[A-Za-z0-9]{36}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.github.com/user
|
||||||
|
headers:
|
||||||
|
Authorization: "token {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/cursor.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: cursor
|
||||||
|
display_name: Cursor AI
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "cursor"
|
||||||
|
- "CURSOR_API_KEY"
|
||||||
|
- "cursor.sh"
|
||||||
|
- "cursor.com"
|
||||||
|
- "cursor-ide"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/tabnine.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: tabnine
|
||||||
|
display_name: Tabnine
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "tabnine"
|
||||||
|
- "TABNINE_API_KEY"
|
||||||
|
- "api.tabnine.com"
|
||||||
|
- "tabnine-pro"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/codeium.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: codeium
|
||||||
|
display_name: Codeium (Windsurf)
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "codeium"
|
||||||
|
- "windsurf"
|
||||||
|
- "CODEIUM_API_KEY"
|
||||||
|
- "WINDSURF_API_KEY"
|
||||||
|
- "codeium.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/sourcegraph.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: sourcegraph
|
||||||
|
display_name: Sourcegraph Cody
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "sourcegraph"
|
||||||
|
- "cody"
|
||||||
|
- "SRC_ACCESS_TOKEN"
|
||||||
|
- "SOURCEGRAPH_TOKEN"
|
||||||
|
- "sourcegraph.com"
|
||||||
|
- "sgp_"
|
||||||
|
patterns:
|
||||||
|
- regex: 'sgp_[A-Fa-f0-9]{16,}_[A-Fa-f0-9]{40}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: high
|
||||||
|
- regex: 'sgp_[A-Fa-f0-9]{40}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: medium
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://sourcegraph.com/.api/graphql
|
||||||
|
headers:
|
||||||
|
Authorization: "token {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 5 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in github-copilot cursor tabnine codeium sourcegraph; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 10 files exist
|
||||||
|
- `grep -q 'ghu_' providers/github-copilot.yaml`
|
||||||
|
- `grep -q 'sgp_' providers/sourcegraph.yaml`
|
||||||
|
- `grep -q 'windsurf' providers/codeium.yaml`
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>5 code assistant providers dual-located.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: CodeWhisperer, Replit AI, Codestral, watsonx, Oracle AI YAMLs</name>
|
||||||
|
<files>providers/codewhisperer.yaml, providers/replit-ai.yaml, providers/codestral.yaml, providers/watsonx.yaml, providers/oracle-ai.yaml, pkg/providers/definitions/codewhisperer.yaml, pkg/providers/definitions/replit-ai.yaml, pkg/providers/definitions/codestral.yaml, pkg/providers/definitions/watsonx.yaml, pkg/providers/definitions/oracle-ai.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/codewhisperer.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: codewhisperer
|
||||||
|
display_name: Amazon CodeWhisperer / Q Developer
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "codewhisperer"
|
||||||
|
- "q-developer"
|
||||||
|
- "amazonq"
|
||||||
|
- "codewhisperer.us-east-1.amazonaws.com"
|
||||||
|
- "CODEWHISPERER_PROFILE_ARN"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/replit-ai.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: replit-ai
|
||||||
|
display_name: Replit AI (Ghostwriter)
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "replit"
|
||||||
|
- "ghostwriter"
|
||||||
|
- "REPLIT_TOKEN"
|
||||||
|
- "REPLIT_DB_URL"
|
||||||
|
- "replit.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/codestral.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: codestral
|
||||||
|
display_name: Codestral (Mistral Code)
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "codestral"
|
||||||
|
- "CODESTRAL_API_KEY"
|
||||||
|
- "codestral.mistral.ai"
|
||||||
|
- "codestral-latest"
|
||||||
|
patterns:
|
||||||
|
- regex: '[a-zA-Z0-9]{32}'
|
||||||
|
entropy_min: 4.5
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://codestral.mistral.ai/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/watsonx.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: watsonx
|
||||||
|
display_name: IBM watsonx
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "watsonx"
|
||||||
|
- "WATSONX_API_KEY"
|
||||||
|
- "WATSONX_PROJECT_ID"
|
||||||
|
- "IBM_CLOUD_API_KEY"
|
||||||
|
- "us-south.ml.cloud.ibm.com"
|
||||||
|
- "watsonx.ai"
|
||||||
|
verify:
|
||||||
|
method: POST
|
||||||
|
url: https://iam.cloud.ibm.com/identity/token
|
||||||
|
headers: {}
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [400, 401]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/oracle-ai.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: oracle-ai
|
||||||
|
display_name: Oracle Generative AI
|
||||||
|
tier: 7
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "oci-genai"
|
||||||
|
- "oracle-genai"
|
||||||
|
- "OCI_GENAI"
|
||||||
|
- "generativeai.oci.oraclecloud.com"
|
||||||
|
- "oraclecloud.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 5 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in codewhisperer replit-ai codestral watsonx oracle-ai; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1 && test $(grep -l 'tier: 7' providers/*.yaml | wc -l) -eq 10</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 10 files exist
|
||||||
|
- `grep -q 'codewhisperer' providers/codewhisperer.yaml`
|
||||||
|
- `grep -q 'watsonx.ai' providers/watsonx.yaml`
|
||||||
|
- `grep -q 'oraclecloud' providers/oracle-ai.yaml`
|
||||||
|
- Total Tier 7 count = 10
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 10 Tier 7 code/dev tools providers dual-located. PROV-07 satisfied.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 7' providers/*.yaml | wc -l` returns 10.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 10 Tier 7 code/dev tools providers created
|
||||||
|
- Sourcegraph uses documented sgp_ high-confidence pattern
|
||||||
|
- Undocumented providers (cursor, tabnine, codeium, codewhisperer, replit-ai, oracle-ai) use keyword-only
|
||||||
|
- No engine regression
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-04-SUMMARY.md`
|
||||||
|
</output>
|
||||||
364
.planning/phases/03-tier-3-9-providers/03-05-PLAN.md
Normal file
364
.planning/phases/03-tier-3-9-providers/03-05-PLAN.md
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 05
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/ollama.yaml
|
||||||
|
- providers/vllm.yaml
|
||||||
|
- providers/localai.yaml
|
||||||
|
- providers/lmstudio.yaml
|
||||||
|
- providers/llamacpp.yaml
|
||||||
|
- providers/gpt4all.yaml
|
||||||
|
- providers/text-gen-webui.yaml
|
||||||
|
- providers/tensorrt-llm.yaml
|
||||||
|
- providers/triton.yaml
|
||||||
|
- providers/jan.yaml
|
||||||
|
- pkg/providers/definitions/ollama.yaml
|
||||||
|
- pkg/providers/definitions/vllm.yaml
|
||||||
|
- pkg/providers/definitions/localai.yaml
|
||||||
|
- pkg/providers/definitions/lmstudio.yaml
|
||||||
|
- pkg/providers/definitions/llamacpp.yaml
|
||||||
|
- pkg/providers/definitions/gpt4all.yaml
|
||||||
|
- pkg/providers/definitions/text-gen-webui.yaml
|
||||||
|
- pkg/providers/definitions/tensorrt-llm.yaml
|
||||||
|
- pkg/providers/definitions/triton.yaml
|
||||||
|
- pkg/providers/definitions/jan.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-08]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "10 Tier 8 Self-Hosted runtime provider YAMLs load"
|
||||||
|
- "Self-hosted runtimes mostly use keyword-only detection (local auth, not API keys)"
|
||||||
|
- "Runtimes exposing API key auth (vLLM --api-key, LocalAI) include env var keywords"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/ollama.yaml"
|
||||||
|
provides: "Ollama localhost endpoint keywords"
|
||||||
|
contains: "ollama"
|
||||||
|
- path: "providers/vllm.yaml"
|
||||||
|
provides: "vLLM --api-key detection keywords"
|
||||||
|
contains: "vllm"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 10 Tier 8 Self-Hosted LLM runtime provider YAMLs — local inference servers (Ollama, vLLM, LocalAI, LM Studio, llama.cpp, GPT4All, text-generation-webui, TensorRT-LLM, Triton, Jan AI).
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-08 (10 Tier 8 Self-Hosted providers). Self-hosted runtimes are interesting for OSINT (exposed endpoints via Shodan) even without API keys — keyword anchors enable later recon phases to correlate.
|
||||||
|
|
||||||
|
Output: 20 YAML files.
|
||||||
|
|
||||||
|
Addresses PROV-08.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Self-hosted runtimes rarely use bearer tokens. Detection relies on config env vars, localhost endpoints (11434, 8000, 1234), CLI flags. All use keyword-only — omit patterns entirely.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Ollama, vLLM, LocalAI, LM Studio, llama.cpp YAMLs</name>
|
||||||
|
<files>providers/ollama.yaml, providers/vllm.yaml, providers/localai.yaml, providers/lmstudio.yaml, providers/llamacpp.yaml, pkg/providers/definitions/ollama.yaml, pkg/providers/definitions/vllm.yaml, pkg/providers/definitions/localai.yaml, pkg/providers/definitions/lmstudio.yaml, pkg/providers/definitions/llamacpp.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
All 5 use keyword-only detection — omit patterns field.
|
||||||
|
|
||||||
|
providers/ollama.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: ollama
|
||||||
|
display_name: Ollama
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "ollama"
|
||||||
|
- "OLLAMA_HOST"
|
||||||
|
- "OLLAMA_API_KEY"
|
||||||
|
- "OLLAMA_MODELS"
|
||||||
|
- "localhost:11434"
|
||||||
|
- "127.0.0.1:11434"
|
||||||
|
- "api/generate"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/vllm.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: vllm
|
||||||
|
display_name: vLLM
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "vllm"
|
||||||
|
- "VLLM_API_KEY"
|
||||||
|
- "vllm-openai"
|
||||||
|
- "--api-key"
|
||||||
|
- "openai.api_server"
|
||||||
|
- "vllm.entrypoints"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/localai.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: localai
|
||||||
|
display_name: LocalAI
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "localai"
|
||||||
|
- "LOCALAI_API_KEY"
|
||||||
|
- "go-skynet"
|
||||||
|
- "localai.io"
|
||||||
|
- "localhost:8080"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/lmstudio.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: lmstudio
|
||||||
|
display_name: LM Studio
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "lmstudio"
|
||||||
|
- "lm-studio"
|
||||||
|
- "LMSTUDIO_API_KEY"
|
||||||
|
- "localhost:1234"
|
||||||
|
- "lmstudio.ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/llamacpp.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: llamacpp
|
||||||
|
display_name: llama.cpp server
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "llama.cpp"
|
||||||
|
- "llama-cpp"
|
||||||
|
- "llama_cpp"
|
||||||
|
- "LLAMA_API_KEY"
|
||||||
|
- "ggml"
|
||||||
|
- "gguf"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 5 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in ollama vllm localai lmstudio llamacpp; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 10 files exist
|
||||||
|
- `grep -q 'localhost:11434' providers/ollama.yaml`
|
||||||
|
- `grep -q 'vllm.entrypoints' providers/vllm.yaml`
|
||||||
|
- `grep -q 'gguf' providers/llamacpp.yaml`
|
||||||
|
- All 5 omit patterns field: `grep -L 'patterns:' providers/{ollama,vllm,localai,lmstudio,llamacpp}.yaml` returns all 5
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>5 self-hosted runtimes dual-located, keyword-only.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: GPT4All, text-gen-webui, TensorRT-LLM, Triton, Jan AI YAMLs</name>
|
||||||
|
<files>providers/gpt4all.yaml, providers/text-gen-webui.yaml, providers/tensorrt-llm.yaml, providers/triton.yaml, providers/jan.yaml, pkg/providers/definitions/gpt4all.yaml, pkg/providers/definitions/text-gen-webui.yaml, pkg/providers/definitions/tensorrt-llm.yaml, pkg/providers/definitions/triton.yaml, pkg/providers/definitions/jan.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
All keyword-only (no patterns field).
|
||||||
|
|
||||||
|
providers/gpt4all.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: gpt4all
|
||||||
|
display_name: GPT4All
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "gpt4all"
|
||||||
|
- "nomic-ai"
|
||||||
|
- "GPT4ALL_API_KEY"
|
||||||
|
- "gpt4all.io"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/text-gen-webui.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: text-gen-webui
|
||||||
|
display_name: text-generation-webui (oobabooga)
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "text-generation-webui"
|
||||||
|
- "oobabooga"
|
||||||
|
- "TEXTGEN_API_KEY"
|
||||||
|
- "text-gen-webui"
|
||||||
|
- "localhost:5000"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/tensorrt-llm.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: tensorrt-llm
|
||||||
|
display_name: NVIDIA TensorRT-LLM
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "tensorrt-llm"
|
||||||
|
- "trtllm"
|
||||||
|
- "TRTLLM_API_KEY"
|
||||||
|
- "tensorrt_llm"
|
||||||
|
- "nvidia-nim"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/triton.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: triton
|
||||||
|
display_name: NVIDIA Triton Inference Server
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "triton-inference-server"
|
||||||
|
- "tritonserver"
|
||||||
|
- "TRITON_API_KEY"
|
||||||
|
- "triton_grpc"
|
||||||
|
- "v2/models"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/jan.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: jan
|
||||||
|
display_name: Jan AI
|
||||||
|
tier: 8
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "jan-ai"
|
||||||
|
- "janhq"
|
||||||
|
- "JAN_API_KEY"
|
||||||
|
- "jan.ai"
|
||||||
|
- "cortex-cpp"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 5 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in gpt4all text-gen-webui tensorrt-llm triton jan; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1 && test $(grep -l 'tier: 8' providers/*.yaml | wc -l) -eq 10</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 10 files exist
|
||||||
|
- `grep -q 'oobabooga' providers/text-gen-webui.yaml`
|
||||||
|
- `grep -q 'tritonserver' providers/triton.yaml`
|
||||||
|
- `grep -q 'janhq' providers/jan.yaml`
|
||||||
|
- Total Tier 8 count = 10
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 10 Tier 8 self-hosted runtimes dual-located. PROV-08 satisfied.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 8' providers/*.yaml | wc -l` returns 10.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 10 Tier 8 self-hosted runtimes created
|
||||||
|
- All keyword-only (no regex patterns — avoids false positives)
|
||||||
|
- Localhost endpoints and env vars captured as keywords
|
||||||
|
- No engine regression
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-05-SUMMARY.md`
|
||||||
|
</output>
|
||||||
331
.planning/phases/03-tier-3-9-providers/03-06-PLAN.md
Normal file
331
.planning/phases/03-tier-3-9-providers/03-06-PLAN.md
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 06
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/salesforce-einstein.yaml
|
||||||
|
- providers/servicenow.yaml
|
||||||
|
- providers/sap-ai-core.yaml
|
||||||
|
- providers/palantir.yaml
|
||||||
|
- providers/databricks.yaml
|
||||||
|
- providers/snowflake.yaml
|
||||||
|
- providers/oracle-genai.yaml
|
||||||
|
- providers/hpe-greenlake.yaml
|
||||||
|
- pkg/providers/definitions/salesforce-einstein.yaml
|
||||||
|
- pkg/providers/definitions/servicenow.yaml
|
||||||
|
- pkg/providers/definitions/sap-ai-core.yaml
|
||||||
|
- pkg/providers/definitions/palantir.yaml
|
||||||
|
- pkg/providers/definitions/databricks.yaml
|
||||||
|
- pkg/providers/definitions/snowflake.yaml
|
||||||
|
- pkg/providers/definitions/oracle-genai.yaml
|
||||||
|
- pkg/providers/definitions/hpe-greenlake.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-09]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "8 Tier 9 Enterprise provider YAMLs load"
|
||||||
|
- "Databricks dapi-prefix and Snowflake JWT keywords captured"
|
||||||
|
- "All enterprise providers have strong env var keyword anchors"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/databricks.yaml"
|
||||||
|
provides: "Databricks dapi token pattern"
|
||||||
|
contains: "dapi"
|
||||||
|
- path: "providers/snowflake.yaml"
|
||||||
|
provides: "Snowflake Cortex keyword detection"
|
||||||
|
contains: "snowflake"
|
||||||
|
- path: "providers/palantir.yaml"
|
||||||
|
provides: "Palantir AIP keyword detection"
|
||||||
|
contains: "palantir"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 8 Tier 9 Enterprise AI platform provider YAMLs — enterprise SaaS AI (Salesforce Einstein, ServiceNow Now Assist, SAP Joule, Palantir AIP, Databricks, Snowflake Cortex, Oracle GenAI, HPE GreenLake).
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-09 (8 Tier 9 Enterprise providers). These target regulated enterprise estates where leaked keys carry high blast radius.
|
||||||
|
|
||||||
|
Output: 16 YAML files.
|
||||||
|
|
||||||
|
Addresses PROV-09.
|
||||||
|
|
||||||
|
Note: `oracle-genai` here is distinct from `oracle-ai` in plan 03-04 (which is Tier 7 code tools). Tier 9 entry uses name `oracle-genai` to avoid collision.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Dual-location required. Keyword-only for most; databricks has a documented `dapi` prefix.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Salesforce, ServiceNow, SAP, Palantir YAMLs</name>
|
||||||
|
<files>providers/salesforce-einstein.yaml, providers/servicenow.yaml, providers/sap-ai-core.yaml, providers/palantir.yaml, pkg/providers/definitions/salesforce-einstein.yaml, pkg/providers/definitions/servicenow.yaml, pkg/providers/definitions/sap-ai-core.yaml, pkg/providers/definitions/palantir.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
All 4 use keyword-only detection (no public key formats documented).
|
||||||
|
|
||||||
|
providers/salesforce-einstein.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: salesforce-einstein
|
||||||
|
display_name: Salesforce Einstein GPT
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "einstein-gpt"
|
||||||
|
- "einsteinGPT"
|
||||||
|
- "SALESFORCE_CONSUMER_KEY"
|
||||||
|
- "SALESFORCE_CONSUMER_SECRET"
|
||||||
|
- "api.salesforce.com"
|
||||||
|
- "einstein.ai"
|
||||||
|
- "salesforce-einstein"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/servicenow.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: servicenow
|
||||||
|
display_name: ServiceNow Now Assist
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "servicenow"
|
||||||
|
- "now-assist"
|
||||||
|
- "SERVICENOW_INSTANCE"
|
||||||
|
- "SERVICENOW_USERNAME"
|
||||||
|
- "SERVICENOW_PASSWORD"
|
||||||
|
- "service-now.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/sap-ai-core.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: sap-ai-core
|
||||||
|
display_name: SAP AI Core / Joule
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "sap-ai-core"
|
||||||
|
- "sap-joule"
|
||||||
|
- "SAP_AICORE_CLIENT_ID"
|
||||||
|
- "SAP_AICORE_CLIENT_SECRET"
|
||||||
|
- "SAP_AICORE_AUTH_URL"
|
||||||
|
- "hana.ondemand.com"
|
||||||
|
- "aicore"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/palantir.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: palantir
|
||||||
|
display_name: Palantir AIP
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "palantir"
|
||||||
|
- "foundry"
|
||||||
|
- "PALANTIR_TOKEN"
|
||||||
|
- "FOUNDRY_TOKEN"
|
||||||
|
- "palantirfoundry.com"
|
||||||
|
- "aip-agents"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 4 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in salesforce-einstein servicenow sap-ai-core palantir; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 8 files exist
|
||||||
|
- `grep -q 'einsteinGPT' providers/salesforce-einstein.yaml`
|
||||||
|
- `grep -q 'foundry' providers/palantir.yaml`
|
||||||
|
- `grep -q 'SAP_AICORE_CLIENT_ID' providers/sap-ai-core.yaml`
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>4 enterprise platform providers dual-located.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Databricks, Snowflake, Oracle GenAI, HPE GreenLake YAMLs</name>
|
||||||
|
<files>providers/databricks.yaml, providers/snowflake.yaml, providers/oracle-genai.yaml, providers/hpe-greenlake.yaml, pkg/providers/definitions/databricks.yaml, pkg/providers/definitions/snowflake.yaml, pkg/providers/definitions/oracle-genai.yaml, pkg/providers/definitions/hpe-greenlake.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/databricks.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: databricks
|
||||||
|
display_name: Databricks (DBRX / Mosaic)
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "databricks"
|
||||||
|
- "DATABRICKS_TOKEN"
|
||||||
|
- "DATABRICKS_HOST"
|
||||||
|
- "dbrx"
|
||||||
|
- "mosaicml"
|
||||||
|
- "dapi"
|
||||||
|
- ".cloud.databricks.com"
|
||||||
|
patterns:
|
||||||
|
- regex: 'dapi[a-f0-9]{32}(-[0-9]{1,2})?'
|
||||||
|
entropy_min: 3.5
|
||||||
|
confidence: high
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/snowflake.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: snowflake
|
||||||
|
display_name: Snowflake Cortex
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "snowflake"
|
||||||
|
- "SNOWFLAKE_ACCOUNT"
|
||||||
|
- "SNOWFLAKE_USER"
|
||||||
|
- "SNOWFLAKE_PASSWORD"
|
||||||
|
- "SNOWFLAKE_PRIVATE_KEY"
|
||||||
|
- "snowflakecomputing.com"
|
||||||
|
- "cortex"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/oracle-genai.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: oracle-genai
|
||||||
|
display_name: Oracle Cloud Generative AI Service
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "oci-generative-ai"
|
||||||
|
- "OCI_GENAI_COMPARTMENT"
|
||||||
|
- "oracle-cloud-genai"
|
||||||
|
- "inference.generativeai.us-chicago-1"
|
||||||
|
- "oci-cli"
|
||||||
|
- "OCI_CONFIG_FILE"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/hpe-greenlake.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: hpe-greenlake
|
||||||
|
display_name: HPE GreenLake for LLMs
|
||||||
|
tier: 9
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "hpe-greenlake"
|
||||||
|
- "greenlake"
|
||||||
|
- "HPE_CLIENT_ID"
|
||||||
|
- "HPE_CLIENT_SECRET"
|
||||||
|
- "common.cloud.hpe.com"
|
||||||
|
- "hpe-ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 4 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in databricks snowflake oracle-genai hpe-greenlake; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1 && test $(grep -l 'tier: 9' providers/*.yaml | wc -l) -eq 8</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 8 files exist
|
||||||
|
- `grep -q 'dapi' providers/databricks.yaml`
|
||||||
|
- `grep -q 'snowflakecomputing.com' providers/snowflake.yaml`
|
||||||
|
- `grep -q 'greenlake' providers/hpe-greenlake.yaml`
|
||||||
|
- Total Tier 9 count = 8
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 8 Tier 9 enterprise providers dual-located. PROV-09 satisfied.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 9' providers/*.yaml | wc -l` returns 8.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 8 Tier 9 enterprise providers created
|
||||||
|
- Databricks uses documented `dapi` high-confidence pattern
|
||||||
|
- Strong env var keyword anchors on all
|
||||||
|
- No engine regression
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-06-SUMMARY.md`
|
||||||
|
</output>
|
||||||
504
.planning/phases/03-tier-3-9-providers/03-07-PLAN.md
Normal file
504
.planning/phases/03-tier-3-9-providers/03-07-PLAN.md
Normal file
@@ -0,0 +1,504 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 07
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- providers/reka.yaml
|
||||||
|
- providers/aleph-alpha.yaml
|
||||||
|
- providers/writer.yaml
|
||||||
|
- providers/jasper.yaml
|
||||||
|
- providers/typeface.yaml
|
||||||
|
- providers/comet.yaml
|
||||||
|
- providers/wandb.yaml
|
||||||
|
- providers/langsmith.yaml
|
||||||
|
- providers/pinecone.yaml
|
||||||
|
- providers/weaviate.yaml
|
||||||
|
- providers/qdrant.yaml
|
||||||
|
- providers/chroma.yaml
|
||||||
|
- providers/milvus.yaml
|
||||||
|
- providers/neon.yaml
|
||||||
|
- providers/lamini.yaml
|
||||||
|
- pkg/providers/definitions/reka.yaml
|
||||||
|
- pkg/providers/definitions/aleph-alpha.yaml
|
||||||
|
- pkg/providers/definitions/writer.yaml
|
||||||
|
- pkg/providers/definitions/jasper.yaml
|
||||||
|
- pkg/providers/definitions/typeface.yaml
|
||||||
|
- pkg/providers/definitions/comet.yaml
|
||||||
|
- pkg/providers/definitions/wandb.yaml
|
||||||
|
- pkg/providers/definitions/langsmith.yaml
|
||||||
|
- pkg/providers/definitions/pinecone.yaml
|
||||||
|
- pkg/providers/definitions/weaviate.yaml
|
||||||
|
- pkg/providers/definitions/qdrant.yaml
|
||||||
|
- pkg/providers/definitions/chroma.yaml
|
||||||
|
- pkg/providers/definitions/milvus.yaml
|
||||||
|
- pkg/providers/definitions/neon.yaml
|
||||||
|
- pkg/providers/definitions/lamini.yaml
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-06]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "15 Tier 6 Emerging/Niche provider YAMLs load"
|
||||||
|
- "W&B uses documented 40-hex key; LangSmith uses lsv2_ prefix; Pinecone uses pcsk_ prefix"
|
||||||
|
- "Vector DBs and writing tools have strong env var keyword anchors"
|
||||||
|
artifacts:
|
||||||
|
- path: "providers/langsmith.yaml"
|
||||||
|
provides: "LangSmith lsv2_ prefix pattern"
|
||||||
|
contains: "lsv2_"
|
||||||
|
- path: "providers/pinecone.yaml"
|
||||||
|
provides: "Pinecone pcsk_ prefix pattern"
|
||||||
|
contains: "pcsk_"
|
||||||
|
- path: "providers/wandb.yaml"
|
||||||
|
provides: "Weights & Biases 40-hex key pattern"
|
||||||
|
contains: "WANDB_API_KEY"
|
||||||
|
key_links:
|
||||||
|
- from: "provider keywords[]"
|
||||||
|
to: "Registry Aho-Corasick automaton"
|
||||||
|
via: "NewRegistry()"
|
||||||
|
pattern: "keywords"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create 15 Tier 6 Emerging/Niche provider YAMLs — emerging LLM labs (Reka, Aleph Alpha, Lamini), writing tools (Writer, Jasper, Typeface), observability (Comet, W&B, LangSmith), and vector DBs (Pinecone, Weaviate, Qdrant, Chroma, Milvus, Neon).
|
||||||
|
|
||||||
|
Purpose: Satisfy PROV-06 (15 Tier 6 Emerging/Niche providers).
|
||||||
|
|
||||||
|
Output: 30 YAML files.
|
||||||
|
|
||||||
|
Addresses PROV-06.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Dual-location required. Several providers in this group have documented prefixes (LangSmith lsv2_, Pinecone pcsk_, W&B 40-hex). Others use keyword-only.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Emerging labs + writing tools (Reka, Aleph Alpha, Lamini, Writer, Jasper, Typeface, Comet, W&B)</name>
|
||||||
|
<files>providers/reka.yaml, providers/aleph-alpha.yaml, providers/lamini.yaml, providers/writer.yaml, providers/jasper.yaml, providers/typeface.yaml, providers/comet.yaml, providers/wandb.yaml, pkg/providers/definitions/reka.yaml, pkg/providers/definitions/aleph-alpha.yaml, pkg/providers/definitions/lamini.yaml, pkg/providers/definitions/writer.yaml, pkg/providers/definitions/jasper.yaml, pkg/providers/definitions/typeface.yaml, pkg/providers/definitions/comet.yaml, pkg/providers/definitions/wandb.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/reka.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: reka
|
||||||
|
display_name: Reka AI
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "reka"
|
||||||
|
- "REKA_API_KEY"
|
||||||
|
- "api.reka.ai"
|
||||||
|
- "reka-core"
|
||||||
|
- "reka-flash"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.reka.ai/v1/models
|
||||||
|
headers:
|
||||||
|
X-Api-Key: "{KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/aleph-alpha.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: aleph-alpha
|
||||||
|
display_name: Aleph Alpha
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "aleph-alpha"
|
||||||
|
- "aleph_alpha"
|
||||||
|
- "ALEPH_ALPHA_API_KEY"
|
||||||
|
- "AA_TOKEN"
|
||||||
|
- "api.aleph-alpha.com"
|
||||||
|
- "luminous"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.aleph-alpha.com/models_available
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/lamini.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: lamini
|
||||||
|
display_name: Lamini
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "lamini"
|
||||||
|
- "LAMINI_API_KEY"
|
||||||
|
- "api.lamini.ai"
|
||||||
|
- "lamini.ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.lamini.ai/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/writer.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: writer
|
||||||
|
display_name: Writer
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "writer.com"
|
||||||
|
- "WRITER_API_KEY"
|
||||||
|
- "api.writer.com"
|
||||||
|
- "palmyra"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.writer.com/v1/models
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/jasper.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: jasper
|
||||||
|
display_name: Jasper AI
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "jasper.ai"
|
||||||
|
- "JASPER_API_KEY"
|
||||||
|
- "api.jasper.ai"
|
||||||
|
- "jasper-ai"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/typeface.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: typeface
|
||||||
|
display_name: Typeface
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "typeface"
|
||||||
|
- "typeface.ai"
|
||||||
|
- "TYPEFACE_API_KEY"
|
||||||
|
- "typeface-app"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/comet.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: comet
|
||||||
|
display_name: Comet ML / Opik
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "comet_ml"
|
||||||
|
- "comet-ml"
|
||||||
|
- "COMET_API_KEY"
|
||||||
|
- "COMET_WORKSPACE"
|
||||||
|
- "opik"
|
||||||
|
- "comet.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://www.comet.com/api/rest/v2/workspaces
|
||||||
|
headers:
|
||||||
|
Authorization: "{KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/wandb.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: wandb
|
||||||
|
display_name: Weights & Biases
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "wandb"
|
||||||
|
- "weights_and_biases"
|
||||||
|
- "WANDB_API_KEY"
|
||||||
|
- "api.wandb.ai"
|
||||||
|
- "wandb.ai"
|
||||||
|
patterns:
|
||||||
|
- regex: '[a-f0-9]{40}'
|
||||||
|
entropy_min: 3.5
|
||||||
|
confidence: low
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.wandb.ai/graphql
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic {KEY}"
|
||||||
|
valid_status: [200, 400]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 8 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in reka aleph-alpha lamini writer jasper typeface comet wandb; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 16 files exist
|
||||||
|
- `grep -q 'luminous' providers/aleph-alpha.yaml`
|
||||||
|
- `grep -q 'palmyra' providers/writer.yaml`
|
||||||
|
- `grep -q 'WANDB_API_KEY' providers/wandb.yaml`
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>8 emerging/writing/observability providers dual-located.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: LangSmith + vector DBs (LangSmith, Pinecone, Weaviate, Qdrant, Chroma, Milvus, Neon)</name>
|
||||||
|
<files>providers/langsmith.yaml, providers/pinecone.yaml, providers/weaviate.yaml, providers/qdrant.yaml, providers/chroma.yaml, providers/milvus.yaml, providers/neon.yaml, pkg/providers/definitions/langsmith.yaml, pkg/providers/definitions/pinecone.yaml, pkg/providers/definitions/weaviate.yaml, pkg/providers/definitions/qdrant.yaml, pkg/providers/definitions/chroma.yaml, pkg/providers/definitions/milvus.yaml, pkg/providers/definitions/neon.yaml</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/schema.go
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
providers/langsmith.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: langsmith
|
||||||
|
display_name: LangSmith (LangChain)
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "langsmith"
|
||||||
|
- "langchain"
|
||||||
|
- "LANGCHAIN_API_KEY"
|
||||||
|
- "LANGSMITH_API_KEY"
|
||||||
|
- "LANGCHAIN_TRACING_V2"
|
||||||
|
- "api.smith.langchain.com"
|
||||||
|
- "lsv2_"
|
||||||
|
patterns:
|
||||||
|
- regex: 'lsv2_(pt|sk)_[a-f0-9]{32}_[a-f0-9]{10}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: high
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.smith.langchain.com/info
|
||||||
|
headers:
|
||||||
|
X-API-Key: "{KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/pinecone.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: pinecone
|
||||||
|
display_name: Pinecone
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "pinecone"
|
||||||
|
- "PINECONE_API_KEY"
|
||||||
|
- "PINECONE_ENVIRONMENT"
|
||||||
|
- "api.pinecone.io"
|
||||||
|
- "pinecone.io"
|
||||||
|
- "pcsk_"
|
||||||
|
patterns:
|
||||||
|
- regex: 'pcsk_[A-Za-z0-9]{40,}'
|
||||||
|
entropy_min: 4.0
|
||||||
|
confidence: high
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://api.pinecone.io/indexes
|
||||||
|
headers:
|
||||||
|
Api-Key: "{KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/weaviate.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: weaviate
|
||||||
|
display_name: Weaviate
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "weaviate"
|
||||||
|
- "WEAVIATE_API_KEY"
|
||||||
|
- "WEAVIATE_URL"
|
||||||
|
- "weaviate.io"
|
||||||
|
- "wcs.api"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/qdrant.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: qdrant
|
||||||
|
display_name: Qdrant
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "qdrant"
|
||||||
|
- "QDRANT_API_KEY"
|
||||||
|
- "QDRANT_URL"
|
||||||
|
- "qdrant.tech"
|
||||||
|
- "cloud.qdrant.io"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/chroma.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: chroma
|
||||||
|
display_name: Chroma
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "chromadb"
|
||||||
|
- "chroma-client"
|
||||||
|
- "CHROMA_API_KEY"
|
||||||
|
- "CHROMA_HOST"
|
||||||
|
- "trychroma.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/milvus.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: milvus
|
||||||
|
display_name: Milvus / Zilliz
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "milvus"
|
||||||
|
- "zilliz"
|
||||||
|
- "ZILLIZ_API_KEY"
|
||||||
|
- "MILVUS_TOKEN"
|
||||||
|
- "zilliz.com"
|
||||||
|
- "api.cloud.zilliz.com"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: ""
|
||||||
|
headers: {}
|
||||||
|
valid_status: []
|
||||||
|
invalid_status: []
|
||||||
|
```
|
||||||
|
|
||||||
|
providers/neon.yaml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format_version: 1
|
||||||
|
name: neon
|
||||||
|
display_name: Neon (Serverless Postgres + pgvector)
|
||||||
|
tier: 6
|
||||||
|
last_verified: "2026-04-05"
|
||||||
|
keywords:
|
||||||
|
- "neon-db"
|
||||||
|
- "neondb"
|
||||||
|
- "NEON_API_KEY"
|
||||||
|
- "NEON_CONNECTION_STRING"
|
||||||
|
- "console.neon.tech"
|
||||||
|
- "pg.neon.tech"
|
||||||
|
verify:
|
||||||
|
method: GET
|
||||||
|
url: https://console.neon.tech/api/v2/projects
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {KEY}"
|
||||||
|
valid_status: [200]
|
||||||
|
invalid_status: [401, 403]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all 7 files verbatim to pkg/providers/definitions/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && for f in langsmith pinecone weaviate qdrant chroma milvus neon; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1 && test $(grep -l 'tier: 6' providers/*.yaml | wc -l) -eq 15</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- All 14 files exist
|
||||||
|
- `grep -q 'lsv2_' providers/langsmith.yaml`
|
||||||
|
- `grep -q 'pcsk_' providers/pinecone.yaml`
|
||||||
|
- `grep -q 'zilliz' providers/milvus.yaml`
|
||||||
|
- Total Tier 6 count = 15
|
||||||
|
- `go test ./pkg/providers/... -count=1` passes
|
||||||
|
- `go test ./pkg/engine/... -count=1` passes
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>All 15 Tier 6 emerging/niche providers dual-located. PROV-06 satisfied.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`grep -l 'tier: 6' providers/*.yaml | wc -l` returns 15.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- 15 Tier 6 providers created
|
||||||
|
- LangSmith lsv2_ and Pinecone pcsk_ use high-confidence regex
|
||||||
|
- Vector DB env vars captured
|
||||||
|
- No engine regression
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-07-SUMMARY.md`
|
||||||
|
</output>
|
||||||
284
.planning/phases/03-tier-3-9-providers/03-08-PLAN.md
Normal file
284
.planning/phases/03-tier-3-9-providers/03-08-PLAN.md
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
---
|
||||||
|
phase: 03-tier-3-9-providers
|
||||||
|
plan: 08
|
||||||
|
type: execute
|
||||||
|
wave: 2
|
||||||
|
depends_on: ["03-01", "03-02", "03-03", "03-04", "03-05", "03-06", "03-07"]
|
||||||
|
files_modified:
|
||||||
|
- pkg/providers/tier39_test.go
|
||||||
|
autonomous: true
|
||||||
|
requirements: [PROV-03, PROV-04, PROV-05, PROV-06, PROV-07, PROV-08, PROV-09]
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "Registry loads 108 total providers (26 Tier 1-2 + 82 Tier 3-9)"
|
||||||
|
- "Per-tier counts enforced: T3=12, T4=16, T5=11, T6=15, T7=10, T8=10, T9=8"
|
||||||
|
- "All 82 Tier 3-9 provider names are known (lock set against drift)"
|
||||||
|
- "All regex patterns compile under RE2"
|
||||||
|
- "Every provider has ≥1 keyword (Aho-Corasick pre-filter requirement)"
|
||||||
|
- "Phase 2 Tier 1-2 guardrails still pass (no regression)"
|
||||||
|
artifacts:
|
||||||
|
- path: "pkg/providers/tier39_test.go"
|
||||||
|
provides: "Tier 3-9 guardrail tests"
|
||||||
|
contains: "TestTier39"
|
||||||
|
key_links:
|
||||||
|
- from: "pkg/providers/tier39_test.go"
|
||||||
|
to: "registry.NewRegistry() Stats() Get() All()"
|
||||||
|
via: "go test ./pkg/providers/..."
|
||||||
|
pattern: "NewRegistry"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create the Tier 3-9 guardrail test file `pkg/providers/tier39_test.go` that locks in exact provider counts, names, regex compilation, and keyword presence across all 82 new Tier 3-9 providers. Replicates the `tier12_test.go` pattern and serves as the regression net for all future phases.
|
||||||
|
|
||||||
|
Purpose: Satisfy all 7 Phase 3 requirements (PROV-03..PROV-09) with a single enforceable test. Any future change that drops a provider, renames one, or introduces a non-compiling regex will break this test in CI.
|
||||||
|
|
||||||
|
Output: 1 test file with 10+ test functions. Total registry provider count locked at 108.
|
||||||
|
|
||||||
|
Addresses PROV-03, PROV-04, PROV-05, PROV-06, PROV-07, PROV-08, PROV-09.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
|
||||||
|
@pkg/providers/tier12_test.go
|
||||||
|
@pkg/providers/schema.go
|
||||||
|
|
||||||
|
<interfaces>
|
||||||
|
Replicate the `tier12_test.go` pattern exactly. Registry API: `NewRegistry()`, `Stats()`, `Get(name)`, `List()`.
|
||||||
|
|
||||||
|
Expected provider name sets (must match plans 03-01..03-07 exactly):
|
||||||
|
- Tier 3 (12): perplexity, you, voyage, jina, unstructured, assemblyai, deepgram, elevenlabs, stability, runway, midjourney, huggingface
|
||||||
|
- Tier 4 (16): deepseek, zhipu, moonshot, qwen, baidu, bytedance, 01ai, minimax, baichuan, stepfun, sensetime, iflytek, tencent, siliconflow, 360ai, kuaishou
|
||||||
|
- Tier 5 (11): openrouter, litellm, cloudflare-ai, vercel-ai, portkey, helicone, martian, kong, bricksai, aether, notdiamond
|
||||||
|
- Tier 6 (15): reka, aleph-alpha, lamini, writer, jasper, typeface, comet, wandb, langsmith, pinecone, weaviate, qdrant, chroma, milvus, neon
|
||||||
|
- Tier 7 (10): github-copilot, cursor, tabnine, codeium, sourcegraph, codewhisperer, replit-ai, codestral, watsonx, oracle-ai
|
||||||
|
- Tier 8 (10): ollama, vllm, localai, lmstudio, llamacpp, gpt4all, text-gen-webui, tensorrt-llm, triton, jan
|
||||||
|
- Tier 9 (8): salesforce-einstein, servicenow, sap-ai-core, palantir, databricks, snowflake, oracle-genai, hpe-greenlake
|
||||||
|
|
||||||
|
Total Tier 3-9: 82. Combined with Tier 1-2 (26): 108 total.
|
||||||
|
</interfaces>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Create tier39_test.go guardrail test file</name>
|
||||||
|
<files>pkg/providers/tier39_test.go</files>
|
||||||
|
<read_first>
|
||||||
|
- pkg/providers/tier12_test.go (pattern to replicate)
|
||||||
|
- pkg/providers/schema.go (Registry API)
|
||||||
|
</read_first>
|
||||||
|
<action>
|
||||||
|
Create `pkg/providers/tier39_test.go` with the following contents. The expected name slices MUST match the names in each plan's files exactly.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package providers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// expectedTier3 lists all 12 Tier 3 Specialized provider names (PROV-03).
|
||||||
|
var expectedTier3 = []string{
|
||||||
|
"perplexity", "you", "voyage", "jina", "unstructured", "assemblyai",
|
||||||
|
"deepgram", "elevenlabs", "stability", "runway", "midjourney", "huggingface",
|
||||||
|
}
|
||||||
|
|
||||||
|
// expectedTier4 lists all 16 Tier 4 Chinese/Regional provider names (PROV-04).
|
||||||
|
var expectedTier4 = []string{
|
||||||
|
"deepseek", "zhipu", "moonshot", "qwen", "baidu", "bytedance",
|
||||||
|
"01ai", "minimax", "baichuan", "stepfun", "sensetime", "iflytek",
|
||||||
|
"tencent", "siliconflow", "360ai", "kuaishou",
|
||||||
|
}
|
||||||
|
|
||||||
|
// expectedTier5 lists all 11 Tier 5 Infrastructure/Gateway provider names (PROV-05).
|
||||||
|
var expectedTier5 = []string{
|
||||||
|
"openrouter", "litellm", "cloudflare-ai", "vercel-ai", "portkey",
|
||||||
|
"helicone", "martian", "kong", "bricksai", "aether", "notdiamond",
|
||||||
|
}
|
||||||
|
|
||||||
|
// expectedTier6 lists all 15 Tier 6 Emerging/Niche provider names (PROV-06).
|
||||||
|
var expectedTier6 = []string{
|
||||||
|
"reka", "aleph-alpha", "lamini", "writer", "jasper", "typeface",
|
||||||
|
"comet", "wandb", "langsmith", "pinecone", "weaviate", "qdrant",
|
||||||
|
"chroma", "milvus", "neon",
|
||||||
|
}
|
||||||
|
|
||||||
|
// expectedTier7 lists all 10 Tier 7 Code/Dev Tools provider names (PROV-07).
|
||||||
|
var expectedTier7 = []string{
|
||||||
|
"github-copilot", "cursor", "tabnine", "codeium", "sourcegraph",
|
||||||
|
"codewhisperer", "replit-ai", "codestral", "watsonx", "oracle-ai",
|
||||||
|
}
|
||||||
|
|
||||||
|
// expectedTier8 lists all 10 Tier 8 Self-Hosted provider names (PROV-08).
|
||||||
|
var expectedTier8 = []string{
|
||||||
|
"ollama", "vllm", "localai", "lmstudio", "llamacpp",
|
||||||
|
"gpt4all", "text-gen-webui", "tensorrt-llm", "triton", "jan",
|
||||||
|
}
|
||||||
|
|
||||||
|
// expectedTier9 lists all 8 Tier 9 Enterprise provider names (PROV-09).
|
||||||
|
var expectedTier9 = []string{
|
||||||
|
"salesforce-einstein", "servicenow", "sap-ai-core", "palantir",
|
||||||
|
"databricks", "snowflake", "oracle-genai", "hpe-greenlake",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier3Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[3]; got != 12 {
|
||||||
|
t.Errorf("Tier 3 count = %d, want 12", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier4Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[4]; got != 16 {
|
||||||
|
t.Errorf("Tier 4 count = %d, want 16", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier5Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[5]; got != 11 {
|
||||||
|
t.Errorf("Tier 5 count = %d, want 11", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier6Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[6]; got != 15 {
|
||||||
|
t.Errorf("Tier 6 count = %d, want 15", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier7Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[7]; got != 10 {
|
||||||
|
t.Errorf("Tier 7 count = %d, want 10", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier8Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[8]; got != 10 {
|
||||||
|
t.Errorf("Tier 8 count = %d, want 10", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier9Count(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().ByTier[9]; got != 8 {
|
||||||
|
t.Errorf("Tier 9 count = %d, want 8", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTotalProviderCount(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
if got := reg.Stats().Total; got != 108 {
|
||||||
|
t.Errorf("Total provider count = %d, want 108", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTier39ProviderNames(t *testing.T) {
|
||||||
|
reg, err := NewRegistry()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewRegistry failed: %v", err)
|
||||||
|
}
|
||||||
|
checks := []struct {
|
||||||
|
tier int
|
||||||
|
names []string
|
||||||
|
}{
|
||||||
|
{3, expectedTier3},
|
||||||
|
{4, expectedTier4},
|
||||||
|
{5, expectedTier5},
|
||||||
|
{6, expectedTier6},
|
||||||
|
{7, expectedTier7},
|
||||||
|
{8, expectedTier8},
|
||||||
|
{9, expectedTier9},
|
||||||
|
}
|
||||||
|
for _, c := range checks {
|
||||||
|
for _, name := range c.names {
|
||||||
|
p, ok := reg.Get(name)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("Tier %d provider %q not found in registry", c.tier, name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if p.Tier != c.tier {
|
||||||
|
t.Errorf("provider %q tier = %d, want %d", name, p.Tier, c.tier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Do NOT add package-level imports for `regexp` — `TestAllPatternsCompile` and `TestAllProvidersHaveKeywords` already exist in `tier12_test.go` and will exercise every provider (including Tier 3-9) once the registry loads them.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
<automated>cd /home/salva/Documents/apikey && go test ./pkg/providers/... -count=1 -v -run 'TestTier[3-9]|TestTotalProviderCount|TestTier39ProviderNames|TestAllPatternsCompile|TestAllProvidersHaveKeywords' && go test ./... -count=1</automated>
|
||||||
|
</verify>
|
||||||
|
<acceptance_criteria>
|
||||||
|
- `pkg/providers/tier39_test.go` exists
|
||||||
|
- `grep -c "^func Test" pkg/providers/tier39_test.go` returns ≥ 9
|
||||||
|
- `go test ./pkg/providers/... -run TestTotalProviderCount -v` passes with Total == 108
|
||||||
|
- `go test ./pkg/providers/... -run TestTier3Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier4Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier5Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier6Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier7Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier8Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier9Count -v` passes
|
||||||
|
- `go test ./pkg/providers/... -run TestTier39ProviderNames -v` passes (all 82 names resolve)
|
||||||
|
- `go test ./pkg/providers/... -run TestAllPatternsCompile -v` passes (inherited from tier12_test.go — all Tier 3-9 regexes compile under RE2)
|
||||||
|
- `go test ./pkg/providers/... -run TestAllProvidersHaveKeywords -v` passes (every provider ≥1 keyword)
|
||||||
|
- Phase 2 guardrails still pass: `go test ./pkg/providers/... -run 'TestTier1|TestTier2'` green
|
||||||
|
- Full repo regression: `go test ./... -count=1` green (engine, storage, providers)
|
||||||
|
</acceptance_criteria>
|
||||||
|
<done>Tier 3-9 guardrail test file exists, 9+ test functions pass, total provider count locked at 108, all 82 Tier 3-9 provider names verified, no regression in Phase 1/2 tests.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
`go test ./... -count=1` passes. `go run . providers stats` shows Total 108, with Tier 1: 12, Tier 2: 14, Tier 3: 12, Tier 4: 16, Tier 5: 11, Tier 6: 15, Tier 7: 10, Tier 8: 10, Tier 9: 8.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- tier39_test.go created with ≥9 test functions
|
||||||
|
- Total provider count locked at 108
|
||||||
|
- All 82 Tier 3-9 provider names locked against drift
|
||||||
|
- All regex patterns compile under RE2 (via existing TestAllPatternsCompile)
|
||||||
|
- Every provider has ≥1 keyword (via existing TestAllProvidersHaveKeywords)
|
||||||
|
- Full repo `go test ./...` green
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/03-tier-3-9-providers/03-08-SUMMARY.md`
|
||||||
|
</output>
|
||||||
Reference in New Issue
Block a user