← 返回聊天
新建
删除
Models
gpt5.php
gpt5_file.php
gpt5_mini_file.php
openai_chat.php
Tools
get_time.php
get_weather.php
global_search_messages.php
math.php
memo.php
news.php
search_arxiv.php
search_crossref.php
search_github_code.php
search_pubmed.php
search_semantic_scholar.php
stock_market.php
url.php
<?php declare(strict_types=1); function http_get_text(string $url, int $timeoutSec = 10, array $headers = []): string { $ch = curl_init($url); if ($ch === false) throw new RuntimeException('curl_init failed'); $hdr = array_merge(['Accept: application/atom+xml, application/xml, text/xml'], $headers); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => $timeoutSec, CURLOPT_TIMEOUT => $timeoutSec, CURLOPT_HTTPHEADER => $hdr, ]); $resp = curl_exec($ch); $errno = curl_errno($ch); $err = curl_error($ch); $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($errno !== 0) throw new RuntimeException('cURL error: ' . $err); if ($status < 200 || $status >= 300) throw new RuntimeException('HTTP ' . $status); return (string)$resp; } return [ 'name' => 'search_arxiv', 'description' => '在 arXiv 检索论文(Atom API,返回标题/作者/日期/abs链接/pdf链接/摘要)。', 'parameters' => [ 'type' => 'object', 'properties' => [ 'query' => ['type' => 'string', 'description' => '检索关键词,例如:diffusion model'], 'max_results' => ['type' => 'integer', 'description' => '返回条数,默认 5', 'default' => 5], ], 'required' => ['query'], ], 'run' => function(array $args, array $context) { $query = trim((string)($args['query'] ?? '')); $max = (int)($args['max_results'] ?? 5); if ($max <= 0) $max = 5; if ($query === '') throw new RuntimeException('query 不能为空'); // arXiv Atom API // search_query=all:<query> $apiUrl = 'https://export.arxiv.org/api/query?' . http_build_query([ 'search_query' => 'all:' . $query, 'start' => 0, 'max_results' => $max, 'sortBy' => 'relevance', 'sortOrder' => 'descending', ]); try { $xmlText = http_get_text($apiUrl, 15); } catch (Throwable $e) { return "An error occurred while searching arXiv: " . $e->getMessage(); } libxml_use_internal_errors(true); $feed = simplexml_load_string($xmlText); if ($feed === false) { return "An error occurred while searching arXiv: Invalid XML response."; } // Atom namespace $feed->registerXPathNamespace('a', 'http://www.w3.org/2005/Atom'); $entries = $feed->xpath('//a:entry'); if (!is_array($entries) || count($entries) === 0) { return "No results found on arXiv for '{$query}'."; } $resultsList = []; $citationsList = []; $emitter = $context['event_emitter'] ?? null; $canEmit = is_callable($emitter); $i = 0; foreach ($entries as $entry) { $i++; // title / summary 里经常有换行和多空格 $title = trim(preg_replace('/\s+/', ' ', (string)$entry->title)); if ($title === '') $title = 'N/A'; $published = (string)$entry->published; $publishedDate = 'N/A'; if ($published) { // 取 YYYY-MM-DD $publishedDate = substr($published, 0, 10) ?: 'N/A'; } $summary = trim(preg_replace('/\s+/', ' ', (string)$entry->summary)); if ($summary === '') $summary = 'N/A'; // authors $authors = []; if (isset($entry->author)) { foreach ($entry->author as $a) { $nm = trim((string)$a->name); if ($nm !== '') $authors[] = $nm; } } $authorsStr = count($authors) ? implode(', ', $authors) : 'N/A'; // abs url (entry->id) $absUrl = trim((string)$entry->id); if ($absUrl === '') $absUrl = 'N/A'; // pdf url: 在 link 里找 title="pdf" 或 type="application/pdf" $pdfUrl = ''; if (isset($entry->link)) { foreach ($entry->link as $lnk) { $attrs = $lnk->attributes(); $href = (string)($attrs['href'] ?? ''); $type = (string)($attrs['type'] ?? ''); $titleAttr = (string)($attrs['title'] ?? ''); if ($href !== '' && (strtolower($titleAttr) === 'pdf' || strtolower($type) === 'application/pdf')) { $pdfUrl = $href; break; } } } $resultsList[] = "{$i}. {$title}\n" . " Authors: {$authorsStr}\n" . " Published: {$publishedDate}\n" . " URL: {$absUrl}\n" . " PDF URL: " . ($pdfUrl !== '' ? $pdfUrl : 'N/A') . "\n" . " Summary: {$summary}"; if ($pdfUrl !== '') { $citationsList[] = "[{$i}] {$pdfUrl}"; if ($canEmit) { $emitter([ 'type' => 'citation', 'data' => [ 'document' => [$summary], 'metadata' => [['source' => $pdfUrl]], 'source' => ['name' => $title], ], ]); } } if ($i >= $max) break; } $output = implode("\n\n", $resultsList); if (count($citationsList)) { $output .= "\n\n---\n\n**Citation Links:**\n" . implode("\n", $citationsList); } return $output; }, ];
保存