Skip to content

feat(oauth): add the dynamic_tools capability from the official models endpoint - #3667

Open
sailist wants to merge 5 commits into
MoonshotAI:mainfrom
sailist:feat-176-09-09-official-models-dynamic-tools
Open

feat(oauth): add the dynamic_tools capability from the official models endpoint#3667
sailist wants to merge 5 commits into
MoonshotAI:mainfrom
sailist:feat-176-09-09-official-models-dynamic-tools

Conversation

@sailist

@sailist sailist commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — internal feature request.

Problem

The official Kimi Code /models endpoint now returns supports_dynamic_tools: bool per model, but the refresh/provisioning flow drops the field, so config.toml never records which models accept message-level tool declarations. Meanwhile the runtime capability vocabulary for that feature is dynamically_loaded_tools, which diverges from the upstream field name.

What changed

  • Parse supports_dynamic_tools from the official /models response (toModelInfo in packages/oauth/src/managed-kimi-code.ts); non-boolean or absent values are ignored, matching the existing field-tolerance style.
  • Models declaring support get capabilities = [ "dynamic_tools" ] in their config.toml entries via the existing capabilitiesForModel() path; the merge/diff/write pipeline needed no changes.
  • Unified the internal vocabulary on dynamic_tools: renamed dynamically_loaded_tools across kosong, agent-core-v2, node-sdk, the catalog publish script, and tests (config declaration string, ModelCapability field, ToolSelectService and human tool-select consumers). No alias mapping — old spelling is no longer recognized.
  • Tests: extended the existing supports_thinking_type fixtures/assertions in packages/oauth/test/managed-kimi-code.test.ts to cover parsing and capability mapping (test count unchanged); renamed affected assertions elsewhere.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f791d9a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 9, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@f791d9a
npx https://pkg.pr.new/@moonshot-ai/kimi-code@f791d9a

commit: f791d9a

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 279e72ed39

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// catalogModelToCapability reads it; stripping it here would silently
// disable tool-select for catalog-imported aliases.
"dynamically_loaded_tools",
"dynamic_tools",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the models.dev capability field

The models.dev catalog schema and compatible mirrors expose this as dynamically_loaded_tools; replacing that wire key with the internal dynamic_tools name causes stripModel() to discard the capability from fetched catalogs. Consequently, catalog-imported models that previously advertised support are emitted without the bit and tool selection remains disabled; retain the wire key here and translate it while normalizing the catalog.

Useful? React with 👍 / 👎.

Comment on lines +497 to +499
dynamic_tools:
declared.has('dynamic_tools') ||
detected.dynamic_tools === true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Continue recognizing the existing config capability

For users whose existing config.toml model aliases declare dynamically_loaded_tools, this resolver now silently ignores that declaration, so enabling the tool-select flag no longer activates progressive disclosure after upgrading. Since this is being released as a patch rather than a confirmed major change, accept both spellings during resolution and normalize to dynamic_tools internally.

AGENTS.md reference: AGENTS.md:L64-L64

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e274157fc7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

});
const disposable = this._register(this.registry.register(tool, { source: 'mcp' }));
const disposable = this._register(
this.registry.register(tool, { source: 'mcp', disclosure: 'deferred' }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor deferred:false for MCP authentication tools

When a remote MCP server configured with deferred: false initially enters needs-auth while the tool-select gate is active, this branch still marks its synthetic authentication tool as deferred. AgentToolSelectService consequently hides that tool from the top-level tool list until it is selected dynamically, so the server's explicit inline-disclosure opt-out is not honored during authentication; propagate the server's configured disclosure setting here as the connected-server path does.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant