Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/prism.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,9 @@
'x_title' => env('OPENROUTER_SITE_X_TITLE', null),
],
],
'z' => [
'url' => env('Z_URL', 'https://api.z.ai/api/coding/paas/v4'),
'api_key' => env('Z_API_KEY', ''),
],
],
];
4 changes: 4 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ export default defineConfig({
text: "XAI",
link: "/providers/xai",
},
{
text: "Z AI",
link: "/providers/z",
},
],
},
{
Expand Down
248 changes: 248 additions & 0 deletions docs/providers/z.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# Z AI
## Configuration

```php
'z' => [
'url' => env('Z_URL', 'https://api.z.ai/api/coding/paas/v4'),
'api_key' => env('Z_API_KEY', ''),
]
```

## Text Generation

Generate text responses with Z AI models:

```php
$response = Prism::text()
->using('z', 'glm-4.6')
->withPrompt('Write a short story about a robot learning to love')
->asText();

echo $response->text;
```

## Multi-modal Support

Z AI provides comprehensive multi-modal capabilities through the `glm-4.6v` model, allowing you to work with images, documents, and videos in your AI requests.

### Images

Z AI supports image analysis through URLs using the `glm-4.6v` model:

```php
use Prism\Prism\Facades\Prism;
use Prism\Prism\ValueObjects\Media\Image;
use Prism\Prism\ValueObjects\Messages\UserMessage;

$response = Prism::text()
->using('z', 'glm-4.6v')
->withMessages([
new UserMessage(
'What is in this image?',
additionalContent: [
Image::fromUrl('https://example.com/image.png'),
]
),
])
->asText();
```

### Documents

Process documents directly from URLs:

```php
use Prism\Prism\Facades\Prism;
use Prism\Prism\ValueObjects\Media\Document;
use Prism\Prism\ValueObjects\Messages\UserMessage;

$response = Prism::text()
->using('z', 'glm-4.6v')
->withMessages([
new UserMessage(
'What does this document say about?',
additionalContent: [
Document::fromUrl('https://example.com/document.pdf'),
]
),
])
->asText();
```

### Videos

Z AI can analyze video content from URLs:

```php
use Prism\Prism\Facades\Prism;
use Prism\Prism\ValueObjects\Media\Video;
use Prism\Prism\ValueObjects\Messages\UserMessage;

$response = Prism::text()
->using('z', 'glm-4.6v')
->withMessages([
new UserMessage(
'What does this video show?',
additionalContent: [
Video::fromUrl('https://example.com/video.mp4'),
]
),
])
->asText();
```

### Combining Multiple Media Types

You can combine images, documents, and videos in a single request:

```php
$response = Prism::text()
->using('z', 'glm-4.6v')
->withMessages([
new UserMessage(
'Analyze this image, document, and video together',
additionalContent: [
Image::fromUrl('https://example.com/image.png'),
Document::fromUrl('https://example.com/document.txt'),
Video::fromUrl('https://example.com/video.mp4'),
]
),
])
->asText();
```

## Tools and Function Calling

Z AI supports function calling, allowing the model to execute your custom tools during conversation.

### Basic Tool Usage

```php
use Prism\Prism\Facades\Prism;
use Prism\Prism\Tool;

$weatherTool = Tool::as('get_weather')
->for('Get current weather for a location')
->withStringParameter('city', 'The city and state')
->using(fn (string $city): string => "Weather in {$city}: 72°F, sunny");

$response = Prism::text()
->using('z', 'glm-4.6')
->withPrompt('What is the weather in San Francisco?')
->withTools([$weatherTool])
->asText();
```

### Multiple Tools

Z AI can use multiple tools in a single request:

```php
$tools = [
Tool::as('get_weather')
->for('Get current weather for a location')
->withStringParameter('city', 'The city that you want the weather for')
->using(fn (string $city): string => 'The weather will be 45° and cold'),

Tool::as('search_games')
->for('Search for current game times in a city')
->withStringParameter('city', 'The city that you want the game times for')
->using(fn (string $city): string => 'The tigers game is at 3pm in detroit'),
];

$response = Prism::text()
->using('z', 'glm-4.6')
->withTools($tools)
->withMaxSteps(4)
->withPrompt('What time is the tigers game today in Detroit and should I wear a coat?')
->asText();
```

### Tool Choice

Control when tools are called:

```php
use Prism\Prism\Enums\ToolChoice;

// Require at least one tool to be called
$response = Prism::text()
->using('z', 'glm-4.6')
->withPrompt('Search for information')
->withTools([$searchTool, $weatherTool])
->withToolChoice(ToolChoice::Any)
->asText();

// Require a specific tool to be called
$response = Prism::text()
->using('z', 'glm-4.6')
->withPrompt('Get the weather')
->withTools([$searchTool, $weatherTool])
->withToolChoice(ToolChoice::from('get_weather'))
->asText();

// Let the model decide (default)
$response = Prism::text()
->using('z', 'glm-4.6')
->withPrompt('What do you think?')
->withTools([$tools])
->withToolChoice(ToolChoice::Auto)
->asText();
```

For complete tool documentation, see [Tools & Function Calling](/core-concepts/tools-function-calling).

## Structured Output

Z AI supports structured output through schema-based JSON generation, ensuring responses match your defined structure.

### Basic Structured Output

```php
use Prism\Prism\Facades\Prism;
use Prism\Prism\Schema\ObjectSchema;
use Prism\Prism\Schema\StringSchema;
use Prism\Prism\Schema\EnumSchema;
use Prism\Prism\Schema\BooleanSchema;

$schema = new ObjectSchema(
'interview_response',
'Structured response from AI interviewer',
[
new StringSchema('message', 'The interviewer response message'),
new EnumSchema(
'action',
'The next action to take',
['ask_question', 'ask_followup', 'complete_interview']
),
new BooleanSchema('is_question', 'Whether this contains a question'),
],
['message', 'action', 'is_question']
);

$response = Prism::structured()
->using('z', 'glm-4.6')
->withSchema($schema)
->withPrompt('Conduct an interview')
->asStructured();

// Access structured data
dump($response->structured);
// [
// 'message' => '...',
// 'action' => 'ask_question',
// 'is_question' => true
// ]
```

For complete structured output documentation, see [Structured Output](/core-concepts/structured-output).

## Limitations

### Media Types

- Does not support `Image::fromPath` or `Image::fromBase64` - only `Image::fromUrl`
- Does not support `Document::fromPath` or `Document::fromBase64` - only `Document::fromUrl`
- Does not support `Video::fromPath` or `Video::fromBase64` - only `Video::fromUrl`

All media must be provided as publicly accessible URLs that Z AI can fetch and process.
1 change: 1 addition & 0 deletions src/Enums/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ enum Provider: string
case Gemini = 'gemini';
case VoyageAI = 'voyageai';
case ElevenLabs = 'elevenlabs';
case Z = 'z';
}
12 changes: 12 additions & 0 deletions src/PrismManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Prism\Prism\Providers\Provider;
use Prism\Prism\Providers\VoyageAI\VoyageAI;
use Prism\Prism\Providers\XAI\XAI;
use Prism\Prism\Providers\Z\Z;
use RuntimeException;

class PrismManager
Expand Down Expand Up @@ -225,4 +226,15 @@ protected function createElevenlabsProvider(array $config): ElevenLabs
url: $config['url'] ?? 'https://api.elevenlabs.io/v1/',
);
}

/**
* @param array<string, string> $config
*/
protected function createZProvider(array $config): Z
{
return new Z(
apiKey: $config['api_key'],
baseUrl: $config['url'],
);
}
}
19 changes: 19 additions & 0 deletions src/Providers/Z/Concerns/MapsFinishReason.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Prism\Prism\Providers\Z\Concerns;

use Prism\Prism\Enums\FinishReason;
use Prism\Prism\Providers\Z\Maps\FinishReasonMap;

trait MapsFinishReason
{
/**
* @param array<string, mixed> $data
*/
protected function mapFinishReason(array $data): FinishReason
{
return FinishReasonMap::map(data_get($data, 'choices.0.finish_reason', ''));
}
}
12 changes: 12 additions & 0 deletions src/Providers/Z/Enums/DocumentType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Prism\Prism\Providers\Z\Enums;

enum DocumentType: string
{
case FileUrl = 'file_url';

case VideoUrl = 'video_url';

case ImageUrl = 'image_url';
}
Loading