Skip to content

Comments

feat: enhanced GitHub Copilot integration — SDK provider, CLI backend, and thinking signature fix#3

Open
tag-assistant wants to merge 693 commits intomainfrom
copilot
Open

feat: enhanced GitHub Copilot integration — SDK provider, CLI backend, and thinking signature fix#3
tag-assistant wants to merge 693 commits intomainfrom
copilot

Conversation

@tag-assistant
Copy link
Owner

Summary

  • Problem: OpenClaw's existing Copilot support lacks SDK-based auth/model discovery, CLI backend support, and has a critical bug where multi-turn conversations crash with HTTP 400 when Claude models replay thinking blocks with field-name-as-signature through the openai-completions API.
  • Why it matters: Users leveraging GitHub Copilot as a model provider (Claude Opus 4.6, GPT-5.3, etc.) get proper token management, automatic model discovery, CLI-mode support, and reliable multi-turn conversations without crashes.
  • What changed: (1) Full Copilot SDK provider with auth and model discovery, (2) Copilot CLI backend for terminal usage, (3) Sanitizer that strips thinking blocks with fake signatures before they poison future turns.
  • What did NOT change: No modifications to existing Copilot provider behavior — these are additive enhancements. Direct Anthropic/OpenAI/Google API paths are untouched.

Change Type (select all)

  • Bug fix
  • Feature

Scope (select all touched areas)

  • Auth / tokens
  • Integrations
  • API / contracts

Linked Issue/PR

Commits

  1. feat: add GitHub Copilot SDK as CLI backend — Copilot credentials, SDK wrapper, CLI runner with streaming + tool call support (22 tests)
  2. feat: add Copilot SDK provider for auth and model discovery — Full provider registration, token management, auto model discovery (31 tests)
  3. fix: strip thinking blocks with field-name-as-signature — Sanitizer + transcript policy for the openai-completions thinking signature bug (15 tests)

User-visible / Behavior Changes

  • New provider github-copilot available for model configuration with SDK-based auth
  • Copilot models (Claude Opus 4.6, GPT-5.3, etc.) auto-discovered from the API
  • copilot CLI backend available for terminal usage
  • Multi-turn conversations with Claude models via Copilot no longer crash with "Invalid signature in thinking block" errors
  • New stripCompletionsReasoningFieldSignatures transcript policy flag — enabled automatically for non-native providers using openai-completions

Security Impact (required)

  • New permissions/capabilities? Yes — Copilot SDK auth reads/refreshes tokens from GitHub
  • Secrets/tokens handling changed? Yes — new Copilot token management flow
  • New/changed network calls? Yes — calls to Copilot API for auth and model discovery
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • Risk + mitigation: Token handling follows existing auth profile patterns. Tokens stored in standard credential store, not logged. API calls use HTTPS only.

Evidence

68 tests passing across 6 test files. Live-tested all models: Claude Opus 4.6 ✅, 4.6 Fast ✅, 4.6 1M ✅, GPT-5.3 Codex ✅

Human Verification (required)

  • Verified: Multi-turn conversations with all Copilot Claude models, thinking block replay, fallback chain, CLI backend streaming
  • Edge cases: Real signatures preserved (not stripped), non-Copilot providers unaffected, mixed thinking/non-thinking turns
  • Not verified: Windows, Docker sandbox mode

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? Yes — new optional github-copilot provider config
  • Migration needed? No

Failure Recovery (if this breaks)

  • Remove github-copilot provider from config, switch to another provider
  • Known symptoms: Auth failures if token expires (auto-refreshes)

Risks and Mitigations

  • Risk: Copilot API changes model IDs or auth flow
    • Mitigation: SDK-based discovery adapts automatically
  • Risk: Thinking signature stripping too aggressive
    • Mitigation: Only targets field-name patterns, real cryptographic signatures preserved. Policy only activates for non-native providers.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

1 similar comment
@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

1 similar comment
@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

11 similar comments
@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@austenstone austenstone requested a review from Copilot February 16, 2026 13:58
@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@tag-assistant tag-assistant force-pushed the copilot branch 2 times, most recently from fe39ae1 to 45b5082 Compare February 17, 2026 00:59
@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

@github-actions
Copy link

⚠️ Formal models conformance drift detected

