Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,33 +244,51 @@ jobs:
if: ${{ inputs.use_ai_notes }}
shell: bash
env:
MODELS_TOKEN: ${{ secrets.MODELS_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Grant models permission before using GITHUB_TOKEN

When use_ai_notes is true, this step now authenticates GitHub Models with the workflow GITHUB_TOKEN, but the workflow permissions block only grants contents and pull-requests; GitHub Actions sets omitted permissions to none, and the GitHub Models quickstart/API docs require models: read for workflows calling the inference endpoint. As a result, the curl request will return an authorization error and fail every AI-notes release run unless models: read is added.

Useful? React with 👍 / 👎.

run: |
set -euo pipefail

python <<'PY'
from pathlib import Path
import json
import os

prompt = Path(".github/release-artifacts/release-prompt.txt").read_text(encoding="utf-8")
payload = {
"model": "gpt-5.4",
"model": "openai/gpt-5.4",
"messages": [
{"role": "user", "content": prompt}
],
{
"role": "system",
"content": "You write concise, accurate release notes in markdown."
},
{
"role": "user",
"content": prompt
}
]
}
Path(".github/release-artifacts/openai-payload.json").write_text(
json.dumps(payload, ensure_ascii=False),
encoding="utf-8",
)
PY

curl -fsSL https://models.inference.ai.azure.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MODELS_TOKEN" \
-d @.github/release-artifacts/openai-payload.json \
> .github/release-artifacts/openai-response.json
status_code=$(
curl -sS -L \
-o .github/release-artifacts/openai-response.json \
-w "%{http_code}" \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2026-03-10" \
-H "Content-Type: application/json" \
https://models.github.ai/orgs/dataelement/inference/chat/completions \
-d @.github/release-artifacts/openai-payload.json
)

echo "HTTP status: $status_code"
cat .github/release-artifacts/openai-response.json

test "$status_code" -lt 400

python <<'PY'
from pathlib import Path
Expand Down
6 changes: 4 additions & 2 deletions backend/app/services/trigger_runtime/executions.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ async def claim_pending_trigger_executions(
claimed_pairs.append((execution, trigger))
await db.commit()
for execution, trigger in claimed_pairs:
db.expunge(execution)
db.expunge(trigger)
if execution in db:
db.expunge(execution)
if trigger in db:
db.expunge(trigger)
return claimed_pairs


Expand Down
6 changes: 6 additions & 0 deletions backend/app/services/trigger_runtime/invoker.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,21 @@ async def invoke_agent_for_triggers(agent_id: uuid.UUID, triggers: list[AgentTri
result = await db.execute(select(Agent).where(Agent.id == agent_id))
agent = result.scalar_one_or_none()
if not agent or agent.is_expired:
if execution_ids:
await mark_trigger_executions_failed(execution_ids, "Agent not found or is expired")
return

if not agent.primary_model_id:
logger.warning(f"Agent {agent.name} has no LLM model, skipping trigger invocation")
if execution_ids:
await mark_trigger_executions_failed(execution_ids, "Agent has no LLM model configured")
return
result = await db.execute(select(LLMModel).where(LLMModel.id == agent.primary_model_id))
model = result.scalar_one_or_none()
if not model or not model.enabled:
logger.warning(f"Agent {agent.name}'s model is unavailable, skipping trigger invocation")
if execution_ids:
await mark_trigger_executions_failed(execution_ids, "Agent primary model is unavailable or disabled")
return

context_parts = []
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/MarkdownRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ function renderInline(text: string): string {
.replace(/\*\*\*(.*?)\*\*\*/g, '<strong><em>$1</em></strong>')
// Bold
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/__(.*?)__/g, '<strong>$1</strong>')
.replace(/(?<!\w)__(?!\s)(.+?)(?<!\s)__(?!\w)/g, '<strong>$1</strong>')
// Italic
.replace(/\*(.*?)\*/g, '<em>$1</em>')
.replace(/_(.*?)_/g, '<em>$1</em>')
.replace(/(?<!\w)_(?!\s)(.+?)(?<!\s)_(?!\w)/g, '<em>$1</em>')
// Strikethrough
.replace(/~~(.*?)~~/g, '<del>$1</del>');

Expand Down