Skip to content

Commit 9a4668a

Browse files
committed
com
1 parent 842368d commit 9a4668a

File tree

140 files changed

+118884
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+118884
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
name: Model PR Adjustments
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
issues: read
11+
12+
env:
13+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
14+
15+
jobs:
16+
adjust:
17+
if: |
18+
github.event.issue.pull_request &&
19+
contains(github.event.issue.labels.*.name, 'models') &&
20+
startsWith(github.event.comment.body, '/models ')
21+
runs-on: depot-ubuntu-24.04-16
22+
timeout-minutes: 10
23+
steps:
24+
- name: Get PR branch
25+
id: pr
26+
run: |
27+
PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }})
28+
echo "ref=$(echo "$PR_DATA" | jq -r '.head.ref')" >> "$GITHUB_OUTPUT"
29+
echo "sha=$(echo "$PR_DATA" | jq -r '.head.sha')" >> "$GITHUB_OUTPUT"
30+
env:
31+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- uses: actions/checkout@v4
34+
with:
35+
ref: ${{ steps.pr.outputs.ref }}
36+
fetch-depth: 0
37+
38+
- name: Install Claude Code
39+
run: npm install -g @anthropic-ai/claude-code
40+
41+
- name: Parse instruction
42+
id: instruction
43+
run: |
44+
COMMENT=$(cat <<'COMMENT_EOF'
45+
${{ github.event.comment.body }}
46+
COMMENT_EOF
47+
)
48+
# Strip the /models prefix
49+
INSTRUCTION="${COMMENT#/models }"
50+
echo "instruction<<EOF" >> "$GITHUB_OUTPUT"
51+
echo "$INSTRUCTION" >> "$GITHUB_OUTPUT"
52+
echo "EOF" >> "$GITHUB_OUTPUT"
53+
54+
- name: React to comment
55+
run: |
56+
gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
57+
-f content=eyes
58+
env:
59+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
61+
- name: Apply adjustment
62+
id: adjust
63+
run: |
64+
PROMPT="$(cat <<'PROMPT_EOF'
65+
You are making a targeted adjustment to AI model configuration files for the Botpress cognitive service.
66+
67+
## Context
68+
69+
Provider config files live in: packages/cognitive/src/features/providers/{provider}/{provider}.config.ts
70+
The schema is in: packages/cognitive/src/features/model-selection/schemas.models.ts
71+
72+
Providers: openai, anthropic, google-ai, groq, cerebras, xai, openrouter, fireworks-ai
73+
74+
## Rules
75+
76+
- ONLY modify files matching packages/cognitive/src/features/providers/*/*.config.ts
77+
- Follow the exact existing TypeScript patterns (numeric separators, field order, etc.)
78+
- Do NOT remove the mock provider config
79+
- When removing a model, actually remove it from the array — do not just mark it deprecated (unless the instruction says to deprecate it)
80+
- When updating pricing, only change the cost fields
81+
- When adding a model, place it in the correct position (newest first) and include ALL required fields
82+
83+
## Instruction from reviewer
84+
85+
INSTRUCTION_PLACEHOLDER
86+
87+
## Output
88+
89+
After applying changes, write a SHORT summary (2-3 lines) of what you changed to /tmp/adjustment-summary.txt
90+
PROMPT_EOF
91+
)"
92+
93+
PROMPT="${PROMPT//INSTRUCTION_PLACEHOLDER/${{ steps.instruction.outputs.instruction }}}"
94+
95+
claude --print \
96+
--model claude-sonnet-4-6 \
97+
--max-turns 15 \
98+
--allowedTools "Read,Edit,Glob,Grep" \
99+
"$PROMPT" | tee /tmp/claude-output.txt
100+
101+
if git diff --quiet; then
102+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
103+
else
104+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
105+
fi
106+
107+
- name: Commit and push
108+
if: steps.adjust.outputs.has_changes == 'true'
109+
run: |
110+
git config user.name "github-actions[bot]"
111+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
112+
git add packages/cognitive/src/features/providers/
113+
SUMMARY="apply model adjustment"
114+
if [ -f /tmp/adjustment-summary.txt ]; then
115+
SUMMARY=$(head -1 /tmp/adjustment-summary.txt)
116+
fi
117+
git commit -m "chore(cognitive): $SUMMARY"
118+
git push
119+
120+
- name: Reply to comment
121+
if: always()
122+
run: |
123+
if [ "${{ steps.adjust.outputs.has_changes }}" = "true" ]; then
124+
BODY="Applied the adjustment and pushed a new commit."
125+
if [ -f /tmp/adjustment-summary.txt ]; then
126+
SUMMARY=$(cat /tmp/adjustment-summary.txt)
127+
BODY="$BODY"$'\n\n'"**Changes:**"$'\n'"$SUMMARY"
128+
fi
129+
else
130+
BODY="No changes were needed for this instruction. The config files already match, or the instruction could not be applied."
131+
if [ -f /tmp/claude-output.txt ]; then
132+
# Include last 10 lines of Claude output for context
133+
TAIL=$(tail -10 /tmp/claude-output.txt)
134+
BODY="$BODY"$'\n\n'"<details><summary>Claude output</summary>"$'\n\n'"\`\`\`"$'\n'"$TAIL"$'\n'"\`\`\`"$'\n'"</details>"
135+
fi
136+
fi
137+
gh api repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments \
138+
-f body="$BODY"
139+
env:
140+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
141+
142+
- name: React success/failure
143+
if: always()
144+
run: |
145+
if [ "${{ steps.adjust.outputs.has_changes }}" = "true" ]; then
146+
REACTION="rocket"
147+
else
148+
REACTION="confused"
149+
fi
150+
gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
151+
-f content="$REACTION"
152+
env:
153+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Validate Model Configs
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
branches: [master]
7+
paths:
8+
- 'packages/cognitive/src/features/providers/**/*.config.ts'
9+
- 'packages/cognitive/src/features/model-selection/schemas.models.ts'
10+
11+
permissions:
12+
contents: read
13+
pull-requests: write
14+
15+
env:
16+
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
17+
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
18+
19+
jobs:
20+
validate:
21+
runs-on: depot-ubuntu-24.04-16
22+
timeout-minutes: 10
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- uses: pnpm/action-setup@v4
27+
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version-file: '.nvmrc'
31+
cache: 'pnpm'
32+
33+
- run: pnpm install --frozen-lockfile
34+
35+
- name: Typecheck cognitive package
36+
run: pnpm --filter cognitive typecheck
37+
38+
- name: Validate model schemas
39+
run: |
40+
node --loader ts-node/esm -e "
41+
const { getModels } = await import('./packages/cognitive/src/features/providers/provider-config-reader.js');
42+
const { ModelSchema } = await import('./packages/cognitive/src/features/model-selection/schemas.models.js');
43+
const models = getModels();
44+
let errors = 0;
45+
for (const model of models) {
46+
const result = ModelSchema.safeParse(model);
47+
if (!result.success) {
48+
console.error('Invalid model:', model.id, result.error.format());
49+
errors++;
50+
}
51+
}
52+
console.log('Validated', models.length, 'models across all providers.');
53+
if (errors > 0) {
54+
console.error(errors, 'model(s) failed validation.');
55+
process.exit(1);
56+
}
57+
console.log('All models valid.');
58+
"
59+
60+
- name: Check for duplicate model IDs
61+
run: |
62+
node --loader ts-node/esm -e "
63+
const { getModels } = await import('./packages/cognitive/src/features/providers/provider-config-reader.js');
64+
const models = getModels();
65+
const seen = new Map();
66+
let dupes = 0;
67+
for (const model of models) {
68+
const fullId = model.provider + ':' + model.id;
69+
if (seen.has(fullId)) {
70+
console.error('Duplicate model ID:', fullId);
71+
dupes++;
72+
}
73+
seen.set(fullId, true);
74+
}
75+
if (dupes > 0) {
76+
process.exit(1);
77+
}
78+
console.log('No duplicate model IDs found.');
79+
"
80+
81+
- name: Diff summary
82+
if: github.event_name == 'pull_request'
83+
run: |
84+
node --loader ts-node/esm -e "
85+
const { getModels } = await import('./packages/cognitive/src/features/providers/provider-config-reader.js');
86+
const models = getModels();
87+
const active = models.filter(m => m.lifecycle === 'production' || m.lifecycle === 'preview');
88+
const deprecated = models.filter(m => m.lifecycle === 'deprecated');
89+
const discontinued = models.filter(m => m.lifecycle === 'discontinued');
90+
const byProvider = {};
91+
for (const m of models) {
92+
byProvider[m.provider] = (byProvider[m.provider] || 0) + 1;
93+
}
94+
console.log('## Model Catalog Summary');
95+
console.log('| Provider | Models |');
96+
console.log('|----------|--------|');
97+
for (const [p, c] of Object.entries(byProvider).sort()) {
98+
console.log('|', p, '|', c, '|');
99+
}
100+
console.log('');
101+
console.log('**Total:**', models.length, '|',
102+
'**Active:**', active.length, '|',
103+
'**Deprecated:**', deprecated.length, '|',
104+
'**Discontinued:**', discontinued.length);
105+
" >> "$GITHUB_STEP_SUMMARY"

0 commit comments

Comments
 (0)