Initial commit
This commit is contained in:
commit
2c78bb9c76
201 changed files with 196806 additions and 0 deletions
201
.codex-home/skills/.system/openai-docs/LICENSE.txt
Normal file
201
.codex-home/skills/.system/openai-docs/LICENSE.txt
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf of
|
||||
any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don\'t include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
38
.codex-home/skills/.system/openai-docs/SKILL.md
Normal file
38
.codex-home/skills/.system/openai-docs/SKILL.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
name: "openai-docs"
|
||||
description: "Use for Codex models/pricing, scheduled tasks, skills, settings, setup, troubleshooting, customization, automations, and self-knowledge—including 'you,' 'your,' 'this app,' or 'this coding agent' when they refer to Codex—and for OpenAI APIs/products and ChatGPT Work. Also use for model choice/migration, prompting, SDKs, Responses, Realtime, agents, evals, and Chat/Work/Codex comparisons. Do not use for generic app/software tasks that merely mention Codex."
|
||||
metadata:
|
||||
short-description: "Codex models/pricing, scheduled tasks, skills, settings, setup, troubleshooting, and self-knowledge; OpenAI APIs and ChatGPT Work. 'You'/'this app' means Codex only."
|
||||
---
|
||||
|
||||
# OpenAI Docs
|
||||
|
||||
Provide current, cited OpenAI product, API, model, and Codex guidance. Read zero or one primary reference.
|
||||
|
||||
**First substantive action:** Search the user's exact requested official OpenAI documentation topic and any explicitly named model using a concise, topic-specific query of 2-6 essential terms. When an already-available direct official documentation search and page-retrieval capability is present, use it first: search, then fetch or open the matching official page before general web search. Otherwise, immediately use official-domain web search, then actually open or fetch the relevant official page. Complete this source order before reading a reference, inspecting local or repository files, running a Codex manual or model resolver, drafting a plan, or answering from memory. Use the actual fetched page, not a search snippet or an unopened link. If one official search or page does not establish the answer, search another appropriate official domain and actually open or fetch the result. Preserve the exact requested model; never substitute a newer model.
|
||||
|
||||
**Only exception:** An explicitly requested, genuinely broad, cross-topic Codex setup, orientation, or system-map synthesis may use the manual first when shell execution and an allowed temporary cache are available. A specific Codex feature, setting, command, error, model, or requested citation remains docs-first. Mixed Chat/Work/Codex comparisons are official documentation questions, not manual-first Codex requests.
|
||||
|
||||
For generic software tasks, answer the software task directly. OpenAI implementation, debugging, SDK, API, prompting, agent, and eval requests are not generic.
|
||||
|
||||
For a straightforward factual or citation-only request, follow the source order and do not read a route reference. This includes straightforward API facts, ChatGPT Work or mixed Chat/Work/Codex comparisons, model tiers, aliases, Pro mode, reasoning settings, factual migration baselines, and narrow Codex facts. Prioritize `learn.chatgpt.com` for ChatGPT Work.
|
||||
|
||||
## Choose one primary route
|
||||
|
||||
Use the first matching route, and read its reference only when the requested task needs that specialized workflow:
|
||||
|
||||
- **Explicitly requested local documentation integration:** Read [integration guidance](references/mcp-diagnostics.md) only when the user explicitly requests that local integration.
|
||||
- **Model migration, upgrades, or model-specific prompting:** Read [model-migration.md](references/model-migration.md) for actual migration planning, implementation, dynamic target resolution, or prompt changes. Preserve an explicitly requested target.
|
||||
- **Model selection and comparisons:** Read [model-selection.md](references/model-selection.md) only when nuanced current, latest, default, cost, latency, quality, or modality tradeoffs need more guidance. Do not run a migration resolver for selection alone.
|
||||
- **Product, API, ChatGPT Work, and mixed Chat/Work/Codex documentation:** Read [official-docs.md](references/official-docs.md) only when fetched official pages leave source selection, API schemas, or the requested implementation unresolved. This route is not manual-first.
|
||||
- **Explicitly broad Codex setup, orientation, or cross-topic synthesis:** Read [codex-self-knowledge.md](references/codex-self-knowledge.md) when the eligible Codex manual or deeper Codex procedures are needed.
|
||||
|
||||
Read at most one primary reference. Do not open every route, bundled model guide, or helper script. Read a supporting reference or run a helper only when the chosen workflow demonstrably needs it.
|
||||
|
||||
## Source and execution boundaries
|
||||
|
||||
- Search, open, fetch, and cite only `developers.openai.com`, `platform.openai.com`, and `learn.chatgpt.com`. Cite the page that supports the claim. State uncertainty when official sources do not establish pricing, availability, account access, limits, or behavior.
|
||||
- Preserve an explicitly requested model for selection, migration, and prompting. Resolve an unspecified latest or current migration target only after searching and fetching current official guidance.
|
||||
- Use `references/latest-model.md` only as a disclosed fallback after current official model guidance does not answer the question. Read `references/upgrading-to-gpt-5p6-sol.md` only for an actual, requested GPT-5.6-family migration; read `references/prompting-guide.md` only for requested prompting work.
|
||||
- Before building, running, editing, debugging, or testing an API-backed app or tool, use `openai-platform-api-key` first when available. Documentation, conceptual examples, model selection, and read-only guidance do not require an API key.
|
||||
- Say "OpenAI Docs" or "official OpenAI documentation" in user-facing answers. Keep exact official citations and examples concise.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
interface:
|
||||
display_name: "OpenAI Docs"
|
||||
short_description: "OpenAI and Codex docs for models, skills, tasks, and setup"
|
||||
icon_small: "./assets/openai-small.svg"
|
||||
icon_large: "./assets/openai.png"
|
||||
default_prompt: "Use OpenAI Docs for official docs lookup, questions about Codex itself or Codex surfaces, model selection, model migration, and prompt-upgrade work."
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 14 14">
|
||||
<path d="M10.931 3.34a.112.112 0 0 0-.069-.104l-.038-.007c-1.537.05-2.45.318-3.714 1.002v6.683c.48-.248.936-.44 1.414-.58.695-.203 1.417-.292 2.303-.305l.038-.008a.113.113 0 0 0 .066-.104V3.341ZM2.363 9.919c0 .064.051.11.105.111l.33.008c1.162.046 2.042.243 2.975.662-.403-.585-1.008-1.075-1.654-1.292a.991.991 0 0 1-.674-.941v-5.14a6.36 6.36 0 0 0-.59-.076l-.37-.02a.115.115 0 0 0-.122.111v6.577Zm9.455-.001a.998.998 0 0 1-.877.992l-.101.007c-.832.012-1.47.095-2.066.27-.599.174-1.176.448-1.883.863a.444.444 0 0 1-.449 0c-1.299-.763-2.229-1.07-3.689-1.125l-.299-.008a.997.997 0 0 1-.977-.998V3.342c0-.573.478-1.017 1.038-.999l.417.023c.188.015.35.037.513.062v-.754c0-.708.749-1.244 1.429-.903.984.492 1.836 1.449 2.15 2.505 1.216-.617 2.222-.884 3.771-.934l.105.003a.998.998 0 0 1 .918.996v6.576ZM4.332 8.466c0 .049.03.087.07.1l.24.091a4.319 4.319 0 0 1 1.581 1.176V3.721c-.164-.803-.799-1.617-1.584-2.07l-.162-.088c-.025-.012-.054-.013-.088.009a.12.12 0 0 0-.057.102v6.792Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
.codex-home/skills/.system/openai-docs/assets/openai.png
Normal file
BIN
.codex-home/skills/.system/openai-docs/assets/openai.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,71 @@
|
|||
# Codex self-knowledge
|
||||
|
||||
Use this manual-first route only for genuinely broad Codex setup, orientation, customization, troubleshooting, local-state guidance, or system-map synthesis across skills, plugins, MCP, hooks, `AGENTS.md`, automations, and product surfaces. Mixed Chat/Work/Codex comparisons belong to `official-docs.md` instead.
|
||||
|
||||
Narrow Codex documentation questions require official documentation search first, then an actual page open or fetch using an available documentation or official-domain web capability. This includes a single feature such as Codex Goals, a specific setting, documented behavior, exact error, or requested page citation. Search and fetch the exact official topic before inspecting local files or bundled references. Do not fetch the manual, read bundled references, inspect local configuration or caches, or turn a targeted documentation lookup into broad product synthesis. Current or latest model questions follow the model-selection route.
|
||||
|
||||
## Start with the manual
|
||||
|
||||
Reuse a manual path and outline path already established in the same thread when both remain usable and current. Refresh before relying on a path fetched more than about a day ago, obtained from another thread or uncertain source, or missing likely-current information.
|
||||
|
||||
Otherwise, run the bundled manual helper first. Skip it without probing only when policy explicitly makes the session read-only, shell execution unavailable, or every allowed temporary cache location unavailable. Workspace-only write access is not enough: the helper needs an allowed writable temp cache. A guessed sandbox restriction is not evidence that the helper is unavailable.
|
||||
|
||||
Resolve `<skill-dir>` to the actual installed skill directory, then run:
|
||||
|
||||
```bash
|
||||
node <skill-dir>/scripts/fetch-codex-manual.mjs
|
||||
```
|
||||
|
||||
The helper automatically chooses the first usable cache location in this order:
|
||||
|
||||
1. `$TMPDIR/openai-docs-cache`
|
||||
2. `%TEMP%\openai-docs-cache`
|
||||
3. `%TMP%\openai-docs-cache`
|
||||
4. `/private/tmp/openai-docs-cache`
|
||||
5. `/tmp/openai-docs-cache`
|
||||
|
||||
Use an explicit override only when the allowed cache must be selected manually:
|
||||
|
||||
```bash
|
||||
node <skill-dir>/scripts/fetch-codex-manual.mjs --cache-dir <cache-dir>
|
||||
```
|
||||
|
||||
On Windows, `%TEMP%` and `%TMP%` are discovered automatically; `$env:TEMP\openai-docs-cache` is a typical PowerShell override. The helper handles configured HTTP(S) proxies and falls back to `curl` when needed. Do not require a POSIX-only environment prefix or an unnecessary cache override.
|
||||
|
||||
The helper verifies the current source and returns a manual path, outline path, freshness status, and heading outline. Use that outline to locate relevant headings and line ranges, then read or search only the returned manual and outline paths. Do not inspect unrelated repositories, caches, source trees, or local state to establish a public Codex product claim.
|
||||
|
||||
For follow-up questions in the same thread, reuse those fresh paths instead of fetching again. If asked whether the manual is current enough to rely on now, rerun the helper when an allowed temp cache is available and answer from its reported status and returned paths.
|
||||
|
||||
## Fill only genuine documentation gaps
|
||||
|
||||
If the manual answers a claim, stop retrieving sources for that claim. Its official source pages and known anchors are sufficient citation support. Continue the user's broader task when the documentation lookup was only one dependency.
|
||||
|
||||
If the helper was legitimately skipped, actually fails, or the fresh manual lacks a material or likely-current claim, use the narrowest official follow-up. Search the exact topic using an available documentation or approved-domain web capability, then actually open or fetch a clearly relevant official result. A page-specific citation can justify the same narrow follow-up.
|
||||
|
||||
For an undocumented Codex term, mode, acronym, or exact error, first check adjacent manual terminology. Map it to the closest documented concept when possible. If the exact term is material or likely current, perform one targeted official search-and-fetch; if it remains undocumented, say so. Do not expand into internal knowledge bases, private source trees, guessed roadmap details, or account-specific workarounds.
|
||||
|
||||
If official documentation conflicts with a callable capability verified in the current session, explicitly state the conflict and prefer that verified behavior for this environment. Otherwise, resolve unsupported claims with bounded uncertainty or route the user to support, an administrator, or product feedback.
|
||||
|
||||
## Choose the smallest matching Codex surface
|
||||
|
||||
- Prompt or thread context: one-off task constraints.
|
||||
- Repository `AGENTS.md`: durable team conventions, commands, and verification expectations; nested files apply more specifically within their subtree.
|
||||
- Project `.codex/config.toml`: settings for a trusted repository, including sandbox, MCP, hooks, model, and reasoning defaults.
|
||||
- Global config or global guidance: personal defaults across repositories.
|
||||
- Skill: a reusable workflow, optionally with focused references or scripts.
|
||||
- Plugin: an installable bundle of skills, tools, commands, MCP configuration, hooks, apps, assets, or related metadata.
|
||||
- MCP server or app connector: authorized live external data and actions. Use an authenticated connector, not web search or memory, for private Google Docs, Calendar, Slack, GitHub, Notion, or similar workspace data.
|
||||
- Automation: scheduled checks, reminders, monitors, or follow-ups; use an existing-thread heartbeat when continuity matters.
|
||||
- Hook: mechanical enforcement around lifecycle events, tool calls, commands, or edits.
|
||||
|
||||
Split requests that combine one-off, durable, repository-scoped, and recurring behavior instead of forcing them onto a single surface. For example, "always do this, but only for this PR" belongs in the current prompt or thread unless the user explicitly wants persistence or enforcement.
|
||||
|
||||
For a surface recommendation, state what to use, why it fits, what to avoid, and the manual or official documentation supporting the answer.
|
||||
|
||||
For product surfaces, distinguish terminal-first CLI work, editor-attached IDE work, desktop planning or review, hosted cloud execution, in-app browser testing, the user's existing Chrome session, and desktop Computer Use. Keep `config.toml` defaults, `requirements.toml` constraints, and managed or administrator policy separate. An API key does not establish ChatGPT, Codex cloud, connector, or account access.
|
||||
|
||||
For plugin or app failures, check the installed bundle, enabled state, connector authorization, MCP setup, restart or new-thread expectations, and workspace policy before inferring a cause. Route billing, entitlements, undocumented rollout labels, and unsupported access paths to the appropriate support or administrative owner.
|
||||
|
||||
Memory can provide user preferences or context, but explicit prompt instructions win and memory is not a source for current external facts. Sandbox or network denials require narrowly scoped escalation with a clear justification; destructive commands, writes outside the workspace, and broad access changes require explicit approval.
|
||||
|
||||
When a page-specific citation helps, useful official anchors include `concepts/customization#agents-guidance`, `concepts/customization#skills`, `plugins/build#plugin-structure`, `concepts/customization#mcp`, `config-advanced#hooks`, `app/automations#thread-automations`, and `config-reference#configtoml`.
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Latest model fallback
|
||||
|
||||
This is a compact, non-authoritative fallback, not a source for current availability, prices, aliases, or defaults. First search for and fetch current official model guidance at `https://developers.openai.com/api/docs/guides/latest-model` and the relevant official model page. The fetched official documentation wins if this snapshot has drifted. Disclose any use of this fallback.
|
||||
|
||||
## GPT-5.6 family
|
||||
|
||||
| Model ID | Documented workload to verify against the current model page |
|
||||
| --- | --- |
|
||||
| `gpt-5.6` | GPT-5.6 family alias; verify its currently documented routing and availability. |
|
||||
| `gpt-5.6-sol` | Quality-first flagship, reasoning, and difficult coding work. |
|
||||
| `gpt-5.6-terra` | Balanced quality, latency, and cost. |
|
||||
| `gpt-5.6-luna` | High-throughput, lower-latency work. |
|
||||
|
||||
Use `https://developers.openai.com/api/docs/guides/upgrading-to-gpt-5p6-sol` for an actual GPT-5.6 migration and `https://developers.openai.com/api/docs/guides/prompt-guidance-gpt-5p6` for requested GPT-5.6 prompting. Open and read the relevant page before recommending a request shape, reasoning setting, endpoint, tool behavior, or migration.
|
||||
|
||||
## Explicitly requested existing models
|
||||
|
||||
| Model ID | Boundary |
|
||||
| --- | --- |
|
||||
| `gpt-4.1` | Preserve only when the user explicitly requests this model or existing migration target; search and fetch its own current official guide. |
|
||||
| `gpt-5.4` | Preserve only when the user explicitly requests this model or existing migration target; search and fetch its own current official guide. |
|
||||
|
||||
Do not promote a legacy model as the current default, substitute it into an unrelated task, or replace an explicitly requested legacy target with GPT-5.6. Recommend a specialized image, audio, realtime, coding, moderation, or embedding model only after verifying the requested modality against current official documentation.
|
||||
|
||||
Verify GPT-5.6 Pro against current official Responses and model documentation before describing model IDs, reasoning modes, request parameters, or account availability; do not invent a separate `gpt-5.6-pro` model slug.
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Local documentation MCP setup and diagnostics
|
||||
|
||||
Use this route only when the user explicitly asks to configure or troubleshoot the official OpenAI documentation MCP server in a supported **local Codex client**. A missing documentation tool during an ordinary documentation request is not a setup request: answer with the root skill's official-domain web fallback without installation, sandbox escalation, configuration changes, or restart.
|
||||
|
||||
## Verify the supported local setup
|
||||
|
||||
1. Search and fetch current official Codex MCP setup documentation when those tools are callable. Otherwise, search and fetch the relevant official OpenAI documentation directly.
|
||||
2. Confirm the documented endpoint is `https://developers.openai.com/mcp` and verify the supported command or configuration against that current documentation before recommending it.
|
||||
3. When the current documentation supports it, the local Codex CLI setup is:
|
||||
|
||||
```sh
|
||||
codex mcp add openaiDeveloperDocs --url https://developers.openai.com/mcp
|
||||
```
|
||||
|
||||
The equivalent documented configuration is:
|
||||
|
||||
```toml
|
||||
[mcp_servers.openaiDeveloperDocs]
|
||||
url = "https://developers.openai.com/mcp"
|
||||
```
|
||||
|
||||
4. Check the supported local client's MCP listing or configuration, its enabled state, relevant workspace/admin policy, and any documented authentication requirement. Verify success from the actual command result, configuration, or a callable documentation-tool search/fetch; never claim installation or access without evidence.
|
||||
5. Recommend a local-client restart or new local session only when current official documentation or observed client behavior requires it. Clearly identify which local client must refresh.
|
||||
|
||||
A skill dependency declaration, configured server, or local-client setup does not make a tool callable in an already running session. In particular, editing a hosted container's local configuration cannot install a tool into the host or model's current tool inventory. Never claim a local command installed the server into a current hosted session.
|
||||
|
||||
Only perform a local installation or configuration change when the user explicitly authorizes that change. Never request sandbox escalation, edit hosted configuration, install a dependency, or ask the user to restart a hosted session merely to answer an ordinary documentation question.
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# Model migration and prompting
|
||||
|
||||
Use this route for model upgrades, migration planning, model-specific prompting, or latest/current/default prompting guidance. First search current official OpenAI documentation for the exact requested topic and model, then open or fetch the relevant official page using an available documentation or official-domain web capability. Do not run a resolver, open bundled references, or rely on a guide URL before completing that official search and actual page fetch.
|
||||
|
||||
## Choose the target before loading more context
|
||||
|
||||
- **Explicit model target:** Preserve the user's exact requested target, including an explicitly requested GPT-4.1 or GPT-5.4 migration. Do not run the latest-model resolver and do not substitute a newer model. Search for and fetch current guidance for that exact model. A GPT-5.4 migration must not load GPT-5.6 guidance or references.
|
||||
- **Unspecified, latest, current, or default target:** Search for and fetch `https://developers.openai.com/api/docs/guides/latest-model` first. Use the corresponding `latest-model.md` metadata only when dynamic migration resolution is needed, then run the platform-specific resolver below and preserve its returned model and exact guide URLs.
|
||||
- **Latest/current/default prompting:** Follow the dynamic-target route, then use the returned prompting guide. Do not run the resolver for explicitly named-model prompting.
|
||||
- **Pure model selection:** Use `references/model-selection.md` instead. Do not run the resolver.
|
||||
|
||||
For POSIX shells, invoke the resolver through `sh`, without assuming an executable bit:
|
||||
|
||||
```sh
|
||||
sh <skill-dir>/scripts/resolve-latest-model-info
|
||||
```
|
||||
|
||||
On Windows, use the CommonJS entry point with Node.js 18 or newer:
|
||||
|
||||
```text
|
||||
node <skill-dir>\scripts\resolve-latest-model-info.cjs
|
||||
```
|
||||
|
||||
If the Windows Node runtime is unavailable and `load_workspace_dependencies` is callable, use its returned runtime and retry once. Do not execute the extensionless POSIX wrapper directly on Windows.
|
||||
|
||||
Do not suppress or redirect resolver stdout. Success requires JSON with nonempty `model`, `migrationGuideUrl`, and `promptingGuideUrl` fields. If the command fails or any required field is missing, retry the platform-specific command once, then fall back to current official documentation and finally disclosed bundled references.
|
||||
|
||||
## Retrieve only the guidance this request needs
|
||||
|
||||
Treat returned guide URLs as opaque: fetch those exact URLs without deriving, substituting, or appending a model query. Use an available official documentation or first-party-domain capability to open and read the relevant official page. Retry the exact guide URL when its response contains only a title or no substantive body.
|
||||
|
||||
- Fetch `migrationGuideUrl` for a requested migration or upgrade plan.
|
||||
- Fetch `promptingGuideUrl` only when the user asks for prompting guidance or the migration requires a prompt change. Extract only `## Prompting Best Practices` through the next H2 heading.
|
||||
- For explicitly named-model prompting, fetch that model's official prompting guidance and extract only `## Prompting Best Practices` through the next H2 heading. Do not load a migration reference or run the resolver.
|
||||
- For an actual GPT-5.6-family migration or implementation plan, fetch `https://developers.openai.com/api/docs/guides/upgrading-to-gpt-5p6-sol`. For specifically requested GPT-5.6 prompting, fetch `https://developers.openai.com/api/docs/guides/prompt-guidance-gpt-5p6`. Read `references/upgrading-to-gpt-5p6-sol.md` only when fetched official guidance does not resolve needed compatibility gates, scoped code changes, tier-aware routing, validation, or other migration-specific judgment. Never load it for documentation-only questions about model tiers, the family alias, Pro mode, reasoning effort, or current guidance when the fetched official documentation already answers them.
|
||||
- Read `references/prompting-guide.md` only when prompting guidance or prompt changes are actually needed and current official guidance is unavailable.
|
||||
- Read `references/upgrade-guide.md` only when current official migration guidance is unavailable. Disclose when a bundled fallback was used.
|
||||
|
||||
## Keep implementation changes scoped
|
||||
|
||||
Change active model defaults and directly related prompt surfaces only when the user requested that work. Update registries, model pickers, capability metadata, routing, pricing, or tests only when they are in scope and current official documentation verifies the relevant values.
|
||||
|
||||
Preserve each workload's cost, latency, quality, reasoning, tool, endpoint, and output-contract role. Do not collapse a tiered router into one flagship model, replace intentionally pinned fallbacks, or rewrite historical examples, fixtures, eval baselines, provider comparisons, or unrelated SDK and authentication configuration.
|
||||
|
||||
If a safe migration requires an endpoint change, request-schema change, tool-handler change, or other implementation outside the requested scope, report the exact compatibility blocker and smallest follow-up instead of silently changing behavior.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Model selection
|
||||
|
||||
Use this route for model recommendations, comparisons, and latest/current/default choices when the user is not requesting a migration or prompting guidance.
|
||||
|
||||
1. Search current official OpenAI documentation for the exact requested workload and any explicitly named model; then open or fetch the relevant official page. For current or latest family guidance, use `https://developers.openai.com/api/docs/guides/latest-model`.
|
||||
2. Use any available official documentation or first-party-domain search. Read the actual source; do not make a recommendation from a search snippet, guessed default, or bundled snapshot.
|
||||
3. Match the documented model to the user's requested modality, quality, latency, cost, context, and workload. Distinguish flagship, balanced, high-throughput, coding, audio, image, or other specialized roles only when the fetched current documentation supports the distinction.
|
||||
4. Preserve an explicitly requested model or existing target. Cite the current official page and state uncertainty about availability, pricing, limits, or account access.
|
||||
|
||||
Pure model selection does not require migration metadata. **Do not run the resolver.**
|
||||
|
||||
Read `references/latest-model.md` only when fetched current official sources cannot answer the question. Disclose that bundled fallback guidance was used and may be outdated.
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Official documentation, API references, and ChatGPT Work
|
||||
|
||||
Use this route for OpenAI product or API documentation, examples, citations, ChatGPT Work, learning content, mixed Chat/Work/Codex comparisons, and narrow Codex product documentation. Follow the root skill's official-source order and credential boundary.
|
||||
|
||||
An explicit OpenAI documentation question stays documentation-first even when embedded in a broader repository, Promptfoo, agent-evaluation, `PLANS.md`, frontend, tool-use, image, Realtime API, SDK installation, or streaming-debugging task. Search the exact requested official documentation and open or fetch its relevant page before inspecting local files, drafting a plan, running evals, reading bundled references, or invoking the Codex manual. Then use the fetched official source to complete the requested work.
|
||||
|
||||
## Find the smallest useful source
|
||||
|
||||
1. Search the exact topic with a specific, title-like query containing 2-6 essential terms. Prefer an already-available direct official documentation search and page-retrieval capability; search, then fetch or open the best page or section. Otherwise, immediately use official-domain web search and actually open or fetch the result.
|
||||
2. If the results are noisy, narrow the query. When a plausible official documentation URL is available, open or fetch the page instead of relying on search snippets. Use an already available documentation index only when there is no clear search query.
|
||||
3. For API schemas, required fields, parameters, or endpoint shapes, use an already available OpenAPI or specification capability when it directly resolves the question. Otherwise verify the shape against the fetched official API guide or reference.
|
||||
4. Cite the exact official page supporting each consequential claim. Keep examples minimal, paraphrase instead of quoting at length, and state when official sources do not establish a capability, parameter, price, or availability.
|
||||
|
||||
Preserve an explicitly requested model in the search and answer. Search the requested topic directly for model-specific frontend and tool-use prompting, image input or generation, Realtime voice or translation, official Agents SDK installation, Responses streaming errors, and Codex Goals. A specific Codex feature, error, setting, or requested citation is a narrow documentation lookup, not the broad manual-first exception. Current or latest model recommendations follow the model-selection route and the same official search-and-fetch order.
|
||||
|
||||
## ChatGPT Work and mixed surfaces
|
||||
|
||||
Treat a comparison between Chat, Work, and Codex as ChatGPT Work documentation, not broad Codex self-knowledge. Search `learn.chatgpt.com` and open or fetch the relevant official page. Useful starting pages are:
|
||||
|
||||
- `https://learn.chatgpt.com/docs/use-chatgpt`
|
||||
- `https://learn.chatgpt.com/docs/get-started-with-work`
|
||||
|
||||
If someone simply asks an API question from ChatGPT Work, answer the API question from the relevant API guide. Being in Work does not make it a question about the Work product.
|
||||
|
||||
Separate documented user-facing purposes from unsupported claims about underlying models, hard capability boundaries, file or context inheritance, exact UI labels, account entitlements, and rollout availability. When those details cannot be verified, cite the closest allowed official source and state the uncertainty.
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
## Retrieve the live GPT-5.6 prompting guidance
|
||||
|
||||
Use already-callable official documentation search and fetch, or immediately use official-domain web search and fetch, to retrieve the live GPT-5.6 prompting guidance from:
|
||||
|
||||
https://developers.openai.com/api/docs/guides/model-guidance?model=gpt-5.6#prompting-best-practices
|
||||
|
||||
Read only the `## Prompting Best Practices` section, stopping at the next H2 heading. The URL anchor points to the section visually, but a documentation fetch may return the full page, so explicitly extract only that section.
|
||||
|
||||
Treat the live section as the canonical model-specific prompting guidance. Use the local guidance below only for skill-specific migration judgment: deciding what to preserve, remove, rewrite, or test when adapting an existing prompt stack to GPT-5.6.
|
||||
|
||||
## Skill-specific migration judgment
|
||||
|
||||
GPT-5.6 works best when prompts define the outcome, important constraints, available evidence, and completion bar, then leave room for the model to choose an efficient path. Compared with earlier GPT-5 models, many applications can use shorter prompts and smaller tool sets without losing quality.
|
||||
|
||||
Do not carry over every instruction from an older prompt stack. Legacy prompts often repeat rules, prescribe unnecessary steps, expose irrelevant tools, or include examples that no longer change behavior. With GPT-5.6, this can encourage extra exploration, repeated validation, and larger accumulated context.
|
||||
|
||||
Start with the smallest prompt and tool set that passes your evals. Add an instruction, example, or tool only when it fixes a measured failure mode.
|
||||
|
||||
## Simplify prompts first
|
||||
|
||||
When migrating an existing prompt, remove redundant scaffolding before adding new GPT-5.6-specific instructions.
|
||||
|
||||
Trim:
|
||||
|
||||
- repeated statements of the same rule;
|
||||
- generic “be thorough,” “be concise,” or “think step by step” language;
|
||||
- examples that do not change behavior;
|
||||
- process instructions for behavior the model already performs reliably;
|
||||
- tools and tool descriptions unrelated to the task.
|
||||
|
||||
Keep:
|
||||
|
||||
- the user-visible outcome;
|
||||
- success criteria and stopping conditions;
|
||||
- safety, business, evidence, and permission constraints;
|
||||
- tool-routing rules when the correct route is not obvious;
|
||||
- required output shape and validation requirements.
|
||||
|
||||
Review the remaining instructions for contradictions. GPT-5-class models follow prompt contracts closely, so conflicting rules can create more instability than missing detail.
|
||||
|
||||
## Outcome-first prompts and stopping conditions
|
||||
|
||||
Describe the destination rather than prescribing every step. GPT-5.6 can usually choose an efficient search, tool, or reasoning path when the prompt states what good looks like.
|
||||
|
||||
Prefer:
|
||||
|
||||
Resolve the customer's issue end to end.
|
||||
|
||||
Success means:
|
||||
- make the eligibility decision from available policy and account evidence
|
||||
- complete any allowed action before responding
|
||||
- return completed_actions, customer_message, and blockers
|
||||
- if required evidence is missing, ask for the smallest missing field
|
||||
|
||||
Avoid unnecessary absolute rules. Use ALWAYS, NEVER, must, and only for true invariants such as safety rules, required fields, or actions that should never happen. For judgment calls, such as when to search, ask, use a tool, or keep iterating, prefer decision rules.
|
||||
|
||||
Preserve explicit user values. When the correct value is implicit, provide decision criteria and let the model reason from context or schema. Avoid universal defaults, keyword maps, and broad semantic shortcuts.
|
||||
|
||||
Add stopping conditions:
|
||||
|
||||
Resolve the request in the fewest useful tool loops, but do not let loop
|
||||
minimization outrank correctness, required evidence, calculations, or
|
||||
required citations.
|
||||
|
||||
After each result, ask whether the core request can now be answered with
|
||||
useful evidence. If yes, answer. If required evidence is still missing,
|
||||
name the missing fact and use the smallest useful fallback.
|
||||
|
||||
## Personality, collaboration, and response length
|
||||
|
||||
GPT-5.6 is efficient, direct, and more compressed than recent models. For customer-facing assistants and collaborative products, define both personality and collaboration style.
|
||||
|
||||
- Personality controls tone, warmth, directness, formality, humor, empathy, and polish.
|
||||
- Collaboration style controls when the model asks questions, makes assumptions, takes initiative, explains tradeoffs, checks work, and handles uncertainty.
|
||||
|
||||
Keep both short. Personality should shape the user experience; collaboration instructions should shape task behavior. Neither should replace clear goals, success criteria, tool rules, or stopping conditions.
|
||||
|
||||
Use concrete writing controls:
|
||||
|
||||
Lead with the conclusion. Include the evidence needed to support it, any
|
||||
material caveat, and the next action. Keep all required facts, decisions,
|
||||
caveats, and next steps. Trim introductions, repetition, generic reassurance,
|
||||
and optional background first.
|
||||
|
||||
Avoid generic “be brief,” “keep it short,” or “use minimal text” instructions. GPT-5.6 is already biased toward compression, and generic brevity can make it omit required evidence or parts of an artifact.
|
||||
|
||||
For customer-facing tone, prefer concrete guidance:
|
||||
|
||||
Be direct and tactful. Acknowledge friction specifically when relevant.
|
||||
Avoid canned reassurance and unnecessary sign-offs.
|
||||
|
||||
Avoid blanket language rules such as “always respond in the user's language” unless that is truly the product requirement. Specify the intended output language and when it should change.
|
||||
|
||||
For editing, rewriting, summaries, and customer-facing drafts, tell the model what to preserve:
|
||||
|
||||
Preserve the requested artifact, length, structure, genre, and factual claims
|
||||
first. Improve clarity, flow, and correctness without adding new claims,
|
||||
sections, or a more promotional tone unless requested.
|
||||
|
||||
## Autonomy and permissions
|
||||
|
||||
GPT-5.6 can be proactive and persistent. Define which level of action each request authorizes.
|
||||
|
||||
For requests to answer, explain, review, diagnose, or plan, inspect the
|
||||
relevant materials and report the result. Do not implement changes unless
|
||||
the request also asks for them.
|
||||
|
||||
For requests to change, build, or fix, make the requested in-scope local
|
||||
changes and run relevant non-destructive validation without asking first.
|
||||
|
||||
Require confirmation for external writes, destructive actions, purchases,
|
||||
or a material expansion of scope.
|
||||
|
||||
Specify which local actions are safe without approval, such as reading files, inspecting logs, searching, editing in-scope code, and running non-destructive tests.
|
||||
|
||||
Avoid repeating “ask first” throughout the prompt. Repetition can cause unnecessary permission checks even for safe, expected actions.
|
||||
|
||||
For long-running work, define the current layer of work. Distinguish research, design, implementation, review, and external coordination so the model does not silently move from one layer to another.
|
||||
|
||||
## Tool routing
|
||||
|
||||
Expose only task-relevant tools. Tool descriptions should state what the tool does, when to use it, important return fields, and error behavior.
|
||||
|
||||
When correctness depends on prerequisite retrieval or lookup, say so:
|
||||
|
||||
Before taking an action, resolve required discovery, retrieval, and
|
||||
validation steps. Do not skip a prerequisite because the intended final
|
||||
state seems obvious.
|
||||
|
||||
When several reads are independent, parallelize them. When one result determines the next action, keep the work sequential. After parallel retrieval, synthesize before acting.
|
||||
|
||||
If a tool returns empty, partial, or suspiciously narrow results, try one or two meaningful fallbacks before concluding that no result exists.
|
||||
|
||||
## Programmatic Tool Calling
|
||||
|
||||
Programmatic Tool Calling is useful when code can reduce large, structured intermediate results before they return to model context.
|
||||
|
||||
Use it for:
|
||||
|
||||
- filtering, joining, sorting, ranking, deduplication, and aggregation;
|
||||
- batching across many similar records;
|
||||
- repeated deterministic validation;
|
||||
- large structured results that can be reduced to a compact schema.
|
||||
|
||||
Prefer direct tool calls when:
|
||||
|
||||
- one call is sufficient;
|
||||
- intermediate outputs are already small;
|
||||
- each result may change the next decision;
|
||||
- an action requires approval;
|
||||
- the final answer must preserve citations or native artifacts;
|
||||
- the workflow requires semantic judgment between calls.
|
||||
|
||||
Do not rely on generic instructions such as “use Programmatic Tool Calling efficiently.” State the bounded stage, eligible tools, output schema, retry limit, stop condition, and handoff back to direct model judgment.
|
||||
|
||||
Use Programmatic Tool Calling only for the bounded record-reduction stage.
|
||||
Call only the documented read-only tools. Filter and deduplicate the
|
||||
intermediate results, then emit exactly the required compact schema with
|
||||
evidence fields. Retry transient failures at most twice. Use direct tool
|
||||
calls for approval, semantic judgment, citations, and final validation.
|
||||
|
||||
Evaluate the final user-visible answer, not only the program result. Lower tokens, latency, calls, or turns are improvements only when the final answer still meets the required quality bar.
|
||||
|
||||
## Grounding, citations, and retrieval budgets
|
||||
|
||||
For grounded answers, citation behavior should be part of the prompt. Define what needs support, what counts as enough evidence, and how to behave when evidence is missing. Absence of evidence should not automatically become a factual “no.”
|
||||
|
||||
For ordinary Q&A, start with one broad search using short, discriminative
|
||||
keywords. If the top results contain enough support for the core request,
|
||||
answer from those results.
|
||||
|
||||
Make another retrieval call only when a required fact, owner, date, ID, or
|
||||
source is missing; the user asked for exhaustive coverage or comparison; a
|
||||
specific artifact must be read; or an important claim would otherwise be
|
||||
unsupported.
|
||||
|
||||
Do not search again only to improve phrasing, add examples, or support
|
||||
nonessential detail.
|
||||
|
||||
For research and synthesis:
|
||||
|
||||
- cite only retrieved sources;
|
||||
- attach citations to the claims they support;
|
||||
- label inference separately from directly supported facts;
|
||||
- state conflicts between sources;
|
||||
- narrow the answer or report missing evidence instead of guessing.
|
||||
|
||||
For creative drafting, distinguish source-backed facts from creative wording. Do not invent names, metrics, dates, roadmap status, customer outcomes, or product capabilities to make a draft sound stronger.
|
||||
|
||||
## Long-running workflows and state
|
||||
|
||||
For multi-step or tool-heavy tasks, prompt for a short visible preamble before the first tool call, then sparse outcome-based updates at major phase changes. Do not ask the model to narrate routine tool calls.
|
||||
|
||||
Before tool calls for a multi-step task, send a one- or two-sentence
|
||||
user-visible update that states the first step. During the task, update only
|
||||
when a major phase begins or a finding changes the plan. Each update should
|
||||
state one concrete outcome and the next step.
|
||||
|
||||
Preserve assistant phase values when replaying history so the model can distinguish commentary from the final answer. If using previous_response_id, prior assistant state is preserved automatically. If replaying history manually, preserve each original phase value unchanged.
|
||||
|
||||
Compact after major milestones rather than every turn. Keep the prompt functionally consistent after compaction and treat compacted items as opaque state.
|
||||
|
||||
Persisted reasoning is useful when the objective, assumptions, and priorities remain stable across turns. Use current-turn behavior when earlier reasoning is no longer relevant. Do not treat persisted reasoning as an always-on optimization: stale reasoning can add tokens, increase latency, and anchor the model to an outdated approach.
|
||||
|
||||
Prompt caching also affects prompt construction. Keep reusable prefixes stable and avoid unnecessary churn in large system prompts. Use explicit cache breakpoints only when they improve measured cache behavior and cost for the workload.
|
||||
|
||||
## Reasoning effort
|
||||
|
||||
Treat reasoning effort as a last-mile tuning knob, not the first response to a weak result.
|
||||
|
||||
- Preserve the current GPT-5.5 or GPT-5.4 reasoning effort as the baseline.
|
||||
- Test the same setting and one level lower on representative tasks.
|
||||
- Use low for latency-sensitive work when it preserves quality.
|
||||
- Use medium as a balanced starting point.
|
||||
- Use high or xhigh only when evals show a meaningful gain.
|
||||
- Reserve max for the hardest quality-first workloads; do not recommend it globally.
|
||||
|
||||
Before increasing reasoning effort, check whether the prompt is missing a success criterion, dependency rule, tool-routing rule, or verification loop.
|
||||
|
||||
## Frontend and visual tasks
|
||||
|
||||
GPT-5.6 has stronger layout, visual hierarchy, and design judgment. Still provide product context, preserve the existing design system, and name the states and constraints that matter.
|
||||
|
||||
For incremental frontend changes:
|
||||
|
||||
- inspect and preserve existing design tokens, components, and patterns;
|
||||
- do not add extra features or decorative UI unless requested;
|
||||
- preserve responsive behavior and expected states;
|
||||
- render and inspect the result before finalizing.
|
||||
|
||||
For vision, computer use, localization, or OCR tasks where spatial precision matters, choose image detail intentionally. Use original detail for large, dense, or coordinate-sensitive images when the extra input cost and latency are justified.
|
||||
|
||||
## Check work before finishing
|
||||
|
||||
Give GPT-5.6 access to tools that can validate the output, and state what validation matters.
|
||||
|
||||
For coding:
|
||||
|
||||
After making changes, run the most relevant validation available:
|
||||
- targeted tests for changed behavior
|
||||
- type checks or lint checks when applicable
|
||||
- build checks for affected packages
|
||||
- a minimal smoke test when full validation is too expensive
|
||||
|
||||
If validation cannot be run, explain why and describe the next best check.
|
||||
|
||||
For visual artifacts:
|
||||
|
||||
Render the artifact before finalizing. Inspect layout, clipping, spacing,
|
||||
missing content, and visual consistency. Revise until the rendered output
|
||||
matches the requirements.
|
||||
|
||||
For implementation plans, include requirements, named resources or files, state transitions or data flow, validation checks, failure behavior, privacy or security considerations, and open questions that materially affect implementation.
|
||||
|
||||
## Suggested prompt structure
|
||||
|
||||
Use this structure as a starting point for complex prompts. Keep each section short. Add detail only where it changes behavior.
|
||||
|
||||
Role: [the model's function and context]
|
||||
|
||||
Personality: [tone and collaboration style]
|
||||
|
||||
Goal: [user-visible outcome]
|
||||
|
||||
Success criteria: [what must be true before the final answer]
|
||||
|
||||
Constraints: [policy, safety, business, evidence, and side-effect limits]
|
||||
|
||||
Tools: [which tools to use, when, and what not to use]
|
||||
|
||||
Output: [sections, length, format, and tone]
|
||||
|
||||
Stop rules: [when to retry, fallback, abstain, ask, or stop]
|
||||
|
||||
## Prompt migration workflow
|
||||
|
||||
When moving an existing application to GPT-5.6:
|
||||
|
||||
1. Switch the model and preserve the current reasoning effort.
|
||||
2. Run representative evals before changing the prompt.
|
||||
3. Remove obsolete scaffolding, repeated instructions, and irrelevant tools.
|
||||
4. Add only the smallest targeted instruction that fixes a measured regression.
|
||||
5. Re-run evals after each prompt or reasoning change.
|
||||
|
||||
Do not rewrite a working prompt stack all at once. Otherwise you cannot tell whether a behavior change came from the model, reasoning setting, prompt, tool set, or runtime.
|
||||
|
||||
When a prompt regresses, debug it with a small set of real traces. Identify the failure mode, find the instruction or contradiction that likely caused it, make a surgical edit, and rerun the same cases.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Model upgrade guidance
|
||||
|
||||
Use this file only as a bundled routing fallback when the live migration guide cannot be fetched.
|
||||
|
||||
For latest, current, default, or unspecified-model upgrades:
|
||||
|
||||
1. Run `scripts/resolve-latest-model-info`.
|
||||
2. Fetch the returned `migrationGuideUrl` and `promptingGuideUrl` exactly.
|
||||
3. Treat the live guides as canonical.
|
||||
4. If remote retrieval fails, disclose that bundled fallback guidance is being used.
|
||||
|
||||
For an explicit GPT-5.6 Sol or GPT-5.6-family migration:
|
||||
|
||||
1. Preserve the user's explicit target; do not run the latest-model resolver.
|
||||
2. Fetch the live GPT-5.6 model guidance:
|
||||
|
||||
https://developers.openai.com/api/docs/guides/model-guidance?model=gpt-5.6
|
||||
|
||||
3. Read `references/upgrading-to-gpt-5p6-sol.md` for skill-specific migration judgment.
|
||||
4. Read `references/prompting-guide.md` only when prompt changes are needed.
|
||||
|
||||
For another explicit model target, preserve that target and fetch its current official guidance. Do not reuse GPT-5.6-specific defaults, API shapes, or compatibility rules for a different model.
|
||||
|
|
@ -0,0 +1,448 @@
|
|||
# Upgrading to GPT-5.6 Sol
|
||||
|
||||
Use this guide when the user asks to migrate an existing OpenAI API integration, repository, prompt stack, agent, model router, or model picker to GPT-5.6 Sol or the GPT-5.6 family.
|
||||
|
||||
The default explicit target is `gpt-5.6-sol`. The alias `gpt-5.6` routes to Sol; use it only when the repository intentionally prefers family aliases. Do not treat every old model usage as a Sol candidate: GPT-5.6 is a family with different cost, latency, context, and quality roles.
|
||||
|
||||
Before changing code, retrieve the current live GPT-5.6 model guidance using already-callable official documentation search and fetch, or immediately use official-domain web search and fetch:
|
||||
|
||||
https://developers.openai.com/api/docs/guides/model-guidance?model=gpt-5.6
|
||||
|
||||
For prompt changes, also read only the `## Prompting Best Practices` section from:
|
||||
|
||||
https://developers.openai.com/api/docs/guides/model-guidance?model=gpt-5.6#prompting-best-practices
|
||||
|
||||
Treat live docs as canonical for current model IDs, parameters, limits, pricing, and feature availability. This file supplies migration judgment: where to look, what can break, what to preserve, what not to adopt automatically, and how to validate the result.
|
||||
|
||||
## Core principle
|
||||
|
||||
Do not perform a blind model-string replacement.
|
||||
|
||||
First preserve the behavior, latency class, cost class, reasoning level, endpoint contract, tool semantics, cache behavior, and output contract of each usage site. Then make the smallest safe migration. Adopt new GPT-5.6 capabilities only when they solve a measured problem or the user explicitly asks for them.
|
||||
|
||||
A model upgrade alone does not authorize adding reasoning fields, changing request schemas, or rewriting tests. Only add explicit reasoning when the old effective behavior is established and omission would change behavior on GPT-5.6.
|
||||
|
||||
The main 5.6 migration hazards are:
|
||||
|
||||
- choosing Sol for workloads that were intentionally mini, nano, low-cost, or latency-sensitive;
|
||||
- inheriting 5.6's default `medium` reasoning where the old effective effort was `none`;
|
||||
- using Chat Completions with function tools without explicitly setting effective reasoning to `none`;
|
||||
- losing prompt-cache hits when a stable prefix is followed by a changing suffix;
|
||||
- increasing image or PDF input tokens because omitted or `auto` detail behaves differently;
|
||||
- applying new cache, persisted-reasoning, Pro, Programmatic Tool Calling, or multi-agent fields to routes that do not support them;
|
||||
- updating model strings but forgetting registries, allowlists, pricing metadata, capability flags, tests, and UI model pickers.
|
||||
|
||||
## Migration posture
|
||||
|
||||
Classify every usage site before editing:
|
||||
|
||||
1. `simple Sol migration`
|
||||
- One flagship model usage.
|
||||
- Same endpoint and request shape can remain.
|
||||
- Reasoning effort is explicit or its old effective value is known.
|
||||
- No cache, vision, file, tool, or parser behavior needs implementation changes.
|
||||
2. `tier-aware family migration`
|
||||
- The repository exposes multiple model roles, model choices, fallbacks, routers, pricing data, or capability metadata.
|
||||
- Map each role to Sol, Terra, or Luna instead of replacing everything with Sol.
|
||||
3. `compatibility migration`
|
||||
- The safe move requires parameter, endpoint, cache, state, tool-loop, or multimodal-detail changes.
|
||||
- Make these changes only when implementation work is inside the user's requested scope. Otherwise report the exact blocker and smallest follow-up.
|
||||
4. `prompt migration`
|
||||
- The API shape can remain, but representative traces show a prompt-specific regression.
|
||||
- Make a surgical prompt edit tied to that failure; do not rewrite a working prompt stack wholesale.
|
||||
- When the task is to update prompting guidance, edit the directly tied prompt surface only. Do not modify runtime request code, model schemas, or tests unless the prompt change requires it.
|
||||
5. `optional feature adoption`
|
||||
- Pro mode, persisted reasoning, explicit caching, Programmatic Tool Calling, or multi-agent behavior is being added deliberately.
|
||||
- Keep this separate from the baseline migration so its effect can be measured.
|
||||
6. `leave unchanged`
|
||||
- Historical examples, documentation about old models, snapshots, fixtures, eval baselines, comparison code, intentionally pinned fallbacks, unsupported providers, or ambiguous usages.
|
||||
|
||||
When intent is unclear, prefer leaving a usage unchanged and list it for confirmation over silently changing its role.
|
||||
|
||||
## Inventory before editing
|
||||
|
||||
Search for more than literal model IDs. Inventory:
|
||||
|
||||
- model strings, aliases, environment variables, CLI flags, config defaults, and deployment settings;
|
||||
- SDK calls to Responses, Chat Completions, Batch, or provider adapters;
|
||||
- reasoning settings, token budgets, sampling settings, and latency timeouts;
|
||||
- function tools, hosted tools, structured outputs, response parsers, and replay logic;
|
||||
- system, developer, user, and tool-description prompts tied to each usage;
|
||||
- routers, fallbacks, model allowlists, enums, regexes, validation schemas, and capability maps;
|
||||
- model picker UI, display labels, descriptions, context limits, pricing metadata, and provider catalogs;
|
||||
- prompt-cache keys, retention options, stable-prefix construction, and cache metrics;
|
||||
- image, PDF, file, OCR, and computer-use inputs;
|
||||
- tests, fixtures, snapshots, evals, analytics labels, billing tables, and docs.
|
||||
|
||||
When changing a default model, search every active default surface: runtime config, environment/config files, setup docs, tests, CLI defaults, and deployment examples. Update them together.
|
||||
|
||||
For each usage site, record:
|
||||
|
||||
- source model and why it appears to be used;
|
||||
- endpoint and SDK/client surface;
|
||||
- prompt surface;
|
||||
- effective reasoning effort, including defaults;
|
||||
- latency, cost, context, and quality role;
|
||||
- tools, structured outputs, caching, state replay, and multimodal inputs;
|
||||
- downstream parsers or user-visible contracts;
|
||||
- migration class and validation plan.
|
||||
|
||||
## Choose the target model by role
|
||||
|
||||
Use this as a starting map, then validate against the repository's workload:
|
||||
|
||||
| Existing role | Starting GPT-5.6 target | Reason |
|
||||
| --- | --- | --- |
|
||||
| Unsuffixed GPT-5 flagship, GPT-5.5, or GPT-5.4 flagship | `gpt-5.6-sol` | Sol is the flagship-equivalent tier. |
|
||||
| Mini model, balanced lower-cost route, or medium-throughput worker | `gpt-5.6-terra` | Terra is the mini-like tier. |
|
||||
| Nano model, classification, extraction, routing, high-volume, or strict-latency route | `gpt-5.6-luna` | Luna is the nano-like tier. |
|
||||
| GPT-4.1 or GPT-4o latency-sensitive flow | Evaluate Luna and Terra first; use Sol only if quality requires it | A flagship replacement can change latency and cost materially. |
|
||||
| Reasoning-heavy or hardest quality-first flow | Start with Sol at the old effective effort | Preserve the reasoning contract before tuning. |
|
||||
| Old Pro usage | Sol plus `reasoning.mode: "pro"`, only if the user wants Pro behavior | GPT-5.6 Pro is a mode, not a separate model slug. |
|
||||
| Router, fallback, or model picker | Add the family by role | Do not collapse a multi-model design into Sol. |
|
||||
| Third-party or provider-specific model | Leave unchanged unless the user explicitly requests provider migration | Model-name similarity is not a safe mapping. |
|
||||
|
||||
Important limits to check in live docs:
|
||||
|
||||
- Sol and Terra have roughly 1.05M context and 128K maximum output.
|
||||
- Luna has a smaller 400K context and 128K maximum output.
|
||||
- Sol and Terra long-context requests above 272K input tokens can change pricing for the full request.
|
||||
|
||||
Do not invent prices, limits, or capability flags. Fetch them from current docs before updating a registry or UI.
|
||||
|
||||
For model pickers and registries, preserve existing model entries by default. Add GPT-5.6 Sol, Terra, and Luna as new options unless the user explicitly asks to replace or remove older models. Do not invent pricing, context limits, capabilities, or metadata unless confirmed from canonical docs.
|
||||
|
||||
If using the `gpt-5.6` alias, record the returned `response.model` during validation. Do not assume an alias and an explicit Sol slug appear identically in dashboards, rate-limit configuration, analytics, or billing metadata.
|
||||
|
||||
## Preserve effective reasoning before tuning
|
||||
|
||||
GPT-5.6 supports `none`, `low`, `medium`, `high`, `xhigh`, and `max`. If omitted, GPT-5.6 defaults to `medium`.
|
||||
|
||||
This is a behavioral migration hazard:
|
||||
|
||||
- GPT-5.5 commonly defaulted to `medium`.
|
||||
- GPT-5.4, mini, and nano usages commonly defaulted to `none`.
|
||||
- A previously omitted setting can therefore become slower, more expensive, and incompatible with Chat Completions function tools after the model swap.
|
||||
|
||||
For each usage:
|
||||
|
||||
1. If effort is explicit, preserve it for the first 5.6 run when supported.
|
||||
2. If effort is omitted and the old effective default is known, add it explicitly only when GPT-5.6's omitted default would change behavior. If both old and new omitted defaults are the same, keep it omitted.
|
||||
3. If the old effective value is unknown, do not guess. Flag it and compare the old behavior with 5.6 at the likely baseline.
|
||||
4. After the baseline passes, test the same setting and one lower on representative tasks.
|
||||
5. Use `xhigh` or `max` only for hard quality-first workloads where evals show a meaningful gain.
|
||||
|
||||
Do not globally recommend `max`. Before increasing effort, check whether the actual failure is a missing success criterion, dependency rule, tool-routing rule, state-replay bug, or validation loop.
|
||||
|
||||
Use the field shape that belongs to the endpoint.
|
||||
|
||||
Responses:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-5.6-sol",
|
||||
"reasoning": { "effort": "none" }
|
||||
}
|
||||
```
|
||||
|
||||
Chat Completions:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-5.6-sol",
|
||||
"reasoning_effort": "none"
|
||||
}
|
||||
```
|
||||
|
||||
## Chat Completions and function tools
|
||||
|
||||
This is the most important endpoint-specific check.
|
||||
|
||||
For GPT-5.6, function tools in Chat Completions are compatible only with effective reasoning `none`. Reasoning with tools should use the Responses API.
|
||||
|
||||
Because GPT-5.6 defaults to `medium`, this combination is unsafe:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-5.6-luna",
|
||||
"tools": [{ "type": "function", "function": { "...": "..." } }]
|
||||
}
|
||||
```
|
||||
|
||||
For a latency-sensitive Chat Completions flow that must keep function tools, explicitly preserve `none`:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-5.6-luna",
|
||||
"reasoning_effort": "none",
|
||||
"tools": [{ "type": "function", "function": { "...": "..." } }]
|
||||
}
|
||||
```
|
||||
|
||||
If the application needs both reasoning and tools:
|
||||
|
||||
- migrate that flow to Responses when implementation changes are in scope;
|
||||
- otherwise report it as a compatibility blocker;
|
||||
- do not hide the incompatibility by removing tools, dropping required reasoning, or changing the workload's behavior without approval.
|
||||
|
||||
If the live API rejects the intended `none` path, treat it as a current API compatibility issue and report the exact request and error rather than inventing a workaround.
|
||||
|
||||
## Responses API and conversation state
|
||||
|
||||
Prefer Responses for reasoning, tools, multi-turn agents, and new 5.6 capabilities.
|
||||
|
||||
For ordinary multi-turn Responses calls, preserve the repository's existing state strategy. Do not add persisted reasoning merely because it exists.
|
||||
|
||||
If deliberately enabling persisted reasoning:
|
||||
|
||||
- use `reasoning.context: "all_turns"` only when the objective and assumptions remain stable;
|
||||
- prefer `previous_response_id` when the server can carry state;
|
||||
- when replaying manually, preserve every prior user input and every relevant output item, not only assistant text;
|
||||
- with `store: false` or ZDR, request and replay `reasoning.encrypted_content`;
|
||||
- use current-turn behavior when old reasoning may be stale or misleading.
|
||||
|
||||
For manual replay, preserve item types, IDs, call IDs, caller metadata, and assistant phase values exactly. Incomplete replay can silently reduce quality or break tool continuation.
|
||||
|
||||
## Prompt caching
|
||||
|
||||
Do not assume old cache-hit behavior survives the model swap.
|
||||
|
||||
GPT-5.6 implicit caching places a managed breakpoint near the latest user or tool message and no longer relies on 128-token rounding. A prompt with a large stable prefix followed by a changing suffix can therefore lose cache hits even when the stable prefix itself has not changed.
|
||||
|
||||
Audit:
|
||||
|
||||
- large reusable system/developer prompts;
|
||||
- dynamic suffixes appended to otherwise stable prompts;
|
||||
- changing timestamps, request IDs, user-specific values, or tool lists in the prefix;
|
||||
- cache keys, retention settings, and cache dashboards;
|
||||
- token accounting that assumes reads only and ignores writes.
|
||||
|
||||
Migration rules:
|
||||
|
||||
- keep reusable prefixes stable;
|
||||
- do not churn large system prompts unnecessarily;
|
||||
- compare old and new `cached_tokens`, `cache_write_tokens`, latency, and cost;
|
||||
- use explicit cache breakpoints only when a measured workload has a stable boundary that implicit caching misses;
|
||||
- do not globally convert every prompt to explicit caching;
|
||||
- do not send 5.6-only cache fields to older routes in a mixed-model system.
|
||||
|
||||
When old and GPT-5.6 routes share a request builder, isolate GPT-5.6-only fields instead of applying them globally.
|
||||
|
||||
The new top-level request shape uses `prompt_cache_options`, for example:
|
||||
|
||||
```json
|
||||
{
|
||||
"prompt_cache_options": {
|
||||
"mode": "explicit",
|
||||
"ttl": "30m"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Place explicit breakpoints at the actual stable rendered boundary using `prompt_cache_breakpoint`. Preserve `prompt_cache_key` when the application already uses it. Treat the older `prompt_cache_retention` shape as deprecated and verify the live docs before rewriting it.
|
||||
|
||||
Cache writes cost more than ordinary uncached input, so a lower hit rate can be both slower and more expensive.
|
||||
|
||||
## Images, PDFs, files, and long context
|
||||
|
||||
GPT-5.6 can change token and latency behavior without any prompt change:
|
||||
|
||||
- for image inputs, omitted or `auto` image detail can preserve original dimensions;
|
||||
- for PDF/file inputs in Responses, omitted or `input_file.detail: "auto"` can use high page-image detail;
|
||||
- Chat Completions file inputs do not expose the same detail control;
|
||||
- long-context Sol and Terra requests can cross pricing thresholds;
|
||||
- Luna's smaller context can break workloads that fit in Sol or Terra.
|
||||
|
||||
For multimodal or long-context usages:
|
||||
|
||||
1. Measure input tokens and latency before and after.
|
||||
2. Make detail explicit when cost or latency matters.
|
||||
3. Resize images or use lower detail when the task does not need original spatial precision.
|
||||
4. Keep original/high detail for dense, coordinate-sensitive, OCR, localization, or visual-inspection tasks where it materially improves quality.
|
||||
5. Test worst-case context lengths, not only typical requests.
|
||||
|
||||
Do not claim a capability was removed based only on a missing metadata flag. Verify against current docs and a representative request.
|
||||
|
||||
## Structured outputs, parsers, and tool contracts
|
||||
|
||||
Keep output contracts explicit:
|
||||
|
||||
- preserve JSON schemas, required fields, enums, refusal handling, and parser expectations;
|
||||
- preserve tool names, parameter schemas, call IDs, and retry behavior;
|
||||
- keep citations, evidence fields, or native artifacts when downstream consumers require them;
|
||||
- validate that the final answer still satisfies the contract, not merely that a tool call succeeded.
|
||||
|
||||
Do not fix a failing migration by weakening a schema, deleting required behavior, removing routes, dropping tools, or changing business logic unless the user explicitly asked for that product change.
|
||||
|
||||
## Optional: Pro mode
|
||||
|
||||
Do not enable Pro mode during a baseline migration unless the old usage was Pro-like or the user explicitly asks for it.
|
||||
|
||||
GPT-5.6 Pro uses the base model with a reasoning mode:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "gpt-5.6-sol",
|
||||
"reasoning": {
|
||||
"mode": "pro",
|
||||
"effort": "medium"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- use Responses, not Chat Completions;
|
||||
- do not search for or invent a separate `gpt-5.6-pro` slug;
|
||||
- supported Pro efforts begin at `medium`;
|
||||
- mode and effort are separate decisions;
|
||||
- compare task quality, total latency, and actual billed token usage against standard mode.
|
||||
|
||||
If migrating a legacy Pro slug, make the mode change explicit and evaluate it separately from ordinary Sol migration.
|
||||
|
||||
## Optional: Programmatic Tool Calling
|
||||
|
||||
Programmatic Tool Calling is not a required part of moving to GPT-5.6. Add it only when code can reduce large structured intermediate results before they return to model context.
|
||||
|
||||
Good candidates:
|
||||
|
||||
- bounded read-only filtering, joining, sorting, ranking, deduplication, and aggregation;
|
||||
- batching many similar records;
|
||||
- repeated deterministic validation;
|
||||
- map-reduce style retrieval with a compact result schema.
|
||||
|
||||
Poor candidates:
|
||||
|
||||
- one direct tool call;
|
||||
- adaptive workflows where each result changes the next decision;
|
||||
- write, approval, or side-effecting flows;
|
||||
- citation-heavy or native-artifact flows;
|
||||
- semantic judgment that should remain visible to the model.
|
||||
|
||||
Request-shape requirements:
|
||||
|
||||
```json
|
||||
{
|
||||
"tools": [
|
||||
{ "type": "programmatic_tool_calling" },
|
||||
{
|
||||
"type": "function",
|
||||
"name": "lookup_records",
|
||||
"allowed_callers": ["programmatic"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Do not nest `programmatic_tool_calling` under another `tools` property. When enabled, the host must handle `program`, program-issued `function_call`, `function_call_output`, and `program_output` items. Preserve the original `call_id` and `caller` when returning function results.
|
||||
|
||||
Constrain the stage, eligible read-only tools, output schema, retry limit, and handoff back to direct judgment. Validate the final user-visible answer; a correct program result can still become an incorrect final answer.
|
||||
|
||||
## Optional: multi-agent beta
|
||||
|
||||
Do not enable multi-agent behavior during a baseline migration unless the application already has a clear parallelizable workflow and the user asks for it.
|
||||
|
||||
Enabling it requires:
|
||||
|
||||
- the `OpenAI-Beta: responses_multi_agent=v1` header;
|
||||
- `multi_agent: { "enabled": true, "max_concurrent_subagents": 3 }`;
|
||||
- handling `multi_agent_call`, `multi_agent_call_output`, and `agent_message` items;
|
||||
- executing ordinary developer-defined function calls from any agent and returning all required outputs;
|
||||
- preserving new items for replay and tracing;
|
||||
- checking incompatibilities with compaction, reasoning summaries, and tool-call limits in current docs.
|
||||
|
||||
Cap concurrency. Do not let a migration task create unbounded subagents, duplicate work, or finish without a final synthesis.
|
||||
|
||||
## Prompt migration judgment
|
||||
|
||||
After the model and API baseline is working, run representative traces before editing prompts. Change prompts only for measured failures.
|
||||
|
||||
For GPT-5.6, prefer:
|
||||
|
||||
- shorter, outcome-oriented prompts;
|
||||
- explicit success criteria, dependencies, stopping conditions, and completion boundaries;
|
||||
- preserved user-provided values;
|
||||
- decision criteria for implicit choices instead of universal defaults or keyword maps;
|
||||
- explicit autonomy and permission boundaries;
|
||||
- explicit tool routing, resource links, breadcrumbs, and expected tool choice;
|
||||
- staged plans, current-layer awareness, and concise handoffs for long work;
|
||||
- real validation before declaring completion.
|
||||
|
||||
Avoid:
|
||||
|
||||
- generic `be brief`, `be thorough`, or `think step by step` instructions;
|
||||
- blanket language instructions that can cause unwanted language switching;
|
||||
- repeating `ask first` until safe local work becomes blocked;
|
||||
- giant prompt rewrites that make the source of a regression impossible to identify;
|
||||
- telling the model to minimize tool loops when correctness, evidence, or required validation needs more work.
|
||||
|
||||
For coding or agentic migrations, add concrete preservation and verification rules:
|
||||
|
||||
```
|
||||
Preserve existing functionality, routes, outputs, and user-visible behavior.
|
||||
Do not delete or disable required behavior merely to make the build pass.
|
||||
Before finishing, run the relevant build, tests, type checks, render or smoke
|
||||
checks, and report the evidence.
|
||||
```
|
||||
|
||||
For long-running work, define the current layer: research, design, implementation, review, or external coordination. Do not let the model silently move to another layer.
|
||||
|
||||
## Upgrade workflow
|
||||
|
||||
1. Fetch current live 5.6 docs and the Prompting Best Practices section.
|
||||
2. Inventory every usage site and its adjacent prompt, config, registry, parser, and test surfaces.
|
||||
3. Classify each usage by role and migration class.
|
||||
4. Choose Sol, Terra, or Luna by the existing workload's role.
|
||||
5. Preserve the old effective reasoning effort explicitly.
|
||||
6. Run the compatibility gates:
|
||||
- endpoint and SDK support;
|
||||
- Chat Completions plus function tools;
|
||||
- cache topology and cache fields;
|
||||
- context length and long-context cost;
|
||||
- image, PDF, and file detail;
|
||||
- structured outputs and parsers;
|
||||
- Responses state replay and tool continuation;
|
||||
- mixed-model routing and unsupported new fields.
|
||||
7. Apply the smallest safe model, config, registry, and prompt changes.
|
||||
8. Do not add optional Pro, persisted reasoning, PTC, explicit caching, or multi-agent behavior unless needed and measurable.
|
||||
9. Run existing tests and representative evals.
|
||||
10. Report changed, unchanged, blocked, and confirmation-needed sites separately.
|
||||
|
||||
## Validation matrix
|
||||
|
||||
Prefer a controlled comparison:
|
||||
|
||||
1. old model + old prompt + old settings;
|
||||
2. GPT-5.6 target + same prompt + preserved effective reasoning;
|
||||
3. GPT-5.6 target + same prompt + one lower effort;
|
||||
4. GPT-5.6 target + the smallest prompt or API fix required by a measured failure;
|
||||
5. optional feature treatment, isolated from the baseline.
|
||||
|
||||
Measure what matters for the workflow:
|
||||
|
||||
- task success and user-visible quality;
|
||||
- structured-output validity and parser success;
|
||||
- tool choice, tool arguments, retries, loop count, and completion rate;
|
||||
- TTFT, end-to-end latency, timeout rate, and concurrency behavior;
|
||||
- input, output, reasoning, cached, and cache-write tokens;
|
||||
- cost per successful task;
|
||||
- long-context, compaction, and replay behavior;
|
||||
- image/PDF token use and visual/OCR accuracy;
|
||||
- completeness, preserved behavior, citations, and validation evidence.
|
||||
|
||||
For model routers and pickers, test at least one representative workload for each role. Verify that the cheapest or fastest tier is not accidentally used for quality-critical work and that Sol is not accidentally used for every workload.
|
||||
|
||||
## Required final report
|
||||
|
||||
Return:
|
||||
|
||||
- `Current usage inventory`: each model site, endpoint, role, prompt surface, and old effective reasoning.
|
||||
- `Target mapping`: Sol, Terra, Luna, unchanged, or confirmation-needed, with the reason.
|
||||
- `Changes made`: model strings, reasoning settings, prompts, registries, metadata, tests, and API-shape changes.
|
||||
- `Compatibility checks`: Chat Completions/tools, caching, state replay, multimodal detail, context/cost, schemas, and mixed-model routing.
|
||||
- `Prompt changes`: each surgical edit and the failure mode it addresses.
|
||||
- `Validation`: commands, evals, traces, before/after measurements, and remaining gaps.
|
||||
- `Unchanged sites`: historical, pinned, ambiguous, or intentionally role-specific usages.
|
||||
- `Blockers and open questions`: exact issue, why it is unsafe to guess, and the smallest next step.
|
||||
|
||||
Never say the migration is complete merely because model strings changed. It is complete only when the affected behavior and contracts have been validated or the remaining gaps are stated explicitly.
|
||||
|
|
@ -0,0 +1,598 @@
|
|||
#!/usr/bin/env node
|
||||
import {
|
||||
access,
|
||||
mkdir,
|
||||
readFile,
|
||||
rename,
|
||||
rm,
|
||||
stat,
|
||||
writeFile,
|
||||
} from "node:fs/promises";
|
||||
import { constants as fsConstants } from "node:fs";
|
||||
import { execFile } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { inspect, promisify } from "node:util";
|
||||
|
||||
const DEFAULT_MANUAL_URL = "https://developers.openai.com/codex/codex-manual.md";
|
||||
const DEFAULT_CACHE_DIR_NAME = "openai-docs-cache";
|
||||
const CACHE_FILE_NAME = "codex-manual.md";
|
||||
const OUTLINE_FILE_NAME = "codex-manual.outline.md";
|
||||
const HASH_HEADER = "x-content-sha256";
|
||||
const USER_AGENT = "codex-openai-docs";
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
class ManualFetchError extends Error {
|
||||
constructor(message, options) {
|
||||
super(message, options);
|
||||
this.name = "ManualFetchError";
|
||||
}
|
||||
}
|
||||
|
||||
const sha256 = (value) => createHash("sha256").update(value).digest("hex");
|
||||
|
||||
const withTimeout = async (promiseFactory, timeoutMs) => {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
||||
try {
|
||||
return await promiseFactory(controller.signal);
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
};
|
||||
|
||||
const proxyConfigured = () =>
|
||||
process.env.HTTP_PROXY ||
|
||||
process.env.HTTPS_PROXY ||
|
||||
process.env.http_proxy ||
|
||||
process.env.https_proxy;
|
||||
|
||||
const responseHeaders = (headers) => ({
|
||||
get(name) {
|
||||
return headers.get(name.toLowerCase()) ?? null;
|
||||
},
|
||||
});
|
||||
|
||||
const makeResponse = ({ body, headers, status }) => ({
|
||||
headers: responseHeaders(headers),
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
async text() {
|
||||
return body;
|
||||
},
|
||||
});
|
||||
|
||||
const parseCurlHeaders = (rawHeaders) => {
|
||||
const normalized = rawHeaders.replace(/\r\n/g, "\n").trim();
|
||||
const blocks = normalized.split(/\n\n+/).filter(Boolean);
|
||||
const headerBlock = [...blocks]
|
||||
.reverse()
|
||||
.find((block) => block.startsWith("HTTP/"));
|
||||
|
||||
if (!headerBlock) {
|
||||
throw new ManualFetchError("curl did not return HTTP response headers.");
|
||||
}
|
||||
|
||||
const [statusLine, ...lines] = headerBlock.split("\n");
|
||||
const statusMatch = /^HTTP\/\S+\s+(\d{3})/.exec(statusLine);
|
||||
if (!statusMatch) {
|
||||
throw new ManualFetchError(
|
||||
`Could not parse HTTP status from curl response: ${statusLine}`
|
||||
);
|
||||
}
|
||||
|
||||
const headers = new Map();
|
||||
lines.forEach((line) => {
|
||||
const separator = line.indexOf(":");
|
||||
if (separator === -1) return;
|
||||
const name = line.slice(0, separator).trim().toLowerCase();
|
||||
const value = line.slice(separator + 1).trim();
|
||||
headers.set(name, value);
|
||||
});
|
||||
|
||||
return {
|
||||
headers,
|
||||
status: Number(statusMatch[1]),
|
||||
};
|
||||
};
|
||||
|
||||
const tempFilePath = (cacheDir, suffix) =>
|
||||
path.join(
|
||||
cacheDir,
|
||||
`.fetch-codex-manual-${process.pid}-${Date.now()}-${Math.random()
|
||||
.toString(16)
|
||||
.slice(2)}${suffix}`
|
||||
);
|
||||
|
||||
const requestManualWithCurl = async (url, { cacheDir, method, timeoutMs }) => {
|
||||
const headerPath = tempFilePath(cacheDir, ".headers");
|
||||
const bodyPath = tempFilePath(cacheDir, ".body");
|
||||
const curlNames =
|
||||
process.platform === "win32" ? ["curl.exe", "curl"] : ["curl"];
|
||||
const args = [
|
||||
"--silent",
|
||||
"--show-error",
|
||||
"--location",
|
||||
"--dump-header",
|
||||
headerPath,
|
||||
"--output",
|
||||
bodyPath,
|
||||
"--user-agent",
|
||||
USER_AGENT,
|
||||
"--max-time",
|
||||
String(Math.max(1, Math.ceil(timeoutMs / 1000))),
|
||||
];
|
||||
|
||||
if (method === "HEAD") {
|
||||
args.push("--head");
|
||||
} else {
|
||||
args.push("--request", method);
|
||||
}
|
||||
args.push(url);
|
||||
|
||||
let lastError;
|
||||
for (const curlName of curlNames) {
|
||||
try {
|
||||
await execFileAsync(curlName, args, { windowsHide: true });
|
||||
const [rawHeaders, body] = await Promise.all([
|
||||
readFile(headerPath, "utf8"),
|
||||
readFile(bodyPath, "utf8"),
|
||||
]);
|
||||
const { headers, status } = parseCurlHeaders(rawHeaders);
|
||||
return makeResponse({ body, headers, status });
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
if (error?.code !== "ENOENT") break;
|
||||
} finally {
|
||||
await Promise.all([
|
||||
rm(headerPath, { force: true }),
|
||||
rm(bodyPath, { force: true }),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastError?.code === "ENOENT") {
|
||||
throw new ManualFetchError("curl is unavailable in this environment.", {
|
||||
cause: lastError,
|
||||
});
|
||||
}
|
||||
throw new ManualFetchError(`${method} ${url} could not be fetched.`, {
|
||||
cause: lastError,
|
||||
});
|
||||
};
|
||||
|
||||
const requestManualWithFetch = async (url, { method, timeoutMs }) => {
|
||||
if (typeof fetch !== "function") {
|
||||
throw new ManualFetchError(
|
||||
"Native fetch is unavailable in this Node runtime."
|
||||
);
|
||||
}
|
||||
|
||||
return withTimeout(
|
||||
(signal) =>
|
||||
fetch(url, {
|
||||
method,
|
||||
headers: { "User-Agent": USER_AGENT },
|
||||
signal,
|
||||
}),
|
||||
timeoutMs
|
||||
);
|
||||
};
|
||||
|
||||
const requestManual = async (url, { cacheDir, method, timeoutMs }) => {
|
||||
const preferCurl = Boolean(proxyConfigured()) || typeof fetch !== "function";
|
||||
const transports = preferCurl
|
||||
? [
|
||||
() => requestManualWithCurl(url, { cacheDir, method, timeoutMs }),
|
||||
() => requestManualWithFetch(url, { method, timeoutMs }),
|
||||
]
|
||||
: [
|
||||
() => requestManualWithFetch(url, { method, timeoutMs }),
|
||||
() => requestManualWithCurl(url, { cacheDir, method, timeoutMs }),
|
||||
];
|
||||
|
||||
let lastError;
|
||||
for (const transport of transports) {
|
||||
try {
|
||||
const response = await transport();
|
||||
if (!response.ok) {
|
||||
throw new ManualFetchError(
|
||||
`${method} ${url} failed with HTTP ${response.status}.`
|
||||
);
|
||||
}
|
||||
return response;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ManualFetchError(`${method} ${url} could not be fetched.`, {
|
||||
cause: lastError,
|
||||
});
|
||||
};
|
||||
|
||||
const readHeaderSha = (response) => {
|
||||
const value = response.headers.get(HASH_HEADER);
|
||||
if (!value || !/^[a-f0-9]{64}$/i.test(value)) {
|
||||
throw new ManualFetchError(`Manual response is missing ${HASH_HEADER}.`);
|
||||
}
|
||||
return value.toLowerCase();
|
||||
};
|
||||
|
||||
const nearestExistingParent = async (target) => {
|
||||
let current = target;
|
||||
while (true) {
|
||||
try {
|
||||
const info = await stat(current);
|
||||
return info.isDirectory() ? current : null;
|
||||
} catch (error) {
|
||||
if (error?.code !== "ENOENT") return null;
|
||||
}
|
||||
|
||||
const parent = path.dirname(current);
|
||||
if (parent === current) return null;
|
||||
current = parent;
|
||||
}
|
||||
};
|
||||
|
||||
const usableCacheDir = async (cacheDir) => {
|
||||
if (!cacheDir) return null;
|
||||
const resolved = path.resolve(cacheDir);
|
||||
|
||||
try {
|
||||
const info = await stat(resolved);
|
||||
if (!info.isDirectory()) return null;
|
||||
} catch (error) {
|
||||
if (error?.code !== "ENOENT") return null;
|
||||
}
|
||||
|
||||
const parent = await nearestExistingParent(resolved);
|
||||
if (!parent) return null;
|
||||
|
||||
try {
|
||||
await access(parent, fsConstants.W_OK | fsConstants.X_OK);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
};
|
||||
|
||||
const defaultCacheDirCandidates = () => {
|
||||
const candidates = [];
|
||||
const seen = new Set();
|
||||
const pushCandidate = (candidate) => {
|
||||
if (!candidate || seen.has(candidate)) return;
|
||||
seen.add(candidate);
|
||||
candidates.push(candidate);
|
||||
};
|
||||
|
||||
[process.env.TMPDIR, process.env.TEMP, process.env.TMP].forEach((baseDir) => {
|
||||
if (baseDir) {
|
||||
pushCandidate(path.join(baseDir, DEFAULT_CACHE_DIR_NAME));
|
||||
}
|
||||
});
|
||||
|
||||
if (process.platform !== "win32") {
|
||||
pushCandidate(`/private/tmp/${DEFAULT_CACHE_DIR_NAME}`);
|
||||
pushCandidate(`/tmp/${DEFAULT_CACHE_DIR_NAME}`);
|
||||
}
|
||||
|
||||
return candidates;
|
||||
};
|
||||
|
||||
const resolveCacheDir = async (cacheDir) => {
|
||||
if (cacheDir) {
|
||||
return usableCacheDir(cacheDir);
|
||||
}
|
||||
|
||||
for (const candidate of defaultCacheDirCandidates()) {
|
||||
const usable = await usableCacheDir(candidate);
|
||||
if (usable) return usable;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const cacheFilePath = (cacheDir) => path.join(cacheDir, CACHE_FILE_NAME);
|
||||
|
||||
const outlineFilePath = (cacheDir) => path.join(cacheDir, OUTLINE_FILE_NAME);
|
||||
|
||||
const manualLines = (manual) => {
|
||||
const lines = manual.replace(/\r\n/g, "\n").split("\n");
|
||||
if (lines[lines.length - 1] === "") lines.pop();
|
||||
return lines;
|
||||
};
|
||||
|
||||
const sectionTitle = (rawTitle) =>
|
||||
rawTitle.replace(/\s+#+\s*$/, "").replace(/\s+/g, " ").trim();
|
||||
|
||||
const buildOutline = (manual) => {
|
||||
const lines = manualLines(manual);
|
||||
const headings = [];
|
||||
let inFence = false;
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
if (/^\s*(```|~~~)/.test(line)) {
|
||||
inFence = !inFence;
|
||||
return;
|
||||
}
|
||||
if (inFence) return;
|
||||
|
||||
const match = /^(#{1,6})\s+(.+?)\s*$/.exec(line);
|
||||
if (!match) return;
|
||||
|
||||
const level = match[1].length;
|
||||
if (level < 2 || level > 3) return;
|
||||
|
||||
headings.push({
|
||||
level,
|
||||
title: sectionTitle(match[2]),
|
||||
startLine: index + 1,
|
||||
endLine: lines.length,
|
||||
});
|
||||
});
|
||||
|
||||
for (let index = 0; index < headings.length; index += 1) {
|
||||
const heading = headings[index];
|
||||
const nextPeer = headings
|
||||
.slice(index + 1)
|
||||
.find((candidate) => candidate.level <= heading.level);
|
||||
if (nextPeer) {
|
||||
heading.endLine = nextPeer.startLine - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (headings.length === 0) {
|
||||
return {
|
||||
headingCount: 0,
|
||||
lineCount: lines.length,
|
||||
text: "No markdown headings found.",
|
||||
};
|
||||
}
|
||||
|
||||
const minLevel = Math.min(...headings.map((heading) => heading.level));
|
||||
return {
|
||||
headingCount: headings.length,
|
||||
lineCount: lines.length,
|
||||
text: headings
|
||||
.map((heading) => {
|
||||
const indent = " ".repeat(heading.level - minLevel);
|
||||
return `${indent}- ${heading.title} (lines ${heading.startLine}-${heading.endLine})`;
|
||||
})
|
||||
.join("\n"),
|
||||
};
|
||||
};
|
||||
|
||||
const outlineMarkdown = (outline) => `# Codex Manual Outline\n\n${outline.text}\n`;
|
||||
|
||||
const manualStatusLine = (status) =>
|
||||
status.cacheStatus === "hit"
|
||||
? "Manual status: local manual was already current."
|
||||
: "Manual status: local manual was updated.";
|
||||
|
||||
const formatResult = ({ status, outlineText }) =>
|
||||
[
|
||||
`Manual path: ${status.manualPath}`,
|
||||
`Outline path: ${status.outlinePath}`,
|
||||
manualStatusLine(status),
|
||||
"",
|
||||
outlineText,
|
||||
].join("\n");
|
||||
|
||||
const readCachedManual = async (cacheDir, expectedSha256) => {
|
||||
try {
|
||||
const manual = await readFile(cacheFilePath(cacheDir), "utf8");
|
||||
return sha256(manual) === expectedSha256 ? manual : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const writeCachedManual = async (cacheDir, manual) => {
|
||||
await mkdir(cacheDir, { recursive: true });
|
||||
const tmpPath = tempFilePath(cacheDir, `.${CACHE_FILE_NAME}.tmp`);
|
||||
await writeFile(tmpPath, manual, "utf8");
|
||||
await rename(tmpPath, cacheFilePath(cacheDir));
|
||||
};
|
||||
|
||||
const writeOutline = async (cacheDir, outlineText) => {
|
||||
await mkdir(cacheDir, { recursive: true });
|
||||
const tmpPath = tempFilePath(cacheDir, `.${OUTLINE_FILE_NAME}.tmp`);
|
||||
await writeFile(tmpPath, outlineText, "utf8");
|
||||
await rename(tmpPath, outlineFilePath(cacheDir));
|
||||
};
|
||||
|
||||
const fetchCodexManual = async ({
|
||||
manualUrl = DEFAULT_MANUAL_URL,
|
||||
cacheDir,
|
||||
timeoutMs = 30000,
|
||||
} = {}) => {
|
||||
const resolvedCacheDir = await resolveCacheDir(cacheDir);
|
||||
if (!resolvedCacheDir) {
|
||||
throw new ManualFetchError(
|
||||
"Manual cache directory is unavailable; pass --cache-dir to override or use OpenAI Docs MCP fallback."
|
||||
);
|
||||
}
|
||||
await mkdir(resolvedCacheDir, { recursive: true });
|
||||
|
||||
const headResponse = await requestManual(manualUrl, {
|
||||
cacheDir: resolvedCacheDir,
|
||||
method: "HEAD",
|
||||
timeoutMs,
|
||||
});
|
||||
const expectedSha256 = readHeaderSha(headResponse);
|
||||
const manualPath = cacheFilePath(resolvedCacheDir);
|
||||
const outlinePath = outlineFilePath(resolvedCacheDir);
|
||||
const checkedAt = new Date().toISOString();
|
||||
|
||||
const cachedManual = await readCachedManual(resolvedCacheDir, expectedSha256);
|
||||
if (cachedManual !== null) {
|
||||
const outline = buildOutline(cachedManual);
|
||||
const outlineText = outlineMarkdown(outline);
|
||||
await writeOutline(resolvedCacheDir, outlineText);
|
||||
|
||||
return {
|
||||
outlineText,
|
||||
status: {
|
||||
manualUrl,
|
||||
headerSha256: expectedSha256,
|
||||
fetchedManualSha256: expectedSha256,
|
||||
manualHashMatches: true,
|
||||
cacheStatus: "hit",
|
||||
cacheDir: resolvedCacheDir,
|
||||
manualPath,
|
||||
outlinePath,
|
||||
checkedAt,
|
||||
lineCount: outline.lineCount,
|
||||
headingCount: outline.headingCount,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const getResponse = await requestManual(manualUrl, {
|
||||
cacheDir: resolvedCacheDir,
|
||||
method: "GET",
|
||||
timeoutMs,
|
||||
});
|
||||
const getHeaderSha256 = readHeaderSha(getResponse);
|
||||
if (getHeaderSha256 !== expectedSha256) {
|
||||
throw new ManualFetchError(
|
||||
`${HASH_HEADER} changed between HEAD and GET for ${manualUrl}.`
|
||||
);
|
||||
}
|
||||
|
||||
const manualText = await getResponse.text();
|
||||
const actualSha256 = sha256(manualText);
|
||||
const manualHashMatches = actualSha256 === expectedSha256;
|
||||
if (!manualHashMatches) {
|
||||
throw new ManualFetchError(
|
||||
`${HASH_HEADER} did not match the fetched manual body for ${manualUrl}.`
|
||||
);
|
||||
}
|
||||
|
||||
await writeCachedManual(resolvedCacheDir, manualText);
|
||||
const outline = buildOutline(manualText);
|
||||
const outlineText = outlineMarkdown(outline);
|
||||
await writeOutline(resolvedCacheDir, outlineText);
|
||||
|
||||
return {
|
||||
outlineText,
|
||||
status: {
|
||||
manualUrl,
|
||||
headerSha256: expectedSha256,
|
||||
fetchedManualSha256: actualSha256,
|
||||
manualHashMatches,
|
||||
cacheStatus: "updated",
|
||||
cacheDir: resolvedCacheDir,
|
||||
manualPath,
|
||||
outlinePath,
|
||||
checkedAt,
|
||||
lineCount: outline.lineCount,
|
||||
headingCount: outline.headingCount,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const parseArgs = (argv) => {
|
||||
const args = {
|
||||
manualUrl: DEFAULT_MANUAL_URL,
|
||||
cacheDir: undefined,
|
||||
timeoutMs: 30000,
|
||||
statusJson: false,
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index];
|
||||
if (arg === "--manual-url") {
|
||||
args.manualUrl = argv[++index];
|
||||
} else if (arg === "--cache-dir") {
|
||||
args.cacheDir = argv[++index];
|
||||
} else if (arg === "--timeout-ms") {
|
||||
args.timeoutMs = Number(argv[++index]);
|
||||
} else if (arg === "--status-json") {
|
||||
args.statusJson = true;
|
||||
} else {
|
||||
throw new ManualFetchError(`Unknown argument: ${arg}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!args.manualUrl) {
|
||||
throw new ManualFetchError("--manual-url cannot be empty.");
|
||||
}
|
||||
if (!Number.isFinite(args.timeoutMs) || args.timeoutMs <= 0) {
|
||||
throw new ManualFetchError("--timeout-ms must be a positive number.");
|
||||
}
|
||||
|
||||
return args;
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const { outlineText, status } = await fetchCodexManual(args);
|
||||
|
||||
process.stdout.write(formatResult({ status, outlineText }));
|
||||
|
||||
if (args.statusJson) {
|
||||
console.error(JSON.stringify(status));
|
||||
}
|
||||
};
|
||||
|
||||
const envProxyHint = () => {
|
||||
if (proxyConfigured()) {
|
||||
return "Hint: proxy env vars are present. This helper prefers `curl` in proxied sessions; if requests still fail, verify `curl` is installed and the proxy configuration is valid.";
|
||||
}
|
||||
if (typeof fetch !== "function") {
|
||||
return "Hint: native fetch is unavailable in this Node runtime. Install `curl` or use a newer Node version to fetch the manual.";
|
||||
}
|
||||
if (process.platform === "win32") {
|
||||
return "Hint: on Windows, pass a cache dir under `%TEMP%` or `%TMP%`.";
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const formatErrorDetails = (error) => {
|
||||
const details = inspect(error, {
|
||||
breakLength: 120,
|
||||
colors: false,
|
||||
compact: false,
|
||||
depth: 8,
|
||||
});
|
||||
if (!error?.cause) {
|
||||
return details;
|
||||
}
|
||||
|
||||
return `${details}\n\nCause:\n${inspect(error.cause, {
|
||||
breakLength: 120,
|
||||
colors: false,
|
||||
compact: false,
|
||||
depth: 8,
|
||||
})}`;
|
||||
};
|
||||
|
||||
const isCliEntrypoint = () => {
|
||||
const entrypoint = process.argv[1];
|
||||
if (!entrypoint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pathToFileURL(entrypoint).href === import.meta.url;
|
||||
};
|
||||
|
||||
if (isCliEntrypoint()) {
|
||||
main().catch((error) => {
|
||||
console.error(`Error: ${error.message}`);
|
||||
const hint = envProxyHint();
|
||||
if (hint) {
|
||||
console.error(hint);
|
||||
}
|
||||
console.error("");
|
||||
console.error("Details:");
|
||||
console.error(formatErrorDetails(error));
|
||||
process.exitCode = 1;
|
||||
});
|
||||
}
|
||||
|
||||
export { DEFAULT_MANUAL_URL, fetchCodexManual };
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
SCRIPT_PATH="$SCRIPT_DIR/resolve-latest-model-info.cjs"
|
||||
|
||||
is_compatible_node() {
|
||||
"$1" -e 'const major = Number(process.versions.node.split(".")[0]); process.exit(major >= 18 ? 0 : 1)' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
run_if_compatible() {
|
||||
CANDIDATE=$1
|
||||
shift
|
||||
if [ -n "$CANDIDATE" ] && [ -x "$CANDIDATE" ] && is_compatible_node "$CANDIDATE"; then
|
||||
exec "$CANDIDATE" "$SCRIPT_PATH" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -n "${NODE:-}" ]; then
|
||||
run_if_compatible "$NODE" "$@"
|
||||
fi
|
||||
|
||||
PATH_NODE=$(command -v node 2>/dev/null || true)
|
||||
if [ -n "$PATH_NODE" ]; then
|
||||
run_if_compatible "$PATH_NODE" "$@"
|
||||
fi
|
||||
|
||||
for CANDIDATE in \
|
||||
"$HOME/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node" \
|
||||
"$HOME/.cache/codex-runtimes/codex-primary-runtime/dependencies/bin/node" \
|
||||
"/opt/homebrew/bin/node" \
|
||||
"/usr/local/bin/node" \
|
||||
"/usr/bin/node"
|
||||
do
|
||||
run_if_compatible "$CANDIDATE" "$@"
|
||||
done
|
||||
|
||||
echo "No usable Node.js 18+ runtime found for resolve-latest-model-info.cjs" >&2
|
||||
exit 127
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
// Keep this entrypoint CommonJS-safe when the skill is copied into a type=module repo.
|
||||
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("node:path");
|
||||
|
||||
const DEFAULT_URL =
|
||||
"https://developers.openai.com/api/docs/guides/latest-model.md";
|
||||
const DEFAULT_BASE_URL = "https://developers.openai.com";
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = {
|
||||
source: process.env.LATEST_MODEL_URL || DEFAULT_URL,
|
||||
baseUrl: process.env.LATEST_MODEL_BASE_URL || DEFAULT_BASE_URL,
|
||||
};
|
||||
|
||||
for (let i = 2; i < argv.length; i += 1) {
|
||||
const arg = argv[i];
|
||||
if (arg === "--source" || arg === "--url") {
|
||||
args.source = argv[i + 1];
|
||||
i += 1;
|
||||
} else if (arg === "--base-url") {
|
||||
args.baseUrl = argv[i + 1];
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
async function readSource(source) {
|
||||
if (source.startsWith("file://")) {
|
||||
return fs.readFile(new URL(source), "utf8");
|
||||
}
|
||||
|
||||
if (!/^https?:\/\//.test(source)) {
|
||||
return fs.readFile(path.resolve(source), "utf8");
|
||||
}
|
||||
|
||||
let lastError;
|
||||
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
||||
try {
|
||||
const response = await fetch(source, {
|
||||
headers: { accept: "text/markdown,text/plain,*/*" },
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
return response.text();
|
||||
}
|
||||
|
||||
lastError = new Error("failed to fetch " + source + ": " + response.status);
|
||||
if (response.status < 500 && response.status !== 429) {
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
|
||||
if (attempt < 3) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 250 * attempt));
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
function parseIndentedInfo(lines, startIndex) {
|
||||
const info = {};
|
||||
|
||||
for (let i = startIndex + 1; i < lines.length; i += 1) {
|
||||
const line = lines[i];
|
||||
if (!line.trim()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const match = line.match(/^ {2}([A-Za-z][A-Za-z0-9_-]*):\s*(.+?)\s*$/);
|
||||
if (!match) {
|
||||
break;
|
||||
}
|
||||
|
||||
info[match[1]] = match[2].replace(/^["']|["']$/g, "");
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
function parseFlatInfo(block) {
|
||||
const info = {};
|
||||
|
||||
for (const line of block.split(/\r?\n/)) {
|
||||
const match = line.match(/^\s*([A-Za-z][A-Za-z0-9_-]*):\s*(.+?)\s*$/);
|
||||
if (match) {
|
||||
info[match[1]] = match[2].replace(/^["']|["']$/g, "");
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
function extractLatestModelInfo(markdown) {
|
||||
const lines = markdown.split(/\r?\n/);
|
||||
const latestModelInfoIndex = lines.findIndex((line) =>
|
||||
/^latestModelInfo:\s*$/.test(line)
|
||||
);
|
||||
|
||||
if (latestModelInfoIndex >= 0) {
|
||||
return parseIndentedInfo(lines, latestModelInfoIndex);
|
||||
}
|
||||
|
||||
const commentMatch = markdown.match(
|
||||
/<!--\s*latestModelInfo\s*\n([\s\S]*?)\n\s*-->/m
|
||||
);
|
||||
if (commentMatch) {
|
||||
return parseFlatInfo(commentMatch[1]);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function modelToSkillSlug(model) {
|
||||
return model.trim().replace(/\./g, "p");
|
||||
}
|
||||
|
||||
function absoluteUrl(baseUrl, value) {
|
||||
return new URL(value, baseUrl).toString();
|
||||
}
|
||||
|
||||
function normalizeInfo(info, baseUrl) {
|
||||
const model = info?.model?.trim();
|
||||
const migrationGuide = info?.migrationGuide?.trim();
|
||||
const promptingGuide = info?.promptingGuide?.trim();
|
||||
|
||||
if (!model || !migrationGuide || !promptingGuide) {
|
||||
throw new Error(
|
||||
"latestModelInfo must include model, migrationGuide, and promptingGuide"
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
model,
|
||||
modelSlug: modelToSkillSlug(model),
|
||||
migrationGuideUrl: absoluteUrl(baseUrl, migrationGuide),
|
||||
promptingGuideUrl: absoluteUrl(baseUrl, promptingGuide),
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { source, baseUrl } = parseArgs(process.argv);
|
||||
const markdown = await readSource(source);
|
||||
const info = extractLatestModelInfo(markdown);
|
||||
|
||||
if (!info) {
|
||||
throw new Error(`latestModelInfo block not found in ${source}`);
|
||||
}
|
||||
|
||||
process.stdout.write(
|
||||
`${JSON.stringify(normalizeInfo(info, baseUrl), null, 2)}\n`
|
||||
);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue