Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0fa93b6
codegen metadata
stainless-app[bot] Aug 27, 2026
76252a9
feat(tracing): add opt-in commit SHA stamping for SGP spans (#505)
cyntwang99 Aug 31, 2026
f394ce7
codegen metadata
stainless-app[bot] Sep 1, 2026
f44750a
Repository Setup
github-actions[bot] Sep 2, 2026
cd28f5f
Merge remote-tracking branch 'stainless/next' into next
aringuyen3 Sep 4, 2026
490843e
chore(sync): back-sync production release #506 (a71fa670)
Sep 18, 2026
e5697db
ci: guard production-only workflows so they no-op on staging
Sep 18, 2026
ebbf900
ci(bandit): read scan results from file instead of passing them as argv
Sep 18, 2026
18bc39d
chore(stlc): reconcile staging main and back-sync production release …
aringuyen3 Sep 21, 2026
cb47a16
chore(sync): back-sync production releases #520 and #525
Sep 21, 2026
86514dd
chore(stlc): restore trunk ancestry and back-sync production
Sep 21, 2026
c051379
Merge pull request #5 from scaleapi/stlc/restore-trunk-ancestry
aringuyen3 Sep 21, 2026
567abff
Build SDK
aringuyen3 Sep 21, 2026
9ae1fa1
chore(stlc): back-sync the 0.28.1 release from production
aringuyen3 Sep 25, 2026
90387d2
chore(release): point release-please config at the stock schema
aringuyen3 Sep 25, 2026
40ab658
ci(stlc): stand up Promote and Release
agentex-sdk-sync[bot] Sep 25, 2026
24aa92b
ci(release): wire release-please to the App token and the CLI
aringuyen3 Sep 25, 2026
6da13c3
ci(lint-pr): exempt the SDK automation App from the PR title and base…
aringuyen3 Sep 25, 2026
86d29c7
ci(bandit): add the jq template the scan's logging step feeds
aringuyen3 Sep 25, 2026
73ea73e
fix(stlc): restore the custom-code tree a stale seal anchor reverted
aringuyen3 Sep 25, 2026
bc1a463
fix: align the base-URL test with this trunk, and stop Bandit failing…
aringuyen3 Sep 26, 2026
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
6 changes: 5 additions & 1 deletion .github/workflows/agentex-tutorials-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:

jobs:
find-tutorials:
# Repo guard: this workflow is specific to the production repo. Staging carries the
# same file (the trunks are kept SHA-identical) but has none of its secrets, so
# without this it runs and fails red on every codegen push.
if: github.repository == 'scaleapi/scale-agentex-python'
runs-on: ubuntu-latest
outputs:
tutorials: ${{ steps.get-tutorials.outputs.tutorials }}
Expand Down Expand Up @@ -235,7 +239,7 @@ jobs:
retention-days: 1

test-summary:
if: always()
if: always() && github.repository == 'scaleapi/scale-agentex-python'
needs: [find-tutorials, test-tutorial]
runs-on: ubuntu-latest
name: Test Summary
Expand Down
82 changes: 82 additions & 0 deletions .github/workflows/bandit-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Bandit

on:
# Scan changed files in PRs:
pull_request: {}

jobs:
bandit-scan:
name: Bandit
runs-on: ubuntu-22.04
if: (github.actor != 'dependabot[bot]') && (github.actor != 'github-actions[bot]')
steps:
- name: Install PyCQA/bandit
shell: bash
run: |
pip install bandit
- name: Checkout base branch
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 1
submodules: false
- name: Run a baseline scan
shell: bash
run: |
bandit --recursive --aggregate file . -f json -o baseline.json || true
- name: Checkout feature branch
shell: bash
run: |
git fetch origin $GITHUB_HEAD_REF
git checkout $GITHUB_HEAD_REF
Comment on lines +30 to +31

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 This fetch uses the base repository's origin, but $GITHUB_HEAD_REF names the source branch. For a fork pull request, that branch usually exists only in the fork, so git fetch exits before the changed-code scan runs. Check out the pull request head SHA or fetch from github.event.pull_request.head.repo instead.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/bandit-ci.yml
Line: 30-31

Comment:
This fetch uses the base repository's `origin`, but `$GITHUB_HEAD_REF` names the source branch. For a fork pull request, that branch usually exists only in the fork, so `git fetch` exits before the changed-code scan runs. Check out the pull request head SHA or fetch from `github.event.pull_request.head.repo` instead.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Cursor Fix in Claude Code Fix in Codex

- name: Run Scan off of baseline
shell: bash
run: |
bandit --recursive --aggregate file . --baseline baseline.json -f json -o results.json || true
- name: Install logging prerequisites
shell: bash {0}
run: |
sudo apt-get -y install jq curl
- name: Generate logger template
shell: bash {0} # don't fail the job if the logging fails
run: |
jq -n --arg organization $GITHUB_REPOSITORY_OWNER \
-n --arg time $( date +'%Y-%m-%dT%H:%M:%SZ' ) \
-n --arg action $GITHUB_WORKFLOW \
-n --arg repository $GITHUB_REPOSITORY \
-n --arg sha $GITHUB_SHA \
-n --arg branch $GITHUB_HEAD_REF \
-n --arg link "https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" \
-f .github/workflows/output-template.json > tmp-output.json
- name: Format results appropriately from results.json
shell: bash {0} # don't fail the job if the logging fails
run: |
jq '.results | map({"path": .filename, "message": .issue_text, "line": .line_number})' results.json > tmp.json
# --slurpfile, not --argjson "$(<tmp.json)": the latter passes the whole results file
# as a single argv entry, which Linux caps at MAX_ARG_STRLEN (128KB) regardless of the
# much larger total ARG_MAX. Once a scan produced more than ~128KB of findings the step
# died with "Argument list too long" (exit 126) and failed the job -- despite the
# `shell: bash {0}` above intending it to be non-fatal. --slurpfile reads the file
# directly, so size is irrelevant; it wraps the file's values in an array, hence [0].
jq --slurpfile scanResults tmp.json '.results += $scanResults[0]' tmp-output.json > output.json
- name: Send unified results to logging cluster
# `shell: bash {0}` drops `-e`, but a step still fails when its LAST command does,
# and curl was the last command -- so a repo without these secrets failed the whole
# Bandit job on a reporting problem, contradicting the intent stated right here.
# Neither this repo nor the production repo defines them, so this failed every run.
# Stay non-fatal, but say so rather than reporting nothing silently.
shell: bash {0} # don't fail the job if the logging fails
env:
ENDPOINT: ${{ secrets.N8N_PRODSEC_ACTIONS_ENDPOINT }}
TOKEN: ${{ secrets.N8N_PRODSEC_ACTIONS_TOKEN }}
run: |
if [ -z "${ENDPOINT:-}" ]; then
echo "::warning title=Bandit results not reported::N8N_PRODSEC_ACTIONS_ENDPOINT is not set on this repository, so the scan results were not sent to the logging cluster. The scan itself ran and its findings are in the job log."
exit 0
fi
curl -sS -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d @./output.json \
"$ENDPOINT" \
|| echo "::warning title=Bandit results not reported::the POST to the logging cluster failed; the scan itself still ran."
4 changes: 4 additions & 0 deletions .github/workflows/build-and-push-tutorial-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ permissions:

jobs:
check-permissions:
# Repo guard: this workflow is specific to the production repo. Staging carries the
# same file (the trunks are kept SHA-identical) but has none of its secrets, so
# without this it runs and fails red on every codegen push.
if: github.repository == 'scaleapi/scale-agentex-python'
runs-on: ubuntu-latest
steps:
- name: Check event type and permissions
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/harness-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:

jobs:
conformance:
# Repo guard: this workflow is specific to the production repo. Staging carries the
# same file (the trunks are kept SHA-identical) but has none of its secrets, so
# without this it runs and fails red on every codegen push.
if: github.repository == 'scaleapi/scale-agentex-python'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -38,6 +42,10 @@ jobs:
# trigger above uses a `test_harness_*.py` glob so new suites are picked up
# automatically.
live-matrix:
# Repo guard: this workflow is specific to the production repo. Staging carries the
# same file (the trunks are kept SHA-identical) but has none of its secrets, so
# without this it runs and fails red on every codegen push.
if: github.repository == 'scaleapi/scale-agentex-python'
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/lint-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@ jobs:
# These bots may not always emit Conventional-Commits-formatted titles
# (dependabot's default "Bump foo from 1.0 to 1.1" doesn't match) and we
# don't want their PRs blocked by this check. Mirrors validate-pr-base.
#
# agentex-sdk-sync[bot] is this repo's own SDK automation. release-please
# runs here as a CLI under that App rather than as the release-please[bot]
# GitHub App, so its release pull requests are authored by
# agentex-sdk-sync[bot] and the entry above never matched them. Their
# titles come from release-please's configured pull-request-title-pattern,
# "release: <version>", which is not a Conventional Commits type and cannot
# be changed without also changing the string release-please parses back
# when it cuts the release. The same App opens the promote pull requests.
case "$PR_AUTHOR" in
stainless-app|stainless-app\[bot\]|release-please\[bot\]|github-actions\[bot\]|dependabot\[bot\])
stainless-app|stainless-app\[bot\]|release-please\[bot\]|github-actions\[bot\]|dependabot\[bot\]|agentex-sdk-sync\[bot\])
echo "PR is from automation ($PR_AUTHOR); skipping title check."
exit 0
;;
Expand Down Expand Up @@ -93,7 +102,7 @@ jobs:

