Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
51b8f3c
FEAT: Implement Deep Agent Architecture with Orchestrator and Subagen…
tuhinsharma121 Apr 20, 2026
d5994d8
FEAT: productionize agent — dead code removal, middleware fix, observ…
NP-compete May 23, 2026
cdaf2c4
fix(agent): expose MCP tools when servers are declared without explic…
mimran-khan Jun 3, 2026
918047b
fix: skip aegra db_manager initialization in in-memory mode (#60)
mimran-khan Jun 3, 2026
5b21754
fix: subagents inherit model and MCPs from parent orchestrator
NP-compete Jun 4, 2026
65d8703
Merge pull request #61 from redhat-data-and-ai/fix/subagent-inherit-p…
karankraina Jun 4, 2026
1530254
fix: inherit model and MCP tools for subagents missing frontmatter fi…
mimran-khan Jun 4, 2026
c24550c
Fix auth token caching and add Claude Sonnet 4.6 support (#67)
AtrikGhosh Jun 11, 2026
2549b88
feat: add graceful SIGTERM shutdown with drain and resource cleanup
NP-compete Jun 15, 2026
afa5b74
fix: use atexit as primary shutdown path, signal handlers as upgrade
NP-compete Jun 15, 2026
73bccfb
fix: make shutdown visible in container logs
NP-compete Jun 15, 2026
ef442ad
fix: guard atexit double-registration, validate timeout budget, set A…
NP-compete Jun 15, 2026
9262199
Merge pull request #68 from redhat-data-and-ai/feat/graceful-shutdown
karankraina Jun 15, 2026
c478b8c
Add support for subagent fallback and provider aware setup for chat i…
vishnusrichand Jun 21, 2026
f42b460
Add base image pattern with config volume mount (#71)
nirmchan Jun 21, 2026
b81f122
fix: removed unused config files (#74)
vishnusrichand Jun 23, 2026
466b188
ci: Update workflow triggers and sync with upstream deep-agent and ma…
nirmchan Jun 23, 2026
1f12507
feat: Adds per-thread and per-user daily LLM token tracking with Mong…
vishnusrichand Jun 25, 2026
3613204
feat: add per-MCP OAuth/DCR support with token store and HTTP routes …
abhiskum Jun 25, 2026
5bcddcf
feat: add OpenTelemetry observability with direct OTLP export (#83)
NP-compete Jun 30, 2026
1eaee38
feat: human in the loop (#84)
Anish701 Jun 30, 2026
2637a29
fix: prevent blocking for human-in-loop feature for subagent internal…
Anish701 Jul 2, 2026
1629c74
refactor: consolidate Containerfile and Containerfile.base into singl…
NP-compete Jul 2, 2026
8aac1ff
feat: implement tool access control per subagent
nsaharan Jul 3, 2026
33a7ca7
docs: add ADR for tool access control per subagent
nsaharan Jul 3, 2026
2dbef59
docs: convert ADR diagrams to Mermaid format
nsaharan Jul 3, 2026
6a1a6dc
Adds opt-in platform audit logging to template-agent (#79)
vishnusrichand Jul 3, 2026
62eacbf
fix: resolve pre-commit failures (ruff, mypy, pydocstyle, formatting)…
shahfasal Jul 5, 2026
6c1ab66
FEAT: Add api_key authentication method for mcp (#95)
AtrikGhosh Jul 5, 2026
6ffff54
FIX: Fixed skill reading in deep agent (#94)
AtrikGhosh Jul 6, 2026
e1b65dc
ci: trigger base image build on feat/rhitaif-221 branch
nsaharan Jul 6, 2026
c760522
Merge pull request #1 from saharannaveen/feat/rhitaif-221
saharannaveen Jul 6, 2026
e0d0003
feat(mcp): add DCR OAuth authentication flow for MCP tool servers (#97)
pratistha19 Jul 7, 2026
4bf5c52
chore: allow workflow to trigger on any tag pattern (#105)
nirmchan Jul 7, 2026
3647231
Deep agent new (#106)
nirmchan Jul 7, 2026
3485904
feat: add custom CA certificate support at container startup (#107)
NP-compete Jul 13, 2026
42c43da
feat: harden template-agent for production deployment (#93)
nirmchan Jul 13, 2026
662778f
feat: add /version endpoint and bump to 0.2.0 (#89)
NP-compete Jul 13, 2026
29561be
feat: unify trace_id propagation across OTEL, Langfuse, and token bud…
NP-compete Jul 13, 2026
974c3dd
feat: MCP server and LLM provider health checks with OTEL gauges (#86)
NP-compete Jul 13, 2026
881803a
feat: X-Request-ID propagation with org_id and agent_id log binding (…
NP-compete Jul 13, 2026
77f773e
feat: add vulnerability scanning to base image build pipeline (#100)
vishnusrichand Jul 13, 2026
38b3640
Feat/rhitaif 196 headless agent (#90)
saharannaveen Jul 13, 2026
a6df3ea
feat(agent): mcp oauth dcr agent (#103)
pratistha19 Jul 13, 2026
e42b622
feat: add CodeExecutionMiddleware with K8s Job backend
nsaharan Jul 13, 2026
1d048dc
docs: expand future capabilities section with detailed designs and di…
nsaharan Jul 13, 2026
3bc992f
fix(code-execution): handle K8s container 'Completed' reason and byte…
nsaharan Jul 13, 2026
f08eb1c
docs: add chat/headless agent usage section and future capabilities d…
nsaharan Jul 13, 2026
5e1162c
fix(code-execution): reliable logging and auto-use prompt guidance
nsaharan Jul 13, 2026
904908a
feat(code-execution): add 6 production capabilities
nsaharan Jul 13, 2026
26985af
docs: add image configuration flow (3-level hierarchy) to design spec
nsaharan Jul 13, 2026
0c93bb1
docs: add ephemeral pod observability section with query guide and lo…
nsaharan Jul 14, 2026
e1bb8e3
feat(code-execution): update orchestrator prompt for autonomous code …
nsaharan Jul 14, 2026
c486a32
fix: bump pytest-asyncio from 1.0.0 to 1.4.0 (#114)
vishnusrichand Jul 14, 2026
581f8b7
fix: set defualt human in the loop setting to true (#115)
Anish701 Jul 15, 2026
c779706
fix(docs): fix Mermaid syntax errors in security, state diagram, and …
nsaharan Jul 16, 2026
3c0481c
fix(docs): replace gantt chart with flowchart for roadmap rendering
nsaharan Jul 16, 2026
9e6fb44
fix(docs): update roadmap to reflect all 6 Phase 2 features as done
nsaharan Jul 16, 2026
be89fbe
fix(docs): update roadmap based on actual code — 7 implemented, 6 future
nsaharan Jul 16, 2026
e090f10
fix(docs): remove output file collection from roadmap — stdout is the…
nsaharan Jul 16, 2026
0cf2cca
fix(code-execution): 7 bugs found by code review
nsaharan Jul 16, 2026
371ccad
fix(code-execution): enable by default, fix V1LabelSelector snake_cas…
nsaharan Jul 16, 2026
7d9d9c1
docs: clarify image config — explain language variants and TODO for d…
nsaharan Jul 16, 2026
702140e
feat(code-execution): wire SSE streaming, fix prompt, enable by default
nsaharan Jul 16, 2026
f3be08c
feat(code-execution): complete 4-layer observability with OTEL + audit
nsaharan Jul 16, 2026
033fb5e
merge: resolve conflicts with origin/deep-agent
nsaharan Jul 16, 2026
2f4df30
feat(code-execution): add scheduling_seconds to audit event
nsaharan Jul 16, 2026
140445a
chore: remove dev-only dashboard script from repo
nsaharan Jul 16, 2026
77b3576
ci: remove feat/rhitaif-221 from build trigger
nsaharan Jul 16, 2026
4e180aa
chore: remove docs/ from tracking (design spec stays local)
nsaharan Jul 16, 2026
6b57914
fix: restore deep-agent docs, keep our specs local via gitignore
nsaharan Jul 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
131 changes: 107 additions & 24 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,38 +1,121 @@
# Agent Server Configuration
AGENT_HOST=0.0.0.0
AGENT_PORT=5002
#AGENT_SSL_KEYFILE=/path_to/ssl_key.pem
#AGENT_SSL_CERTFILE=/path_to/ssl_cert.pem
# ==============================================================================
# Environment Variables
#
# Only secrets and infrastructure endpoints belong here.
# All operational config (cache, middleware, filesystem, providers) lives in
# config/agent/runtime/agent.yaml — the single source of truth.
#
# OpenShift: secrets come via Secrets, infra via ConfigMaps.
# ==============================================================================

# Python Logging
PYTHON_LOG_LEVEL=INFO
# --- Environment ---
# Set to "production" to enforce security hardening:
# - ENABLE_AUTH must be true
# - MCP ssl_verify cannot be disabled
# - PII is scrubbed from error responses
# - Security headers are enforced
ENVIRONMENT=development

# --- Security ---
# Request body size limit (bytes) - prevents DoS attacks
REQUEST_BODY_MAX_SIZE=10485760 # 10MB

# --- SSO / OIDC Authentication ---
# Supports any OIDC-compliant provider (Keycloak, Okta, Azure AD, Auth0, etc.)
ENABLE_AUTH=false
SSO_ISSUER_URL=https://sso.example.com/realms/myrealm
SSO_CLIENT_ID=your-client-id
SSO_CLIENT_SECRET=your-client-secret
# SSO_JWKS_URI=https://sso.example.com/realms/myrealm/protocol/openid-connect/certs

# Dev fallback identity (used when ENABLE_AUTH=false)
SSO_DEV_USERNAME=John Doe
SSO_DEV_USER_ID=dev-user

# User ID encryption for observability privacy
ENABLE_USER_ID_ENCRYPTION=false
# USER_ID_ENCRYPTION_KEY=your-32-byte-hex-key

USE_INMEMORY_SAVER=true
# MCP OAuth token encryption (Fernet key — required when using auth_mode oauth/dcr)
# Encrypts access/refresh tokens in Redis and DCR client secrets in Postgres.
# Generate: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# MCP_TOKEN_ENCRYPTION_KEY=
# Optional previous key during rotation (decrypt only — see README)
# MCP_TOKEN_ENCRYPTION_KEY_PREVIOUS=
# AGENT_PUBLIC_BASE_URL=http://localhost:5002

# pgvector credentials for agentic memory (used when USE_INMEMORY_SAVER=false)
POSTGRES_USER=pgvector
POSTGRES_PASSWORD=pgvector
POSTGRES_HOST=0.0.0.0
# --- Infrastructure ---

# Postgres (checkpoints, memory, feedback)
# Local dev (`make local`): localhost + port published by compose pgvector (5432)
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=pgvector
POSTGRES_DB=template_agent
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres

# Redis (Aegra broker: SSE streaming, job queue, crash recovery)
# Local dev (`make local`): localhost + port published by compose redis (6379)
REDIS_URL=redis://localhost:6379/0
REDIS_BROKER_ENABLED=true

# MongoDB (platform token usage rollup — optional, set by deploy components)
#
# SECURITY: MONGODB_URI may contain credentials in the URI itself:
# mongodb://user:password@host:27017/tokenusage?authSource=tokenusage
#
# - NEVER commit a URI with credentials to version control.
# - NEVER log or expose this value in error messages or debug output.
# - In production, inject via secrets management:
# Kubernetes : mount as a Secret, reference via envFrom or env.valueFrom.secretKeyRef
# AWS : use Secrets Manager or SSM Parameter Store with an operator/init container
# GCP : use Secret Manager with Workload Identity
# Vault : use the Vault Agent injector or ESO (External Secrets Operator)
# - Scope the MongoDB user to read/write on the tokenusage DB only — no admin privileges.
# - Rotate credentials without redeploying by updating the secret and triggering a rollout.
#
# Local dev (unauthenticated, never in production):
# MONGODB_URI=mongodb://localhost:27017
# MONGODB_DB=tokenusage

# --- Observability ---

# exception
LANGFUSE_SECRET_KEY=sk-lf-f46b492e-9335-
LANGFUSE_PUBLIC_KEY=pk-lf-dfa0dab0-c486-
# Langfuse (v4 SDK — auto-read by client and CallbackHandler)
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_BASE_URL=https://cloud.langfuse.com
LANGFUSE_TRACING_ENVIRONMENT=development

#Google Vertex AI service creds
# OpenTelemetry — token budget export (metrics/traces via otel_setup.py)
# Agent lifecycle metrics (conversations, streams, threads) via observability.yaml
# ENABLE_OTEL_METRICS=false
# OTEL_EXPORTER_OTLP_ENDPOINT=
# ENABLE_OTEL_TRACES=false
# OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317
# OTEL_SERVICE_NAME=template-agent
# OTEL_AUTH_TOKEN=
# OTEL_METRIC_EXPORT_INTERVAL_MILLIS=10000
# ENABLE_OTEL=false
# OTEL_EXPORTER_OTLP_INSECURE=true
# OTEL_METRIC_EXPORT_INTERVAL=5000

# --- Model Provider Credentials ---

# Google Vertex AI
GOOGLE_APPLICATION_CREDENTIALS_CONTENT='{
"type": "service_account",
"project_id": "data-and-ai-gemini",
...
...
"project_id": "your-project-id",
...
"universe_domain": "googleapis.com"
}'

# MCP config
MCP_SERVER_NAME=template-mcp-server
MCP_SERVER_URL=http://localhost:5001/mcp
MCP_TRANSPORT_PROTOCOL=streamable_http
# vLLM / OpenAI-compatible (optional)
# VLLM_BASE_URL=http://vllm-server:8000/v1
# VLLM_API_KEY=EMPTY

# --- Runtime (rarely changed) ---

PYTHON_LOG_LEVEL=INFO

# Per-MCP OAuth client secret (auth_mode: oauth — referenced via oauth.client_secret_env in mcp.json)
# MY_OAUTH_MCP_CLIENT_SECRET=your-client-secret
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly

- package-ecosystem: docker
directory: "/"
schedule:
interval: weekly

- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
180 changes: 180 additions & 0 deletions .github/workflows/build-base-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: Build and Push Base Image

on:
push:
tags:
- '*'
branches:
# - main
- deep-agent
workflow_dispatch: # Allow manual trigger for testing

permissions:
contents: write
packages: write
security-events: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

jobs:
build-and-push:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=tag
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix={{branch}}-,enable=${{ !startsWith(github.ref, 'refs/tags/') }}

- name: Extract version for deployment package
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
VERSION="${GITHUB_REF#refs/heads/}-${GITHUB_SHA::7}"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "package_name=agent-deployment.zip" >> $GITHUB_OUTPUT

- name: Build image locally for scanning
uses: docker/build-push-action@v5
with:
context: .
file: ./Containerfile
push: false
load: true
tags: scan-target:${{ steps.version.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64

- name: Scan image for vulnerabilities
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: scan-target:${{ steps.version.outputs.version }}
format: table
severity: CRITICAL,HIGH
scanners: vuln
trivyignores: .trivyignore
exit-code: '1'

- name: Generate SARIF report
uses: aquasecurity/trivy-action@v0.36.0
if: always()
with:
image-ref: scan-target:${{ steps.version.outputs.version }}
format: sarif
output: trivy-results.sarif
scanners: vuln
exit-code: '0'

- name: Upload Trivy scan results to GitHub Security tab
if: always() && hashFiles('trivy-results.sarif') != ''
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: trivy-results.sarif

- name: Upload Trivy report as artifact
if: always() && hashFiles('trivy-results.sarif') != ''
uses: actions/upload-artifact@v4
with:
name: trivy-report-${{ steps.version.outputs.version }}
path: trivy-results.sarif
retention-days: 30

- name: Push multi-platform image
uses: docker/build-push-action@v5
with:
context: .
file: ./Containerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64

- name: Create deployment package metadata
run: |
cat > deployment/release-info.json <<EOF
{
"version": "${{ steps.version.outputs.version }}",
"git_ref": "${{ github.ref }}",
"git_sha": "${{ github.sha }}",
"build_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"container_image": "ghcr.io/${{ github.repository }}:${{ steps.version.outputs.version }}",
"repository": "${{ github.repository }}"
}
EOF
cat deployment/release-info.json

- name: Create deployment package
run: |
cd deployment
zip -r ../${{ steps.version.outputs.package_name }} . -x "*.git*"
cd ..
echo "Created package: ${{ steps.version.outputs.package_name }}"
ls -lh ${{ steps.version.outputs.package_name }}

- name: Create GitHub Release (for tags only)
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1
with:
files: ${{ steps.version.outputs.package_name }}
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload deployment package as artifact (for branch builds)
if: "!startsWith(github.ref, 'refs/tags/')"
uses: actions/upload-artifact@v4
with:
name: ${{ steps.version.outputs.package_name }}
path: ${{ steps.version.outputs.package_name }}
retention-days: 30

- name: Build summary
run: |
echo "### Base Image Built Successfully! 🚀" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version:** \`${{ steps.version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Container Image Tags:**" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "docker pull ghcr.io/${{ github.repository }}:${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Deployment Package:**" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "📦 \`${{ steps.version.outputs.package_name }}\` attached to release" >> $GITHUB_STEP_SUMMARY
else
echo "📦 \`${{ steps.version.outputs.package_name }}\` uploaded as workflow artifact" >> $GITHUB_STEP_SUMMARY
fi
Loading