PHP code example of arcp / sdk

1. Go to this page and download the library: Download arcp/sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

arcp / sdk example snippets




declare(strict_types=1);

ketHandshake;
use function Amp\Websocket\Client\connect;
use Arcp\Client\ARCPClient;
use Arcp\Envelope\Envelope;
use Arcp\Envelope\MessageCatalog;
use Arcp\Json\EnvelopeSerializer;
use Arcp\Messages\Execution\JobProgress;
use Arcp\Messages\Session\Auth;
use Arcp\Messages\Session\Capabilities;
use Arcp\Messages\Session\PeerInfo;
use Arcp\Transport\WebSocketTransport;

$serializer = new EnvelopeSerializer(MessageCatalog::create());
$transport = new WebSocketTransport(
    connect(new WebsocketHandshake('wss://runtime.example.com/arcp')),
    $serializer,
);

$client = new ARCPClient($transport);
$client->open(
    Auth::bearer((string) getenv('ARCP_TOKEN')),
    new PeerInfo('quickstart', '1.0.0'),
    new Capabilities(streaming: true, subscriptions: true),
);

$client->subscribe(
    ['types' => ['job.progress', 'log', 'metric']],
    static function (Envelope $env): void {
        if ($env->payload instanceof JobProgress) {
            printf("[progress %d%%] %s\n", $env->payload->percent, $env->payload->message ?? '');
        }
    },
);

$result = $client->invokeTool('data-analyzer', ['dataset' => 's3://example/sales.csv']);
printf("final: %s\n", json_encode($result->value));

$client->close();

use Amp\Websocket\Client\WebsocketHandshake;
use function Amp\Websocket\Client\connect;
use Arcp\Client\ARCPClient;
use Arcp\Envelope\Envelope;
use Arcp\Envelope\MessageCatalog;
use Arcp\Ids\MessageId;
use Arcp\Json\EnvelopeSerializer;
use Arcp\Messages\Control\Resume;
use Arcp\Messages\Session\Auth;
use Arcp\Messages\Session\Capabilities;
use Arcp\Messages\Session\PeerInfo;
use Arcp\Transport\WebSocketTransport;

$serializer = new EnvelopeSerializer(MessageCatalog::create());
$openTransport = static fn (): WebSocketTransport => new WebSocketTransport(
    connect(new WebsocketHandshake('wss://runtime.example.com/arcp')),
    $serializer,
);

$client = new ARCPClient($openTransport());
$accepted = $client->open(
    Auth::bearer((string) getenv('ARCP_TOKEN')),
    new PeerInfo('resumable', '1.0.0'),
    new Capabilities(streaming: true, durableJobs: true),
);
$sessionId = $accepted->sessionId;
$lastMessageId = null;

// ... transport drops ...

$resumed = new ARCPClient($openTransport());
$resumed->open(Auth::bearer((string) getenv('ARCP_TOKEN')), new PeerInfo('resumable', '1.0.0'), new Capabilities(streaming: true, durableJobs: true));
$resumed->session->transport->send(new Envelope(
    id: MessageId::random(),
    payload: new Resume(afterMessageId: (string) $lastMessageId, 

use Arcp\Ids\IdempotencyKey;

$result = $client->invokeTool(
    tool: '[email protected]',
    arguments: [
        'week' => '2026-W19',
        'lease' => ['net.fetch' => ['s3://reports/**']],
        'expires_at' => (new DateTimeImmutable('+60 seconds'))->format(DateTimeInterface::RFC3339_EXTENDED),
    ],
    deadlineSeconds: 300.0,
    idempotencyKey: new IdempotencyKey('weekly-report-2026-W19'),
);

printf("resolved value = %s\n", json_encode($result->value));

use Arcp\Envelope\Envelope;
use Arcp\Messages\Execution\JobProgress;
use Arcp\Messages\Execution\ResultChunk;
use Arcp\Messages\Telemetry\EventEmit;
use Arcp\Messages\Telemetry\LogEvent;
use Arcp\Messages\Telemetry\MetricEvent;

$client->subscribe(
    ['session_id' => [(string) $client->session->sessionId]],
    static function (Envelope $env) use ($client): void {
        match (true) {
            $env->payload instanceof LogEvent      => printf("[log] %s\n", $env->payload->message),
            $env->payload instanceof MetricEvent   => printf("[metric] %s=%s %s\n", $env->payload->name, $env->payload->value, $env->payload->unit),
            $env->payload instanceof JobProgress   => printf("[progress %d%%] %s\n", $env->payload->percent, $env->payload->message ?? ''),
            $env->payload instanceof ResultChunk   => $client->resultChunks->push($env->payload),
            $env->payload instanceof EventEmit     => printf("[event] %s\n", $env->payload->eventType),
            default                                => null,
        };
    },
);

use Arcp\Envelope\Envelope;
use Arcp\Errors\BudgetExhaustedException;
use Arcp\Messages\Telemetry\MetricEvent;

$client->subscribe(
    ['types' => ['metric']],
    static function (Envelope $env): void {
        if ($env->payload instanceof MetricEvent && $env->payload->name === 'cost.budget.remaining') {
            printf("budget remaining: %.2f %s\n", $env->payload->value, $env->payload->unit);
        }
    },
);

try {
    $client->invokeTool('web-research', [
        'iterations' => 8,
        'per_call_usd' => 0.30,
        'lease' => [
            'tool.call'   => ['search.*', 'fetch.*'],
            'cost.budget' => ['USD:1.00'],
            'model.use'   => ['anthropic/claude-*'],
        ],
        'expires_at' => (new DateTimeImmutable('+10 minutes'))->format(DateTimeInterface::RFC3339_EXTENDED),
    ]);
} catch (BudgetExhaustedException $e) {
    // BUDGET_EXHAUSTED / LEASE_EXPIRED are never retryable: resubmit with a fresh lease.
    fwrite(STDERR, "job ended: {$e->code()->value}\n");
}

use Arcp\Envelope\Envelope;

$listing = $observer->listJobs(['status' => ['running']], limit: 10);
$first = $listing->jobs[0] ?? null;
if ($first === null) {
    return;
}

$subscriptionId = $observer->subscribe(
    [
        'job_id' => [$first['job_id']],
        'since_message_id' => null,           // omit to start live; set for backfill
    ],
    static function (Envelope $env): void {
        printf("[seq=%s] %s\n", (string) $env->id, $env->type());
    },
);

// ... later ...
$observer->unsubscribe($subscriptionId);

use Arcp\Errors\ARCPException;
use Arcp\Errors\BudgetExhaustedException;
use Arcp\Errors\ErrorCode;
use Arcp\Errors\LeaseExpiredException;

try {
    $client->invokeTool('flaky');
} catch (BudgetExhaustedException | LeaseExpiredException $e) {
    throw $e; // resubmit with a fresh lease / budget instead
} catch (ARCPException $e) {
    if ($e->isRetryable()) {
        // safe to retry with backoff (e.g. UNAVAILABLE, DEADLINE_EXCEEDED, INTERNAL)
        return;
    }
    fprintf(STDERR, "fatal: %s (%s)\n", $e->code()->value, $e->getMessage());
    throw $e;
}