# Exempt automated PRs (must mirror validate-pr-title's list).
case "$PR_AUTHOR" in
stainless-app|stainless-app\[bot\]|release-please\[bot\]|github-actions\[bot\]|dependabot\[bot\])
stainless-app|stainless-app\[bot\]|release-please\[bot\]|github-actions\[bot\]|dependabot\[bot\]|agentex-sdk-sync\[bot\])
delete_comment
echo "PR is from automation ($PR_AUTHOR); allowing PR targeting main."
exit 0
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/opengrep-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: OpenGrep

on:
pull_request: {}

concurrency:
group: opengrep-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write
id-token: write

jobs:
opengrep:
uses: scaleapi/required-actions/.github/workflows/opengrep-ci.yml@opengrep-4core-runner
secrets: inherit
18 changes: 18 additions & 0 deletions .github/workflows/opengrep-fp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: OpenGrep FP Triage

on:
pull_request_review_comment:
types: [created]

permissions:
pull-requests: write
id-token: write

jobs:
triage:
if: |
(startsWith(github.event.comment.body, '/fp') ||
startsWith(github.event.comment.body, '/FP')) &&
!endsWith(github.actor, '[bot]')
uses: scaleapi/required-actions/.github/workflows/opengrep-fp.yml@main
secrets: inherit
13 changes: 13 additions & 0 deletions .github/workflows/output-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"source": "github",
"organization": "\($organization)",
"timestamp": "\($time)",
"action": "\($action)",
"meta": {
"repository": "\($repository)",
"commit": "\($sha)",
"branch": "\($branch)",
"link": "\($link)"
},
"results": []
}
4 changes: 4 additions & 0 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:

