Skip to content

feat(sdk,sdkx): pod-runtime L3 — llm redesign, tool middleware, script caps, catalog refresh [skip-tag:sdkx]#52

Merged
lIang70 merged 4 commits into
mainfrom
feat/pod-runtime-l3-llm-redesign
Apr 30, 2026
Merged

feat(sdk,sdkx): pod-runtime L3 — llm redesign, tool middleware, script caps, catalog refresh [skip-tag:sdkx]#52
lIang70 merged 4 commits into
mainfrom
feat/pod-runtime-l3-llm-redesign

Conversation

@lIang70

@lIang70 lIang70 commented Apr 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Major rework grouped under the Pod for Agents pod-runtime gaps L3 plan (see docs/sdk-pod-runtime-gaps.md and docs/sdk-llm-redesign.md). Touches three SDK areas plus a full sdkx/llm provider catalog refresh.

sdk/llm — redesigned around ModelSpec

  • ModelSpec (Caps + Defaults + Limits) is now the unified model-fixed property set. Old ModelInfo.Caps kept as deprecated alias with warn-once auto-promote (removal: v0.3.0).
  • Three middleware layers, assembled one-shot by the resolver: WithDefaults (fill nil) → WithCaps (drop / downgrade / validate unsupported features) → WithLimits (clamp numeric ceilings). Replaces the previous ad-hoc capsLLM wrapper.
  • Capability surface extended: TopP, TopK, Vision, Audio, File, ParallelTools, SystemPrompt, Streaming, JSONMode, JSONSchema. System-prompt folding and streaming downgrade kick in automatically when caps are disabled.
  • Credential profiles (profile.go): per-call profile via context, profile-aware resolver cache, three-dimensional cacheKey {provider, model, profile}. InvalidateCache now takes variadic WithProvider / WithModel / WithProfile options with AND semantics.
  • ModelDeprecation field on ModelInfo plus a one-shot resolver telemetry warning per (provider, model). Catalog metadata only — does NOT participate in SpecOverride merge so a deployment cannot accidentally un-deprecate an upstream declaration.
  • File layout cleanup: caps/middleware split into capability.go, spec.go, with_caps.go, with_defaults.go, with_limits.go; types.goaliases.go; deprecated APIs collected in deprecated.go with explicit v0.3.0 removal banners.

sdk/tool — registry middleware

  • Dispatch / Middleware types and Registry.Use for cross-cutting tool concerns (rate-limit, audit, allow-list). Composed chain runs around coreDispatch.
  • ToolMeta / ToolMetadata interface for static tool metadata.

sdk/script — runtime resource caps

  • jsrt: WithMaxCallStackSize and WithMaxExecTime options.
  • luart: WithMaxExecTime option. Memory limit removed — gopher-lua does not expose a safe enforcement hook (see luart.go comment for rationale).

sdkx/llm — catalog refresh against 2026-04-30 provider docs

Provider Highlights
Anthropic claude-opus-4-7 (new flagship), opus-4-6, sonnet-4-6, haiku-4-5 with corrected family-first ID convention. JSONMode enabled (Beta API path), JSONSchema disabled across the family.
OpenAI gpt-5.5 / gpt-5.5-pro (released 2026-04-23), gpt-5.4 family, gpt-5 family, plus o3 / o3-pro / o4-mini reasoning models with sampling-control caps disabled per o-series convention. o4-mini marked deprecated (RetiresAt: 2026-10-23, Replacement: gpt-5-mini) per the 2026-04-22 OpenAI deprecation announcement. gpt-4.1 removed from catalog. defaultModel changed gpt-4ogpt-5 (gpt-4o lineage is legacy / declining usage).
MiniMax M2.7 / M2.7-highspeed / M2.5 / M2.5-highspeed / M2.1 / M2 (legacy). Caps reflect the Anthropic-compat endpoint surface — JSONMode/JSONSchema both disabled with documented evidence (no response_format honoring on M2-series).
ByteDance Doubao Seed 2.0 — current limits and caps.
Qwen Qwen-Max / Plus / Turbo — current limits and caps.
DeepSeek V4 (flash + pro) added; V3 / R1 specs refreshed; legacy aliases marked.

