@nijaru/pi-search 0.0.1 → 0.0.3
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/README.md +44 -9
- package/package.json +6 -6
- package/src/anthropic-auth.ts +108 -0
- package/src/anthropic.ts +64 -48
- package/src/brave-answers.ts +9 -2
- package/src/brave.ts +9 -6
- package/src/cloudflare.ts +175 -0
- package/src/codex.ts +4 -4
- package/src/contracts.ts +21 -3
- package/src/errors.ts +15 -1
- package/src/gemini.ts +10 -3
- package/src/grounding.ts +17 -3
- package/src/index.ts +17 -5
- package/src/model-selection.ts +23 -5
- package/src/openai.ts +32 -35
- package/src/parallel-responses.ts +1 -0
- package/src/parallel.ts +4 -1
- package/src/provider-availability.ts +2 -0
- package/src/provider-http.ts +3 -2
- package/src/research-tool.ts +47 -30
- package/src/router.ts +10 -2
- package/src/search-cleanup.ts +7 -6
- package/src/search-tool.ts +38 -8
- package/src/search.ts +2 -1
- package/src/x.ts +2 -2
- package/src/xai.ts +1 -1
- package/src/local-llama-compat.ts +0 -134
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import net from "node:net";
|
|
2
|
-
|
|
3
|
-
const LLAMA_NESTED_MAX_LENGTH_THRESHOLD = 2_000;
|
|
4
|
-
export const LLAMA_SAFE_NESTED_MAX_LENGTH = LLAMA_NESTED_MAX_LENGTH_THRESHOLD - 1;
|
|
5
|
-
|
|
6
|
-
const OPENAI_COMPATIBLE_APIS = new Set([
|
|
7
|
-
"openai-completions",
|
|
8
|
-
"openai-responses",
|
|
9
|
-
"azure-openai-responses",
|
|
10
|
-
"openai-codex-responses",
|
|
11
|
-
]);
|
|
12
|
-
|
|
13
|
-
export interface ModelEndpointIdentity {
|
|
14
|
-
readonly api: string;
|
|
15
|
-
readonly baseUrl: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function normalizedHostname(hostname: string): string {
|
|
19
|
-
return hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function isPrivateIpv4(hostname: string): boolean {
|
|
23
|
-
if (net.isIP(hostname) !== 4) return false;
|
|
24
|
-
const parts = hostname.split(".").map(Number);
|
|
25
|
-
const [first, second] = parts;
|
|
26
|
-
return first === 10 || first === 127 || (first === 100 && second >= 64 && second <= 127) || (first === 169 && second === 254) || (first === 172 && second >= 16 && second <= 31) || (first === 192 && second === 168);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function isPrivateIpv6(hostname: string): boolean {
|
|
30
|
-
const normalized = normalizedHostname(hostname);
|
|
31
|
-
if (net.isIP(normalized) !== 6) return false;
|
|
32
|
-
if (normalized === "::1" || normalized.startsWith("fc") || normalized.startsWith("fd") || normalized.startsWith("fe80:")) return true;
|
|
33
|
-
return normalized.startsWith("::ffff:") && isPrivateIpv4(normalized.slice("::ffff:".length));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function isLocalEndpoint(baseUrl: string): boolean {
|
|
37
|
-
try {
|
|
38
|
-
const url = new URL(baseUrl);
|
|
39
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return false;
|
|
40
|
-
const hostname = normalizedHostname(url.hostname);
|
|
41
|
-
const isLocalName = hostname === "localhost" || hostname.endsWith(".localhost") || hostname.endsWith(".local") || hostname.endsWith(".home.arpa") || hostname === "host.docker.internal" || hostname === "gateway.docker.internal";
|
|
42
|
-
const isSingleLabelName = net.isIP(hostname) === 0 && !hostname.includes(".");
|
|
43
|
-
return isLocalName || isSingleLabelName || isPrivateIpv4(hostname) || isPrivateIpv6(hostname);
|
|
44
|
-
} catch {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Pi does not expose the upstream server implementation. Local/private
|
|
51
|
-
* OpenAI-compatible endpoints are therefore the safe compatibility boundary:
|
|
52
|
-
* llama.cpp is fixed without changing schemas sent to hosted providers.
|
|
53
|
-
*/
|
|
54
|
-
export function isLocalOpenAICompatibleModel(model: ModelEndpointIdentity | undefined): boolean {
|
|
55
|
-
if (model === undefined || !OPENAI_COMPATIBLE_APIS.has(model.api)) return false;
|
|
56
|
-
return isLocalEndpoint(model.baseUrl);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
type JsonObject = Record<string, unknown>;
|
|
60
|
-
|
|
61
|
-
function isJsonObject(value: unknown): value is JsonObject {
|
|
62
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function adaptResearchParameters(parameters: unknown): unknown {
|
|
66
|
-
if (!isJsonObject(parameters) || !isJsonObject(parameters.properties)) return parameters;
|
|
67
|
-
const queries = parameters.properties.queries;
|
|
68
|
-
if (!isJsonObject(queries) || !isJsonObject(queries.items) || queries.items.type !== "string") return parameters;
|
|
69
|
-
const maxLength = queries.items.maxLength;
|
|
70
|
-
if (typeof maxLength !== "number" || maxLength < LLAMA_NESTED_MAX_LENGTH_THRESHOLD) return parameters;
|
|
71
|
-
return {
|
|
72
|
-
...parameters,
|
|
73
|
-
properties: {
|
|
74
|
-
...parameters.properties,
|
|
75
|
-
queries: {
|
|
76
|
-
...queries,
|
|
77
|
-
items: { ...queries.items, maxLength: LLAMA_SAFE_NESTED_MAX_LENGTH },
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function rewritePayload(value: unknown): { value: unknown; changed: boolean } {
|
|
84
|
-
if (Array.isArray(value)) {
|
|
85
|
-
let changed = false;
|
|
86
|
-
const rewritten = value.map((item) => {
|
|
87
|
-
const result = rewritePayload(item);
|
|
88
|
-
changed ||= result.changed;
|
|
89
|
-
return result.value;
|
|
90
|
-
});
|
|
91
|
-
return { value: changed ? rewritten : value, changed };
|
|
92
|
-
}
|
|
93
|
-
if (!isJsonObject(value)) return { value, changed: false };
|
|
94
|
-
|
|
95
|
-
let changed = false;
|
|
96
|
-
let rewritten: JsonObject = value;
|
|
97
|
-
for (const [key, child] of Object.entries(value)) {
|
|
98
|
-
const result = rewritePayload(child);
|
|
99
|
-
if (result.changed) {
|
|
100
|
-
if (!changed) rewritten = { ...value };
|
|
101
|
-
rewritten[key] = result.value;
|
|
102
|
-
changed = true;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const toolName = typeof rewritten.name === "string" ? rewritten.name : undefined;
|
|
107
|
-
if (toolName === "web_research") {
|
|
108
|
-
const directParameters = adaptResearchParameters(rewritten.parameters);
|
|
109
|
-
if (directParameters !== rewritten.parameters) {
|
|
110
|
-
if (!changed) rewritten = { ...rewritten };
|
|
111
|
-
rewritten.parameters = directParameters;
|
|
112
|
-
changed = true;
|
|
113
|
-
}
|
|
114
|
-
const functionDefinition = rewritten.function;
|
|
115
|
-
if (isJsonObject(functionDefinition)) {
|
|
116
|
-
const functionParameters = adaptResearchParameters(functionDefinition.parameters);
|
|
117
|
-
if (functionParameters !== functionDefinition.parameters) {
|
|
118
|
-
if (!changed) rewritten = { ...rewritten };
|
|
119
|
-
rewritten.function = { ...functionDefinition, parameters: functionParameters };
|
|
120
|
-
changed = true;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return { value: rewritten, changed };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Adapt only the outgoing JSON schema for local llama-compatible tool calls.
|
|
130
|
-
* The input is treated as immutable and returned by identity when unchanged.
|
|
131
|
-
*/
|
|
132
|
-
export function adaptLocalLlamaPayload(payload: unknown): unknown {
|
|
133
|
-
return rewritePayload(payload).value;
|
|
134
|
-
}
|