-
Notifications
You must be signed in to change notification settings - Fork 84
[#281] Add generic metadata to function declarations #282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
7e12e4b
ac965d2
55a42d9
2f88b1a
dec7664
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # Function declaration metadata | ||
|
|
||
| `FunctionDeclaration` accepts an optional fourth constructor argument containing | ||
| generic metadata (annotations): | ||
|
|
||
| ```php | ||
| $function = new FunctionDeclaration( | ||
| 'get_weather', | ||
| 'Gets the weather', | ||
| null, | ||
| ['deferredLoading' => true] | ||
| ); | ||
|
|
||
| $metadata = $function->getMetadata(); | ||
| ``` | ||
|
|
||
| Metadata is an `array<string, mixed>` whose values should be JSON-serializable. | ||
| The SDK preserves it during declaration and model-configuration serialization | ||
| without interpreting annotation names or values. Empty metadata is omitted from | ||
| serialized declarations, preserving the existing shape for callers that do not | ||
| use this argument. Missing metadata is restored as an empty array. | ||
|
|
||
| Providers and other consumers define which annotations they recognize, their value | ||
| types, and their interaction with request-level custom options. Unknown annotations | ||
| can be ignored. Provider-specific annotations should use a namespaced key or nested | ||
| provider-specific map to avoid collisions. Metadata must not be blindly merged into | ||
| a provider request or the function's JSON parameter schema. | ||
|
|
||
| For example, a provider can interpret a `deferredLoading` annotation together with | ||
| `ModelConfig::setCustomOptions(['deferredLoading' => true])`. This example does not | ||
| establish a core deferred-loading capability, guarantee provider support, or add a | ||
| model-selection requirement. Automatic tool-count thresholds remain provider policy. | ||
| Annotations are not authorization; applications must still validate tool execution. | ||
|
|
||
| This extension concerns outgoing function definitions only. It adds no message | ||
| types or native response replay mechanism. An OpenAI provider experiment can use | ||
| existing `previous_response_id` custom options and send only new input for | ||
| server-managed continuation; stateless replay of discovery items remains separate | ||
| work requiring further evidence. | ||
|
|
||
| The [Vercel AI SDK OpenAI provider](https://ai-sdk.dev/providers/ai-sdk-providers/openai) | ||
| uses per-tool `providerOptions` for comparable provider-owned configuration. Its | ||
| documented deferred-loading API is explicit, rather than count-triggered. Generic | ||
| metadata provides an extension point for exploring such features without adding | ||
| feature-specific properties or fluent builder methods to this SDK. |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The descriptions throughout this are inconsistent. Let's clean that up. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,14 +10,15 @@ | |
| * Represents a function declaration for AI models. | ||
| * | ||
| * This DTO describes a function that can be called by the AI model, | ||
| * including its name, description, and parameter schema. | ||
| * including its name, description, parameter schema, and optional metadata. | ||
| * | ||
| * @since 0.1.0 | ||
| * | ||
| * @phpstan-type FunctionDeclarationArrayShape array{ | ||
| * name: string, | ||
| * description: string, | ||
| * parameters?: array<string, mixed> | ||
| * parameters?: array<string, mixed>, | ||
| * metadata?: array<string, mixed> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the word |
||
| * } | ||
| * | ||
| * @extends AbstractDataTransferObject<FunctionDeclarationArrayShape> | ||
|
|
@@ -27,6 +28,7 @@ class FunctionDeclaration extends AbstractDataTransferObject | |
| public const KEY_NAME = 'name'; | ||
| public const KEY_DESCRIPTION = 'description'; | ||
| public const KEY_PARAMETERS = 'parameters'; | ||
| public const KEY_METADATA = 'metadata'; | ||
| /** | ||
| * @var string The name of the function. | ||
| */ | ||
|
|
@@ -42,20 +44,32 @@ class FunctionDeclaration extends AbstractDataTransferObject | |
| */ | ||
| private ?array $parameters; | ||
|
|
||
| /** | ||
| * @var array<string, mixed> Optional annotations interpreted by consumers, not the core SDK. | ||
| */ | ||
| private array $metadata; | ||
|
|
||
| /** | ||
| * Constructor. | ||
| * | ||
| * @since 0.1.0 | ||
| * @since n.e.x.t Adds the optional $metadata parameter. | ||
| * | ||
| * @param string $name The name of the function. | ||
| * @param string $description A description of what the function does. | ||
| * @param array<string, mixed>|null $parameters The JSON schema for the function parameters. | ||
| * @param array<string, mixed> $metadata Optional metadata with JSON-serializable values. | ||
| */ | ||
| public function __construct(string $name, string $description, ?array $parameters = null) | ||
| { | ||
| public function __construct( | ||
| string $name, | ||
| string $description, | ||
| ?array $parameters = null, | ||
| array $metadata = [] | ||
| ) { | ||
| $this->name = $name; | ||
| $this->description = $description; | ||
| $this->parameters = $parameters; | ||
| $this->metadata = $metadata; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -94,6 +108,18 @@ public function getParameters(): ?array | |
| return $this->parameters; | ||
| } | ||
|
|
||
| /** | ||
| * Gets the function metadata without interpreting its annotations. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return array<string, mixed> The metadata, or an empty array if none was provided. | ||
| */ | ||
| public function getMetadata(): array | ||
| { | ||
| return $this->metadata; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| * | ||
|
|
@@ -117,6 +143,11 @@ public static function getJsonSchema(): array | |
| 'description' => 'The JSON schema for the function parameters.', | ||
| 'additionalProperties' => true, | ||
| ], | ||
| self::KEY_METADATA => [ | ||
| 'type' => 'object', | ||
| 'description' => 'Optional metadata whose annotations are interpreted by consumers.', | ||
| 'additionalProperties' => true, | ||
| ], | ||
| ], | ||
| 'required' => [self::KEY_NAME, self::KEY_DESCRIPTION], | ||
| ]; | ||
|
|
@@ -140,6 +171,10 @@ public function toArray(): array | |
| $data[self::KEY_PARAMETERS] = $this->parameters; | ||
| } | ||
|
|
||
| if ($this->metadata !== []) { | ||
| $data[self::KEY_METADATA] = $this->metadata; | ||
| } | ||
|
|
||
| return $data; | ||
| } | ||
|
|
||
|
|
@@ -155,7 +190,8 @@ public static function fromArray(array $array): self | |
| return new self( | ||
| $array[self::KEY_NAME], | ||
| $array[self::KEY_DESCRIPTION], | ||
| $array[self::KEY_PARAMETERS] ?? null | ||
| $array[self::KEY_PARAMETERS] ?? null, | ||
| $array[self::KEY_METADATA] ?? [] | ||
| ); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update ARCHITECTURE.md instead of adding this.