Tag note

[skip-tag:sdkx] is set in the title (and commit subject) so the auto-tag workflow only bumps sdk/ on this push. sdkx/ will be tagged manually after a follow-up review of catalog accuracy.

Test plan

  • make vet (sdk + sdkx + voice + GOWORK=off bench/examples/conformance)
  • make test (full)
  • Targeted: sdk/llm, sdk/tool, sdk/script, sdkx/llm/...
  • Smoke test against a live OpenAI key (gpt-5, gpt-5.5) — recommend running before merge

Made with Cursor

lIang70 added 4 commits April 30, 2026 12:06
…t caps, catalog refresh [skip-tag:sdkx]

Major rework grouped under the "Pod for Agents" pod-runtime gaps L3
plan (see docs/sdk-pod-runtime-gaps.md and docs/sdk-llm-redesign.md):

sdk/llm — redesigned around ModelSpec
  * Introduce ModelSpec (Caps + Defaults + Limits) as the unified
    model-fixed property set; ModelInfo.Caps kept as deprecated
    alias with a warn-once auto-promote path (removal: v0.3.0).
  * Three middleware layers, assembled one-shot by the resolver:
    WithDefaults (fill nil) → WithCaps (drop / downgrade /
    validate unsupported features) → WithLimits (clamp numeric
    ceilings). Replaces the previous ad-hoc capsLLM wrapper.
  * Capability surface extended: TopP, TopK, Vision, Audio, File,
    ParallelTools, SystemPrompt, Streaming, JSONMode, JSONSchema.
    System-prompt folding and streaming downgrade behaviors
    happen automatically when the corresponding cap is disabled.
  * Credential profiles (sdk/llm/profile.go): per-call profile
    via context, profile-aware resolver cache, three-dimensional
    cacheKey (provider, model, profile). InvalidateCache now
    takes variadic WithProvider/WithModel/WithProfile options
    with AND semantics.
  * ModelDeprecation field on ModelInfo plus a one-shot resolver
    telemetry warning per (provider, model). Catalog metadata
    only — does NOT participate in SpecOverride merge so a
    deployment cannot accidentally un-deprecate an upstream
    declaration.
  * File layout cleanup: caps/middleware split into capability.go,
    spec.go, with_caps.go, with_defaults.go, with_limits.go;
    types.go renamed to aliases.go; deprecated APIs collected in
    deprecated.go with explicit v0.3.0 removal banners.

sdk/tool — registry middleware
  * Dispatch/Middleware types and Registry.Use for cross-cutting
    tool concerns (rate-limit, audit, allow-list). Composed
    chain runs around coreDispatch.
  * ToolMeta / ToolMetadata interface for static tool metadata.

sdk/script — runtime resource caps
  * jsrt: WithMaxCallStackSize and WithMaxExecTime options.
  * luart: WithMaxExecTime option. Memory limit removed —
    gopher-lua does not expose a safe enforcement hook (see
    luart.go comment for rationale).

sdkx/llm — catalog refresh against 2026-04-30 provider docs
  * Anthropic: claude-opus-4-7 (new flagship), opus-4-6, sonnet-4-6,
    haiku-4-5 with corrected family-first ID convention. JSONMode
    enabled (Beta API path), JSONSchema disabled across the family.
  * OpenAI: gpt-5.5 / gpt-5.5-pro (released 2026-04-23), gpt-5.4,
    gpt-5.4-pro, gpt-5.4-mini, gpt-5.4-nano, gpt-5 family, plus
    o3 / o3-pro / o4-mini reasoning models with sampling-control
    caps disabled per o-series convention. o4-mini marked
    Deprecation{RetiresAt: 2026-10-23, Replacement: gpt-5-mini}
    per the 2026-04-22 OpenAI deprecation announcement. gpt-4.1
    removed from catalog. defaultModel changed gpt-4o → gpt-5
    (gpt-4o lineage is legacy / declining usage).
  * MiniMax: M2.7, M2.7-highspeed, M2.5, M2.5-highspeed, M2.1,
    M2 (legacy). All caps reflect the Anthropic-compat endpoint
    surface — JSONMode/JSONSchema both disabled with documented
    evidence (no response_format honoring on M2-series).
  * ByteDance Doubao Seed 2.0, Qwen-Max/Plus/Turbo, DeepSeek V4
    (flash + pro): all populated with current limits and caps.

