$t['role'], 'content' => $t['text'], ); } return array( 'url' => self::URL, 'headers' => $this->headers( $key ), 'body' => array( 'model' => (string) $model, 'system' => (string) $instructions, 'messages' => $turns, // Thinking counts towards max_tokens; leave room so the answer fits. 'max_tokens' => (int) $max_tokens + self::THINKING_ROOM, ), ); } /** * Headers. * * @param string $key API key. * @return array */ private function headers( $key ) { return array( 'x-api-key' => $key, 'anthropic-version' => self::VERSION, ); } /** * {@inheritDoc} * * @param array $data Decoded reply. * @return array */ protected function parse( array $data ) { $parts = array(); foreach ( isset( $data['content'] ) && is_array( $data['content'] ) ? $data['content'] : array() as $block ) { if ( is_array( $block ) && isset( $block['type'], $block['text'] ) && is_string( $block['text'] ) && 'text' === $block['type'] ) { $parts[] = (string) $block['text']; } } return array( 'text' => implode( "\n\n", $parts ), 'in' => isset( $data['usage']['input_tokens'] ) ? (int) $data['usage']['input_tokens'] : 0, 'out' => isset( $data['usage']['output_tokens'] ) ? (int) $data['usage']['output_tokens'] : 0, 'cut' => isset( $data['stop_reason'] ) && 'max_tokens' === $data['stop_reason'], ); } /** * {@inheritDoc} * * @param int $code HTTP status. * @param array $data Decoded reply. * @return string */ public function classify( $code, array $data ) { $type = isset( $data['error']['type'] ) ? strtolower( (string) $data['error']['type'] ) : ''; $msg = isset( $data['error']['message'] ) ? strtolower( (string) $data['error']['message'] ) : ''; if ( 401 === $code || 'authentication_error' === $type ) { return 'auth'; } if ( false !== strpos( $msg, 'credit balance' ) || 'billing_error' === $type ) { return 'quota'; } if ( 413 === $code || 'request_too_large' === $type || false !== strpos( $msg, 'prompt is too long' ) ) { return 'too_large'; } if ( 429 === $code || 'rate_limit_error' === $type ) { return 'rate_limit'; } if ( 404 === $code || 'not_found_error' === $type ) { return 'model'; } if ( 403 === $code || 'permission_error' === $type ) { return false !== strpos( $msg, 'region' ) || false !== strpos( $msg, 'country' ) ? 'region' : 'permission'; } if ( $code >= 500 || 'overloaded_error' === $type || 'api_error' === $type ) { return 'server'; } return 'bad_request'; } /** * {@inheritDoc} * * @param array $data Decoded reply. * @return array */ protected function said( array $data ) { return array( isset( $data['error']['message'] ) ? (string) $data['error']['message'] : '', isset( $data['error']['type'] ) ? (string) $data['error']['type'] : '', ); } /** * {@inheritDoc} * * @param string $key API key. * @return array */ protected function models_request( $key ) { return array( 'url' => self::MODELS_URL . '?limit=100', 'headers' => $this->headers( $key ), ); } /** * {@inheritDoc} * * @param array $data Decoded reply. * @return string[] */ protected function models_parse( array $data ) { $out = array(); foreach ( isset( $data['data'] ) && is_array( $data['data'] ) ? $data['data'] : array() as $m ) { if ( is_array( $m ) && isset( $m['id'] ) && is_string( $m['id'] ) && 0 === strpos( $m['id'], 'claude' ) ) { $out[] = (string) $m['id']; } } return $out; } }