2323 * properties: array<string, mixed>,
2424 * required: string[]|null
2525 * }
26+ * @phpstan-type ToolOutputSchema array{
27+ * type: 'object',
28+ * properties: array<string, mixed>,
29+ * required: string[]|null
30+ * }
2631 * @phpstan-type ToolData array{
2732 * name: string,
2833 * inputSchema: ToolInputSchema,
2934 * description?: string|null,
3035 * annotations?: ToolAnnotationsData,
36+ * outputSchema?: ToolOutputSchema,
3137 * }
3238 *
3339 * @author Kyrian Obikwelu <[email protected] > 3440 */
3541class Tool implements \JsonSerializable
3642{
3743 /**
38- * @param string $name the name of the tool
39- * @param string|null $description A human-readable description of the tool.
40- * This can be used by clients to improve the LLM's understanding of
41- * available tools. It can be thought of like a "hint" to the model.
42- * @param ToolInputSchema $inputSchema a JSON Schema object (as a PHP array) defining the expected 'arguments' for the tool
43- * @param ToolAnnotations|null $annotations optional additional tool information
44+ * @param string $name the name of the tool
45+ * @param string|null $description A human-readable description of the tool.
46+ * This can be used by clients to improve the LLM's understanding of
47+ * available tools. It can be thought of like a "hint" to the model.
48+ * @param ToolInputSchema $inputSchema a JSON Schema object (as a PHP array) defining the expected 'arguments' for the tool
49+ * @param ToolAnnotations|null $annotations optional additional tool information
50+ * @param ToolOutputSchema|null $outputSchema optional JSON Schema object (as a PHP array) defining the expected output structure
4451 */
4552 public function __construct (
4653 public readonly string $ name ,
4754 public readonly array $ inputSchema ,
4855 public readonly ?string $ description ,
4956 public readonly ?ToolAnnotations $ annotations ,
57+ public readonly ?array $ outputSchema = null ,
5058 ) {
5159 if (!isset ($ inputSchema ['type ' ]) || 'object ' !== $ inputSchema ['type ' ]) {
5260 throw new InvalidArgumentException ('Tool inputSchema must be a JSON Schema of type "object". ' );
5361 }
62+
63+ if (null !== $ outputSchema && (!isset ($ outputSchema ['type ' ]) || 'object ' !== $ outputSchema ['type ' ])) {
64+ throw new InvalidArgumentException ('Tool outputSchema must be a JSON Schema of type "object" or null. ' );
65+ }
5466 }
5567
5668 /**
@@ -71,11 +83,21 @@ public static function fromArray(array $data): self
7183 $ data ['inputSchema ' ]['properties ' ] = new \stdClass ();
7284 }
7385
86+ if (isset ($ data ['outputSchema ' ]) && \is_array ($ data ['outputSchema ' ])) {
87+ if (!isset ($ data ['outputSchema ' ]['type ' ]) || 'object ' !== $ data ['outputSchema ' ]['type ' ]) {
88+ throw new InvalidArgumentException ('Tool outputSchema must be of type "object". ' );
89+ }
90+ if (isset ($ data ['outputSchema ' ]['properties ' ]) && \is_array ($ data ['outputSchema ' ]['properties ' ]) && empty ($ data ['outputSchema ' ]['properties ' ])) {
91+ $ data ['outputSchema ' ]['properties ' ] = new \stdClass ();
92+ }
93+ }
94+
7495 return new self (
7596 $ data ['name ' ],
7697 $ data ['inputSchema ' ],
7798 isset ($ data ['description ' ]) && \is_string ($ data ['description ' ]) ? $ data ['description ' ] : null ,
78- isset ($ data ['annotations ' ]) && \is_array ($ data ['annotations ' ]) ? ToolAnnotations::fromArray ($ data ['annotations ' ]) : null
99+ isset ($ data ['annotations ' ]) && \is_array ($ data ['annotations ' ]) ? ToolAnnotations::fromArray ($ data ['annotations ' ]) : null ,
100+ $ data ['outputSchema ' ]
79101 );
80102 }
81103
@@ -85,6 +107,7 @@ public static function fromArray(array $data): self
85107 * inputSchema: ToolInputSchema,
86108 * description?: string,
87109 * annotations?: ToolAnnotations,
110+ * outputSchema?: ToolOutputSchema,
88111 * }
89112 */
90113 public function jsonSerialize (): array
@@ -99,6 +122,9 @@ public function jsonSerialize(): array
99122 if (null !== $ this ->annotations ) {
100123 $ data ['annotations ' ] = $ this ->annotations ;
101124 }
125+ if (null !== $ this ->outputSchema ) {
126+ $ data ['outputSchema ' ] = $ this ->outputSchema ;
127+ }
102128
103129 return $ data ;
104130 }
0 commit comments