Skip to content

Commit 63b94d3

Browse files
authored
Merge branch 'main' into edburns/80-java-monorepo-add-phase-01
2 parents 6a773d4 + 477834f commit 63b94d3

23 files changed

Lines changed: 222 additions & 27 deletions

File tree

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## Big picture 🔧
66

7-
- The repo implements language SDKs (Node/TS, Python, Go, .NET, Java) that speak to the **Copilot CLI** via **JSON‑RPC** (see `README.md` and `nodejs/src/client.ts`).
7+
- The repo implements language SDKs (Node/TS, Python, Go, .NET, Rust, Java) that speak to the **Copilot CLI** via **JSON‑RPC** (see `README.md` and `nodejs/src/client.ts`).
88
- Typical flow: your App → SDK client → JSON-RPC → Copilot CLI (server mode). The CLI must be installed or you can connect to an external CLI server via the `CLI URL option (language-specific casing)` (Node: `cliUrl`, Go: `CLIUrl`, .NET: `CliUrl`, Python: `cli_url`, Java: `cliUrl`).
99

1010
## Most important files to read first 📚

.github/workflows/publish.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ jobs:
129129
uses: actions/upload-artifact@v7.0.0
130130
with:
131131
name: dotnet-package
132-
path: dotnet/artifacts/*.nupkg
132+
path: |
133+
dotnet/artifacts/*.nupkg
134+
dotnet/artifacts/*.snupkg
133135
- name: NuGet login (OIDC)
134136
if: github.ref == 'refs/heads/main'
135137
uses: NuGet/login@v1
@@ -142,7 +144,9 @@ jobs:
142144
user: stevesanderson
143145
- name: Publish to NuGet
144146
if: github.ref == 'refs/heads/main'
145-
run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
147+
run: |
148+
dotnet nuget push ./artifacts/*.nupkg --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate --no-symbols
149+
dotnet nuget push ./artifacts/*.snupkg --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
146150
147151
publish-rust:
148152
name: Publish Rust SDK

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Thanks for your interest in contributing!
44

5-
This repository contains the Copilot SDK, a set of multi-language SDKs (Node/TypeScript, Python, Go, .NET) for building applications with the GitHub Copilot agent, maintained by the GitHub Copilot team.
5+
This repository contains the Copilot SDK, a set of multi-language SDKs (Node/TypeScript, Python, Go, .NET, Rust) for building applications with the GitHub Copilot agent, maintained by the GitHub Copilot team.
66

77
Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE).
88

docs/features/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Features
22

3-
These guides cover the capabilities you can add to your Copilot SDK application. Each guide includes examples in all supported languages (TypeScript, Python, Go, .NET, and Java).
3+
These guides cover the capabilities you can add to your Copilot SDK application. Each guide includes examples in supported languages (TypeScript, Python, Go, .NET, Java, and Rust) where available.
44

55
> **New to the SDK?** Start with the [Getting Started tutorial](../getting-started.md) first, then come back here to add more capabilities.
66

docs/integrations/microsoft-agent-framework.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The Microsoft Agent Framework is the unified successor to Semantic Kernel and Au
1414
| **A2A protocol** | Agent-to-Agent communication standard supported by the framework |
1515

1616
> [!NOTE]
17-
> MAF integration packages are available for **.NET** and **Python**. For TypeScript, Go, and Java, use the Copilot SDK directly—the standard SDK APIs already provide tool calling, streaming, and custom agents.
17+
> MAF integration packages are available for **.NET** and **Python**. For TypeScript, Go, Java, and Rust, use the Copilot SDK directly—the standard SDK APIs already provide tool calling, streaming, and custom agents.
1818
1919
## Prerequisites
2020

docs/observability/opentelemetry.md

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,30 @@ var client = new CopilotClient(new CopilotClientOptions()
8484

8585
</details>
8686

87+
<details>
88+
<summary><strong>Rust</strong></summary>
89+
90+
<!-- docs-validate: skip -->
91+
```rust
92+
use github_copilot_sdk::{Client, ClientOptions, TelemetryConfig};
93+
94+
let client = Client::start(ClientOptions::new()
95+
.with_telemetry(TelemetryConfig::new()
96+
.with_otlp_endpoint("http://localhost:4318"))
97+
).await?;
98+
```
99+
100+
</details>
101+
87102
### TelemetryConfig options
88103

89-
| Option | Node.js | Python | Go | .NET | Java | Description |
90-
|---|---|---|---|---|---|---|
91-
| OTLP endpoint | `otlpEndpoint` | `otlp_endpoint` | `OTLPEndpoint` | `OtlpEndpoint` | `otlpEndpoint` | OTLP HTTP endpoint URL |
92-
| File path | `filePath` | `file_path` | `FilePath` | `FilePath` | `filePath` | File path for JSON-lines trace output |
93-
| Exporter type | `exporterType` | `exporter_type` | `ExporterType` | `ExporterType` | `exporterType` | `"otlp-http"` or `"file"` |
94-
| Source name | `sourceName` | `source_name` | `SourceName` | `SourceName` | `sourceName` | Instrumentation scope name |
95-
| Capture content | `captureContent` | `capture_content` | `CaptureContent` | `CaptureContent` | `captureContent` | Whether to capture message content |
104+
| Option | Node.js | Python | Go | .NET | Java | Rust | Description |
105+
|---|---|---|---|---|---|---|---|
106+
| OTLP endpoint | `otlpEndpoint` | `otlp_endpoint` | `OTLPEndpoint` | `OtlpEndpoint` | `otlpEndpoint` | `otlp_endpoint` | OTLP HTTP endpoint URL |
107+
| File path | `filePath` | `file_path` | `FilePath` | `FilePath` | `filePath` | `file_path` | File path for JSON-lines trace output |
108+
| Exporter type | `exporterType` | `exporter_type` | `ExporterType` | `ExporterType` | `exporterType` | `exporter_type` | `"otlp-http"` or `"file"` |
109+
| Source name | `sourceName` | `source_name` | `SourceName` | `SourceName` | `sourceName` | `source_name` | Instrumentation scope name |
110+
| Capture content | `captureContent` | `capture_content` | `CaptureContent` | `CaptureContent` | `captureContent` | `capture_content` | Whether to capture message content |
96111

97112
### Trace context propagation
98113

docs/troubleshooting/mcp-debugging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ When opening an issue or asking for help, collect:
446446

447447
* [ ] SDK language and version
448448
* [ ] CLI version (`copilot --version`)
449-
* [ ] MCP server type (Node.js, Python, .NET, Go, etc.)
449+
* [ ] MCP server type (Node.js, Python, .NET, Go, Rust, etc.)
450450
* [ ] Full MCP server configuration (redact secrets)
451451
* [ ] Result of manual `initialize` test
452452
* [ ] Result of manual `tools/list` test

dotnet/src/Types.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1842,7 +1842,7 @@ public sealed class McpStdioServerConfig : McpServerConfig
18421842
/// Arguments to pass to the command.
18431843
/// </summary>
18441844
[JsonPropertyName("args")]
1845-
public IList<string> Args { get => field ??= []; set; }
1845+
public IList<string>? Args { get; set; }
18461846

18471847
/// <summary>
18481848
/// Environment variables to pass to the server.

dotnet/test/E2E/SessionMcpAndAgentConfigE2ETests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ public async Task Should_Accept_MCP_Server_Configuration_On_Session_Create()
4141
await session.DisposeAsync();
4242
}
4343

44+
[Fact]
45+
public async Task Should_Accept_MCP_Server_Configuration_Without_Args()
46+
{
47+
var mcpServers = new Dictionary<string, McpServerConfig>
48+
{
49+
["test-server"] = new McpStdioServerConfig
50+
{
51+
Command = "echo",
52+
Tools = ["*"]
53+
}
54+
};
55+
56+
var session = await CreateSessionAsync(new SessionConfig
57+
{
58+
McpServers = mcpServers
59+
});
60+
61+
Assert.Matches(@"^[a-f0-9-]+$", session.SessionId);
62+
63+
await session.SendAsync(new MessageOptions { Prompt = "What is 2+2?" });
64+
65+
var message = await TestHelper.GetFinalAssistantMessageAsync(session);
66+
Assert.NotNull(message);
67+
Assert.Contains("4", message!.Data.Content);
68+
69+
await session.DisposeAsync();
70+
}
71+
4472
[Fact]
4573
public async Task Should_Accept_MCP_Server_Configuration_On_Session_Resume()
4674
{

go/internal/e2e/mcp_and_agents_e2e_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,47 @@ func TestMCPServersE2E(t *testing.T) {
5757
session.Disconnect()
5858
})
5959

60+
t.Run("accept MCP server config without args", func(t *testing.T) {
61+
ctx.ConfigureForTest(t)
62+
63+
mcpServers := map[string]copilot.MCPServerConfig{
64+
"test-server": copilot.MCPStdioServerConfig{
65+
Command: "echo",
66+
Tools: []string{"*"},
67+
},
68+
}
69+
70+
session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{
71+
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
72+
MCPServers: mcpServers,
73+
})
74+
if err != nil {
75+
t.Fatalf("Failed to create session: %v", err)
76+
}
77+
78+
if session.SessionID == "" {
79+
t.Error("Expected non-empty session ID")
80+
}
81+
82+
_, err = session.Send(t.Context(), copilot.MessageOptions{
83+
Prompt: "What is 2+2?",
84+
})
85+
if err != nil {
86+
t.Fatalf("Failed to send message: %v", err)
87+
}
88+
89+
message, err := testharness.GetFinalAssistantMessage(t.Context(), session)
90+
if err != nil {
91+
t.Fatalf("Failed to get final message: %v", err)
92+
}
93+
94+
if md, ok := message.Data.(*copilot.AssistantMessageData); !ok || !strings.Contains(md.Content, "4") {
95+
t.Errorf("Expected message to contain '4', got: %v", message.Data)
96+
}
97+
98+
session.Disconnect()
99+
})
100+
60101
t.Run("accept MCP server config on resume", func(t *testing.T) {
61102
ctx.ConfigureForTest(t)
62103

0 commit comments

Comments
 (0)