← 返回聊天
新建
删除
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); return [ 'name' => 'search_crossref', 'description' => '在 Crossref 检索 DOI/论文信息(works endpoint)。', 'parameters' => [ 'type' => 'object', 'properties' => [ 'query' => ['type' => 'string', 'description' => '检索关键词,例如:graph neural networks'], 'rows' => ['type' => 'integer', 'description' => '返回条数,默认 5', 'default' => 5], ], 'required' => ['query'], ], 'run' => function(array $args, array $context) { $http_get_json = function(string $url, int $timeoutSec = 10, array $headers = []): array { $ch = curl_init($url); if ($ch === false) throw new RuntimeException('curl_init failed'); $hdr = array_merge(['Accept: application/json'], $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); $data = json_decode((string)$resp, true); if (!is_array($data)) throw new RuntimeException('Invalid JSON'); return $data; }; $query = trim((string)($args['query'] ?? '')); $rows = (int)($args['rows'] ?? 5); if ($rows <= 0) $rows = 5; if ($query === '') throw new RuntimeException('query 不能为空'); $url = 'https://api.crossref.org/works?' . http_build_query([ 'query' => $query, 'rows' => $rows, ]); try { $resp = $http_get_json($url, 12, ['User-Agent: php-tool/1.0']); } catch (Throwable $e) { return "Error fetching data from Crossref: " . $e->getMessage(); } $items = $resp['message']['items'] ?? []; if (!is_array($items) || count($items) === 0) { return "No results found on Crossref for '{$query}'."; } $resultsList = []; $citationsList = []; $emitter = $context['event_emitter'] ?? null; $canEmit = is_callable($emitter); $i = 0; foreach ($items as $itm) { if (!is_array($itm)) continue; $i++; $titleArr = $itm['title'] ?? []; $title = (is_array($titleArr) && isset($titleArr[0])) ? (string)$titleArr[0] : 'N/A'; $authorNames = []; $authorsArr = $itm['author'] ?? []; if (is_array($authorsArr)) { foreach ($authorsArr as $a) { if (!is_array($a)) continue; $given = trim((string)($a['given'] ?? '')); $family = trim((string)($a['family'] ?? '')); $full = trim($given . ' ' . $family); if ($full !== '') $authorNames[] = $full; } } $authors = count($authorNames) ? implode(', ', $authorNames) : 'N/A'; $urlItem = (string)($itm['URL'] ?? '#'); $year = 'N/A'; $dp = $itm['issued']['date-parts'][0] ?? null; if (is_array($dp) && isset($dp[0]) && $dp[0]) $year = (string)$dp[0]; $resultsList[] = "{$i}. {$title}\n Authors: {$authors}\n Year: {$year}\n URL: {$urlItem}"; if ($urlItem !== '#') { $citationsList[] = "[{$i}] {$urlItem}"; if ($canEmit) { $emitter([ 'type' => 'citation', 'data' => [ 'document' => [$title], 'metadata' => [['source' => $urlItem]], 'source' => ['name' => $title], ], ]); } } if ($i >= $rows) break; } $output = implode("\n\n", $resultsList); if (count($citationsList)) { $output .= "\n\n---\n\n**Citation Links:**\n" . implode("\n", $citationsList); } return $output; }, ];
保存