























@@ -1528,6 +1528,32 @@ function readString(record: JsonObject, key: string): string | undefined {
15281528return typeof value === "string" ? value : undefined;
15291529}
153015301531+function normalizeNonEmptyString(value: unknown): string | undefined {
1532+if (typeof value !== "string") {
1533+return undefined;
1534+}
1535+return value.trim() || undefined;
1536+}
1537+1538+function readNonEmptyString(record: JsonObject, key: string): string | undefined {
1539+return normalizeNonEmptyString(record[key]);
1540+}
1541+1542+function readNonEmptyStringArray(record: JsonObject, key: string): string[] {
1543+const value = record[key];
1544+if (!Array.isArray(value)) {
1545+return [];
1546+}
1547+const entries: string[] = [];
1548+for (const entry of value) {
1549+const normalized = normalizeNonEmptyString(entry);
1550+if (normalized) {
1551+entries.push(normalized);
1552+}
1553+}
1554+return entries;
1555+}
1556+15311557function readNullableString(record: JsonObject, key: string): string | null | undefined {
15321558const value = record[key];
15331559if (value === null) {
@@ -1818,15 +1844,48 @@ function itemToolArgs(item: CodexThreadItem): Record<string, unknown> | undefine
18181844changes: itemFileChanges(item),
18191845});
18201846}
1821-if (item.type === "webSearch" && typeof item.query === "string") {
1822-return sanitizeCodexAgentEventRecord({ query: item.query });
1847+if (item.type === "webSearch") {
1848+return webSearchToolArgs(item);
18231849}
18241850if (item.type === "dynamicToolCall" || item.type === "mcpToolCall") {
18251851return sanitizeCodexToolArguments(item.arguments);
18261852}
18271853return undefined;
18281854}
182918551856+function webSearchToolArgs(item: CodexThreadItem): Record<string, unknown> {
1857+const action = isJsonObject(item.action) ? item.action : undefined;
1858+const actionType = action ? readNonEmptyString(action, "type") : undefined;
1859+const queries =
1860+action && actionType === "search" ? readNonEmptyStringArray(action, "queries") : [];
1861+const query =
1862+normalizeNonEmptyString(item.query) ??
1863+(action && actionType === "search" ? readNonEmptyString(action, "query") : undefined) ??
1864+queries[0];
1865+const url = action ? readNonEmptyString(action, "url") : undefined;
1866+const pattern = action ? readNonEmptyString(action, "pattern") : undefined;
1867+const args: Record<string, unknown> = {};
1868+if (query) {
1869+args.query = query;
1870+}
1871+if (queries.length > 0) {
1872+args.queries = queries;
1873+}
1874+if (actionType && actionType !== "search") {
1875+args.action = actionType;
1876+}
1877+if (url) {
1878+args.url = url;
1879+}
1880+if (pattern) {
1881+args.pattern = pattern;
1882+}
1883+if (!query && !url && !pattern) {
1884+args.queryUnavailable = true;
1885+}
1886+return sanitizeCodexAgentEventRecord(args);
1887+}
1888+18301889function itemToolResult(item: CodexThreadItem): { result?: Record<string, unknown> } {
18311890if (item.type === "commandExecution") {
18321891return {
@@ -1856,11 +1915,19 @@ function itemToolResult(item: CodexThreadItem): { result?: Record<string, unknow
18561915};
18571916}
18581917if (item.type === "webSearch") {
1859-return { result: sanitizeCodexAgentEventRecord({ status: "completed" }) };
1918+return { result: webSearchToolResult(item) };
18601919}
18611920return {};
18621921}
186319221923+function webSearchToolResult(item: CodexThreadItem): Record<string, unknown> {
1924+return sanitizeCodexAgentEventRecord({
1925+status: itemStatus(item),
1926+ ...(typeof item.durationMs === "number" ? { durationMs: item.durationMs } : {}),
1927+ ...webSearchToolArgs(item),
1928+});
1929+}
1930+18641931function itemFileChanges(item: CodexThreadItem): Array<{ path: string; kind: string }> {
18651932return Array.isArray(item.changes)
18661933 ? item.changes.map((change) => ({ path: change.path, kind: change.kind }))
@@ -1895,8 +1962,8 @@ function itemMeta(
18951962{ detailMode },
18961963);
18971964}
1898-if (item.type === "webSearch" && typeof item.query === "string") {
1899-return item.query;
1965+if (item.type === "webSearch") {
1966+return inferToolMetaFromArgs("web_search", webSearchToolArgs(item), { detailMode });
19001967}
19011968const toolName = itemName(item);
19021969if ((item.type === "dynamicToolCall" || item.type === "mcpToolCall") && toolName) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。