jobs:
publish:
# Repo guard: this workflow is specific to the production repo. Staging carries the
# same file (the trunks are kept SHA-identical) but has none of its secrets, so
# without this it runs and fails red on every codegen push.
if: github.repository == 'scaleapi/scale-agentex-python'
name: publish
runs-on: ubuntu-latest

Expand Down
80 changes: 80 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Release Please

# Hand-edited from the stlc-generated template. `.github/workflows/*.yml` is
# scaffold-once, so this survives every later build -- upstream's own source cites
# exactly this PAT-to-App swap as the reason that preservation exists. Do NOT run
# `stlc build --rewrite-scaffold` without reapplying these three changes.
#
# What changed from the generated file, and why each is load-bearing:
#
# 1. App token instead of `secrets.RELEASE_PLEASE_TOKEN`, which does not exist
# and which we do not want to create -- eliminating PATs was the point of the
# App migration. It is deliberately NOT `GITHUB_TOKEN`: releases created by
# GITHUB_TOKEN do not trigger other workflows, so publish-*.yml would never
# fire and the release would stop one hop short of the registry.
#
# 2. The `npx release-please@16` CLI instead of googleapis/release-please-action.
# scale-agentex-typescript sets `allowed_actions: selected` and does not permit
# that action; the CLI needs only actions/-owned steps, which
# `github_owned_allowed: true` covers on both production repos.
#
# 3. `issues: write` on the minted token. release-please drives its
# autorelease:pending -> autorelease:tagged labels through the Issues API.
# Without it you get duplicate release pull requests. The generated file omits
# it, and the omission is silent until it bites.
#
# Requires AGENTEX_SDK_SYNC_PRIVATE_KEY (secret) and AGENTEX_SDK_SYNC_APP_ID
# (variable) on the PRODUCTION repo -- a workflow only reads secrets from the repo
# it runs in, and the guard below means that is production.
on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

