pi-codex-search 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +96 -25
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -80,6 +80,7 @@ interface WebSearchDetails {
|
|
|
80
80
|
partial?: boolean;
|
|
81
81
|
completed?: number;
|
|
82
82
|
total?: number;
|
|
83
|
+
elapsedMs?: number;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
function buildToolDescription(config: ResolvedConfig): string {
|
|
@@ -292,6 +293,8 @@ function buildTool(config: ResolvedConfig) {
|
|
|
292
293
|
);
|
|
293
294
|
}
|
|
294
295
|
|
|
296
|
+
const startedAt = Date.now();
|
|
297
|
+
|
|
295
298
|
const token = await ctx.modelRegistry.getApiKeyForProvider(OPENAI_CODEX_PROVIDER);
|
|
296
299
|
if (!token) {
|
|
297
300
|
const err = new CodexError(
|
|
@@ -477,7 +480,9 @@ function buildTool(config: ResolvedConfig) {
|
|
|
477
480
|
|
|
478
481
|
return {
|
|
479
482
|
content: [{ type: "text", text: formatToolText(successes, failures) }],
|
|
480
|
-
details: buildDetails(config, model, freshness, searchContextSize, successes, failures
|
|
483
|
+
details: buildDetails(config, model, freshness, searchContextSize, successes, failures, {
|
|
484
|
+
elapsedMs: Date.now() - startedAt,
|
|
485
|
+
}),
|
|
481
486
|
};
|
|
482
487
|
}
|
|
483
488
|
|
|
@@ -584,7 +589,9 @@ function buildTool(config: ResolvedConfig) {
|
|
|
584
589
|
|
|
585
590
|
return {
|
|
586
591
|
content: [{ type: "text", text: formatToolText(successes, failures) }],
|
|
587
|
-
details: buildDetails(config, model, freshness, searchContextSize, successes, failures
|
|
592
|
+
details: buildDetails(config, model, freshness, searchContextSize, successes, failures, {
|
|
593
|
+
elapsedMs: Date.now() - startedAt,
|
|
594
|
+
}),
|
|
588
595
|
};
|
|
589
596
|
},
|
|
590
597
|
|
|
@@ -604,7 +611,7 @@ function buildTool(config: ResolvedConfig) {
|
|
|
604
611
|
} else {
|
|
605
612
|
text += ` ${theme.fg("accent", `${labels.length} actions`)}`;
|
|
606
613
|
}
|
|
607
|
-
text += theme.fg("dim", `
|
|
614
|
+
text += theme.fg("dim", ` ${formatModeLabel(config.searchApi, ctxSize, fresh)}`);
|
|
608
615
|
if (labels.length > 1) {
|
|
609
616
|
text += `\n${renderCallQueries(labels, theme)}`;
|
|
610
617
|
}
|
|
@@ -627,26 +634,26 @@ function buildTool(config: ResolvedConfig) {
|
|
|
627
634
|
const total = details.queryCount;
|
|
628
635
|
const failed = details.failedQueryCount;
|
|
629
636
|
const ok = total - failed;
|
|
630
|
-
const
|
|
637
|
+
const resultSuffix = formatResultSuffix(details);
|
|
631
638
|
|
|
632
639
|
let header: string;
|
|
633
640
|
if (ok === 0) {
|
|
634
641
|
header = theme.fg("warning", `⚠ Web search failed (${details.failure?.kind ?? "unknown"})`);
|
|
635
642
|
} else if (failed > 0) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
643
|
+
header = theme.fg(
|
|
644
|
+
"warning",
|
|
645
|
+
`Did ${ok}/${total} ${formatOperationNoun(details, total)}${formatDurationSuffix(details.elapsedMs)}${resultSuffix}`,
|
|
646
|
+
);
|
|
639
647
|
} else {
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
header = theme.fg("success", `✓ ${sourceText}${querySuffix}`);
|
|
648
|
+
const operationCount = countSuccessOperations(details);
|
|
649
|
+
header = theme.fg(
|
|
650
|
+
"success",
|
|
651
|
+
`Did ${operationCount} ${formatOperationNoun(details, operationCount)}${formatDurationSuffix(details.elapsedMs)}${resultSuffix}`,
|
|
652
|
+
);
|
|
646
653
|
}
|
|
647
654
|
header += theme.fg(
|
|
648
655
|
"muted",
|
|
649
|
-
`
|
|
656
|
+
` ${formatModeLabel(details.api, details.searchContextSize, details.freshness)}`,
|
|
650
657
|
);
|
|
651
658
|
|
|
652
659
|
if (!expanded) {
|
|
@@ -736,7 +743,7 @@ function buildDetails(
|
|
|
736
743
|
searchContextSize: SearchContextSize,
|
|
737
744
|
successes: QuerySuccess[],
|
|
738
745
|
failures: QueryFailure[],
|
|
739
|
-
extra?: { partial?: boolean; completed?: number; total?: number },
|
|
746
|
+
extra?: { partial?: boolean; completed?: number; total?: number; elapsedMs?: number },
|
|
740
747
|
): WebSearchDetails {
|
|
741
748
|
const queries = successes.map((s) => s.query).concat(failures.map((f) => f.query));
|
|
742
749
|
return {
|
|
@@ -788,8 +795,54 @@ function formatSuccessBlock(success: QuerySuccess, multiple: boolean): string {
|
|
|
788
795
|
return multiple ? `## Query: ${success.query}\n\n${body}` : body;
|
|
789
796
|
}
|
|
790
797
|
|
|
791
|
-
function
|
|
792
|
-
return
|
|
798
|
+
function countSuccessCitations(details: WebSearchDetails): number {
|
|
799
|
+
return details.successes.reduce((acc, success) => acc + success.citations.length, 0);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function countSuccessWebActions(details: WebSearchDetails): number {
|
|
803
|
+
return details.successes.reduce((acc, success) => acc + success.searchCalls.length, 0);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
function countSuccessOperations(details: WebSearchDetails): number {
|
|
807
|
+
if (details.api === "responses") return details.queryCount;
|
|
808
|
+
const count = countSuccessWebActions(details);
|
|
809
|
+
return count > 0 ? count : details.queryCount;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
function formatOperationNoun(details: WebSearchDetails, count: number): string {
|
|
813
|
+
const singular = details.api === "standalone" ? "action" : "search";
|
|
814
|
+
const plural = details.api === "standalone" ? "actions" : "searches";
|
|
815
|
+
return count === 1 ? singular : plural;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
function formatResultSuffix(details: WebSearchDetails): string {
|
|
819
|
+
const parts: string[] = [];
|
|
820
|
+
const webActionCount = countSuccessWebActions(details);
|
|
821
|
+
if (details.api === "responses" && webActionCount > 0) {
|
|
822
|
+
parts.push(`${webActionCount} web action${webActionCount === 1 ? "" : "s"}`);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
const citationCount = countSuccessCitations(details);
|
|
826
|
+
if (citationCount > 0) {
|
|
827
|
+
parts.push(`${citationCount} source${citationCount === 1 ? "" : "s"}`);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
return parts.length > 0 ? ` · ${parts.join(" · ")}` : "";
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function formatDurationSuffix(elapsedMs: number | undefined): string {
|
|
834
|
+
if (elapsedMs === undefined) return "";
|
|
835
|
+
if (elapsedMs < 1000) return ` in ${elapsedMs}ms`;
|
|
836
|
+
return ` in ${Math.max(1, Math.round(elapsedMs / 1000))}s`;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
function formatModeLabel(
|
|
840
|
+
api: string,
|
|
841
|
+
searchContextSize: string,
|
|
842
|
+
freshness: string | undefined,
|
|
843
|
+
): string {
|
|
844
|
+
if (api === "standalone") return `[${api}/${searchContextSize}]`;
|
|
845
|
+
return `[${api}/${searchContextSize}/${freshness ?? "live"}]`;
|
|
793
846
|
}
|
|
794
847
|
|
|
795
848
|
function formatFailureBlock(failure: QueryFailure, multiple: boolean): string {
|
|
@@ -808,8 +861,8 @@ function renderPartial(details: WebSearchDetails | undefined, theme: Theme): str
|
|
|
808
861
|
|
|
809
862
|
function renderCollapsedPreview(details: WebSearchDetails, theme: Theme): string {
|
|
810
863
|
const lines: string[] = [];
|
|
811
|
-
const
|
|
812
|
-
if (
|
|
864
|
+
const successPreview = renderSuccessPreview(details, theme);
|
|
865
|
+
if (successPreview) lines.push(successPreview);
|
|
813
866
|
|
|
814
867
|
const firstFailure = details.failures[0];
|
|
815
868
|
if (firstFailure) {
|
|
@@ -818,12 +871,30 @@ function renderCollapsedPreview(details: WebSearchDetails, theme: Theme): string
|
|
|
818
871
|
return lines.join("\n");
|
|
819
872
|
}
|
|
820
873
|
|
|
821
|
-
function
|
|
822
|
-
if (
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
874
|
+
function renderSuccessPreview(details: WebSearchDetails, theme: Theme): string {
|
|
875
|
+
if (details.api !== "standalone") return "";
|
|
876
|
+
const success = details.successes[0];
|
|
877
|
+
if (!success) return "";
|
|
878
|
+
const line = firstNonEmptyLine(success.text);
|
|
879
|
+
if (!line) return "";
|
|
880
|
+
const actionType = success.searchCalls[0]?.actionType;
|
|
881
|
+
return theme.fg("dim", `${formatStandalonePreviewLabel(actionType)}: ${formatInline(line, 120)}`);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
function firstNonEmptyLine(text: string): string {
|
|
885
|
+
return (
|
|
886
|
+
text
|
|
887
|
+
.split("\n")
|
|
888
|
+
.map((line) => line.trim())
|
|
889
|
+
.find((line) => line.length > 0) ?? ""
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
function formatStandalonePreviewLabel(actionType: string | undefined): string {
|
|
894
|
+
if (actionType === "open_page" || actionType === "click") return "Opened";
|
|
895
|
+
if (actionType === "find_in_page") return "Found";
|
|
896
|
+
if (actionType === "screenshot") return "Screenshot";
|
|
897
|
+
return "Result";
|
|
827
898
|
}
|
|
828
899
|
|
|
829
900
|
function renderCallQueries(queries: unknown[], theme: Theme): string {
|