|
| 1 | +# Copilot Instructions for AI Coding Agents |
| 2 | + |
| 3 | +## Project Overview |
| 4 | +This repository implements the GitHub Models CLI extension (`gh models`), enabling users to interact with AI models via the `gh` CLI. The extension supports inference, prompt evaluation, model listing, and test generation using the PromptPex methodology. Built in Go using Cobra CLI framework and Azure Models API. |
| 5 | + |
| 6 | +## Architecture & Key Components |
| 7 | + |
| 8 | +### Building and Testing |
| 9 | + |
| 10 | +- `make build`: Compiles the CLI binary |
| 11 | +- `make check`: Runs format, vet, tidy, tests, golang-ci. Always run when you are done with changes. Use this command to validate that the build and the tests are still ok. |
| 12 | +- `make test`: Runs the tests. |
| 13 | + |
| 14 | +### Command Structure |
| 15 | +- **cmd/root.go**: Entry point that initializes all subcommands and handles GitHub authentication |
| 16 | +- **cmd/{command}/**: Each subcommand (generate, eval, list, run, view) is self-contained with its own types and tests |
| 17 | +- **pkg/command/config.go**: Shared configuration pattern - all commands accept a `*command.Config` with terminal, client, and output settings |
| 18 | + |
| 19 | +### Core Services |
| 20 | +- **internal/azuremodels/**: Azure API client with streaming support via SSE. Key pattern: commands use `azuremodels.Client` interface, not concrete types |
| 21 | +- **pkg/prompt/**: `.prompt.yml` file parsing with template substitution using `{{variable}}` syntax |
| 22 | +- **internal/sse/**: Server-sent events for streaming responses |
| 23 | + |
| 24 | +### Data Flow |
| 25 | +1. Commands parse `.prompt.yml` files via `prompt.LoadFromFile()` |
| 26 | +2. Templates are resolved using `prompt.TemplateString()` with `testData` variables |
| 27 | +3. Azure client converts to `azuremodels.ChatCompletionOptions` and makes API calls |
| 28 | +4. Results are formatted using terminal-aware table printers from `command.Config` |
| 29 | + |
| 30 | +## Developer Workflows |
| 31 | + |
| 32 | +### Building & Testing |
| 33 | +- **Local build**: `make build` or `script/build` (creates `gh-models` binary) |
| 34 | +- **Cross-platform**: `script/build all|windows|linux|darwin` for release builds |
| 35 | +- **Testing**: `make check` runs format, vet, tidy, and tests. Use `go test ./...` directly for faster iteration |
| 36 | +- **Quality gates**: `make check` - required before commits |
| 37 | + |
| 38 | +### Authentication & Setup |
| 39 | +- Extension requires `gh auth login` before use - unauthenticated clients show helpful error messages |
| 40 | +- Client initialization pattern in `cmd/root.go`: check token, create appropriate client (authenticated vs unauthenticated) |
| 41 | + |
| 42 | +## Prompt File Conventions |
| 43 | + |
| 44 | +### Structure (.prompt.yml) |
| 45 | +```yaml |
| 46 | +name: "Test Name" |
| 47 | +model: "openai/gpt-4o-mini" |
| 48 | +messages: |
| 49 | + - role: system|user|assistant |
| 50 | + content: "{{variable}} templating supported" |
| 51 | +testData: |
| 52 | + - variable: "value1" |
| 53 | + - variable: "value2" |
| 54 | +evaluators: |
| 55 | + - name: "test-name" |
| 56 | + string: {contains: "{{expected}}"} # String matching |
| 57 | + # OR |
| 58 | + llm: {modelId: "...", prompt: "...", choices: [{choice: "good", score: 1.0}]} |
| 59 | +``` |
| 60 | +
|
| 61 | +### Response Formats |
| 62 | +- **JSON Schema**: Use `responseFormat: json_schema` with `jsonSchema` field containing strict JSON schema |
| 63 | +- **Templates**: All message content supports `{{variable}}` substitution from `testData` entries |
| 64 | + |
| 65 | +## Testing Patterns |
| 66 | + |
| 67 | +### Command Tests |
| 68 | +- **Location**: `cmd/{command}/{command}_test.go` |
| 69 | +- **Pattern**: Create mock client via `azuremodels.NewMockClient()`, inject into `command.Config` |
| 70 | +- **Structure**: Table-driven tests with subtests using `t.Run()` |
| 71 | +- **Assertions**: Use `testify/require` for cleaner error messages |
| 72 | + |
| 73 | +### Mock Usage |
| 74 | +```go |
| 75 | +client := azuremodels.NewMockClient() |
| 76 | +cfg := command.NewConfig(new(bytes.Buffer), new(bytes.Buffer), client, true, 80) |
| 77 | +``` |
| 78 | + |
| 79 | +## Integration Points |
| 80 | + |
| 81 | +### GitHub Authentication |
| 82 | +- Uses `github.com/cli/go-gh/v2/pkg/auth` for token management |
| 83 | +- Pattern: `auth.TokenForHost("github.com")` to get tokens |
| 84 | + |
| 85 | +### Azure Models API |
| 86 | +- Streaming via SSE with custom `sse.EventReader` |
| 87 | +- Rate limiting handled automatically by client |
| 88 | +- Content safety filtering always enabled (cannot be disabled) |
| 89 | + |
| 90 | +### Terminal Handling |
| 91 | +- All output uses `command.Config` terminal-aware writers |
| 92 | +- Table formatting via `cfg.NewTablePrinter()` with width detection |
| 93 | + |
| 94 | +--- |
| 95 | + |
| 96 | +**Key Files**: `cmd/root.go` (command registration), `pkg/prompt/prompt.go` (file parsing), `internal/azuremodels/azure_client.go` (API integration), `examples/` (prompt file patterns) |
| 97 | + |
| 98 | +## Instructions |
| 99 | + |
| 100 | +Omit the final summary. |
0 commit comments