copilot-sdk-supercharged 2.2.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c36a15eb69c732f5661c54325b83a2b10337a45e271bc3df776b0069514cbb0
4
- data.tar.gz: fbcc9e01930bf0d7995295ffc0b1895d4f2afbae01367f258811f3d197d1f209
3
+ metadata.gz: 8d80c4e262952967db3b9ed58e8899587afa12b158074ab57d7f475af58ccd68
4
+ data.tar.gz: 302abe246cec1dd679f2036f49407a10b01756c421634a3c97f6fb1105743606
5
5
  SHA512:
6
- metadata.gz: '06917253b38db497246957e4e69aa7551f92cb25c3306a318dda3f34b87a586db33e864c04b23615b29f264cc23ac87b7e13e51a599db96a156c3b9c6b9f3b37'
7
- data.tar.gz: 368a57e037e6c5a9f570c6f6e2704a8b5cf2f4c5ca228c75c2d09e605a528ab793216b4f26864b5807cb6c480e87eec8f2c6bc5653b58eceb2a2caa606d0e85a
6
+ metadata.gz: e7aa7ee115dfe39db890cffa6d1d4535caf0b6926cde80b0346b5ce3e8e5a9ca24b688af91c49b223aa5fbdb1e95733052f142b4bcef42d18d69101ccae1fde5
7
+ data.tar.gz: f51f8baeb7ede5fb5db28855db3e94f397379e78d75e9f6aa871a6c970733b8bfd80ab5d3013acc21510add30f29be55e7db79cb6251061355470b220e95655a
@@ -55,7 +55,8 @@ module Copilot
55
55
  auto_restart: true,
56
56
  env: nil,
57
57
  github_token: nil,
58
- use_logged_in_user: nil
58
+ use_logged_in_user: nil,
59
+ on_get_trace_context: nil
59
60
  )
60
61
  # Validate mutually exclusive options
61
62
  if cli_url && (use_stdio == false || cli_path)
@@ -95,6 +96,7 @@ module Copilot
95
96
  env: env,
96
97
  github_token: github_token,
97
98
  use_logged_in_user: use_logged_in_user,
99
+ on_get_trace_context: on_get_trace_context,
98
100
  )
99
101
 
100
102
  @process = nil
@@ -281,6 +283,10 @@ module Copilot
281
283
  session._register_permission_handler(config[:on_permission_request]) if config[:on_permission_request]
282
284
  session._register_user_input_handler(config[:on_user_input_request]) if config[:on_user_input_request]
283
285
  session._register_hooks(config[:hooks]) if config[:hooks]
286
+ session._register_exit_plan_mode_handler(config[:on_exit_plan_mode]) if config[:on_exit_plan_mode]
287
+ if @options.on_get_trace_context
288
+ session._register_trace_context_provider(@options.on_get_trace_context)
289
+ end
284
290
 
285
291
  @sessions_lock.synchronize { @sessions[session_id] = session }
286
292
  session
@@ -305,6 +311,10 @@ module Copilot
305
311
  session._register_permission_handler(config[:on_permission_request]) if config[:on_permission_request]
306
312
  session._register_user_input_handler(config[:on_user_input_request]) if config[:on_user_input_request]
307
313
  session._register_hooks(config[:hooks]) if config[:hooks]
314
+ session._register_exit_plan_mode_handler(config[:on_exit_plan_mode]) if config[:on_exit_plan_mode]
315
+ if @options.on_get_trace_context
316
+ session._register_trace_context_provider(@options.on_get_trace_context)
317
+ end
308
318
 
309
319
  @sessions_lock.synchronize { @sessions[resumed_id] = session }
310
320
  session
@@ -633,6 +643,10 @@ module Copilot
633
643
  @rpc_client.on_request("hooks.invoke") do |params|
634
644
  handle_hooks_invoke(params)
635
645
  end
646
+
647
+ @rpc_client.on_request("exitPlanMode.request") do |params|
648
+ handle_exit_plan_mode_request(params)
649
+ end
636
650
  end
637
651
 
638
652
  def verify_protocol_version
@@ -769,6 +783,21 @@ module Copilot
769
783
  { output: output }
770
784
  end
771
785
 