[skip-tag:sdkx] is set so the auto-tag workflow only bumps sdk on
this push; sdkx will be tagged manually after a follow-up review of
catalog accuracy.

Made-with: Cursor
…oundary

Before this change, disabling CapParallelTools in a model catalog
was a silent no-op. The middleware comment claimed adapters MUST
consult `caps.Supports(CapParallelTools)` before forwarding the
parallel-tool toggle, but adapters sit BELOW WithCaps in the wrap
chain and only see GenerateOptions — they cannot read caps. As a
result, the DeepSeek catalog declaration that listed
CapParallelTools in DisabledCaps had zero effect at runtime.

Fix it by stripping the protocol-reserved Extra keys directly inside
WithCaps when the cap is disabled:

  - "parallel_tool_calls"        — OpenAI Chat Completions / Responses
                                    (and OpenAI-compatible: Qwen,
                                     ByteDance, MiniMax, DeepSeek)
  - "disable_parallel_tool_use"  — Anthropic Messages API
                                    (and Anthropic-compatible: MiniMax
                                     /anthropic endpoint)

Both keys are protocol-reserved namespaces, not free-form labels —
the previous "stripping is brittle" worry doesn't apply. Other
Extra map keys are preserved unmodified.

For new adapters introducing a non-standard parallel-tool toggle,
RegisterParallelToolExtraKey lets them extend the strip set from
their init() so the catalog cap stays a single source of truth.

Tests cover three contracts:
  * Disabled cap strips both built-in keys and warns once.
  * Enabled cap preserves the keys verbatim.
  * RegisterParallelToolExtraKey picks up custom keys at runtime.

Made-with: Cursor
The Volcengine Ark SDK exposes parallel_tool_calls as the typed
field model.CreateChatCompletionRequest.ParallelToolCalls (*bool).
Our adapter previously did not consume opts.Extra at all, so callers
had no way to control parallel tool calls on Doubao through this
SDK — even though the underlying API supports it.

Bridge opts.Extra["parallel_tool_calls"] (bool) onto the typed
request field. This brings ByteDance to feature parity with the
OpenAI adapter, and dovetails with the new CapParallelTools
enforcement: when a future Doubao SKU drops parallel-tool support,
declaring CapParallelTools disabled in the catalog is enough — the
WithCaps middleware strips the Extra key before we get here, so
this branch falls through and req.ParallelToolCalls stays nil, and
Doubao serves the request with its own default behaviour.

Made-with: Cursor
…ed field

Anthropic carries disable_parallel_tool_use NESTED inside tool_choice
(param.Opt[bool] on Auto / Any / Tool — not on None, where it would
be meaningless), unlike OpenAI's top-level parallel_tool_calls. The
adapter previously did not consume opts.Extra at all on this path,
so callers had no way to disable parallel tool use on Anthropic
through this SDK.

Bridge opts.Extra["disable_parallel_tool_use"] (bool) onto whichever
ToolChoice variant is selected. When the caller sets the toggle
without an explicit ToolChoice, we default to OfAuto since omitted
tool_choice = auto on Anthropic anyway.

This also benefits the MiniMax adapter, which proxies through this
exact code path via sdkx/llm/minimax/New() → anthropic.New(). The
new CapParallelTools enforcement in WithCaps strips the Extra key
before this branch runs when the catalog declares the cap disabled,
keeping behaviour consistent with the OpenAI / ByteDance adapters.

Qwen needed no change: it wraps the OpenAI adapter, so the
parallel_tool_calls Extra key already passes through DashScope's
OpenAI-compatible endpoint via option.WithJSONSet.

Made-with: Cursor
@lIang70
lIang70 merged commit baa3229 into main Apr 30, 2026
16 of 18 checks passed
@lIang70
lIang70 deleted the feat/pod-runtime-l3-llm-redesign branch April 30, 2026 04:25
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