WordPress / WordPress/php-ai-client

Preserve empty JSON Schema object maps in FunctionDeclaration parameters

Open
#233 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
308
Forks
84
Avg merge
7d 21h
Merged PRs (30d)
2

Description

Description

FunctionDeclaration accepts JSON Schema-like parameter definitions, but empty object-map fields inside those schemas currently serialize as JSON arrays. In PHP, callers naturally represent an empty object map as [], but JSON Schema fields such as properties are object maps and should serialize as {} when empty.

This can make an otherwise valid function parameter schema invalid by the time a provider request body is JSON encoded.

Minimal reproduction

use WordPress\AiClient\Tools\DTO\FunctionDeclaration;

$declaration = new FunctionDeclaration(
    'inspectObject',
    'Inspects an object with optional nested metadata',
    [
        'type' => 'object',
        'properties' => [
            'metadata' => [
                'type' => 'object',
                'properties' => [],
            ],
        ],
    ]
);

echo json_encode($declaration, JSON_THROW_ON_ERROR);

Actual behavior

The nested JSON Schema object map is emitted as a JSON array:

{
  "name": "inspectObject",
  "description": "Inspects an object with optional nested metadata",
  "parameters": {
    "type": "object",
    "properties": {
      "metadata": {
        "type": "object",
        "properties": []
      }
    }
  }
}

Expected behavior

JSON Schema object-map fields should preserve object semantics when empty:

{
  "name": "inspectObject",
  "description": "Inspects an object with optional nested metadata",
  "parameters": {
    "type": "object",
    "properties": {
      "metadata": {
        "type": "object",
        "properties": {}
      }
    }
  }
}

Evidence

I added a focused PHPUnit repro locally on trunk:

public function testJsonSerializationPreservesEmptySchemaObjectMaps(): void
{
    $declaration = new FunctionDeclaration(
        'inspectObject',
        'Inspects an object with optional nested metadata',
        [
            'type' => 'object',
            'properties' => [
                'metadata' => [
                    'type' => 'object',
                    'properties' => [],
                ],
            ],
        ]
    );

    $json = json_encode($declaration, JSON_THROW_ON_ERROR);

    $this->assertStringContainsString('"properties":{', $json);
    $this->assertStringNotContainsString('"properties":[]', $json);
}

It fails on current trunk:

Failed asserting that
'{"name":"inspectObject","description":"Inspects an object with optional nested metadata","parameters":{"type":"object","properties":{"metadata":{"type":"object","properties":[]}}}}'
does not contain ""properties":[]".

Tests: 1, Assertions: 2, Failures: 1.

The full FunctionDeclarationTest file also only fails this added assertion:

Tests: 15, Assertions: 56, Failures: 1.

Why this likely belongs in the client abstraction

This is provider-agnostic. The issue is not that one provider has a special rule; it is that FunctionDeclaration stores JSON Schema parameter definitions in PHP arrays, and PHP arrays do not preserve empty object-map semantics during JSON encoding.

The affected concept is shared by all providers that consume FunctionDeclaration parameters. Installed provider code paths also commonly embed raw getParameters() or toArray() output into request payloads, so individual providers can encounter the same empty-map serialization issue.

Related

This is adjacent to #229 because both involve JSON Schema payload correctness, but it is not the same bug. #229 is about the OpenAI-compatible structured-output envelope. This issue is about preserving JSON Schema object-map semantics inside FunctionDeclaration parameters.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the FunctionDeclaration implementation and the FunctionDeclarationTest file mentioned in the issue, then reproduce the focused PHPUnit failure for nested empty schema maps. Trace how parameters are serialized and verify that empty JSON Schema object maps encode as {} rather than [] while the existing test suite remains passing.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend-api-design
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.