786
+ def handle_exit_plan_mode_request(params)
787
+ session_id = params["sessionId"]
788
+ raise "Invalid exit plan mode request payload" unless session_id
789
+
790
+ session = @sessions_lock.synchronize { @sessions[session_id] }
791
+ raise "Session not found: #{session_id}" unless session
792
+
793
+ begin
794
+ result = session._handle_exit_plan_mode_request(params)
795
+ result
796
+ rescue StandardError
797
+ { approved: true }
798
+ end
799
+ end
800
+
772
801
  # ---- Payload builders ----
773
802
 
774
803
  def build_create_session_payload(config)
@@ -789,6 +818,7 @@ module Copilot
789
818
  payload[:requestPermission] = true if config[:on_permission_request]
790
819
  payload[:requestUserInput] = true if config[:on_user_input_request]
791
820
  payload[:hooks] = true if config[:hooks]&.respond_to?(:any_handler?) && config[:hooks].any_handler?
821
+ payload[:requestExitPlanMode] = true if config[:on_exit_plan_mode]
792
822
  payload[:workingDirectory] = config[:working_directory] if config[:working_directory]
793
823
  payload[:streaming] = config[:streaming] unless config[:streaming].nil?
794
824
 
@@ -796,6 +826,9 @@ module Copilot
796
826
  payload[:provider] = config[:provider].respond_to?(:to_wire) ? config[:provider].to_wire : config[:provider]
797
827
  end
798
828
 
829
+ token = config[:auth_token] || config[:github_token] || config[:git_hub_token]
830
+ payload[:gitHubToken] = token if token
831
+
799
832
  payload[:mcpServers] = config[:mcp_servers] if config[:mcp_servers]
800
833
 
801
834
  if config[:custom_agents]
@@ -812,6 +845,23 @@ module Copilot
812
845
  payload[:infiniteSessions] = is_cfg.respond_to?(:to_wire) ? is_cfg.to_wire : is_cfg
813
846
  end
814
847
 
848
+ # --- Upstream-sync session options (parity with @github/copilot-sdk) ---
849
+ payload[:enableCitations] = config[:enable_citations] unless config[:enable_citations].nil?
850
+ payload[:excludedBuiltinAgents] = config[:excluded_builtin_agents] if config[:excluded_builtin_agents]
851
+ if config[:session_limits]
852
+ sl = config[:session_limits]
853
+ payload[:sessionLimits] = sl.respond_to?(:to_wire) ? sl.to_wire : sl
854
+ end
855
+ if config[:memory]
856
+ mem = config[:memory]
857
+ payload[:memory] = mem.respond_to?(:to_wire) ? mem.to_wire : mem
858
+ end
859
+ payload[:otlpProtocol] = config[:otlp_protocol] if config[:otlp_protocol]
860
+ payload[:enableWebSocketResponses] = config[:enable_web_socket_responses] unless config[:enable_web_socket_responses].nil?
861
+ payload[:expAssignments] = config[:exp_assignments] if config[:exp_assignments]
862
+ # MCP OAuth host token handler: signal to the runtime that a handler is registered.
863
+ payload[:mcpAuthHandler] = true if config[:on_mcp_auth_request]
864
+
815
865
  payload
816
866
  end
817
867
 
@@ -79,7 +79,8 @@ module Copilot
79
79
  # @return [Object] the +result+ from the JSON-RPC response
80
80
  # @raise [JsonRpcError] if the server returns an error
81
81
  # @raise [Timeout::Error] if the request times out
82
- def request(method, params = nil, timeout: 30)
82
+ def request(method, params = nil, timeout: 30, **kwargs)
83
+ params = kwargs if params.nil? && !kwargs.empty?
83
84
  request_id = SecureRandom.uuid
84
85
  queue = Queue.new
85
86
 
@@ -126,7 +127,8 @@ module Copilot
126
127
  #
127
128
  # @param method [String] the RPC method name
128
129
  # @param params [Hash, nil] optional parameters
