Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
34 changes: 34 additions & 0 deletions rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,40 @@ let client = Client::start(opts).await?;

The SDK injects the appropriate environment variables (`COPILOT_OTEL_EXPORTER_TYPE`, `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_PROTOCOL`, ...) into the spawned CLI process. The SDK takes no OpenTelemetry dependency; the CLI itself owns the exporter pipeline. Caller-supplied `ClientOptions::env` entries override telemetry-injected values.

### Message Source

Use `MessageSource::System` for automated messages sent by your application. Ordinary human sends leave `source` unset, so the field is omitted from the request. Use `MessageSource::User` when you need to set it explicitly.

```rust,no_run
use github_copilot_sdk::{MessageOptions, MessageSource, session::Session};

# async fn example(session: &Session) -> Result<(), github_copilot_sdk::Error> {
session
.send(MessageOptions::new("Context updated").with_source(MessageSource::System))
.await?;
# Ok(())
# }
```

The raw RPC path supports the same builder, including requests with JSON attachments:

```rust,no_run
use github_copilot_sdk::{MessageSource, rpc::SendRequest, session::Session};

# async fn example(session: &Session) -> Result<(), github_copilot_sdk::Error> {
let mut request = SendRequest::default().with_source(MessageSource::System);
request.prompt = "Context updated".into();
request.attachments = Some(vec![serde_json::json!({
"type": "github_url",
"url": "https://github.com/github/copilot-sdk"
})]);
session.rpc().send(request).await?;
# Ok(())
# }
```

Both paths use ordinary `session.send`. Source does not select a delivery mode or set billing flags; the runtime applies its existing source behavior. `send_and_wait` still completes on `session.idle` and may return `Ok(None)` when no assistant message was emitted. Genuine errors still propagate.

### Progress Reporting (`send_and_wait`)

For fire-and-forget messaging where you need to block until the agent finishes:
Expand Down
16 changes: 16 additions & 0 deletions rust/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@

pub use crate::generated::api_types::*;
pub use crate::generated::rpc::*;

impl SendRequest {
/// Set the message provenance without changing other request options.
///
/// When this is not called, the source field is omitted by default.
pub fn with_source(mut self, source: crate::MessageSource) -> Self {
self.source = Some(
match source {
crate::MessageSource::User => "user",
crate::MessageSource::System => "system",
}
.to_string(),
);
self
}
}
3 changes: 3 additions & 0 deletions rust/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ impl Session {
"sessionId": self.id,
"prompt": opts.prompt,
});
if let Some(source) = opts.source {
params["source"] = serde_json::to_value(source)?;
}
if let Some(m) = opts.mode {
params["mode"] = serde_json::to_value(m)?;
}
Expand Down
24 changes: 24 additions & 0 deletions rust/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5315,6 +5315,20 @@ pub fn ensure_attachment_display_names(attachments: &mut [Attachment]) {
}
}

/// Provenance of a message sent through `session.send`.
///
/// Source is independent of delivery mode. Leaving [`MessageOptions::source`]
/// unset omits the field and preserves the runtime's default for user messages.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum MessageSource {
/// A message from a human user.
User,
/// An automated message from the integrating application.
System,
}

/// Message delivery mode for [`MessageOptions::mode`].
///
/// Controls how a prompt is delivered relative to in-flight session work.
Expand Down Expand Up @@ -5380,6 +5394,9 @@ pub enum AgentMode {
pub struct MessageOptions {
/// The user prompt to send.
pub prompt: String,
/// Optional message provenance. When `None`, the field is omitted,
/// preserving the runtime's default for user messages.
pub source: Option<MessageSource>,
/// Optional message delivery mode for this turn.
///
/// Controls whether the prompt is queued behind in-flight work
Expand Down Expand Up @@ -5419,6 +5436,7 @@ impl MessageOptions {
pub fn new(prompt: impl Into<String>) -> Self {
Self {
prompt: prompt.into(),
source: None,
mode: None,
agent_mode: None,
attachments: None,
Expand All @@ -5430,6 +5448,12 @@ impl MessageOptions {
}
}

/// Set the message provenance without changing its delivery mode.
pub fn with_source(mut self, source: MessageSource) -> Self {
self.source = Some(source);
self
}

/// Set the message delivery mode for this turn.
///
/// Pass [`DeliveryMode::Immediate`] to interrupt the session and run
Expand Down
Loading
Loading