.Net: Python: KernelJsonSchemaBuilder emits {"type": "object"} with no enum for typing.Literal parameters and fields
メンテナーはふだん 3 日以内に返信
評価
調査の方向性
python/semantic_kernel/schema/kernel_json_schema_builder.py を読み、handle_complex_type() と get_json_schema() に注目してください。まず KernelJsonSchemaBuilder.build() の直接的な例と、提供されている kernel-function の再現を実行してください。完了条件は、Literal の値がオブジェクトスキーマではなく、nullable のケースやリストにネストされたケースを含む、型付き enum スキーマを生成することです。
索引モデルが issue の本文から書いたものです。
説明
What happens
KernelJsonSchemaBuilder has no handling for typing.Literal. A parameter typed Literal["fast", "slow"] is advertised to the model as a bare {"type": "object"} with no enum. The model is told the argument is an object and is never told the allowed values.
This affects @kernel_function parameters, Pydantic model fields, and Literal nested inside list[...] or Optional[...].
Where
python/semantic_kernel/schema/kernel_json_schema_builder.py, KernelJsonSchemaBuilder.handle_complex_type() and get_json_schema().
Literal[...] has __args__, so build() sends it to handle_complex_type(). That method handles list, set, dict, tuple and Union, but not Literal, so it reaches the final fallback:
schema = cls.get_json_schema(parameter_type) # TYPE_MAPPING.get(Literal[...], "object")
TYPE_MAPPING has no entry for a Literal alias, so the default "object" is returned. build_enum_schema() already produces the right shape for Enum classes ({"type": ..., "enum": [...]}), but nothing does that for Literal.
Repro
Tested with semantic-kernel==1.44.1. I diffed kernel_json_schema_builder.py against current main and the file is identical.
import json
from typing import Annotated, Literal
from pydantic import BaseModel
from semantic_kernel import Kernel
from semantic_kernel.functions import kernel_function
from semantic_kernel.connectors.ai.function_calling_utils import kernel_function_metadata_to_function_call_format
class Opts(BaseModel):
level: Literal["low", "high"]
class Plugin:
@kernel_function(name="run")
def run(self, mode: Annotated[Literal["fast", "slow"], "speed mode"], opts: Annotated[Opts, "options"]) -> str:
return mode
k = Kernel(); k.add_plugin(Plugin(), "p")
fn = k.get_function("p", "run")
print(json.dumps(kernel_function_metadata_to_function_call_format(fn.metadata)["function"]["parameters"], indent=1))
Output:
{
"type": "object",
"properties": {
"mode": {"type": "object", "description": "speed mode"},
"opts": {
"type": "object",
"properties": {"level": {"type": "object"}},
"required": ["level"],
"description": "options"
}
},
"required": ["mode", "opts"]
}
Direct builder calls:
KernelJsonSchemaBuilder.build(Literal["fast", "slow"]) # {'type': 'object'}
KernelJsonSchemaBuilder.build(Optional[Literal["fast", "slow"]]) # {'type': ['object', 'null']}
KernelJsonSchemaBuilder.build(list[Literal["a", "b"]]) # {'type': 'array', 'items': {'type': 'object'}}
Expected
{"type": "string", "enum": ["fast", "slow"], "description": "speed mode"}
This is the same shape build_enum_schema() already returns for an Enum subclass. Optional[Literal[...]] should be nullable and list[Literal[...]] should have an enum on items.
Actual
{"type": "object"} with no allowed values. The model can emit any value, including a JSON object, and the kernel then tries to bind it to a str parameter. Tools that use Literal to constrain choices (a very common pattern) lose that constraint entirely.
Suggested fix
Add a Literal branch in handle_complex_type():
if origin is Literal:
values = list(args)
types = {TYPE_MAPPING.get(type(v), "string") for v in values}
schema = {"type": types.pop() if len(types) == 1 else sorted(types), "enum": values}
if description:
schema["description"] = description
return schema
The Optional[...] branch also needs to keep working with an enum schema (add None to the enum when making it nullable).
I searched open and closed issues and PRs for Literal, KernelJsonSchemaBuilder, and schema builder problems. #14239, #14241 and #14310 are about string forward references and only make sure Literal values are left alone while resolving them. #14482 and #14155 are about NoneType in unions. None of them adds Literal support.
- 主要言語
- C#
- スター
- 28.7k
- フォーク
- 4.8k
- 平均マージ
- 2日 15時間
- マージ済み PR(30日)
- 23
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/semantic-kernel のほかの issue
-
Python: Rejected system messages leave AgentChat permanently active対応中かも @Michael-Duck が今日担当しました。 オープンpython triage
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
microsoft/semantic-kernel#14638 ·
メンテナーはふだん 3 日以内に返信
-
Python: Bug: Anthropic, Bedrock, Google AI and Vertex AI tool formatters ignore include_in_function_choices=False対応中かも @wasim-builds が 5 日前に担当しました。 オープンpython triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
microsoft/semantic-kernel#14615 ·
メンテナーはふだん 3 日以内に返信
-
Python: Bug: AnnotationContent and StreamingAnnotationContent to_element writes CitationType.X, so annotations in a rendered chat history fail to parse対応中かも @CRYPTONIKAV が 9 日前に担当しました。 オープンpython triage
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
microsoft/semantic-kernel#14590 ·
メンテナーはふだん 3 日以内に返信
-
Python: Bug: TimePlugin timeZoneOffset and timeZoneName always return an empty string対応中かも @jeevan1098 が 7 日前に担当しました。 オープンpython triage
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
microsoft/semantic-kernel#14583 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
-
.Net: gpt-image-1 is the default image model in the .NET OpenAI connector, and OpenAI shuts it down on October 23対応中かも @nightcityblade が 20 日前に担当しました。 オープン.NET triage
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
microsoft/semantic-kernel#14526 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
microsoft/semantic-kernel の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
AvaloniaUI/Avalonia#22568 ·
メンテナーはふだん 2 日以内に返信
-
[bug] 截图失败日志冲爆硬盘オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 63/100
babalae/better-genshin-impact#3846 · コメント 2 件 ·
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
lugassawan/swe-workbench#823 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
microsoft/fluentui-blazor#5518 ·
メンテナーはふだん 1 日以内に返信
-
devtools
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信