Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

.Net: Python: KernelJsonSchemaBuilder emits {"type": "object"} with no enum for typing.Literal parameters and fields

Aperta Adatta ai principianti
#14,511 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 3 giorni

@VANDRANKI ci sta già lavorando.

Dal 30/9/2026.

  • #14514 di @VANDRANKI — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
82/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
api

Direzione di ricerca

Leggi python/semantic_kernel/schema/kernel_json_schema_builder.py, concentrandoti su handle_complex_type() e get_json_schema(). Esegui prima gli esempi diretti di KernelJsonSchemaBuilder.build() e la riproduzione fornita di kernel-function. Il lavoro è completato quando i valori Literal producono schemi enum tipizzati, inclusi i casi nullable e annidati in liste, invece di schemi di oggetti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

.NET python triage

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.

Lingua principale
C#
Stelle
28.7k
Fork
4.8k
Merge medio
2g 12h
PR unite (30g)
22

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/semantic-kernel

Tutte le issue di microsoft/semantic-kernel

Issue simili

Altre issue su C#

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.