Gemini Test
This commit is contained in:
@@ -47,20 +47,19 @@ class function TAstSchema.GetJsonType(Kind: TFieldKind): TJSONObject;
|
||||
Result.AddPair('type', ATypeName);
|
||||
end;
|
||||
|
||||
function JConst(const AVal: string): TJSONObject;
|
||||
// Use enum for const strings as it's widely supported
|
||||
function JEnum(const AVal: string): TJSONObject;
|
||||
var
|
||||
arr: TJSONArray;
|
||||
begin
|
||||
Result := TJSONObject.Create;
|
||||
Result.AddPair('const', AVal);
|
||||
Result := JType('string');
|
||||
arr := TJSONArray.Create;
|
||||
arr.Add(AVal);
|
||||
Result.AddPair('enum', arr);
|
||||
end;
|
||||
|
||||
function JArray(AItems: TJSONValue): TJSONObject;
|
||||
begin
|
||||
Result := JType('array');
|
||||
Result.AddPair('items', AItems);
|
||||
end;
|
||||
|
||||
// Combined function: Creates array from items and sets prefixItems + limits
|
||||
function JFixedArray(const AItems: array of TJSONValue): TJSONObject;
|
||||
// Tuple Array (Fixed items)
|
||||
function JTupleArray(const AItems: array of TJSONValue): TJSONObject;
|
||||
var
|
||||
arr: TJSONArray;
|
||||
item: TJSONValue;
|
||||
@@ -68,19 +67,22 @@ class function TAstSchema.GetJsonType(Kind: TFieldKind): TJSONObject;
|
||||
begin
|
||||
Result := JType('array');
|
||||
|
||||
// "items" as an array defines a Tuple schema in older drafts (supported by Gemini)
|
||||
arr := TJSONArray.Create;
|
||||
for item in AItems do
|
||||
arr.AddElement(item);
|
||||
|
||||
count := arr.Count;
|
||||
Result.AddPair('prefixItems', arr);
|
||||
Result.AddPair('items', arr); // Items as Array = Tuple Definition
|
||||
Result.AddPair('minItems', TJSONNumber.Create(count));
|
||||
Result.AddPair('maxItems', TJSONNumber.Create(count));
|
||||
Result.AddPair('additionalItems', TJSONBool.Create(False)); // No extra items allowed
|
||||
end;
|
||||
|
||||
function JTuple(AItems: TJSONValue): TJSONObject;
|
||||
begin
|
||||
Result := JFixedArray([JConst('Tuple'), AItems]);
|
||||
// ["Tuple", [...]]
|
||||
Result := JTupleArray([JEnum('Tuple'), AItems]);
|
||||
end;
|
||||
|
||||
function JAnyOf(AOptions: array of TJSONValue): TJSONObject;
|
||||
@@ -97,7 +99,7 @@ class function TAstSchema.GetJsonType(Kind: TFieldKind): TJSONObject;
|
||||
{$endregion}
|
||||
|
||||
var
|
||||
pair, selItems, selTuple, entryContent, entryNode: TJSONObject;
|
||||
pair, selTuple, entryNode: TJSONObject;
|
||||
begin
|
||||
case Kind of
|
||||
fkNode: Result := JDefRef('Node');
|
||||
@@ -105,28 +107,54 @@ begin
|
||||
fkKeyword: Result := JDefRef('Key');
|
||||
fkLambda: Result := JDefRef('Fn');
|
||||
fkIdentifier: Result := JDefRef('Id');
|
||||
|
||||
fkString: Result := JType('string');
|
||||
fkValue: Result := JAnyOf([JType('number'), JType('string'), JType('boolean')]);
|
||||
fkNullableNode: Result := JAnyOf([JDefRef('Node'), JType('null')]);
|
||||
fkArrayOfNodes: Result := JArray(JDefRef('Node'));
|
||||
|
||||
fkValue:
|
||||
begin
|
||||
// number | string | boolean
|
||||
Result := JAnyOf([JType('number'), JType('string'), JType('boolean')]);
|
||||
end;
|
||||
|
||||
fkNullableNode:
|
||||
begin
|
||||
// Node | null
|
||||
// Note: OpenAPI/Gemini often prefers 'nullable: true' over explicit null type,
|
||||
// but anyOf [Node, {type: null}] works in full JSON schema.
|
||||
Result := JAnyOf([JDefRef('Node'), JType('null')]);
|
||||
end;
|
||||
|
||||
fkArrayOfNodes:
|
||||
begin
|
||||
// standard array of Nodes
|
||||
Result := JType('array');
|
||||
Result.AddPair('items', JDefRef('Node'));
|
||||
end;
|
||||
|
||||
fkArrayOfPairs:
|
||||
begin
|
||||
// [[Cond, Branch], ...]
|
||||
pair := JFixedArray([JDefRef('Node'), JDefRef('Node')]);
|
||||
Result := JArray(pair);
|
||||
pair := JTupleArray([JDefRef('Node'), JDefRef('Node')]);
|
||||
Result := JType('array');
|
||||
Result.AddPair('items', pair);
|
||||
end;
|
||||
|
||||
fkPipeInputs:
|
||||
begin
|
||||
// 1. Selector Tuple: ["Tuple", [Key, ...]]
|
||||
selTuple := JTuple(JArray(JDefRef('Key')));
|
||||
// Note: This is an array of Keys inside the Tuple structure
|
||||
var keyArray := JType('array');
|
||||
keyArray.AddPair('items', JDefRef('Key'));
|
||||
selTuple := JTuple(keyArray);
|
||||
|
||||
// 2. Entry Node: ["Tuple", [Id, SelectorTuple]]
|
||||
entryNode := JTuple(JFixedArray([JDefRef('Id'), selTuple]));
|
||||
entryNode := JTupleArray([JDefRef('Id'), selTuple]);
|
||||
|
||||
// 3. Outer Inputs List: ["Tuple", [EntryNode, ...]]
|
||||
Result := JTuple(JArray(entryNode));
|
||||
// 3. Wrap in ["Tuple", [Array of EntryNodes]]
|
||||
var entriesArray := JType('array');
|
||||
entriesArray.AddPair('items', entryNode);
|
||||
|
||||
Result := JTuple(entriesArray);
|
||||
end;
|
||||
else
|
||||
Result := TJSONObject.Create;
|
||||
@@ -142,7 +170,11 @@ var
|
||||
anyOfNodes: TJSONArray;
|
||||
tag: string;
|
||||
fields: TList<AstFieldAttribute>;
|
||||
minCount, maxCount: Integer;
|
||||
itemsArr: TJSONArray;
|
||||
|
||||
// Properties Wrapper
|
||||
props, programProp: TJSONObject;
|
||||
reqArr: TJSONArray;
|
||||
begin
|
||||
ctx := TRttiContext.Create;
|
||||
Result := TJSONObject.Create;
|
||||
@@ -150,7 +182,7 @@ begin
|
||||
anyOfNodes := TJSONArray.Create;
|
||||
|
||||
try
|
||||
// 1. Scan all interfaces for AstTag metadata
|
||||
// 1. Scan all interfaces
|
||||
for typ in ctx.GetTypes do
|
||||
begin
|
||||
if typ.TypeKind <> tkInterface then
|
||||
@@ -170,39 +202,41 @@ begin
|
||||
if tag = '' then
|
||||
continue;
|
||||
|
||||
// Sort fields by index
|
||||
// Sort fields
|
||||
fields.Sort(
|
||||
TComparer<AstFieldAttribute>
|
||||
.Construct(function(const L, R: AstFieldAttribute): Integer begin Result := L.Index - R.Index; end)
|
||||
);
|
||||
|
||||
// Construct Tuple Definition for this Tag: ["Tag", Arg1, Arg2]
|
||||
nodeDef := TJSONObject.Create;
|
||||
nodeDef.AddPair('type', 'array');
|
||||
|
||||
var items := TJSONArray.Create;
|
||||
items.AddElement(TJSONObject.Create.AddPair('const', tag));
|
||||
itemsArr := TJSONArray.Create;
|
||||
|
||||
minCount := 1;
|
||||
maxCount := 1;
|
||||
// Item 0: The Tag (as Const/Enum)
|
||||
var tagConst := TJSONObject.Create;
|
||||
tagConst.AddPair('type', 'string');
|
||||
var enumArr := TJSONArray.Create;
|
||||
enumArr.Add(tag);
|
||||
tagConst.AddPair('enum', enumArr);
|
||||
itemsArr.AddElement(tagConst);
|
||||
|
||||
// Items 1..N: The Fields
|
||||
for var f in fields do
|
||||
begin
|
||||
inc(maxCount);
|
||||
// Only non-nullable fields increase minCount
|
||||
if f.Kind <> fkNullableNode then
|
||||
minCount := maxCount;
|
||||
|
||||
items.AddElement(GetJsonType(f.Kind));
|
||||
itemsArr.AddElement(GetJsonType(f.Kind));
|
||||
end;
|
||||
|
||||
nodeDef.AddPair('prefixItems', items);
|
||||
nodeDef.AddPair('minItems', TJSONNumber.Create(minCount));
|
||||
nodeDef.AddPair('maxItems', TJSONNumber.Create(maxCount));
|
||||
// additionalItems removed as maxItems guarantees strictness
|
||||
nodeDef.AddPair('items', itemsArr);
|
||||
nodeDef.AddPair('minItems', TJSONNumber.Create(itemsArr.Count));
|
||||
nodeDef.AddPair('maxItems', TJSONNumber.Create(itemsArr.Count));
|
||||
nodeDef.AddPair('additionalItems', TJSONBool.Create(False));
|
||||
|
||||
// Add to defs
|
||||
defs.AddPair(tag, nodeDef);
|
||||
|
||||
// Add reference to the global AstNode union
|
||||
// Add to main Node Union
|
||||
astNodeRef := TJSONObject.Create;
|
||||
astNodeRef.AddPair('$ref', '#/$defs/' + tag);
|
||||
anyOfNodes.AddElement(astNodeRef);
|
||||
@@ -212,13 +246,29 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// 2. Define the base AstNode anyOf union
|
||||
// 2. Define generic "Node" union
|
||||
var astNodeBase := TJSONObject.Create;
|
||||
|
||||
// WICHTIG: Das fehlende "type": "array" hat den Fehler verursacht.
|
||||
astNodeBase.AddPair('type', 'array');
|
||||
|
||||
astNodeBase.AddPair('anyOf', anyOfNodes);
|
||||
defs.AddPair('Node', astNodeBase);
|
||||
|
||||
// 3. Assemble final Root Object
|
||||
Result.AddPair('$ref', '#/$defs/Node');
|
||||
// 3. ROOT OBJECT WRAPPER
|
||||
Result.AddPair('type', 'object');
|
||||
|
||||
props := TJSONObject.Create;
|
||||
programProp := TJSONObject.Create;
|
||||
programProp.AddPair('$ref', '#/$defs/Node');
|
||||
props.AddPair('program', programProp);
|
||||
Result.AddPair('properties', props);
|
||||
|
||||
reqArr := TJSONArray.Create;
|
||||
reqArr.Add('program');
|
||||
Result.AddPair('required', reqArr);
|
||||
|
||||
Result.AddPair('additionalProperties', TJSONBool.Create(False));
|
||||
Result.AddPair('$defs', defs);
|
||||
|
||||
finally
|
||||
|
||||
Reference in New Issue
Block a user