Skip to content

Commit 5fe27cd

Browse files
committed
Merge main to remove duplicate README churn
The Python README formatting now exists on main independently, so merge the updated base to keep it out of this PR's effective diff. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2 parents c982537 + 7bed2e5 commit 5fe27cd

46 files changed

Lines changed: 1451 additions & 231 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
- Format all: `just format` | Lint all: `just lint` | Test all: `just test`
2525
- Per-language:
2626
- Node: `cd nodejs && npm ci``npm test` (Vitest), `npm run generate:session-types` to regenerate session-event types
27-
- Python: `cd python && uv pip install -e ".[dev]"``uv run pytest` (E2E tests use the test harness)
27+
- Python: `cd python && uv pip install -e . --group dev``uv run pytest` (E2E tests use the test harness)
2828
- Go: `cd go && go test ./...`
2929
- .NET: `cd dotnet && dotnet test test/GitHub.Copilot.SDK.Test.csproj`
3030
- **.NET testing note:** Never add `InternalsVisibleTo` to any project file when writing tests. Tests must only access public APIs.

.github/workflows/sdk-consistency-review.lock.yml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/sdk-consistency-review.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,19 @@ When a pull request modifies any SDK client code, review it to ensure:
7979

8080
## Review Process
8181

82-
1. **Identify the changed SDK(s)**: Determine which language implementation(s) are modified in this PR
83-
2. **Analyze the changes**: Understand what feature/fix is being implemented
84-
3. **Cross-reference other SDKs**: Check if the equivalent functionality exists in other language implementations:
82+
1. **Get the authoritative PR delta**:
83+
- Call `pull_request_read` with `method: get_files` for the PR, paginating until all changed files are retrieved
84+
- Call `pull_request_read` with `method: get_diff` for the PR
85+
- Treat these GitHub API responses as the only authoritative source of which changes belong to the PR, including when the PR head is a merge commit
86+
- Base every claim about what the PR adds or modifies on the API diff; use the local checkout only for surrounding context and cross-SDK comparison
87+
- Never infer the PR base from `HEAD^`, merge-parent ordering, recent commits, or local branch refs
88+
- If the API file list or diff cannot be retrieved, call `missing_data` and stop; do not substitute an inferred local `git diff` range
89+
2. **Identify the changed SDK(s)**: Determine which language implementation(s) are modified in the authoritative PR delta
90+
3. **Analyze the changes**: Understand what feature/fix is being implemented from the authoritative PR delta
91+
4. **Cross-reference other SDKs**: Check if the equivalent functionality exists in other language implementations:
8592
- Read the corresponding files in other SDK directories
8693
- Compare method signatures, behavior, and documentation
87-
4. **Report findings**: If inconsistencies are found:
94+
5. **Report findings**: If inconsistencies are found:
8895
- Use `create-pull-request-review-comment` to add inline comments on specific lines where changes should be made
8996
- Use `add-comment` to provide a summary of cross-SDK consistency findings
9097
- Be specific about which SDKs need updates and what changes would bring them into alignment

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"[go]": {
2626
"editor.defaultFormatter": "golang.go"
2727
},
28+
"java.autobuild.enabled": false,
2829
"java.configuration.updateBuildConfiguration": "automatic",
2930
"java.compile.nullAnalysis.mode": "automatic"
3031
}

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ This is a multi-language SDK repository. Install the tools for the SDK(s) you pl
5050

