From 31dde23b61c15aa120f1cd4747d0a777f423b118 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Fri, 4 Sep 2026 20:26:24 +0000 Subject: [PATCH 1/4] Add Copilot app to enterprise custom agent surfaces (#63079) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../copilot/concepts/agents/cloud-agent/about-custom-agents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md b/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md index f05c5d257c63..00207e306d2b 100644 --- a/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md +++ b/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md @@ -23,6 +23,7 @@ Once you create {% data variables.copilot.custom_agents_short %}, they become av * **{% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}**: The agents tab and panel, issue assignment, and pull requests * **{% data variables.copilot.copilot_cloud_agent %} in IDEs**: {% data variables.product.prodname_vscode %}, JetBrains IDEs, Eclipse, and Xcode +* **{% data variables.copilot.github_copilot_app %}** * **{% data variables.copilot.copilot_cli %}** You can use {% data variables.copilot.agent_profiles %} directly in {% data variables.product.prodname_vscode %}, JetBrains IDEs, Eclipse, and Xcode. Some properties may function differently or be ignored between environments. From 9b94bf03fbbb8b476272df779c5e6705b68cd095 Mon Sep 17 00:00:00 2001 From: docs-bot <77750099+docs-bot@users.noreply.github.com> Date: Fri, 4 Sep 2026 20:27:19 +0000 Subject: [PATCH 2/4] Convert legacy \{\% note/warning/tip/danger %} Liquid blocks to GFM alerts in translations (#63093) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: heiskr <1221423+heiskr@users.noreply.github.com> Co-authored-by: Kevin Heis --- .../lib/correct-translation-content.ts | 97 ++++++++++++++++ .../tests/correct-translation-content.ts | 108 ++++++++++++------ 2 files changed, 168 insertions(+), 37 deletions(-) diff --git a/src/languages/lib/correct-translation-content.ts b/src/languages/lib/correct-translation-content.ts index dc5e65fe0ef8..93a68ae18934 100644 --- a/src/languages/lib/correct-translation-content.ts +++ b/src/languages/lib/correct-translation-content.ts @@ -2721,6 +2721,14 @@ export function correctTranslatedContentStrings( content = content.replaceAll('{%endraw %}', '{% endraw %}') content = content.replaceAll('{%endraw -%}', '{% endraw -%}') + // `{% note %}` / `{% warning %}` / `{% tip %}` / `{% danger %}` were removed + // from the Liquid renderer (replaced by GFM alert blockquotes, see + // PR #62960 / commit 8b174bc4), but many translation files were forked + // before that change and still use the old tag syntax, which now fails + // with "tag not found" render errors. Strip the obsolete tags so the rest + // of the content renders. + content = stripLegacyAlertTags(content) + // Strip stray closing-only Liquid tags that have no matching opener anywhere // in the content. Translators sometimes insert spurious closers (e.g. an // extra `{% endif %}`) when they re-arrange paragraphs. We only remove a @@ -2993,3 +3001,92 @@ function joinDanglingMarkers(content: string): string { return out.join('\n') } + +/** + * Remove the obsolete `{% note %}` / `{% warning %}` / `{% tip %}` / + * `{% danger %}` Liquid tags (and their closers) from translated content. + * + * These tags were removed from the renderer in favour of GFM alert + * blockquotes, so any leftover occurrence now fails to render. Stripping + * them leaves the surrounding text intact. + * + * Skips YAML frontmatter, fenced code blocks, `{% raw %}` blocks, and inline + * code spans, where the tags are literal examples rather than markup. + */ +function stripLegacyAlertTags(content: string): string { + const tagPattern = /\{%-?\s*(?:end)?(?:note|warning|tip|danger)\s*-?%\}[ \t]*/g + const lines = content.split('\n') + const out: string[] = [] + let inFence = false + let fenceChar = '' + let fenceLen = 0 + let inRaw = false + let inFrontmatter = lines[0] === '---' + + const stripOutsideInlineCode = (line: string): string => + line + .split('`') + .map((segment, index) => (index % 2 === 0 ? segment.replace(tagPattern, '') : segment)) + .join('`') + + for (let i = 0; i < lines.length; i++) { + const line = lines[i] + + if (inFrontmatter) { + if (i > 0 && (line === '---' || line === '...')) inFrontmatter = false + out.push(line) + continue + } + + const fenceMatch = line.match(/^[ \t]*(`{3,}|~{3,})/) + if (fenceMatch) { + const marker = fenceMatch[1] + if (!inFence) { + inFence = true + fenceChar = marker[0] + fenceLen = marker.length + } else if (marker[0] === fenceChar && marker.length >= fenceLen) { + inFence = false + fenceChar = '' + fenceLen = 0 + } + out.push(line) + continue + } + + if (inFence) { + out.push(line) + continue + } + + if (inRaw) { + if (/\{%-?\s*endraw\s*-?%\}/.test(line)) inRaw = false + out.push(line) + continue + } + if (/\{%-?\s*raw\s*-?%\}/.test(line) && !/\{%-?\s*endraw\s*-?%\}/.test(line)) { + inRaw = true + out.push(line) + continue + } + + const withoutTags = stripOutsideInlineCode(line) + if (withoutTags === line) { + out.push(line) + continue + } + const stripped = withoutTags.replace(/[ \t]+$/, '') + + // The line contained only the tag: drop it, and collapse the surrounding + // blank lines into one so the alert body keeps its original spacing. + if (stripped === '') { + const previousIsBlank = out.length === 0 || out[out.length - 1] === '' + if (previousIsBlank && lines[i + 1] === '') i++ + continue + } + + out.push(stripped) + } + + return out.join('\n') +} diff --git a/src/languages/tests/correct-translation-content.ts b/src/languages/tests/correct-translation-content.ts index f275480ab2eb..3eec0f15b46f 100644 --- a/src/languages/tests/correct-translation-content.ts +++ b/src/languages/tests/correct-translation-content.ts @@ -127,9 +127,9 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes translated note block tags', () => { - expect(fix('{% nota %}', 'es')).toBe('{% note %}') - expect(fix('{%- nota %}', 'es')).toBe('{%- note %}') - expect(fix('{%- nota -%}', 'es')).toBe('{%- note -%}') + expect(fix('{% nota %}', 'es')).toBe('') + expect(fix('{%- nota %}', 'es')).toBe('') + expect(fix('{%- nota -%}', 'es')).toBe('') }) test('fixes otra → else', () => { @@ -238,8 +238,8 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes note keyword', () => { - expect(fix('{% メモ %}', 'ja')).toBe('{% note %}') - expect(fix('{%- メモ %}', 'ja')).toBe('{%- note %}') + expect(fix('{% メモ %}', 'ja')).toBe('') + expect(fix('{%- メモ %}', 'ja')).toBe('') }) test('fixes Japanese or (または) in ifversion tags', () => { @@ -557,8 +557,8 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes observação → note', () => { - expect(fix('{% observação %}', 'pt')).toBe('{% note %}') - expect(fix('{%- observação %}', 'pt')).toBe('{%- note %}') + expect(fix('{% observação %}', 'pt')).toBe('') + expect(fix('{%- observação %}', 'pt')).toBe('') }) test('fixes comentário → comment', () => { @@ -567,8 +567,8 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes nota de fim → endnote', () => { - expect(fix('{% nota de fim %}', 'pt')).toBe('{% endnote %}') - expect(fix('{%- nota de fim %}', 'pt')).toBe('{%- endnote %}') + expect(fix('{% nota de fim %}', 'pt')).toBe('') + expect(fix('{%- nota de fim %}', 'pt')).toBe('') }) test('fixes Dados variables → data variables', () => { @@ -912,8 +912,8 @@ describe('correctTranslatedContentStrings', () => { test('fixes other translated keywords', () => { expect(fix('{% конечным %}', 'ru')).toBe('{% endif %}') expect(fix('{%- конечным %}', 'ru')).toBe('{%- endif %}') - expect(fix('{% примечание %}', 'ru')).toBe('{% note %}') - expect(fix('{%- примечание %}', 'ru')).toBe('{%- note %}') + expect(fix('{% примечание %}', 'ru')).toBe('') + expect(fix('{%- примечание %}', 'ru')).toBe('') expect(fix('{% конечных головщиков %}', 'ru')).toBe('{% endrowheaders %}') expect(fix('{% эндкёрл %}', 'ru')).toBe('{% endcurl %}') expect(fix('{%- эндкёрл %}', 'ru')).toBe('{%- endcurl %}') @@ -1098,15 +1098,15 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes translated block tags', () => { - expect(fix('{% remarque %}', 'fr')).toBe('{% note %}') - expect(fix('{%- remarque %}', 'fr')).toBe('{%- note %}') - expect(fix('{%- remarque -%}', 'fr')).toBe('{%- note -%}') - expect(fix('{% avertissement %}', 'fr')).toBe('{% warning %}') - expect(fix('{%- avertissement %}', 'fr')).toBe('{%- warning %}') - expect(fix('{%- avertissement -%}', 'fr')).toBe('{%- warning -%}') - expect(fix('{% conseil %}', 'fr')).toBe('{% tip %}') - expect(fix('{%- conseil %}', 'fr')).toBe('{%- tip %}') - expect(fix('{%- conseil -%}', 'fr')).toBe('{%- tip -%}') + expect(fix('{% remarque %}', 'fr')).toBe('') + expect(fix('{%- remarque %}', 'fr')).toBe('') + expect(fix('{%- remarque -%}', 'fr')).toBe('') + expect(fix('{% avertissement %}', 'fr')).toBe('') + expect(fix('{%- avertissement %}', 'fr')).toBe('') + expect(fix('{%- avertissement -%}', 'fr')).toBe('') + expect(fix('{% conseil %}', 'fr')).toBe('') + expect(fix('{%- conseil %}', 'fr')).toBe('') + expect(fix('{%- conseil -%}', 'fr')).toBe('') }) test('removes orphaned endif when no matching ifversion/elsif opener exists', () => { @@ -1136,8 +1136,8 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes note de fin → endnote', () => { - expect(fix('{% note de fin %}', 'fr')).toBe('{% endnote %}') - expect(fix('{%- note de fin %}', 'fr')).toBe('{%- endnote %}') + expect(fix('{% note de fin %}', 'fr')).toBe('') + expect(fix('{%- note de fin %}', 'fr')).toBe('') }) test('fixes éclipse → eclipse platform tag', () => { @@ -1282,8 +1282,8 @@ describe('correctTranslatedContentStrings', () => { test('fixes translated keywords', () => { expect(fix('{% 기타 %}', 'ko')).toBe('{% else %}') expect(fix('{%- 기타 %}', 'ko')).toBe('{%- else %}') - expect(fix('{% 참고 %}', 'ko')).toBe('{% note %}') - expect(fix('{%- 참고 %}', 'ko')).toBe('{%- note %}') + expect(fix('{% 참고 %}', 'ko')).toBe('') + expect(fix('{%- 참고 %}', 'ko')).toBe('') expect(fix('{% 원시 %}', 'ko')).toBe('{% raw %}') expect(fix('{%- 원시 %}', 'ko')).toBe('{%- raw %}') }) @@ -1338,8 +1338,8 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes 주석 끝 → endnote', () => { - expect(fix('{% 주석 끝 %}', 'ko')).toBe('{% endnote %}') - expect(fix('{%- 주석 끝 %}', 'ko')).toBe('{%- endnote %}') + expect(fix('{% 주석 끝 %}', 'ko')).toBe('') + expect(fix('{%- 주석 끝 %}', 'ko')).toBe('') }) test('fixes capitalized Variables → data variables', () => { @@ -1405,15 +1405,15 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes translated block tags', () => { - expect(fix('{% Hinweis %}', 'de')).toBe('{% note %}') - expect(fix('{%- Hinweis %}', 'de')).toBe('{%- note %}') - expect(fix('{%- Hinweis -%}', 'de')).toBe('{%- note -%}') - expect(fix('{% Warnung %}', 'de')).toBe('{% warning %}') - expect(fix('{%- Warnung %}', 'de')).toBe('{%- warning %}') - expect(fix('{%- Warnung -%}', 'de')).toBe('{%- warning -%}') - expect(fix('{% Tipp %}', 'de')).toBe('{% tip %}') - expect(fix('{%- Tipp %}', 'de')).toBe('{%- tip %}') - expect(fix('{%- Tipp -%}', 'de')).toBe('{%- tip -%}') + expect(fix('{% Hinweis %}', 'de')).toBe('') + expect(fix('{%- Hinweis %}', 'de')).toBe('') + expect(fix('{%- Hinweis -%}', 'de')).toBe('') + expect(fix('{% Warnung %}', 'de')).toBe('') + expect(fix('{%- Warnung %}', 'de')).toBe('') + expect(fix('{%- Warnung -%}', 'de')).toBe('') + expect(fix('{% Tipp %}', 'de')).toBe('') + expect(fix('{%- Tipp %}', 'de')).toBe('') + expect(fix('{%- Tipp -%}', 'de')).toBe('') }) test('fixes capitalized Codespaces platform tag', () => { @@ -1515,8 +1515,8 @@ describe('correctTranslatedContentStrings', () => { }) test('fixes Endnotiz → endnote', () => { - expect(fix('{% Endnotiz %}', 'de')).toBe('{% endnote %}') - expect(fix('{%- Endnotiz %}', 'de')).toBe('{%- endnote %}') + expect(fix('{% Endnotiz %}', 'de')).toBe('') + expect(fix('{%- Endnotiz %}', 'de')).toBe('') }) test('fixes endifen → endif (via generic)', () => { @@ -3010,4 +3010,38 @@ Para más información, consulta "[AUTOTITLE](/path)". expect(output).toContain('GitHub нижнего колонтитула, для всех пользователей') }) }) + + describe('universal: strips legacy {% note/warning/tip/danger %} tags', () => { + test('strips a simple flush-left {% note %} block', () => { + const broken = '{% note %}\n\n**Note:** Some note text.\n\n{% endnote %}\n' + expect(fix(broken, 'es')).toBe('**Note:** Some note text.\n') + }) + + test('strips {% warning %}, {% tip %}, and {% danger %} tags', () => { + expect(fix('{% warning %}\nBe careful.\n{% endwarning %}', 'ja')).toBe('Be careful.') + expect(fix('{% tip %}\nHelpful hint.\n{% endtip %}', 'de')).toBe('Helpful hint.') + expect(fix('{% danger %}\nDangerous.\n{% enddanger %}', 'fr')).toBe('Dangerous.') + }) + + test('strips a {% note %} block indented inside a list item', () => { + const broken = '- Item text.\n\n {% note %}\n\n Nested note text.\n\n {% endnote %}\n' + expect(fix(broken, 'pt')).toBe('- Item text.\n\n Nested note text.\n') + }) + + test('leaves already-converted GFM alerts unchanged', () => { + const correct = '> [!NOTE]\n> Already converted note.' + expect(fix(correct, 'ko')).toBe(correct) + }) + + test('strips tags that share a line with other Liquid tags', () => { + const broken = '{% ifversion fpt %} {% note %}\n\nText.\n\n{% endnote %} {% endif %}' + expect(fix(broken, 'zh')).toBe('{% ifversion fpt %}\n\nText.\n\n{% endif %}') + }) + + test('leaves legacy tags inside fenced code blocks and inline code alone', () => { + const example = '```\n{% note %}\nExample.\n{% endnote %}\n```\n' + expect(fix(example, 'es')).toBe(example) + expect(fix('Use `{% note %}` here.', 'es')).toBe('Use `{% note %}` here.') + }) + }) }) From be4d995f7eb07f2bbcf1a9f6b664ff91f7f31a11 Mon Sep 17 00:00:00 2001 From: Sunbrye Ly <56200261+sunbrye@users.noreply.github.com> Date: Fri, 4 Sep 2026 20:51:47 +0000 Subject: [PATCH 3/4] Tented Model 0060 (#63059) Copilot-Session: cf2e091d-5a94-4e29-a003-e5739bd66c49 --- .../reference/ai-models/model-hosting.md | 1 + .../reference/ai-models/supported-models.md | 2 ++ .../copilot-billing/models-and-pricing.md | 2 +- .../copilot-cloud-agent-non-auto-models.md | 1 + data/tables/copilot/model-comparison.yml | 5 +++++ data/tables/copilot/model-release-status.yml | 4 ++++ .../copilot/model-supported-clients.yml | 9 ++++++++ data/tables/copilot/model-supported-plans.yml | 7 ++++++ data/tables/copilot/models-and-pricing.yml | 22 +++++++++++++++++++ data/variables/copilot.yml | 1 + 10 files changed, 53 insertions(+), 1 deletion(-) diff --git a/content/copilot/reference/ai-models/model-hosting.md b/content/copilot/reference/ai-models/model-hosting.md index 01d3967232ea..9dd754d33b1d 100644 --- a/content/copilot/reference/ai-models/model-hosting.md +++ b/content/copilot/reference/ai-models/model-hosting.md @@ -27,6 +27,7 @@ Used for: * {% data variables.copilot.copilot_gpt_56_luna %} * {% data variables.copilot.copilot_gpt_56_sol %} * {% data variables.copilot.copilot_gpt_56_terra %} +* {% data variables.copilot.copilot_gpt_6_astra %} These models are hosted by OpenAI and {% data variables.product.github %}'s Azure infrastructure. diff --git a/content/copilot/reference/ai-models/supported-models.md b/content/copilot/reference/ai-models/supported-models.md index 8553f121ce86..4d67e8352f60 100644 --- a/content/copilot/reference/ai-models/supported-models.md +++ b/content/copilot/reference/ai-models/supported-models.md @@ -92,6 +92,7 @@ Choosing a larger context window or higher reasoning will impact {% data variabl | {% data variables.copilot.copilot_gpt_56_luna %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | {% data variables.copilot.copilot_gpt_56_sol %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | {% data variables.copilot.copilot_gpt_56_terra %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | +| {% data variables.copilot.copilot_gpt_6_astra %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | {% data variables.copilot.copilot_kimi_k3 %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% endrowheaders %} @@ -133,6 +134,7 @@ Some {% data variables.product.prodname_copilot_short %} models require minimum | {% data variables.copilot.copilot_gpt_56_luna %} | `1.128.0` | TBD | TBD | TBD | TBD | | {% data variables.copilot.copilot_gpt_56_sol %} | `1.128.0` | TBD | TBD | TBD | TBD | | {% data variables.copilot.copilot_gpt_56_terra %} | `1.128.0` | TBD | TBD | TBD | TBD | +| {% data variables.copilot.copilot_gpt_6_astra %} | `1.136.1` | `17.14.19` | TBD | TBD | TBD | | {% data variables.copilot.copilot_claude_opus_48 %} | `v1.118` | `17.14.6` | TBD | TBD | TBD | | {% data variables.copilot.copilot_claude_opus_5 %} | `v1.128.0` | `17.14.22` | TBD | TBD | TBD | | {% data variables.copilot.copilot_claude_sonnet_5 %} | `v1.124` | `17.14.6` | TBD | TBD | TBD | diff --git a/content/copilot/reference/copilot-billing/models-and-pricing.md b/content/copilot/reference/copilot-billing/models-and-pricing.md index 8d4ef319e0e0..7bacdf1cee27 100644 --- a/content/copilot/reference/copilot-billing/models-and-pricing.md +++ b/content/copilot/reference/copilot-billing/models-and-pricing.md @@ -33,7 +33,7 @@ All prices are **per 1 million tokens**. {% data reusables.copilot.extended-context-pricing %} -{% data variables.copilot.copilot_gpt_56_sol %}, {% data variables.copilot.copilot_gpt_56_terra %}, and {% data variables.copilot.copilot_gpt_56_luna %} include a cache write cost in addition to cached input. Earlier OpenAI models have no cache write cost. +{% data variables.copilot.copilot_gpt_56_sol %}, {% data variables.copilot.copilot_gpt_56_terra %}, {% data variables.copilot.copilot_gpt_56_luna %}, and {% data variables.copilot.copilot_gpt_6_astra %} include a cache write cost in addition to cached input. Earlier OpenAI models have no cache write cost. | Model | Release status | Category | Tier | Threshold (input tokens) | Input | Cached input | Cache write | Output | | --- | --- | --- | --- | --- | ---: | ---: | ---: | ---: | diff --git a/data/reusables/copilot/copilot-cloud-agent-non-auto-models.md b/data/reusables/copilot/copilot-cloud-agent-non-auto-models.md index 4e6057c35981..99abd0563331 100644 --- a/data/reusables/copilot/copilot-cloud-agent-non-auto-models.md +++ b/data/reusables/copilot/copilot-cloud-agent-non-auto-models.md @@ -9,6 +9,7 @@ * {% data variables.copilot.copilot_gpt_56_luna %} * {% data variables.copilot.copilot_gpt_56_sol %} * {% data variables.copilot.copilot_gpt_56_terra %} +* {% data variables.copilot.copilot_gpt_6_astra %} * {% data variables.copilot.copilot_grok_45 %} * {% data variables.copilot.copilot_grok_46 %} * {% data variables.copilot.copilot_mai_code_1_flash %} diff --git a/data/tables/copilot/model-comparison.yml b/data/tables/copilot/model-comparison.yml index d70e0220908d..92d71a7cc499 100644 --- a/data/tables/copilot/model-comparison.yml +++ b/data/tables/copilot/model-comparison.yml @@ -48,6 +48,11 @@ excels_at: Balanced everyday interactive and agentic coding further_reading: '[GPT-5.6 model card](https://deploymentsafety.openai.com/gpt-5-6/gpt-5-6.pdf)' +- name: GPT-6 Astra + task_area: Long-horizon, autonomous coding and agentic tasks + excels_at: Long-horizon coding tasks with continuous planning, batched diagnosis and verification, and independent result confirmation + further_reading: '[GPT-6 Astra model card](https://deploymentsafety.openai.com/gpt-6-astra/gpt-6-astra.pdf)' + # Anthropic - name: Claude Fable 5 task_area: Long-horizon, autonomous coding and knowledge-work diff --git a/data/tables/copilot/model-release-status.yml b/data/tables/copilot/model-release-status.yml index 5b71281891be..e3aed8a2ca9a 100644 --- a/data/tables/copilot/model-release-status.yml +++ b/data/tables/copilot/model-release-status.yml @@ -51,6 +51,10 @@ provider: 'OpenAI' release_status: 'GA' +- name: 'GPT-6 Astra' + provider: 'OpenAI' + release_status: 'GA' + # Anthropic models - name: 'Claude Fable 5' diff --git a/data/tables/copilot/model-supported-clients.yml b/data/tables/copilot/model-supported-clients.yml index 8e28325a392a..51d50ccc9855 100644 --- a/data/tables/copilot/model-supported-clients.yml +++ b/data/tables/copilot/model-supported-clients.yml @@ -230,6 +230,15 @@ xcode: false jetbrains: false +- name: GPT-6 Astra + dotcom: true + cli: true + vscode: true + vs: true + eclipse: true + xcode: true + jetbrains: true + - name: Grok 4.5 dotcom: false cli: true diff --git a/data/tables/copilot/model-supported-plans.yml b/data/tables/copilot/model-supported-plans.yml index f71dd5d87974..b1560f4c9cf8 100644 --- a/data/tables/copilot/model-supported-plans.yml +++ b/data/tables/copilot/model-supported-plans.yml @@ -166,6 +166,13 @@ business: true enterprise: true +- name: GPT-6 Astra + pro: false + pro_plus: true + max: true + business: true + enterprise: true + - name: Grok 4.5 pro: true pro_plus: true diff --git a/data/tables/copilot/models-and-pricing.yml b/data/tables/copilot/models-and-pricing.yml index 2650488cbc43..054b1fe87753 100644 --- a/data/tables/copilot/models-and-pricing.yml +++ b/data/tables/copilot/models-and-pricing.yml @@ -174,6 +174,28 @@ output: $18.00 cache_write: $5.00 +- model: GPT-6 Astra + provider: openai + release_status: GA + category: Powerful + threshold: '≤ 272K' + tier: Default + input: $10.00 + cached_input: $1.00 + output: $50.00 + cache_write: $12.50 + +- model: GPT-6 Astra + provider: openai + release_status: GA + category: Powerful + threshold: '> 272K' + tier: 'Long context' + input: $20.00 + cached_input: $2.00 + output: $75.00 + cache_write: $25.00 + # Anthropic - model: Claude Haiku 4.5 provider: anthropic diff --git a/data/variables/copilot.yml b/data/variables/copilot.yml index 412fe5c6b891..d4c9ea0d09de 100644 --- a/data/variables/copilot.yml +++ b/data/variables/copilot.yml @@ -232,6 +232,7 @@ copilot_gpt_55: 'GPT-5.5' copilot_gpt_56_luna: 'GPT-5.6 Luna' copilot_gpt_56_sol: 'GPT-5.6 Sol' copilot_gpt_56_terra: 'GPT-5.6 Terra' +copilot_gpt_6_astra: 'GPT-6 Astra' # OpenAI 'o' series: copilot_o3: 'o3' copilot_o4_mini: 'o4-mini' From 334c77944728d2a3abe2b648e9efae687f7c674b Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 4 Sep 2026 21:50:57 +0000 Subject: [PATCH 4/4] Document enterprise managed sandbox enforcement (#63063) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: hubwriter --- content/copilot/concepts/about-cloud-and-local-sandboxes.md | 2 +- .../agents/copilot-cli/understanding-local-sandboxing.md | 2 +- .../configuring-local-sandbox-settings.md | 4 +++- .../cloud-and-local-sandboxes/using-local-sandboxing.md | 6 +++--- .../copilot-cli-reference/cli-command-reference.md | 4 ++-- .../copilot-cli-reference/cli-config-dir-reference.md | 5 +++-- .../enterprise-managed-settings.md | 6 ++++-- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/content/copilot/concepts/about-cloud-and-local-sandboxes.md b/content/copilot/concepts/about-cloud-and-local-sandboxes.md index c3bd49f74a55..7dc5cc5609a0 100644 --- a/content/copilot/concepts/about-cloud-and-local-sandboxes.md +++ b/content/copilot/concepts/about-cloud-and-local-sandboxes.md @@ -53,7 +53,7 @@ To enable local sandboxing inside a {% data variables.copilot.copilot_cli_short /sandbox enable ``` -After you enable local sandboxing, the commands and tools that an agent runs on your behalf—shell commands, file search, and, by default, the MCP and language (LSP) servers the CLI starts—run inside an operating-system-level sandbox, limiting their access to your system. The CLI continues to use local sandboxing whenever you use the CLI in future—for programmatic as well as interactive use—until you run `/sandbox disable` to disable it. If enterprise managed settings require sandboxing, you cannot disable it. +After you enable local sandboxing, the commands and tools that an agent runs on your behalf—shell commands, file search, and, by default, the MCP and language (LSP) servers the CLI starts—run inside an operating-system-level sandbox, limiting their access to your system. The CLI continues to use local sandboxing whenever you use the CLI in future—for programmatic as well as interactive use—until you run `/sandbox disable` to disable it. If enterprise managed settings require sandboxing, ordinary settings, startup options, and `/sandbox disable` cannot turn it off. If the effective policy permits sandbox bypass, you can still explicitly disable sandboxing for the rest of the current session from an active bypass permission prompt. The CLI's built-in file tools—first-party commands that are part of the CLI, rather than shell commands like `sed`—run in-process in the CLI. Because the CLI itself is not sandboxed, the operating-system sandbox never sees the file operations these tools perform and cannot constrain them. Instead, the built-in tools are coded to check the sandbox policy themselves and honor your configured settings on a best-effort basis. diff --git a/content/copilot/concepts/agents/copilot-cli/understanding-local-sandboxing.md b/content/copilot/concepts/agents/copilot-cli/understanding-local-sandboxing.md index b88dc94887af..07cea5583c6f 100644 --- a/content/copilot/concepts/agents/copilot-cli/understanding-local-sandboxing.md +++ b/content/copilot/concepts/agents/copilot-cli/understanding-local-sandboxing.md @@ -111,7 +111,7 @@ You can grant extra read/write or read-only paths, deny paths, and change other ## Enterprise-managed policies -If you get {% data variables.product.prodname_copilot_short %} through an enterprise-owned organization, an administrator can enforce a filesystem policy through managed settings. Managed settings act as a baseline that you cannot loosen: they can require sandboxing, add denied paths, and limit which paths you are allowed to grant. Where a managed setting applies, the `/sandbox config` dialog shows it as a locked **(managed)** value, and `/sandbox policy` reflects it in the resolved policy. +If you get {% data variables.product.prodname_copilot_short %} through an enterprise-owned organization, an administrator can enforce a filesystem policy through managed settings. Managed settings act as a restrictive baseline: they can require sandboxing, add denied paths, and limit which paths you are allowed to grant. Where a managed setting applies, the `/sandbox config` dialog shows it as a locked **(managed)** value, and `/sandbox policy` reflects it in the resolved policy. If the effective policy permits sandbox bypass, a user can explicitly disable sandboxing for the rest of the current session from an active bypass permission prompt. This session opt-out does not loosen the saved policy. Unlike most settings, where a single source wins, the sandbox policy is composed from every source in force at once. Managed settings can arrive through more than one channel simultaneously—server-managed, MDM, and file-based—and these combine with each other, and with your own settings, in the **most restrictive** direction rather than one source overriding another: a required toggle stays on, denied paths from all sources add up, and the paths you are allowed to grant can only be narrowed. For more information, see [AUTOTITLE](/copilot/reference/enterprise-administrators/enterprise-managed-settings#sandbox). diff --git a/content/copilot/how-tos/cloud-and-local-sandboxes/configuring-local-sandbox-settings.md b/content/copilot/how-tos/cloud-and-local-sandboxes/configuring-local-sandbox-settings.md index b64c12fef1c5..295be57c903a 100644 --- a/content/copilot/how-tos/cloud-and-local-sandboxes/configuring-local-sandbox-settings.md +++ b/content/copilot/how-tos/cloud-and-local-sandboxes/configuring-local-sandbox-settings.md @@ -36,7 +36,7 @@ The **General** tab controls the top-level sandbox behavior. When enterprise man | Setting | Description | | --- | --- | | **Enable sandbox** | Run shell commands inside the sandbox. You can also toggle this with `/sandbox enable` and `/sandbox disable`. | -| **Allow sandbox bypass** | Let the model request that individual commands run outside the sandbox, subject to approval. Turned on by default. For more information, see [Allowing sandbox bypass](#allowing-sandbox-bypass). | +| **Allow sandbox bypass** | Let the model request that individual commands run outside the sandbox, subject to approval. A bypass prompt can also let you disable sandboxing for the rest of the current session. Turned on by default. For more information, see [Allowing sandbox bypass](#allowing-sandbox-bypass). | | **Sandbox MCP servers** | Run MCP servers inside the sandbox. Turned on by default. | | **Sandbox LSP servers** | Run language servers (LSP servers) inside the sandbox. Turned on by default. | @@ -47,6 +47,8 @@ The **Allow sandbox bypass** setting controls what happens when {% data variable * **On (default)**: If a command fails inside the sandbox, you are prompted to allow {% data variables.product.prodname_copilot_short %} to run the command outside the sandbox. Your response to this prompt applies to this specific attempt to run the command. Optionally, you can choose to disable the sandbox for the rest of the session (if permitted by your enterprise), or you can enter an instruction for {% data variables.product.prodname_copilot_short %} to work on instead. * **Off**: If {% data variables.product.prodname_copilot_short %} can't run a command successfully in the sandbox, it stops working on the task and reports the failure. +If enterprise managed settings set `sandbox.allowBypass` to `false`, you cannot approve individual commands to run outside the sandbox or disable sandboxing for the rest of the session. If managed settings require sandboxing but the effective policy permits bypass, you can disable sandboxing only from an active bypass permission prompt, not through ordinary settings or `/sandbox disable`. + ## Configuring authentication settings The **Auth** tab controls whether your credentials are made available to commands running inside the sandbox. As on the other tabs, an enterprise-managed value is shown as `(managed)` and can't be changed. diff --git a/content/copilot/how-tos/cloud-and-local-sandboxes/using-local-sandboxing.md b/content/copilot/how-tos/cloud-and-local-sandboxes/using-local-sandboxing.md index 8e90ca24c3e6..f163e5637098 100644 --- a/content/copilot/how-tos/cloud-and-local-sandboxes/using-local-sandboxing.md +++ b/content/copilot/how-tos/cloud-and-local-sandboxes/using-local-sandboxing.md @@ -20,7 +20,7 @@ docsTeamMetrics: Sandboxing is currently an experimental feature. To use it, start {% data variables.copilot.copilot_cli_short %} with the `‑‑experimental` command line option, or enter `/experimental on` during a session. -When you enable local sandboxing, {% data variables.copilot.copilot_cli_short %} runs most of the commands and tools it invokes on your behalf inside an operating-system sandbox. After you enable local sandboxing, it is used for all your {% data variables.copilot.copilot_cli_short %} sessions until you disable it, or turn it off for a specific session. If enterprise managed settings require sandboxing, you cannot disable it. +When you enable local sandboxing, {% data variables.copilot.copilot_cli_short %} runs most of the commands and tools it invokes on your behalf inside an operating-system sandbox. After you enable local sandboxing, it is used for all your {% data variables.copilot.copilot_cli_short %} sessions until you disable it, or turn it off for a specific session. If enterprise managed settings require sandboxing, ordinary configuration, the `--no-sandbox` command line option, and the `/sandbox disable` command cannot disable it. However, if the effective policy permits sandbox bypass, you can explicitly disable sandboxing for the rest of the current session from an active bypass permission prompt. By default, sandboxed commands and tools can write within your current working directory and temporary folders. Your user profile (home) directory, along with system and tool locations are read-only. Other disk locations are blocked. In a Git repository, the rest of the repository above your current working directory is readable but not writable. Access to your local and private network is permitted, as is outbound internet access. @@ -60,7 +60,7 @@ After you enable local sandboxing, it continues to be used for the current and f ## Disabling local sandboxing -If enterprise managed settings require sandboxing, you cannot disable it, and `/sandbox disable` is refused. +If enterprise managed settings require sandboxing, `/sandbox disable` is refused. If the effective policy permits sandbox bypass, you can instead explicitly disable sandboxing for the rest of the current session from an active bypass permission prompt. To stop using local sandboxing, enter the following command in an interactive {% data variables.copilot.copilot_cli_short %} session: @@ -84,7 +84,7 @@ copilot --sandbox -p "PROMPT" ## Running a single command outside the sandbox -When a command needs broader access than the sandbox allows, {% data variables.product.prodname_copilot_short %} can request to run that single command outside the sandbox. You are shown a confirmation prompt describing the command, and it runs outside the sandbox only if you approve it; otherwise it stays sandboxed. The rest of your session remains sandboxed either way. +When a command needs broader access than the sandbox allows, {% data variables.product.prodname_copilot_short %} can request to run that single command outside the sandbox. You are shown a confirmation prompt describing the command. You can approve that single command, keep it inside the sandbox, or disable sandboxing for the rest of the current session. The session opt-out is available only while responding to an active bypass prompt and only if the effective policy permits sandbox bypass. This behavior is enabled by default and can be turned off in your sandbox settings. diff --git a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md index d4e58a2da4f5..358580e14e88 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md @@ -609,11 +609,11 @@ Plan-then-autopilot lets a session start in plan mode and automatically continue ### Enterprise-managed sandbox floor -An enterprise-managed policy can enforce OS-level shell sandboxing as a minimum floor. In other words, even if you pass `--no-sandbox`, the policy can still force sandboxing on. This is a policy override, not a failure of the flag itself. By contrast, `--sandbox` is unaffected because it only turns sandboxing on and never removes it. +An enterprise-managed policy can enforce OS-level shell sandboxing as a minimum floor. In other words, even if you pass `--no-sandbox`, the policy can still force sandboxing on. This is a policy override, not a failure of the flag itself. By contrast, `--sandbox` is unaffected because it only turns sandboxing on and never removes it. If the effective policy permits sandbox bypass, you can explicitly disable sandboxing for the rest of the current session while responding to an active bypass permission prompt. When a managed policy overrides your setting, the CLI shows a warning in the interactive timeline (or on stderr when using `-p`) so it is clear that the behavior comes from policy enforcement rather than the option failing to work. Contact your administrator if you need the policy changed. The `/sandbox` command is also registered whenever a managed policy forces sandboxing on, even without experimental features enabled, so you can still inspect the effective policy and status while the floor applies. {% data reusables.copilot.experimental %} -Adding the managed `sandbox.failIfUnavailable` setting set to `true`, alongside `sandbox.enabled` set to `true`, makes the sandbox mandatory. Instead of falling back to running commands unsandboxed, {% data variables.product.prodname_copilot_short %} blocks model and tool execution if the policy can't be validated, compiled, or enforced by a usable sandbox backend, and you can't disable it. See [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-config-dir-reference#user-settings-copilotsettingsjson). +Adding the managed `sandbox.failIfUnavailable` setting set to `true`, alongside `sandbox.enabled` set to `true`, makes the sandbox mandatory when it cannot be established. Instead of falling back to running commands unsandboxed, {% data variables.product.prodname_copilot_short %} blocks model and tool execution if the policy can't be validated, compiled, or enforced by a usable sandbox backend. See [AUTOTITLE](/copilot/reference/enterprise-administrators/enterprise-managed-settings#sandbox). The CLI also warns when a managed policy enables sandboxing in a session that you did not request, not only when it overrides `--no-sandbox`. This includes sessions where the policy arrives after startup, because server-managed settings are only available after login. The warning is omitted if your own settings or the `--sandbox` option already requested sandboxing, since the session state would then be expected. diff --git a/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md b/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md index e4c18ca8f369..480a58f4102f 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md @@ -420,7 +420,7 @@ Settings are applied in this order (later overrides earlier): 7. Command-line flags -MDM managed settings load at startup and merge with user settings as a policy baseline. For most keys, user settings can override that baseline. For `permissions.disableBypassPermissionsMode`, an MDM value of `"disable"` always wins. For more information, see [MDM managed settings](#mdm-managed-settings). +MDM managed settings load at startup and merge with user settings as a policy baseline. For most keys, user settings can override that baseline. For `permissions.disableBypassPermissionsMode`, an MDM value of `"disable"` always wins. Managed `sandbox` settings are another exception. Instead of being overridable, each managed `sandbox` value sets a floor that you cannot relax. If your own setting is more permissive, the managed value wins. The `sandbox.failIfUnavailable` setting can only be set by an administrator. For more information, see [MDM managed settings](#mdm-managed-settings). | Scope | Location | Purpose | |-------|----------|---------| @@ -483,7 +483,7 @@ These settings apply across all your sessions and repositories. You can use the | `renderMarkdown` | `boolean` | `true` | Render Markdown in terminal output. | | `remoteExport` | `boolean` | `true` | Export sessions remotely when session sync is available. Set to `false` to opt out of remote export by default. The `remoteSessions` setting when set to `true`, or the `--remote` flag, still enables export and steering regardless of this setting. | | `respectGitignore` | `boolean` | `true` | Exclude gitignored files from the `@` file mention picker. When `false`, the picker includes files normally excluded by `.gitignore`. | -| `sandbox.allowBypass` | `boolean` | `true` | Allow sandboxed commands to request a bypass for specific operations (surfaces a permission prompt) so tools like `grep` and `glob` keep working when the sandbox would otherwise block them. Set to `false` to opt out. | +| `sandbox.allowBypass` | `boolean` | `true` | Allow sandboxed commands to request a bypass for specific operations (displays a permission prompt), so tools like `grep` and `glob` keep working when the sandbox would otherwise block them. The prompt also lets you disable sandboxing for the rest of the current session if the effective policy permits bypass. Set to `false` to opt out. | | `sandbox.enabled` | `boolean` | `false` | Restrict shell commands, MCP/LSP servers, and built-in file/web tools to a sandboxed environment with limited file system and network access. Enable it from the `/sandbox` dialog or with `/sandbox enable`. | | `sandbox.auth.git` | `boolean` | `true` | Inject Git credentials into the sandbox so commands running inside it can authenticate with Git. Set to `false` to opt out. Renamed from `sandbox.gitAuth`; the old key has no migration and is ignored wherever it still appears. | | `sandbox.auth.gh` | `boolean` | `true` | Inject {% data variables.product.prodname_cli %} (`gh`) credentials into the sandbox so commands running inside it can authenticate with the {% data variables.product.prodname_cli %}. Set to `false` to opt out. Renamed from `sandbox.ghAuth`; the old key has no migration and is ignored wherever it still appears. | @@ -638,6 +638,7 @@ Only the following keys are supported in MDM managed settings. | `permissions` | Set managed permissions, including `disableBypassPermissionsMode` and `deny` / `ask` / `allow` rule arrays. See [Managed permission rules](#managed-permission-rules). | | `policyHelper` | Register an executable that supplies the lowest-priority managed-settings layer. Fields: `path` (required), plus optional `args`, `timeoutMs`, and `refreshIntervalMs`. If both a device (MDM) and a server policy register a `policyHelper`, the device registration wins. | | `remoteControl` | Control whether sessions on this device can be controlled from other devices. `mode` is `"enabled"`, `"disabled"`, or `"requireSSO"` (requires `githubDotComOrganizations` when set). | +| `sandbox` | Set a sandbox policy floor that users cannot relax. Supported settings include `enabled`, `failIfUnavailable`, `allowBypass`, `addCurrentWorkingDirectory`, `sandboxMcpServers`, `sandboxLspServers`, `auth.git`, `auth.gh`, `allowDevToolAccess`, and the `userPolicy.*` filesystem and network rules. The managed value always takes precedence over a user's own value in the safer direction. Turning the sandbox on, requiring it to succeed, and sandboxing MCP and LSP servers cannot be turned off. Disabling bypass or credential injection cannot be re-enabled. Filesystem allow lists can only be narrowed, and denied paths can only be added to. `failIfUnavailable` can only be set by an administrator and blocks the session when the sandbox cannot be established. For the settings users can set themselves, see [User settings](#user-settings-copilotsettingsjson) or run `copilot help sandbox`. | | `shellShortcut` | Force-enable or force-disable the `$` interactive shell shortcut for all users. A managed value always overrides the user's own `shellShortcut` setting. | | `strictKnownMarketplaces` | Restrict plugins to known marketplaces | | `telemetry` | Push baseline OpenTelemetry export configuration: `enabled`, `endpoint`, `protocol`, `headers`, `resourceAttributes`, `captureContent`, `lockCaptureContent`, and `serviceName`. See [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference#opentelemetry-monitoring). | diff --git a/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md b/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md index 2d280caf154f..c2f804d71b60 100644 --- a/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md +++ b/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md @@ -137,6 +137,7 @@ The following example shows these keys in one managed settings file. ], "sandbox": { "enabled": true, + "failIfUnavailable": true, "allowBypass": false, "sandboxMcpServers": true, "sandboxLspServers": true @@ -293,8 +294,9 @@ Enforces minimum local sandbox restrictions for {% data variables.copilot.copilo The following sub-properties are supported: -* `enabled`: `true` requires sandboxing and prevents users from disabling it. -* `allowBypass`: `false` prevents the model from requesting that an individual command run outside the sandbox. +* `enabled`: `true` requires sandboxing by default. Users cannot disable it through their configuration, the `--no-sandbox` command line option, or the `/sandbox disable` command. If the effective policy permits bypass, a user can still explicitly disable sandboxing for the rest of the current session from an active sandbox-bypass permission prompt. +* `failIfUnavailable`: `true`, combined with `enabled: true`, makes the managed sandbox mandatory. If {% data variables.product.prodname_copilot_short %} cannot validate, compile, or enforce the sandbox policy with an available sandbox backend, it blocks model and tool execution instead of allowing commands to fail or run unsandboxed. This property does not enable sandboxing by itself. +* `allowBypass`: `false` prevents both individual commands from running outside the sandbox and users from disabling sandboxing for the rest of the current session from an active sandbox-bypass permission prompt. * `addCurrentWorkingDirectory`: `false` prevents {% data variables.copilot.copilot_cli_short %} from automatically adding the current working directory to the sandbox's read/write paths. * `sandboxMcpServers`: `true` requires local MCP servers started by {% data variables.copilot.copilot_cli_short %} to run in the sandbox. Remote MCP servers do not run in the local sandbox. * `sandboxLspServers`: `true` requires language servers started by {% data variables.copilot.copilot_cli_short %} to run in the sandbox.