Skip to content
Open
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
96 changes: 96 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# BrainSait AI Platform - Environment Configuration
# Copy this file to .env and fill in your values

# ============================================
# REQUIRED: Core Configuration
# ============================================

# GitHub Token for Models API access
GITHUB_TOKEN=your_github_personal_access_token

# Database password (use a strong password!)
DB_PASSWORD=your_secure_database_password

# ============================================
# REQUIRED: API Security
# ============================================

# Master API key for admin operations
BRAINSAIT_API_KEY=your_master_api_key_here

# JWT Secret for user authentication
JWT_SECRET=your_jwt_secret_minimum_32_characters

# ============================================
# OPTIONAL: Payment Integration (Stripe)
# ============================================

# Stripe API Keys (for monetization)
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key
STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret

# Stripe Price IDs for subscription tiers
STRIPE_PRICE_PRO=price_xxxxxxxxxxxxx
STRIPE_PRICE_ENTERPRISE=price_xxxxxxxxxxxxx

# ============================================
# OPTIONAL: Monitoring & Analytics
# ============================================

# Grafana admin password
GRAFANA_PASSWORD=your_grafana_admin_password

# Sentry DSN for error tracking
SENTRY_DSN=https://xxxx@sentry.io/xxxxx

# ============================================
# OPTIONAL: Email (for notifications)
# ============================================

# SMTP Configuration
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=your_sendgrid_api_key
SMTP_FROM=noreply@brainsait.ai

# ============================================
# OPTIONAL: Cloud Storage (for audit logs)
# ============================================

# AWS S3 (or compatible)
AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=me-south-1
S3_BUCKET=brainsait-audit-logs

# ============================================
# OPTIONAL: Domain-Specific Settings
# ============================================

# Arabic Market
ARABIC_DEFAULT_MODEL=openai/gpt-4o
ARABIC_TRANSLATION_API=your_translation_api_key

# Healthcare (HIPAA)
HIPAA_AUDIT_ENABLED=true
PHI_ENCRYPTION_KEY=your_32_byte_encryption_key_here

# ============================================
# Application Settings
# ============================================

# Log level: debug, info, warn, error
LOG_LEVEL=info

# Server port
PORT=8080

# Environment: development, staging, production
ENVIRONMENT=development

# Rate limiting (requests per minute)
RATE_LIMIT_FREE=60
RATE_LIMIT_PRO=600
RATE_LIMIT_ENTERPRISE=6000
35 changes: 34 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,35 @@ This repository implements the GitHub Models CLI extension (`gh models`), enabli
3. Azure client converts to `azuremodels.ChatCompletionOptions` and makes API calls
4. Results are formatted using terminal-aware table printers from `command.Config`

### Generate Command (PromptPex)
- **Location**: `cmd/generate/` - self-contained implementation of test generation
- **Key files**: `pipeline.go` (orchestration), `prompts.go` (phase prompts), `evaluators.go` (test evaluation)
- **Flow**: Intent → InputSpec → OutputRules → InverseOutputRules → Tests → Evaluation
- **Session state**: `types.go` defines `PromptPexContext` - serialized to JSON for resumability
- **Cleanup**: `cleaner.go` handles post-generation test refinement and deduplication

## Developer Workflows

### Building & Testing
- **Local build**: `make build` or `script/build` (creates `gh-models` binary)
- **Cross-platform**: `script/build all|windows|linux|darwin` for release builds
- Builds for windows/amd64, linux/amd64, android/arm64, android/amd64, darwin/amd64, darwin/arm64
- **Testing**: `make check` runs format, vet, tidy, and tests. Use `go test ./...` directly for faster iteration
- **Quality gates**: `make check` - required before commits
- **Integration tests**: `make integration` - builds binary and runs tests against live endpoints (requires `gh auth login`)
- Located in `integration/` directory with separate go.mod
- Tests gracefully skip when authentication unavailable
- CI runs these via `.github/workflows/integration.yml`

### Authentication & Setup
- Extension requires `gh auth login` before use - unauthenticated clients show helpful error messages
- Client initialization pattern in `cmd/root.go`: check token, create appropriate client (authenticated vs unauthenticated)

### Release Process
- Create git tag: `git tag v0.0.x main && git push origin tag v0.0.x`
- This triggers `.github/workflows/release.yml` for production builds
- Users install with `gh extension install github/gh-models` (pulls latest release, not latest commit)

## Prompt File Conventions

### Structure (.prompt.yml)
Expand All @@ -62,20 +79,36 @@ evaluators:
- **JSON Schema**: Use `responseFormat: json_schema` with `jsonSchema` field containing strict JSON schema
- **Templates**: All message content supports `{{variable}}` substitution from `testData` entries

### PromptPex Test Generation
- **Command**: `gh models generate` - implements [PromptPex](https://github.com/microsoft/promptpex) methodology
- **Effort levels**: `min` (quick validation), `low` (limits to 3 rules), `medium` (better coverage), `high` (complex inputs, more tokens)
- **Custom instructions**: Use `--instruction-{phase}` flags for intent, inputspec, outputrules, inverseoutputrules, tests
- **Session persistence**: `--session-file` to save/load generation state
- **Documentation**: See `cmd/generate/README.md` and https://microsoft.github.io/promptpex/reference/test-generation/

## Testing Patterns

### Command Tests
### Unit Tests (Command Tests)
- **Location**: `cmd/{command}/{command}_test.go`
- **Pattern**: Create mock client via `azuremodels.NewMockClient()`, inject into `command.Config`
- **Structure**: Table-driven tests with subtests using `t.Run()`
- **Assertions**: Use `testify/require` for cleaner error messages
- **Run**: `make test` or `go test -race -cover ./...`

### Mock Usage
```go
client := azuremodels.NewMockClient()
cfg := command.NewConfig(new(bytes.Buffer), new(bytes.Buffer), client, true, 80)
```

### Integration Tests
- **Location**: `integration/integration_test.go` (separate go.mod)
- **Pattern**: Execute compiled binary via `exec.Command()` with timeout protection
- **Prerequisites**: Binary must exist (`make build` first)
- **Authentication**: Tests skip gracefully when `gh auth` unavailable
- **Focus**: Verify basic functionality, command execution, output format - not full feature testing
- **Run**: `make integration` (combines `make check`, `make build`, and integration tests)

## Integration Points

### GitHub Authentication
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Build and Push Docker Image

on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
workflow_dispatch:

env:
REGISTRY: docker.io
IMAGE_NAME: brainsait/api

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

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

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

- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.api
push: ${{ github.event_name != 'pull_request' }}
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: Image digest
if: github.event_name != 'pull_request'
run: echo "Image pushed with digest ${{ steps.docker_build.outputs.digest }}"
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"ms-azuretools.vscode-docker"
]
}
Loading