5151
1. Install [Python 3.8+](https://www.python.org/downloads/)
5252
1. Install [uv](https://github.com/astral-sh/uv)
53-
1. Install dependencies: `cd python && uv pip install -e ".[dev]"`
53+
1. Install dependencies: `cd python && uv pip install -e . --group dev`
5454

5555
### Go SDK
5656

docs/auth/byok.md

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ BYOK allows you to use the Copilot SDK with your own API keys from model provide
77
| Provider | Type Value | Notes |
88
|----------|------------|-------|
99
| OpenAI | `"openai"` | OpenAI API and OpenAI-compatible endpoints |
10-
| Azure OpenAI / Azure AI Foundry | `"azure"` | Azure-hosted models |
10+
| Microsoft Foundry / Azure OpenAI | `"openai"` or `"azure"` | Use `"openai"` for `/openai/v1/`; use `"azure"` for native Azure endpoints |
1111
| Anthropic | `"anthropic"` | Claude models |
1212
| Ollama | `"openai"` | Local models via OpenAI-compatible API |
1313
| Microsoft Foundry Local | `"openai"` | Run AI models locally on your device via OpenAI-compatible API |
1414
| Other OpenAI-compatible | `"openai"` | vLLM, LiteLLM, etc. |
1515

16-
## Quick start: Azure AI Foundry
16+
## Quick start: Microsoft Foundry
1717

18-
Azure AI Foundry (formerly Azure OpenAI) is a common BYOK deployment target for enterprises. Here's a complete example:
18+
Microsoft Foundry is a common BYOK deployment target for enterprises. Here's a complete example:
1919

2020
<details open>
2121
<summary><strong>Python</strong></summary>
@@ -260,9 +260,9 @@ provider: {
260260
}
261261
```
262262

263-
### Azure AI Foundry (OpenAI-compatible endpoint)
263+
### Microsoft Foundry (OpenAI-compatible endpoint)
264264

265-
For Azure AI Foundry deployments with `/openai/v1/` endpoints, use `type: "openai"`:
265+
For Microsoft Foundry deployments with `/openai/v1/` endpoints, use `type: "openai"`:
266266

267267
```typescript
268268
provider: {
@@ -493,14 +493,6 @@ Results are cached after the first call, just like the default behavior. The han
493493

494494
## Limitations
495495

496-
When using BYOK, be aware of these limitations:
497-
498-
### Identity limitations
499-
500-
BYOK authentication uses **static credentials only**.
501-
502-
You must use an API key or static bearer token that you manage yourself.
503-
504496
### Feature limitations
505497

506498
Some Copilot features may behave differently with BYOK:
@@ -514,9 +506,8 @@ Some Copilot features may behave differently with BYOK:
514506

515507
| Provider | Limitations |
516508
|----------|-------------|
517-
| Azure AI Foundry | No Entra ID auth; must use API keys |
518-
| Ollama | No API key; local only; model support varies |
519509
| [Microsoft Foundry Local](https://foundrylocal.ai) | Local only; model availability depends on device hardware; no API key required |
510+
| Ollama | No API key; local only; model support varies |
520511
| OpenAI | Subject to OpenAI rate limits and quotas |
521512

522513
## Troubleshooting
@@ -571,7 +562,7 @@ provider: {
571562
}
572563
```
573564

574-
However, if your Azure AI Foundry deployment provides an OpenAI-compatible endpoint path (e.g., `/openai/v1/`), use `type: "openai"`:
565+
However, if your Microsoft Foundry deployment provides an OpenAI-compatible endpoint path (for example, `/openai/v1/`), use `type: "openai"`:
575566

576567
<!-- docs-validate: hidden -->
577568
```typescript
@@ -589,7 +580,7 @@ const session = await client.createSession({
589580
<!-- /docs-validate: hidden -->
590581

591582
```typescript
592-
// ✅ Correct: OpenAI-compatible Azure AI Foundry endpoint
583+
// ✅ Correct: OpenAI-compatible Microsoft Foundry endpoint
593584
provider: {
594585
type: "openai",
595586
baseUrl: "https://your-resource.openai.azure.com/openai/v1/",

docs/features/custom-agents.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,9 @@ Sub-agent-originated session events share the parent session stream and include
445445
| Event | Emitted when | Data |
446446
|-------|-------------|------|
447447
| `subagent.selected` | Runtime selects an agent for the task | `agentName`, `agentDisplayName`, `tools` |
448-
| `subagent.started` | Sub-agent begins execution | `toolCallId`, `agentName`, `agentDisplayName`, `agentDescription` |
449-
| `subagent.completed` | Sub-agent finishes successfully | `toolCallId`, `agentName`, `agentDisplayName` |
450-
| `subagent.failed` | Sub-agent encounters an error | `toolCallId`, `agentName`, `agentDisplayName`, `error` |
448+
| `subagent.started` | Sub-agent begins execution | `toolCallId`, `agentName`, `agentDisplayName`, `agentDescription`, `model?` |
449+
| `subagent.completed` | Sub-agent finishes successfully | `toolCallId`, `agentName`, `agentDisplayName`, `model?`, `durationMs?`, `totalTokens?`, `totalToolCalls?` |
450+
| `subagent.failed` | Sub-agent encounters an error | `toolCallId`, `agentName`, `agentDisplayName`, `error`, `model?`, `durationMs?`, `totalTokens?`, `totalToolCalls?` |
451451
| `subagent.deselected` | Runtime switches away from the sub-agent ||
452452

453453
### Subscribing to events
@@ -466,11 +466,15 @@ session.on((event) => {
466466

467467
case "subagent.completed":
468468
console.log(`✅ Sub-agent completed: ${event.data.agentDisplayName}`);
469+
if (event.data.durationMs !== undefined) console.log(` Duration: ${event.data.durationMs}ms`);
470+
if (event.data.totalTokens !== undefined) console.log(` Tokens: ${event.data.totalTokens}`);
471+
if (event.data.totalToolCalls !== undefined) console.log(` Tool calls: ${event.data.totalToolCalls}`);
469472
break;
470473

471474
case "subagent.failed":
472475
console.log(`❌ Sub-agent failed: ${event.data.agentDisplayName}`);
473476
console.log(` Error: ${event.data.error}`);
477+
if (event.data.durationMs !== undefined) console.log(` Duration: ${event.data.durationMs}ms`);
474478
break;
475479

476480
case "subagent.selected":

docs/features/fleet-mode.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ Native typed bindings for fleet mode were verified in Node.js/TypeScript, Python
176176
Plan-mode UIs can start fleet deployment by returning the `autopilot_fleet` exit action. The generated session event types describe it as:
177177

178178
```typescript
179-
type PlanModeExitAction =
179+
type ExitPlanModeAction =
180180
| "exit_only"
181181
| "interactive"
182182
| "autopilot"

docs/features/session-limits.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ let limits = SessionLimitsConfig {
131131

132132
let session = client
133133
.create_session(
134-
SessionConfig::new()
134+
SessionConfig::default()
135135
.approve_all_permissions()
136136
.with_session_limits(limits.clone()),
137137
)

docs/features/streaming-events.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,12 +443,20 @@ Ephemeral. Token usage and cost information for an individual API call.
443443
| `model` | `string` || Model identifier (e.g., `"gpt-5.4"`) |
444444
| `inputTokens` | `number` | | Input tokens consumed |
445445
| `outputTokens` | `number` | | Output tokens produced |
446+
| `reasoningTokens` | `number` | | Output tokens used for reasoning/chain-of-thought (subset of `outputTokens`) |
446447
| `cacheReadTokens` | `number` | | Tokens read from prompt cache |
447448
| `cacheWriteTokens` | `number` | | Tokens written to prompt cache |
449+
| `cacheExpiresAt` | `string` | | ISO 8601 timestamp when the prompt cache for this model call expires |
450+
| `contentFilterTriggered` | `boolean` | | Whether the response was blocked or truncated by content filtering (`finish_reason === 'content_filter'`) |
451+
| `finishReason` | `string` | | Model finish reason (e.g., `"stop"`, `"length"`, `"tool_calls"`, `"content_filter"`) |
448452
| `cost` | `number` | | Model multiplier cost for billing |
449453
| `duration` | `number` | | API call duration in milliseconds |
454+
| `timeToFirstTokenMs` | `number` | | Time from request dispatch to first token received (streaming latency) |
455+
| `interTokenLatencyMs` | `number` | | Average latency between consecutive tokens (streaming throughput) |
456+
| `reasoningEffort` | `string` | | Reasoning effort level used for this call (e.g., `"low"`, `"medium"`, `"high"`) |
450457
| `initiator` | `string` | | What triggered this call (e.g., `"sub-agent"`); absent for user-initiated |
451458
| `apiCallId` | `string` | | Completion ID from the provider (e.g., `chatcmpl-abc123`) |
459+
| `serviceRequestId` | `string` | | Copilot service request ID (`x-copilot-service-request-id`) for CAPI log correlation |
452460
| `apiEndpoint` | `"/chat/completions" \| "/v1/messages" \| "/responses" \| "ws:/responses"` | | API endpoint used for the model call; useful for observability and cost attribution. `ws:/responses` is the websocket variant of the responses API |
453461
| `providerCallId` | `string` | | GitHub request tracing ID (`x-github-request-id`) |
454462
| `parentToolCallId` | `string` | | Deprecated. Use envelope-level `agentId` for sub-agent attribution |
@@ -733,6 +741,7 @@ A custom agent was invoked as a sub-agent.
733741
| `agentName` | `string` || Internal name of the sub-agent |
734742
| `agentDisplayName` | `string` || Human-readable display name |
735743
| `agentDescription` | `string` || Description of what the sub-agent does |
744+
| `model` | `string` | | Model the sub-agent will run with, when known at start |
736745

737746
### `subagent.completed`
738747

@@ -743,6 +752,10 @@ A sub-agent finished successfully.
743752
| `toolCallId` | `string` || Matches the corresponding `subagent.started` |
744753
| `agentName` | `string` || Internal name |
745754
| `agentDisplayName` | `string` || Display name |
755+
| `model` | `string` | | Model used by the sub-agent |
756+
| `durationMs` | `number` | | Wall-clock execution duration in milliseconds |
757+
| `totalTokens` | `number` | | Total input and output tokens consumed |
758+
| `totalToolCalls` | `number` | | Total tool calls made |
746759

747760
### `subagent.failed`
748761

@@ -754,6 +767,10 @@ A sub-agent encountered an error.
754767
| `agentName` | `string` || Internal name |
755768
| `agentDisplayName` | `string` || Display name |
756769
| `error` | `string` || Error message |
770+
| `model` | `string` | | Model selected for the sub-agent, when known |
771+
| `durationMs` | `number` | | Wall-clock execution duration in milliseconds |
772+
| `totalTokens` | `number` | | Total input and output tokens consumed before failure |
773+
| `totalToolCalls` | `number` | | Total tool calls made before failure |
757774

758775
### `subagent.selected`
759776

@@ -958,9 +975,9 @@ This table lists key `data` payload fields. Common envelope fields are documente
958975
| `user_input.completed` || User Input | `requestId` |
959976
| `elicitation.requested` || User Input | `requestId`, `message`, `requestedSchema` |
960977
| `elicitation.completed` || User Input | `requestId` |
961-
| `subagent.started` | | Sub-Agent | `toolCallId`, `agentName`, `agentDisplayName` |
962-
| `subagent.completed` | | Sub-Agent | `toolCallId`, `agentName`, `agentDisplayName` |
963-
| `subagent.failed` | | Sub-Agent | `toolCallId`, `agentName`, `error` |
978+
| `subagent.started` | | Sub-Agent | `toolCallId`, `agentName`, `agentDisplayName`, `model?` |
979+
| `subagent.completed` | | Sub-Agent | `toolCallId`, `agentName`, `agentDisplayName`, `model?`, `durationMs?`, `totalTokens?`, `totalToolCalls?` |
980+
| `subagent.failed` | | Sub-Agent | `toolCallId`, `agentName`, `error`, `model?`, `durationMs?`, `totalTokens?`, `totalToolCalls?` |
964981
| `subagent.selected` | | Sub-Agent | `agentName`, `agentDisplayName`, `tools` |
965982
| `subagent.deselected` | | Sub-Agent | *(empty)* |
966983
| `skill.invoked` | | Skill | `name`, `path`, `content`, `allowedTools?` |

0 commit comments

Comments
 (0)