The formal models extracted constants (generated/*) do not match this openclaw PR.

This check is informational (not blocking merges yet).
See the formal-models-conformance-drift artifact for the diff.

If this change is intentional, follow up by updating the formal models repo or regenerating the extracted artifacts there.

vincentkoc and others added 30 commits February 19, 2026 08:32
* changelog: add security deepMerge prototype-pollution fix entry

* update: refresh gateway service env during update restart

* test(cli): fix daemon install mock assertion

* test(cli): guard update restart false path
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 1beca3a
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 31a27b0
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
…s to user context (openclaw#20597)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 175919a
Co-authored-by: anisoptera <768771+anisoptera@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
…aw#21226)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 7705a77
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
* fix(docker): pin base images to SHA256 digests for supply chain security

Pin all 9 Dockerfiles to immutable SHA256 digests to prevent supply chain
attacks where a compromised upstream image could be silently pulled into
production builds.

Also add Docker ecosystem to Dependabot configuration for automated
digest updates.

Images pinned:
- node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935
- node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45
- debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe
- ubuntu:24.04@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b

Fixes openclaw#7731

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(docker): add digest pinning regression coverage

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…nclaw#21086)

* fix: treat HTTP 503 as failover-eligible for LLM provider errors

When LLM SDKs wrap 503 responses, the leading "503" prefix is lost
(e.g. Google Gemini returns "high demand" / "UNAVAILABLE" without a
numeric prefix). The existing isTransientHttpError only matches
messages starting with "503 ...", so these wrapped errors silently
skip failover — no profile rotation, no model fallback.

This patch closes that gap:

- resolveFailoverReasonFromError: map HTTP status 503 → rate_limit
  (covers structured error objects with a status field)
- ERROR_PATTERNS.overloaded: add /\b503\b/, "service unavailable",
  "high demand" (covers message-only classification when the leading
  status prefix is absent)

Existing isTransientHttpError behavior is unchanged; these additions
are complementary and only fire for errors that previously fell
through unclassified.

* fix: address review feedback — drop /\b503\b/ pattern, add test coverage

- Remove `/\b503\b/` from ERROR_PATTERNS.overloaded to resolve the
  semantic inconsistency noted by reviewers: `isTransientHttpError`
  already handles messages prefixed with "503" (→ "timeout"), so a
  redundant overloaded pattern would classify the same class of errors
  differently depending on message formatting.

- Keep "service unavailable" and "high demand" patterns — these are the
  real gap-fillers for SDK-rewritten messages that lack a numeric prefix.

- Add test case for JSON-wrapped 503 error body containing "overloaded"
  to strengthen coverage.

* fix: unify 503 classification — status 503 → timeout (consistent with isTransientHttpError)

resolveFailoverReasonFromError previously mapped status 503 → "rate_limit",
while the string-based isTransientHttpError mapped "503 ..." → "timeout".

Align both paths: structured {status: 503} now also returns "timeout",
matching the existing transient-error convention. Both reasons are
failover-eligible, so runtime behavior is unchanged.

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…0988)

* fix(slack): pass recipient_team_id and recipient_user_id to streaming API calls

The Slack Agents & AI Apps streaming API (chat.startStream / chat.stopStream)
requires recipient_team_id and recipient_user_id parameters. Without them,
stopStream fails with 'missing_recipient_team_id' (all contexts) or
'missing_recipient_user_id' (DM contexts), causing streamed messages to
disappear after generation completes.

This passes:
- team_id (from auth.test at provider startup, stored in monitor context)
- user_id (from the incoming message sender, for DM recipient identification)

through to the ChatStreamer via recipient_team_id and recipient_user_id options.

Fixes openclaw#19839, openclaw#20847, openclaw#20299, openclaw#19791, openclaw#20337

AI-assisted: Written with Claude (Opus 4.6) via OpenClaw. Lightly tested
(unit tests pass, live workspace verification in progress).

* fix(slack): disable block streaming when native streaming is active

When Slack native streaming (`chat.startStream`/`stopStream`) is enabled,
`disableBlockStreaming` was set to `false`, which activated the app-level
block streaming pipeline. This pipeline intercepted agent output, sent it
via block replies, then dropped the final payloads that would have flowed
through `deliverWithStreaming` to the Slack streaming API — resulting in
zero replies delivered.

Set `disableBlockStreaming: true` when native streaming is active so the
final reply flows through the Slack streaming API path as intended.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…#11046)

- Changed "cask" to "formula" in SKILL.md for consistency.
- Enhanced formula parsing in frontmatter.ts to trim whitespace and fallback to cask if formula is not provided.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.