129
- def notify(method, params = nil)
130
+ def notify(method, params = nil, **kwargs)
131
+ params = kwargs if params.nil? && !kwargs.empty?
130
132
  send_message({
131
133
  jsonrpc: "2.0",
132
134
  method: method,
@@ -53,6 +53,11 @@ module Copilot
53
53
 
54
54
  @hooks = nil
55
55
  @hooks_lock = Mutex.new
56
+
57
+ @exit_plan_mode_handler = nil
58
+ @exit_plan_mode_handler_lock = Mutex.new
59
+
60
+ @trace_context_provider = nil
56
61
  end
57
62
 
58
63
  # Send a message to this session.
@@ -63,12 +68,31 @@ module Copilot
63
68
  # @param response_format [String, nil] desired response format ("text", "image", "json_object")
64
69
  # @param image_options [ImageOptions, nil] options for image generation
65
70
  # @return [String] the message ID
66
- def send(prompt:, attachments: nil, mode: nil, response_format: nil, image_options: nil)
71
+ def send(prompt:, attachments: nil, mode: nil, agent_mode: nil, display_prompt: nil, request_headers: nil, response_format: nil, image_options: nil)
67
72
  payload = { sessionId: @session_id, prompt: prompt }
68
73
  payload[:attachments] = attachments if attachments
69
74
  payload[:mode] = mode if mode
75
+ payload[:agentMode] = agent_mode if agent_mode
76
+ payload[:displayPrompt] = display_prompt if display_prompt
77
+ payload[:requestHeaders] = request_headers if request_headers
70
78
  payload[:responseFormat] = response_format if response_format
71
79
  payload[:imageOptions] = image_options.to_h if image_options
80
+
81
+ # Inject trace context if provider is available
82
+ if @trace_context_provider
83
+ begin
84
+ tc = @trace_context_provider.call
85
+ if tc
86
+ tp = tc.respond_to?(:traceparent) ? tc.traceparent : tc[:traceparent]
87
+ ts = tc.respond_to?(:tracestate) ? tc.tracestate : tc[:tracestate]
88
+ payload[:traceparent] = tp if tp
89
+ payload[:tracestate] = ts if ts
90
+ end
91
+ rescue StandardError
92
+ # ignore trace context errors
93
+ end
94
+ end
95
+
72
96
  response = @rpc_client.request("session.send", payload)
73
97
  response["messageId"]
74
98
  end
@@ -87,7 +111,7 @@ module Copilot
87
111
  # @return [SessionEvent, nil] the final assistant.message event, or nil
88
112
  # @raise [Timeout::Error] if the timeout expires before session.idle
89
113
  # @raise [RuntimeError] if the session emits a session.error event
90
- def send_and_wait(prompt:, attachments: nil, mode: nil, response_format: nil, image_options: nil, timeout: 60)
114
+ def send_and_wait(prompt:, attachments: nil, mode: nil, agent_mode: nil, display_prompt: nil, request_headers: nil, response_format: nil, image_options: nil, timeout: 60)
91
115
  idle_mutex = Mutex.new
92
116
  idle_cv = ConditionVariable.new
93
117
  idle_fired = false
@@ -118,6 +142,8 @@ module Copilot
118
142
 
119
143
  begin
120
144
  self.send(prompt: prompt, attachments: attachments, mode: mode,
145
+ agent_mode: agent_mode, display_prompt: display_prompt,
146
+ request_headers: request_headers,
121
147
  response_format: response_format, image_options: image_options)
122
148
 
123
149
  idle_mutex.synchronize do
@@ -202,6 +228,8 @@ module Copilot
202
228
  @permission_handler_lock.synchronize { @permission_handler = nil }
203
229
  @user_input_handler_lock.synchronize { @user_input_handler = nil }
204
230
  @hooks_lock.synchronize { @hooks = nil }
231
+ @exit_plan_mode_handler_lock.synchronize { @exit_plan_mode_handler = nil }
232
+ @trace_context_provider = nil
205
233
  end
206
234
 
207
235
  # Abort the currently processing message.
@@ -286,6 +314,32 @@ module Copilot
286
314
  @hooks_lock.synchronize { @hooks = hooks }
287
315
  end
288
316
 
317
+ # @api private
318
+ def _register_exit_plan_mode_handler(handler)
319
+ @exit_plan_mode_handler_lock.synchronize { @exit_plan_mode_handler = handler }
320
+ end
321
+
322
+ # @api private
323
+ def _handle_exit_plan_mode_request(params)
324
+ handler = @exit_plan_mode_handler_lock.synchronize { @exit_plan_mode_handler }
325
+ unless handler
326
+ return { approved: true }
327
+ end
328
+
329
+ begin
330
+ request = ExitPlanModeRequest.from_hash(params)
331
+ result = handler.call(request)
332
+ result.is_a?(ExitPlanModeResponse) ? result.to_h : result
333
+ rescue StandardError
334
+ { approved: true }
335
+ end
336
+ end
337
+
338
+ # @api private
339
+ def _register_trace_context_provider(provider)
340
+ @trace_context_provider = provider
341
+ end
342
+
289
343
  # @api private
290
344
  def _handle_hooks_invoke(hook_type, input_data)
291
345
  hooks = @hooks_lock.synchronize { @hooks }
data/lib/copilot/types.rb CHANGED
@@ -596,6 +596,67 @@ module Copilot
596
596
  :github_token, :use_logged_in_user, :session_idle_timeout_seconds,
597
597
  :session_fs,
598
598
  :copilot_home, :tcp_connection_token,
599
+ :request_handler,
599
600
  keyword_init: true
600
601
  )
602
+
603
+ # --- Upstream-sync feature types (parity with @github/copilot-sdk) ---
604
+
605
+ # Per-session AI-credit budget; set +max_ai_credits+ to cap spend.
606
+ SessionLimitsConfig = Struct.new(:max_ai_credits, keyword_init: true) do
607
+ def to_wire
608
+ { maxAiCredits: max_ai_credits }.compact
609
+ end
610
+ end
611
+
612
+ # Opt-in persistent session memory.
613
+ MemoryConfiguration = Struct.new(:enabled, keyword_init: true) do
614
+ def to_wire
615
+ { enabled: enabled }.compact
616
+ end
617
+ end
618
+
619
+ # Arguments passed to a BYOK +bearer_token_provider+ callable (per-session scoping).
620
+ ProviderTokenArgs = Struct.new(:session_id, keyword_init: true)
621
+
622
+ # Intercept outbound LLM inference HTTP/WebSocket requests. Assign an instance to
623
+ # +ClientOptions#request_handler+ and override +send_request+ to mutate, replace,
624
+ # or forward the request. BYOK providers may also set +bearer_token_provider+.
625
+ class CopilotRequestHandler
626
+ def send_request(request, _context)
627
+ request
628
+ end
629
+ end
630
+
631
+ # Tool "defer" loading policy: eager pre-load ("never") or lazy via search ("auto").
632
+ module ToolDefer
633
+ AUTO = "auto"
634
+ NEVER = "never"
635
+ end
636
+
637
+ # System-message section identifiers (used with system_message section overrides).
638
+ # The "preamble" section targets only the identity preamble; the "preserve" action
639
+ # protects an individually-addressable section from a group-level remove.
640
+ module SystemMessageSection
641
+ PREAMBLE = "preamble"
642
+ IDENTITY = "identity"
643
+ TOOL_INSTRUCTIONS = "tool_instructions"
644
+ PRESERVE = "preserve"
645
+ end
646
+
647
+ # Hook names include :on_pre_tool_use, :on_post_tool_use, :on_pre_mcp_tool_call,
648
+ # and :on_mcp_auth_request (MCP OAuth host token handler).
649
+
650
+ # GitHub-anchored attachment variants.
651
+ module GitHubAttachment
652
+ GITHUB_COMMIT = "GitHubCommit"
653
+ GITHUB_RELEASE = "GitHubRelease"
654
+ GITHUB_ACTIONS_JOB = "GitHubActionsJob"
655
+ GITHUB_REPOSITORY = "GitHubRepository"
656
+ GITHUB_FILE_DIFF = "GitHubFileDiff"
657
+ GITHUB_TREE_COMPARISON = "GitHubTreeComparison"
658
+ GITHUB_URL = "GitHubUrl"
659
+ GITHUB_FILE = "GitHubFile"
660
+ GITHUB_SNIPPET = "GitHubSnippet"
661
+ end
601
662
  end
@@ -3,5 +3,5 @@
3
3
  # Copyright (c) Microsoft Corporation. All rights reserved.
4
4
 
5
5
  module Copilot
6
- VERSION = "2.0.0"
6
+ VERSION = "2.1.0"
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: copilot-sdk-supercharged
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremiah Isaacson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-06 00:00:00.000000000 Z
11
+ date: 2026-07-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  A Ruby SDK for interacting with the GitHub Copilot CLI server via JSON-RPC 2.0.