jobs:
release-please:
# Self-routing: this file is SHA-identical on the staging trunk, where it must
# stay inert. Only production cuts releases.
if: github.repository == 'scaleapi/scale-agentex-python'
runs-on: ubuntu-latest
steps:
- name: Mint release token
id: release-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.AGENTEX_SDK_SYNC_APP_ID }}
private-key: ${{ secrets.AGENTEX_SDK_SYNC_PRIVATE_KEY }}
owner: scaleapi
repositories: scale-agentex-python
permission-contents: write
permission-pull-requests: write
permission-issues: write
permission-metadata: read

- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Release PR + GitHub release
env:
RP_TOKEN: ${{ steps.release-token.outputs.token }}
run: |
# release-pr opens or updates the version-bump pull request;
# github-release turns an already-merged one into the tag + GitHub Release
# that publish-pypi.yml / publish-npm.yml trigger on. Both are idempotent,
# so running the pair on every push carries a release the whole way.
#
# No checkout step is needed: release-please reads the config and manifest
# from the repo over the API.
npx --yes release-please@16 release-pr \
--token="$RP_TOKEN" --repo-url="${{ github.repository }}" \
--config-file=release-please-config.json \
--manifest-file=.release-please-manifest.json
npx --yes release-please@16 github-release \
--token="$RP_TOKEN" --repo-url="${{ github.repository }}" \
--config-file=release-please-config.json \
--manifest-file=.release-please-manifest.json
16 changes: 16 additions & 0 deletions .github/workflows/trufflehog-bypass.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: TruffleHog Bypass Handler

on:
issue_comment:
types: [created]

jobs:
bypass:
if: |
github.event.issue.pull_request &&
contains(github.event.comment.body, '/trufflehog-bypass')
uses: scaleapi/required-actions/.github/workflows/trufflehog-bypass-handler.yml@main
permissions:
pull-requests: write
contents: read
actions: write
13 changes: 13 additions & 0 deletions .github/workflows/trufflehog-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: TruffleHog Secret Scan

on:
pull_request:
branches: [master, main]

jobs:
scan:
uses: scaleapi/required-actions/.github/workflows/trufflehog-scan.yml@main
permissions:
contents: read
pull-requests: write
id-token: write
26 changes: 26 additions & 0 deletions .github/workflows/trufflehog-weekly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: TruffleHog Weekly Scan

on:
schedule:
- cron: '0 3 * * 0'
workflow_dispatch:
inputs:
since_commit:
description: 'Override: Scan from this commit SHA (leave empty to use stored value)'
required: false
type: string
full_scan:
description: 'Run full history scan (ignores since_commit)'
required: false
type: boolean
default: false

jobs:
scan:
uses: scaleapi/required-actions/.github/workflows/trufflehog-weekly-scan.yml@main
with:
since_commit: ${{ inputs.since_commit || '' }}
full_scan: ${{ inputs.full_scan || false }}
permissions:
contents: read
id-token: write
3 changes: 0 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
configured_endpoints: 75
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-fbc0683871d6abb03588f30d9468eeeeacb2b8538eb0c9002813e6df68c5802b.yml
openapi_spec_hash: 4ecd8d496f056dccf80826264ddf8fe1
config_hash: 593e89b291976a5e84e4c3c3f8324354
2 changes: 1 addition & 1 deletion release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
]
}
],
"$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json",
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"include-v-in-tag": true,
"include-component-in-tag": true,
"versioning": "prerelease",
Expand Down
2 changes: 1 addition & 1 deletion scripts/utils/upload-artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ UPLOAD_RESPONSE=$(curl -v -X PUT \

if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then
echo -e "\033[32mUploaded build to Stainless storage.\033[0m"
echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/agentex-sdk-python/$SHA/$FILENAME'\033[0m"
echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/scale-agentex-python-staging/$SHA/$FILENAME'\033[0m"
else
echo -e "\033[31mFailed to upload artifact.\033[0m"
exit 1
Expand Down
2 changes: 1 addition & 1 deletion src/agentex/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
]

ENVIRONMENTS: Dict[str, str] = {
"production": "http://localhost:5003",
"production": "https://agentex.sgp.scale.com",
"development": "http://localhost:5003",
}

Expand Down
Loading
Loading