@humain/terminal 0.1.0 → 0.1.1
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/CHANGELOG.md +17 -0
- package/dist/bundle/chunks/{chunk-RM336IEI.js → chunk-LYAMSPR2.js} +18 -18
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli.js +1 -5
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/humain/index.d.ts.map +1 -1
- package/dist/humain/index.js +2 -0
- package/dist/humain/index.js.map +1 -1
- package/dist/humain/node-http.d.ts +3 -0
- package/dist/humain/node-http.d.ts.map +1 -0
- package/dist/humain/node-http.js +119 -0
- package/dist/humain/node-http.js.map +1 -0
- package/dist/humain/node-provider.d.ts +4 -0
- package/dist/humain/node-provider.d.ts.map +1 -0
- package/dist/humain/node-provider.js +359 -0
- package/dist/humain/node-provider.js.map +1 -0
- package/dist/index.js +1 -51
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +16 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +7 -2
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +46 -21
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +10 -13
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/humain-terminal.md +6 -0
- package/docs/providers.md +19 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
+
import { createProvider, } from "@earendil-works/pi-ai";
|
|
3
|
+
import { anthropicMessagesApi } from "@earendil-works/pi-ai/api/anthropic-messages.lazy";
|
|
4
|
+
import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy";
|
|
5
|
+
import { openAIResponsesApi } from "@earendil-works/pi-ai/api/openai-responses.lazy";
|
|
6
|
+
import { withHumainNodeHttp } from "./node-http.js";
|
|
7
|
+
export const HUMAIN_NODE_PROVIDER = "humain-node";
|
|
8
|
+
const DEFAULT_BASE_URL = "https://api.node.humain.com/v1";
|
|
9
|
+
const API_KEY_ENV = "HUMAIN_NODE_API_KEY";
|
|
10
|
+
const BASE_URL_ENV = "HUMAIN_NODE_BASE_URL";
|
|
11
|
+
const RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
12
|
+
const PERMANENT_LIMIT_CODES = new Set([
|
|
13
|
+
"billing_hard_limit_reached",
|
|
14
|
+
"insufficient_quota",
|
|
15
|
+
"partner_credit_limit_exceeded",
|
|
16
|
+
"quota_exceeded",
|
|
17
|
+
"weekly_cap_exceeded",
|
|
18
|
+
]);
|
|
19
|
+
const REQUEST_TIMEOUT_MS = 5_000;
|
|
20
|
+
const MAX_RETRIES = 2;
|
|
21
|
+
const MAX_RETRY_DELAY_MS = 2_000;
|
|
22
|
+
const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
23
|
+
function normalizeBaseUrl(value) {
|
|
24
|
+
let url;
|
|
25
|
+
try {
|
|
26
|
+
url = new URL(value.trim());
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error("Invalid HUMAIN Node base URL");
|
|
30
|
+
}
|
|
31
|
+
const local = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
|
|
32
|
+
if (url.protocol !== "https:" && !(local && url.protocol === "http:")) {
|
|
33
|
+
throw new Error("HUMAIN Node base URL must use HTTPS (HTTP is allowed only for localhost)");
|
|
34
|
+
}
|
|
35
|
+
if (url.username || url.password || url.search || url.hash) {
|
|
36
|
+
throw new Error("HUMAIN Node base URL must not contain credentials, a query, or a fragment");
|
|
37
|
+
}
|
|
38
|
+
url.pathname = url.pathname.replace(/\/+$/u, "") || "/";
|
|
39
|
+
return url.toString().replace(/\/$/u, "");
|
|
40
|
+
}
|
|
41
|
+
function credentialBaseUrl(credential) {
|
|
42
|
+
const value = credential?.env?.[BASE_URL_ENV];
|
|
43
|
+
return typeof value === "string" && value.trim() ? normalizeBaseUrl(value) : undefined;
|
|
44
|
+
}
|
|
45
|
+
async function resolveBaseUrl(ctx, credential) {
|
|
46
|
+
return credentialBaseUrl(credential) ?? normalizeBaseUrl((await ctx.env(BASE_URL_ENV)) ?? DEFAULT_BASE_URL);
|
|
47
|
+
}
|
|
48
|
+
function endpointApi(value) {
|
|
49
|
+
const normalized = value
|
|
50
|
+
.trim()
|
|
51
|
+
.toLowerCase()
|
|
52
|
+
.replace(/^https?:\/\/[^/]+/u, "")
|
|
53
|
+
.replace(/\/+$/u, "");
|
|
54
|
+
switch (normalized) {
|
|
55
|
+
case "responses":
|
|
56
|
+
case "/responses":
|
|
57
|
+
case "openai-responses":
|
|
58
|
+
case "openai_responses":
|
|
59
|
+
return "openai-responses";
|
|
60
|
+
case "chat/completions":
|
|
61
|
+
case "/chat/completions":
|
|
62
|
+
case "chat-completions":
|
|
63
|
+
case "chat_completions":
|
|
64
|
+
case "openai-completions":
|
|
65
|
+
case "openai_chat_completions":
|
|
66
|
+
return "openai-completions";
|
|
67
|
+
case "messages":
|
|
68
|
+
case "/messages":
|
|
69
|
+
case "anthropic-messages":
|
|
70
|
+
case "anthropic_messages":
|
|
71
|
+
return "anthropic-messages";
|
|
72
|
+
default:
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function modelApi(id, node) {
|
|
77
|
+
if (typeof node.api_interface === "string") {
|
|
78
|
+
const primary = endpointApi(node.api_interface);
|
|
79
|
+
if (primary)
|
|
80
|
+
return primary;
|
|
81
|
+
}
|
|
82
|
+
const supported = Array.isArray(node.supported_formats)
|
|
83
|
+
? node.supported_formats.flatMap((value) => (typeof value === "string" ? (endpointApi(value) ?? []) : []))
|
|
84
|
+
: [];
|
|
85
|
+
for (const preferred of ["openai-responses", "openai-completions", "anthropic-messages"]) {
|
|
86
|
+
if (supported.includes(preferred))
|
|
87
|
+
return preferred;
|
|
88
|
+
}
|
|
89
|
+
const primary = typeof node.api_interface === "string" ? node.api_interface : "missing";
|
|
90
|
+
throw new Error(`HUMAIN Node model "${id}" has an unsupported API interface: ${primary}`);
|
|
91
|
+
}
|
|
92
|
+
function positiveInteger(value, field, id) {
|
|
93
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
|
|
94
|
+
throw new Error(`HUMAIN Node model "${id}" has invalid ${field}`);
|
|
95
|
+
}
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
function toModel(value, baseUrl) {
|
|
99
|
+
if (typeof value !== "object" || value === null || !("id" in value)) {
|
|
100
|
+
throw new Error("HUMAIN Node returned a malformed model entry");
|
|
101
|
+
}
|
|
102
|
+
const raw = value;
|
|
103
|
+
if (raw.active === false)
|
|
104
|
+
return undefined;
|
|
105
|
+
const node = typeof raw.node === "object" && raw.node !== null ? raw.node : raw;
|
|
106
|
+
const payload = { ...raw, node };
|
|
107
|
+
if (typeof payload.id !== "string" || !payload.id.trim()) {
|
|
108
|
+
throw new Error("HUMAIN Node returned a malformed model entry");
|
|
109
|
+
}
|
|
110
|
+
const id = payload.id.trim();
|
|
111
|
+
if (typeof payload.node.supports_streaming !== "boolean") {
|
|
112
|
+
throw new Error(`HUMAIN Node model "${id}" has invalid supports_streaming`);
|
|
113
|
+
}
|
|
114
|
+
if (typeof payload.node.supports_function_calling !== "boolean") {
|
|
115
|
+
throw new Error(`HUMAIN Node model "${id}" has invalid supports_function_calling`);
|
|
116
|
+
}
|
|
117
|
+
if (payload.node.supports_streaming === false || payload.node.supports_function_calling === false)
|
|
118
|
+
return undefined;
|
|
119
|
+
let api;
|
|
120
|
+
try {
|
|
121
|
+
api = modelApi(id, payload.node);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
if (payload.node.api_interface === "image_generations" || payload.node.api_interface === "realtime")
|
|
125
|
+
return undefined;
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
const contextWindow = payload.node.max_context_tokens;
|
|
129
|
+
const maxTokens = payload.node.max_output_tokens;
|
|
130
|
+
if (contextWindow === null || maxTokens === null || contextWindow === 0 || maxTokens === 0)
|
|
131
|
+
return undefined;
|
|
132
|
+
return {
|
|
133
|
+
id,
|
|
134
|
+
name: typeof payload.display_name === "string" && payload.display_name.trim()
|
|
135
|
+
? payload.display_name.trim()
|
|
136
|
+
: typeof payload.name === "string" && payload.name.trim()
|
|
137
|
+
? payload.name.trim()
|
|
138
|
+
: id,
|
|
139
|
+
api,
|
|
140
|
+
provider: HUMAIN_NODE_PROVIDER,
|
|
141
|
+
baseUrl,
|
|
142
|
+
reasoning: false,
|
|
143
|
+
input: payload.node.supports_images === true ? ["text", "image"] : ["text"],
|
|
144
|
+
cost: ZERO_COST,
|
|
145
|
+
contextWindow: positiveInteger(contextWindow, "max_context_tokens", id),
|
|
146
|
+
maxTokens: positiveInteger(maxTokens, "max_output_tokens", id),
|
|
147
|
+
...(api === "openai-completions"
|
|
148
|
+
? {
|
|
149
|
+
compat: {
|
|
150
|
+
supportsStore: false,
|
|
151
|
+
supportsDeveloperRole: false,
|
|
152
|
+
supportsReasoningEffort: false,
|
|
153
|
+
supportsUsageInStreaming: true,
|
|
154
|
+
supportsStrictMode: false,
|
|
155
|
+
supportsLongCacheRetention: false,
|
|
156
|
+
maxTokensField: "max_tokens",
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
: {}),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function retryDelay(response, attempt) {
|
|
163
|
+
const retryAfter = response.headers.get("retry-after");
|
|
164
|
+
if (retryAfter) {
|
|
165
|
+
const seconds = Number(retryAfter);
|
|
166
|
+
const delay = Number.isFinite(seconds) ? seconds * 1_000 : Date.parse(retryAfter) - Date.now();
|
|
167
|
+
if (Number.isFinite(delay)) {
|
|
168
|
+
const bounded = Math.max(0, delay);
|
|
169
|
+
return bounded <= MAX_RETRY_DELAY_MS ? bounded : undefined;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return 100 * 2 ** attempt;
|
|
173
|
+
}
|
|
174
|
+
function errorDetails(response, payload) {
|
|
175
|
+
const error = payload.error;
|
|
176
|
+
const code = typeof error?.code === "string" ? error.code : undefined;
|
|
177
|
+
const type = typeof error?.type === "string" ? error.type : undefined;
|
|
178
|
+
const detail = typeof error?.message === "string" ? error.message : undefined;
|
|
179
|
+
const retryAfter = response.headers.get("retry-after");
|
|
180
|
+
const requestId = response.headers.get("x-request-id");
|
|
181
|
+
return {
|
|
182
|
+
code,
|
|
183
|
+
message: [
|
|
184
|
+
`HUMAIN Node model discovery failed: ${response.status}`,
|
|
185
|
+
code && `code=${code}`,
|
|
186
|
+
type && `type=${type}`,
|
|
187
|
+
detail,
|
|
188
|
+
retryAfter && `Retry-After: ${retryAfter}`,
|
|
189
|
+
requestId && `X-Request-ID: ${requestId}`,
|
|
190
|
+
]
|
|
191
|
+
.filter(Boolean)
|
|
192
|
+
.join("; "),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
async function fetchModelsUnredacted(baseUrl, apiKey, signal) {
|
|
196
|
+
for (let attempt = 0;; attempt++) {
|
|
197
|
+
signal.throwIfAborted();
|
|
198
|
+
const attemptSignal = AbortSignal.any([signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]);
|
|
199
|
+
let response;
|
|
200
|
+
try {
|
|
201
|
+
response = await fetch(new URL(`${baseUrl}/models`), {
|
|
202
|
+
signal: attemptSignal,
|
|
203
|
+
redirect: "error",
|
|
204
|
+
headers: { Accept: "application/json", Authorization: `Bearer ${apiKey}` },
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
if (signal.aborted || attempt >= MAX_RETRIES)
|
|
209
|
+
throw error;
|
|
210
|
+
await delay(100 * 2 ** attempt, undefined, { signal });
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const payload = await response.json().catch(() => ({}));
|
|
214
|
+
if (!response.ok) {
|
|
215
|
+
const details = errorDetails(response, typeof payload === "object" && payload !== null ? payload : {});
|
|
216
|
+
const retryMs = retryDelay(response, attempt);
|
|
217
|
+
if (attempt < MAX_RETRIES &&
|
|
218
|
+
RETRYABLE_STATUS_CODES.has(response.status) &&
|
|
219
|
+
!PERMANENT_LIMIT_CODES.has(details.code ?? "") &&
|
|
220
|
+
retryMs !== undefined) {
|
|
221
|
+
await delay(retryMs, undefined, { signal });
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
throw new Error(details.message);
|
|
225
|
+
}
|
|
226
|
+
if (typeof payload !== "object" || payload === null) {
|
|
227
|
+
throw new Error("HUMAIN Node returned a malformed model catalog");
|
|
228
|
+
}
|
|
229
|
+
const entries = "data" in payload && Array.isArray(payload.data)
|
|
230
|
+
? payload.data
|
|
231
|
+
: "items" in payload && Array.isArray(payload.items)
|
|
232
|
+
? payload.items
|
|
233
|
+
: undefined;
|
|
234
|
+
if (!entries)
|
|
235
|
+
throw new Error("HUMAIN Node returned a malformed model catalog");
|
|
236
|
+
const ids = new Set();
|
|
237
|
+
for (const entry of entries) {
|
|
238
|
+
if (typeof entry !== "object" || entry === null || !("id" in entry) || typeof entry.id !== "string")
|
|
239
|
+
continue;
|
|
240
|
+
const id = entry.id.trim();
|
|
241
|
+
if (ids.has(id))
|
|
242
|
+
throw new Error(`HUMAIN Node returned duplicate model id "${id}"`);
|
|
243
|
+
ids.add(id);
|
|
244
|
+
}
|
|
245
|
+
return entries.flatMap((entry) => toModel(entry, baseUrl) ?? []);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
async function fetchModels(baseUrl, apiKey, signal) {
|
|
249
|
+
try {
|
|
250
|
+
return await fetchModelsUnredacted(baseUrl, apiKey, signal);
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
if (signal.aborted)
|
|
254
|
+
throw signal.reason;
|
|
255
|
+
const message = (error instanceof Error ? error.message : String(error)).replaceAll(apiKey, "[redacted]");
|
|
256
|
+
const redacted = new Error(message);
|
|
257
|
+
if (error instanceof Error)
|
|
258
|
+
redacted.name = error.name;
|
|
259
|
+
throw redacted;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
export function createHumainNodeProvider(env = process.env) {
|
|
263
|
+
let models = [];
|
|
264
|
+
let activeScope;
|
|
265
|
+
const apiKeyAuth = {
|
|
266
|
+
name: "HUMAIN Node API key",
|
|
267
|
+
login: async (interaction) => {
|
|
268
|
+
if (!env[API_KEY_ENV]?.trim()) {
|
|
269
|
+
interaction.notify({
|
|
270
|
+
type: "info",
|
|
271
|
+
message: "Create a HUMAIN Node API key in Node Users, then paste it below.",
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
const enteredKey = (await interaction.prompt({
|
|
275
|
+
type: "secret",
|
|
276
|
+
message: "Enter HUMAIN Node API key (leave blank to use HUMAIN_NODE_API_KEY)",
|
|
277
|
+
})).trim();
|
|
278
|
+
const key = enteredKey || env[API_KEY_ENV]?.trim();
|
|
279
|
+
if (!key)
|
|
280
|
+
throw new Error("HUMAIN Node API key is required");
|
|
281
|
+
const enteredUrl = await interaction.prompt({
|
|
282
|
+
type: "text",
|
|
283
|
+
message: "HUMAIN Node base URL",
|
|
284
|
+
placeholder: env[BASE_URL_ENV] ?? DEFAULT_BASE_URL,
|
|
285
|
+
});
|
|
286
|
+
const baseUrl = normalizeBaseUrl(enteredUrl.trim() || env[BASE_URL_ENV] || DEFAULT_BASE_URL);
|
|
287
|
+
await fetchModels(baseUrl, key, interaction.signal);
|
|
288
|
+
return {
|
|
289
|
+
type: "api_key",
|
|
290
|
+
key: enteredKey.replaceAll("$", () => "$$").replace(/^!/u, () => "$!") || undefined,
|
|
291
|
+
env: { [BASE_URL_ENV]: baseUrl },
|
|
292
|
+
};
|
|
293
|
+
},
|
|
294
|
+
check: async ({ ctx, credential, signal }) => {
|
|
295
|
+
signal.throwIfAborted();
|
|
296
|
+
const key = credential?.key ?? (await ctx.env(API_KEY_ENV));
|
|
297
|
+
return key
|
|
298
|
+
? { type: "api_key", source: credential?.key ? "stored credential" : API_KEY_ENV }
|
|
299
|
+
: undefined;
|
|
300
|
+
},
|
|
301
|
+
resolve: async ({ ctx, credential, signal }) => {
|
|
302
|
+
signal.throwIfAborted();
|
|
303
|
+
const key = credential?.key ?? (await ctx.env(API_KEY_ENV));
|
|
304
|
+
if (!key)
|
|
305
|
+
return undefined;
|
|
306
|
+
const baseUrl = await resolveBaseUrl(ctx, credential);
|
|
307
|
+
return {
|
|
308
|
+
auth: { apiKey: key, baseUrl },
|
|
309
|
+
env: { ...credential?.env, [BASE_URL_ENV]: baseUrl },
|
|
310
|
+
source: credential?.key ? "stored credential" : API_KEY_ENV,
|
|
311
|
+
};
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
const base = createProvider({
|
|
315
|
+
id: HUMAIN_NODE_PROVIDER,
|
|
316
|
+
name: "HUMAIN Node",
|
|
317
|
+
baseUrl: DEFAULT_BASE_URL,
|
|
318
|
+
auth: { apiKey: apiKeyAuth },
|
|
319
|
+
models: [],
|
|
320
|
+
api: {
|
|
321
|
+
"anthropic-messages": withHumainNodeHttp(anthropicMessagesApi()),
|
|
322
|
+
"openai-completions": withHumainNodeHttp(openAICompletionsApi()),
|
|
323
|
+
"openai-responses": withHumainNodeHttp(openAIResponsesApi()),
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
...base,
|
|
328
|
+
getModels: () => models,
|
|
329
|
+
refreshModels: async (context) => {
|
|
330
|
+
const credential = context.credential?.type === "api_key" ? context.credential : undefined;
|
|
331
|
+
const key = credential?.key;
|
|
332
|
+
const baseUrl = credential ? (credentialBaseUrl(credential) ?? DEFAULT_BASE_URL) : undefined;
|
|
333
|
+
const scope = key && baseUrl ? `${baseUrl}\0${key}` : undefined;
|
|
334
|
+
if (scope !== activeScope) {
|
|
335
|
+
if (!(await context.publish({
|
|
336
|
+
persist: null,
|
|
337
|
+
update: () => {
|
|
338
|
+
models = [];
|
|
339
|
+
activeScope = scope;
|
|
340
|
+
},
|
|
341
|
+
})))
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (!context.allowNetwork || context.signal.aborted || !key || !baseUrl)
|
|
345
|
+
return;
|
|
346
|
+
const refreshed = await fetchModels(baseUrl, key, context.signal);
|
|
347
|
+
if (context.signal.aborted)
|
|
348
|
+
return;
|
|
349
|
+
await context.publish({
|
|
350
|
+
persist: null,
|
|
351
|
+
update: () => {
|
|
352
|
+
models = refreshed;
|
|
353
|
+
activeScope = scope;
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=node-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-provider.js","sourceRoot":"","sources":["../../src/humain/node-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { setTimeout as delay } from \"node:timers/promises\";\nimport {\n\ttype Api,\n\ttype ApiKeyAuth,\n\ttype ApiKeyCredential,\n\ttype AuthContext,\n\ttype AuthResult,\n\tcreateProvider,\n\ttype Model,\n\ttype Provider,\n\ttype RefreshModelsContext,\n} from \"@earendil-works/pi-ai\";\nimport { anthropicMessagesApi } from \"@earendil-works/pi-ai/api/anthropic-messages.lazy\";\nimport { openAICompletionsApi } from \"@earendil-works/pi-ai/api/openai-completions.lazy\";\nimport { openAIResponsesApi } from \"@earendil-works/pi-ai/api/openai-responses.lazy\";\nimport { withHumainNodeHttp } from \"./node-http.ts\";\n\nexport const HUMAIN_NODE_PROVIDER = \"humain-node\";\n\nconst DEFAULT_BASE_URL = \"https://api.node.humain.com/v1\";\nconst API_KEY_ENV = \"HUMAIN_NODE_API_KEY\";\nconst BASE_URL_ENV = \"HUMAIN_NODE_BASE_URL\";\nconst RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);\nconst PERMANENT_LIMIT_CODES = new Set([\n\t\"billing_hard_limit_reached\",\n\t\"insufficient_quota\",\n\t\"partner_credit_limit_exceeded\",\n\t\"quota_exceeded\",\n\t\"weekly_cap_exceeded\",\n]);\nconst REQUEST_TIMEOUT_MS = 5_000;\nconst MAX_RETRIES = 2;\nconst MAX_RETRY_DELAY_MS = 2_000;\nconst ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\ninterface NodeModelPayload {\n\tid: unknown;\n\tname?: unknown;\n\tdisplay_name?: unknown;\n\tnode: {\n\t\tapi_interface?: unknown;\n\t\tsupported_formats?: unknown;\n\t\tmax_context_tokens?: unknown;\n\t\tmax_output_tokens?: unknown;\n\t\tsupports_streaming?: unknown;\n\t\tsupports_function_calling?: unknown;\n\t\tsupports_images?: unknown;\n\t};\n}\n\ninterface NodeErrorPayload {\n\terror?: { code?: unknown; type?: unknown; message?: unknown };\n}\n\nfunction normalizeBaseUrl(value: string): string {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(value.trim());\n\t} catch {\n\t\tthrow new Error(\"Invalid HUMAIN Node base URL\");\n\t}\n\tconst local = url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === \"[::1]\";\n\tif (url.protocol !== \"https:\" && !(local && url.protocol === \"http:\")) {\n\t\tthrow new Error(\"HUMAIN Node base URL must use HTTPS (HTTP is allowed only for localhost)\");\n\t}\n\tif (url.username || url.password || url.search || url.hash) {\n\t\tthrow new Error(\"HUMAIN Node base URL must not contain credentials, a query, or a fragment\");\n\t}\n\turl.pathname = url.pathname.replace(/\\/+$/u, \"\") || \"/\";\n\treturn url.toString().replace(/\\/$/u, \"\");\n}\n\nfunction credentialBaseUrl(credential: ApiKeyCredential | undefined): string | undefined {\n\tconst value = credential?.env?.[BASE_URL_ENV];\n\treturn typeof value === \"string\" && value.trim() ? normalizeBaseUrl(value) : undefined;\n}\n\nasync function resolveBaseUrl(ctx: AuthContext, credential?: ApiKeyCredential): Promise<string> {\n\treturn credentialBaseUrl(credential) ?? normalizeBaseUrl((await ctx.env(BASE_URL_ENV)) ?? DEFAULT_BASE_URL);\n}\n\nfunction endpointApi(value: string): Api | undefined {\n\tconst normalized = value\n\t\t.trim()\n\t\t.toLowerCase()\n\t\t.replace(/^https?:\\/\\/[^/]+/u, \"\")\n\t\t.replace(/\\/+$/u, \"\");\n\tswitch (normalized) {\n\t\tcase \"responses\":\n\t\tcase \"/responses\":\n\t\tcase \"openai-responses\":\n\t\tcase \"openai_responses\":\n\t\t\treturn \"openai-responses\";\n\t\tcase \"chat/completions\":\n\t\tcase \"/chat/completions\":\n\t\tcase \"chat-completions\":\n\t\tcase \"chat_completions\":\n\t\tcase \"openai-completions\":\n\t\tcase \"openai_chat_completions\":\n\t\t\treturn \"openai-completions\";\n\t\tcase \"messages\":\n\t\tcase \"/messages\":\n\t\tcase \"anthropic-messages\":\n\t\tcase \"anthropic_messages\":\n\t\t\treturn \"anthropic-messages\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction modelApi(id: string, node: NodeModelPayload[\"node\"]): Api {\n\tif (typeof node.api_interface === \"string\") {\n\t\tconst primary = endpointApi(node.api_interface);\n\t\tif (primary) return primary;\n\t}\n\tconst supported = Array.isArray(node.supported_formats)\n\t\t? node.supported_formats.flatMap((value) => (typeof value === \"string\" ? (endpointApi(value) ?? []) : []))\n\t\t: [];\n\tfor (const preferred of [\"openai-responses\", \"openai-completions\", \"anthropic-messages\"] as const) {\n\t\tif (supported.includes(preferred)) return preferred;\n\t}\n\tconst primary = typeof node.api_interface === \"string\" ? node.api_interface : \"missing\";\n\tthrow new Error(`HUMAIN Node model \"${id}\" has an unsupported API interface: ${primary}`);\n}\n\nfunction positiveInteger(value: unknown, field: string, id: string): number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n\t\tthrow new Error(`HUMAIN Node model \"${id}\" has invalid ${field}`);\n\t}\n\treturn value;\n}\n\nfunction toModel(value: unknown, baseUrl: string): Model<Api> | undefined {\n\tif (typeof value !== \"object\" || value === null || !(\"id\" in value)) {\n\t\tthrow new Error(\"HUMAIN Node returned a malformed model entry\");\n\t}\n\tconst raw = value as Record<string, unknown>;\n\tif (raw.active === false) return undefined;\n\tconst node = typeof raw.node === \"object\" && raw.node !== null ? raw.node : raw;\n\tconst payload = { ...raw, node } as unknown as NodeModelPayload;\n\tif (typeof payload.id !== \"string\" || !payload.id.trim()) {\n\t\tthrow new Error(\"HUMAIN Node returned a malformed model entry\");\n\t}\n\tconst id = payload.id.trim();\n\tif (typeof payload.node.supports_streaming !== \"boolean\") {\n\t\tthrow new Error(`HUMAIN Node model \"${id}\" has invalid supports_streaming`);\n\t}\n\tif (typeof payload.node.supports_function_calling !== \"boolean\") {\n\t\tthrow new Error(`HUMAIN Node model \"${id}\" has invalid supports_function_calling`);\n\t}\n\tif (payload.node.supports_streaming === false || payload.node.supports_function_calling === false) return undefined;\n\tlet api: Api;\n\ttry {\n\t\tapi = modelApi(id, payload.node);\n\t} catch (error) {\n\t\tif (payload.node.api_interface === \"image_generations\" || payload.node.api_interface === \"realtime\")\n\t\t\treturn undefined;\n\t\tthrow error;\n\t}\n\tconst contextWindow = payload.node.max_context_tokens;\n\tconst maxTokens = payload.node.max_output_tokens;\n\tif (contextWindow === null || maxTokens === null || contextWindow === 0 || maxTokens === 0) return undefined;\n\treturn {\n\t\tid,\n\t\tname:\n\t\t\ttypeof payload.display_name === \"string\" && payload.display_name.trim()\n\t\t\t\t? payload.display_name.trim()\n\t\t\t\t: typeof payload.name === \"string\" && payload.name.trim()\n\t\t\t\t\t? payload.name.trim()\n\t\t\t\t\t: id,\n\t\tapi,\n\t\tprovider: HUMAIN_NODE_PROVIDER,\n\t\tbaseUrl,\n\t\treasoning: false,\n\t\tinput: payload.node.supports_images === true ? [\"text\", \"image\"] : [\"text\"],\n\t\tcost: ZERO_COST,\n\t\tcontextWindow: positiveInteger(contextWindow, \"max_context_tokens\", id),\n\t\tmaxTokens: positiveInteger(maxTokens, \"max_output_tokens\", id),\n\t\t...(api === \"openai-completions\"\n\t\t\t? {\n\t\t\t\t\tcompat: {\n\t\t\t\t\t\tsupportsStore: false,\n\t\t\t\t\t\tsupportsDeveloperRole: false,\n\t\t\t\t\t\tsupportsReasoningEffort: false,\n\t\t\t\t\t\tsupportsUsageInStreaming: true,\n\t\t\t\t\t\tsupportsStrictMode: false,\n\t\t\t\t\t\tsupportsLongCacheRetention: false,\n\t\t\t\t\t\tmaxTokensField: \"max_tokens\" as const,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n}\n\nfunction retryDelay(response: Response, attempt: number): number | undefined {\n\tconst retryAfter = response.headers.get(\"retry-after\");\n\tif (retryAfter) {\n\t\tconst seconds = Number(retryAfter);\n\t\tconst delay = Number.isFinite(seconds) ? seconds * 1_000 : Date.parse(retryAfter) - Date.now();\n\t\tif (Number.isFinite(delay)) {\n\t\t\tconst bounded = Math.max(0, delay);\n\t\t\treturn bounded <= MAX_RETRY_DELAY_MS ? bounded : undefined;\n\t\t}\n\t}\n\treturn 100 * 2 ** attempt;\n}\n\nfunction errorDetails(response: Response, payload: NodeErrorPayload): { code?: string; message: string } {\n\tconst error = payload.error;\n\tconst code = typeof error?.code === \"string\" ? error.code : undefined;\n\tconst type = typeof error?.type === \"string\" ? error.type : undefined;\n\tconst detail = typeof error?.message === \"string\" ? error.message : undefined;\n\tconst retryAfter = response.headers.get(\"retry-after\");\n\tconst requestId = response.headers.get(\"x-request-id\");\n\treturn {\n\t\tcode,\n\t\tmessage: [\n\t\t\t`HUMAIN Node model discovery failed: ${response.status}`,\n\t\t\tcode && `code=${code}`,\n\t\t\ttype && `type=${type}`,\n\t\t\tdetail,\n\t\t\tretryAfter && `Retry-After: ${retryAfter}`,\n\t\t\trequestId && `X-Request-ID: ${requestId}`,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\"; \"),\n\t};\n}\n\nasync function fetchModelsUnredacted(baseUrl: string, apiKey: string, signal: AbortSignal): Promise<Model<Api>[]> {\n\tfor (let attempt = 0; ; attempt++) {\n\t\tsignal.throwIfAborted();\n\t\tconst attemptSignal = AbortSignal.any([signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]);\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(new URL(`${baseUrl}/models`), {\n\t\t\t\tsignal: attemptSignal,\n\t\t\t\tredirect: \"error\",\n\t\t\t\theaders: { Accept: \"application/json\", Authorization: `Bearer ${apiKey}` },\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (signal.aborted || attempt >= MAX_RETRIES) throw error;\n\t\t\tawait delay(100 * 2 ** attempt, undefined, { signal });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst payload: unknown = await response.json().catch(() => ({}));\n\t\tif (!response.ok) {\n\t\t\tconst details = errorDetails(\n\t\t\t\tresponse,\n\t\t\t\ttypeof payload === \"object\" && payload !== null ? (payload as NodeErrorPayload) : {},\n\t\t\t);\n\t\t\tconst retryMs = retryDelay(response, attempt);\n\t\t\tif (\n\t\t\t\tattempt < MAX_RETRIES &&\n\t\t\t\tRETRYABLE_STATUS_CODES.has(response.status) &&\n\t\t\t\t!PERMANENT_LIMIT_CODES.has(details.code ?? \"\") &&\n\t\t\t\tretryMs !== undefined\n\t\t\t) {\n\t\t\t\tawait delay(retryMs, undefined, { signal });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new Error(details.message);\n\t\t}\n\t\tif (typeof payload !== \"object\" || payload === null) {\n\t\t\tthrow new Error(\"HUMAIN Node returned a malformed model catalog\");\n\t\t}\n\t\tconst entries =\n\t\t\t\"data\" in payload && Array.isArray(payload.data)\n\t\t\t\t? payload.data\n\t\t\t\t: \"items\" in payload && Array.isArray(payload.items)\n\t\t\t\t\t? payload.items\n\t\t\t\t\t: undefined;\n\t\tif (!entries) throw new Error(\"HUMAIN Node returned a malformed model catalog\");\n\t\tconst ids = new Set<string>();\n\t\tfor (const entry of entries) {\n\t\t\tif (typeof entry !== \"object\" || entry === null || !(\"id\" in entry) || typeof entry.id !== \"string\") continue;\n\t\t\tconst id = entry.id.trim();\n\t\t\tif (ids.has(id)) throw new Error(`HUMAIN Node returned duplicate model id \"${id}\"`);\n\t\t\tids.add(id);\n\t\t}\n\t\treturn entries.flatMap((entry) => toModel(entry, baseUrl) ?? []);\n\t}\n}\n\nasync function fetchModels(baseUrl: string, apiKey: string, signal: AbortSignal): Promise<Model<Api>[]> {\n\ttry {\n\t\treturn await fetchModelsUnredacted(baseUrl, apiKey, signal);\n\t} catch (error) {\n\t\tif (signal.aborted) throw signal.reason;\n\t\tconst message = (error instanceof Error ? error.message : String(error)).replaceAll(apiKey, \"[redacted]\");\n\t\tconst redacted = new Error(message);\n\t\tif (error instanceof Error) redacted.name = error.name;\n\t\tthrow redacted;\n\t}\n}\n\nexport function createHumainNodeProvider(env: NodeJS.ProcessEnv = process.env): Provider {\n\tlet models: readonly Model<Api>[] = [];\n\tlet activeScope: string | undefined;\n\tconst apiKeyAuth: ApiKeyAuth = {\n\t\tname: \"HUMAIN Node API key\",\n\t\tlogin: async (interaction) => {\n\t\t\tif (!env[API_KEY_ENV]?.trim()) {\n\t\t\t\tinteraction.notify({\n\t\t\t\t\ttype: \"info\",\n\t\t\t\t\tmessage: \"Create a HUMAIN Node API key in Node Users, then paste it below.\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst enteredKey = (\n\t\t\t\tawait interaction.prompt({\n\t\t\t\t\ttype: \"secret\",\n\t\t\t\t\tmessage: \"Enter HUMAIN Node API key (leave blank to use HUMAIN_NODE_API_KEY)\",\n\t\t\t\t})\n\t\t\t).trim();\n\t\t\tconst key = enteredKey || env[API_KEY_ENV]?.trim();\n\t\t\tif (!key) throw new Error(\"HUMAIN Node API key is required\");\n\t\t\tconst enteredUrl = await interaction.prompt({\n\t\t\t\ttype: \"text\",\n\t\t\t\tmessage: \"HUMAIN Node base URL\",\n\t\t\t\tplaceholder: env[BASE_URL_ENV] ?? DEFAULT_BASE_URL,\n\t\t\t});\n\t\t\tconst baseUrl = normalizeBaseUrl(enteredUrl.trim() || env[BASE_URL_ENV] || DEFAULT_BASE_URL);\n\t\t\tawait fetchModels(baseUrl, key, interaction.signal);\n\t\t\treturn {\n\t\t\t\ttype: \"api_key\" as const,\n\t\t\t\tkey: enteredKey.replaceAll(\"$\", () => \"$$\").replace(/^!/u, () => \"$!\") || undefined,\n\t\t\t\tenv: { [BASE_URL_ENV]: baseUrl },\n\t\t\t};\n\t\t},\n\t\tcheck: async ({ ctx, credential, signal }) => {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst key = credential?.key ?? (await ctx.env(API_KEY_ENV));\n\t\t\treturn key\n\t\t\t\t? { type: \"api_key\" as const, source: credential?.key ? \"stored credential\" : API_KEY_ENV }\n\t\t\t\t: undefined;\n\t\t},\n\t\tresolve: async ({ ctx, credential, signal }): Promise<AuthResult | undefined> => {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst key = credential?.key ?? (await ctx.env(API_KEY_ENV));\n\t\t\tif (!key) return undefined;\n\t\t\tconst baseUrl = await resolveBaseUrl(ctx, credential);\n\t\t\treturn {\n\t\t\t\tauth: { apiKey: key, baseUrl },\n\t\t\t\tenv: { ...credential?.env, [BASE_URL_ENV]: baseUrl },\n\t\t\t\tsource: credential?.key ? \"stored credential\" : API_KEY_ENV,\n\t\t\t};\n\t\t},\n\t};\n\tconst base = createProvider({\n\t\tid: HUMAIN_NODE_PROVIDER,\n\t\tname: \"HUMAIN Node\",\n\t\tbaseUrl: DEFAULT_BASE_URL,\n\t\tauth: { apiKey: apiKeyAuth },\n\t\tmodels: [],\n\t\tapi: {\n\t\t\t\"anthropic-messages\": withHumainNodeHttp(anthropicMessagesApi()),\n\t\t\t\"openai-completions\": withHumainNodeHttp(openAICompletionsApi()),\n\t\t\t\"openai-responses\": withHumainNodeHttp(openAIResponsesApi()),\n\t\t},\n\t});\n\treturn {\n\t\t...base,\n\t\tgetModels: () => models,\n\t\trefreshModels: async (context: RefreshModelsContext) => {\n\t\t\tconst credential = context.credential?.type === \"api_key\" ? context.credential : undefined;\n\t\t\tconst key = credential?.key;\n\t\t\tconst baseUrl = credential ? (credentialBaseUrl(credential) ?? DEFAULT_BASE_URL) : undefined;\n\t\t\tconst scope = key && baseUrl ? `${baseUrl}\\0${key}` : undefined;\n\t\t\tif (scope !== activeScope) {\n\t\t\t\tif (\n\t\t\t\t\t!(await context.publish({\n\t\t\t\t\t\tpersist: null,\n\t\t\t\t\t\tupdate: () => {\n\t\t\t\t\t\t\tmodels = [];\n\t\t\t\t\t\t\tactiveScope = scope;\n\t\t\t\t\t\t},\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!context.allowNetwork || context.signal.aborted || !key || !baseUrl) return;\n\t\t\tconst refreshed = await fetchModels(baseUrl, key, context.signal);\n\t\t\tif (context.signal.aborted) return;\n\t\t\tawait context.publish({\n\t\t\t\tpersist: null,\n\t\t\t\tupdate: () => {\n\t\t\t\t\tmodels = refreshed;\n\t\t\t\t\tactiveScope = scope;\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,51 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { parseArgs } from "./cli/args.js";
|
|
3
|
-
// Config paths
|
|
4
|
-
export { CONFIG_DIR_NAME, getAgentDir, getDocsPath, getExamplesPath, getPackageDir, getReadmePath, UPSTREAM_PI_VERSION, VERSION, } from "./config.js";
|
|
5
|
-
export { AgentSession, parseSkillBlock, } from "./core/agent-session.js";
|
|
6
|
-
export { readStoredCredential } from "./core/auth-storage.js";
|
|
7
|
-
// Compaction
|
|
8
|
-
export { calculateContextTokens, collectEntriesForBranchSummary, compact, DEFAULT_COMPACTION_SETTINGS, estimateTokens, findCutPoint, findTurnStartIndex, generateBranchSummary, generateSummary, generateSummaryWithUsage, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, } from "./core/compaction/index.js";
|
|
9
|
-
export { createEventBus } from "./core/event-bus.js";
|
|
10
|
-
export { createExtensionRuntime, defineTool, discoverAndLoadExtensions, ExtensionRunner, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isPowerShellToolResult, isReadToolResult, isToolCallEventType, isWriteToolResult, wrapRegisteredTool, wrapRegisteredTools, } from "./core/extensions/index.js";
|
|
11
|
-
export { convertToLlm } from "./core/messages.js";
|
|
12
|
-
export { ModelRegistry } from "./core/model-registry.js";
|
|
13
|
-
export { resolveCliModel, resolveModelScopeWithDiagnostics, } from "./core/model-resolver.js";
|
|
14
|
-
export { CredentialSynchronizationError, ModelRuntime, } from "./core/model-runtime.js";
|
|
15
|
-
export { DefaultPackageManager } from "./core/package-manager.js";
|
|
16
|
-
export { DefaultResourceLoader, loadProjectContextFiles } from "./core/resource-loader.js";
|
|
17
|
-
// SDK for programmatic usage
|
|
18
|
-
export { AgentSessionRuntime,
|
|
19
|
-
// Factory
|
|
20
|
-
createAgentSession, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, createBashTool,
|
|
21
|
-
// Tool factories (for custom cwd)
|
|
22
|
-
createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createPowerShellTool, createReadOnlyTools, createReadTool, createWriteTool, } from "./core/sdk.js";
|
|
23
|
-
export { buildContextEntries, buildSessionContext, CURRENT_SESSION_VERSION, getLatestCompactionEntry, migrateSessionEntries, parseSessionEntries, SessionManager, sessionEntryToContextMessages, } from "./core/session-manager.js";
|
|
24
|
-
export { SettingsManager, } from "./core/settings-manager.js";
|
|
25
|
-
// Skills
|
|
26
|
-
export { formatSkillsForPrompt, loadSkills, loadSkillsFromDir, } from "./core/skills.js";
|
|
27
|
-
export { createSyntheticSourceInfo } from "./core/source-info.js";
|
|
28
|
-
export { generateDiffString, generateUnifiedPatch } from "./core/tools/edit-diff.js";
|
|
29
|
-
// Tools
|
|
30
|
-
export { createBashToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLocalBashOperations, createLocalPowerShellOperations, createLsToolDefinition, createPowerShellToolDefinition, createReadToolDefinition, createWriteToolDefinition, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, truncateLine, truncateTail, withFileMutationQueue, } from "./core/tools/index.js";
|
|
31
|
-
export { hasTrustRequiringProjectResources, ProjectTrustStore, } from "./core/trust-manager.js";
|
|
32
|
-
export { HUMAIN_AGENT_EXECUTION_FAILURE_CODES, HUMAIN_AGENT_EXECUTION_SCHEMA_VERSION, HumainAgentArtifactSchema, HumainAgentExecutionClaimSchema, HumainAgentExecutionControlsSchema, HumainAgentExecutionOutcomeSchema, HumainAgentExecutionRequestSchema, HumainAgentExecutionResponseSchema, HumainAgentRouteRefSchema, HumainAgentUsageSchema, parseHumainAgentExecutionRequest, parseHumainAgentExecutionResponse, } from "./humain/agent-execution-protocol.js";
|
|
33
|
-
export { executeHumainAgentRequest, } from "./humain/agent-execution-runtime.js";
|
|
34
|
-
export { createPiAgentExecutionHost, } from "./humain/pi-agent-execution-host.js";
|
|
35
|
-
// Main entry point
|
|
36
|
-
export { main } from "./main.js";
|
|
37
|
-
// Run modes for programmatic SDK usage
|
|
38
|
-
export { AgentExecInputError, InteractiveMode, RpcClient, runAgentExecMode, runPrintMode, runRpcMode, } from "./modes/index.js";
|
|
39
|
-
// UI components for extensions
|
|
40
|
-
export { ArminComponent, AssistantMessageComponent, BashExecutionComponent, BorderedLoader, BranchSummaryMessageComponent, CompactionSummaryMessageComponent, CustomEditor, CustomMessageComponent, DynamicBorder, ExtensionEditorComponent, ExtensionInputComponent, ExtensionSelectorComponent, FooterComponent, keyHint, keyText, LoginDialogComponent, ModelSelectorComponent, OAuthSelectorComponent, rawKeyHint, renderDiff, SessionSelectorComponent, SettingsSelectorComponent, ShowImagesSelectorComponent, SkillInvocationMessageComponent, ThemeSelectorComponent, ThinkingSelectorComponent, ToolExecutionComponent, TreeSelectorComponent, truncateToVisualLines, UserMessageComponent, UserMessageSelectorComponent, } from "./modes/interactive/components/index.js";
|
|
41
|
-
// Theme utilities for custom tools and extensions
|
|
42
|
-
export { getLanguageFromPath, getMarkdownTheme, getSelectListTheme, getSettingsListTheme, highlightCode, initTheme, Theme, } from "./modes/interactive/theme/theme.js";
|
|
43
|
-
// Clipboard utilities
|
|
44
|
-
export { copyToClipboard } from "./utils/clipboard.js";
|
|
45
|
-
export { parseFrontmatter, stripFrontmatter } from "./utils/frontmatter.js";
|
|
46
|
-
export { convertToPng } from "./utils/image-convert.js";
|
|
47
|
-
export { formatDimensionNote, resizeImage } from "./utils/image-resize.js";
|
|
48
|
-
export { detectSupportedImageMimeTypeFromFile } from "./utils/mime.js";
|
|
49
|
-
// Shell utilities
|
|
50
|
-
export { getPowerShellConfig, getShellConfig } from "./utils/shell.js";
|
|
51
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export * from "./bundle/index.js";
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EAAE,KAAK,IAAI,EAAmC,MAAM,eAAe,CAAC;AA2C3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAalE,OAAO,EAAwB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EAAE,KAAK,IAAI,EAAmC,MAAM,eAAe,CAAC;AA2C3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAalE,OAAO,EAAwB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA+S7D,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,IAAI,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,eAAe,EAAE,eAAe,GAC9B,OAAO,CAAC,cAAc,CAAC,CAsFzB;AAkHD,MAAM,WAAW,WAAW;IAC3B,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACvC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAM/G;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,iBA0f/D"}
|
package/dist/main.js
CHANGED
|
@@ -38,6 +38,7 @@ import { printTimings, resetTimings, time } from "./core/timings.js";
|
|
|
38
38
|
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "./core/trust-manager.js";
|
|
39
39
|
import { builtInExtensions } from "./extensions/index.js";
|
|
40
40
|
import { getHumainBundledExtensionFactories, getHumainDefaultPackageSources, HUMAIN_FORGE_CWD_ENV, } from "./humain/index.js";
|
|
41
|
+
import { HUMAIN_NODE_PROVIDER } from "./humain/node-provider.js";
|
|
41
42
|
import { createAdmittedPiAgentExecutionHost } from "./humain/pi-agent-execution-host.js";
|
|
42
43
|
import { runMigrations, showDeprecationWarnings } from "./migrations.js";
|
|
43
44
|
import { AgentExecInputError, InteractiveMode, runAgentExecMode, runPrintMode, runRpcMode } from "./modes/index.js";
|
|
@@ -675,6 +676,20 @@ export async function main(args, options) {
|
|
|
675
676
|
message: `Failed to load extension "${path}": ${error}`,
|
|
676
677
|
})),
|
|
677
678
|
];
|
|
679
|
+
if (!parsed.help &&
|
|
680
|
+
process.env.PI_OFFLINE === undefined &&
|
|
681
|
+
modelRuntime.hasConfiguredAuth(HUMAIN_NODE_PROVIDER)) {
|
|
682
|
+
const result = await modelRuntime.refresh({
|
|
683
|
+
providers: [HUMAIN_NODE_PROVIDER],
|
|
684
|
+
signal: AbortSignal.timeout(15_000),
|
|
685
|
+
});
|
|
686
|
+
for (const error of result.errors.values()) {
|
|
687
|
+
diagnostics.push({ type: "warning", message: error.message });
|
|
688
|
+
}
|
|
689
|
+
if (result.aborted) {
|
|
690
|
+
diagnostics.push({ type: "warning", message: "HUMAIN Node model discovery timed out" });
|
|
691
|
+
}
|
|
692
|
+
}
|
|
678
693
|
const modelPatterns = parsed.models ?? settingsManager.getEnabledModels();
|
|
679
694
|
const scopedModels = modelPatterns && modelPatterns.length > 0
|
|
680
695
|
? await resolveModelScope(modelPatterns, modelRuntime, { signal: AbortSignal.timeout(15_000) })
|
|
@@ -734,6 +749,7 @@ export async function main(args, options) {
|
|
|
734
749
|
process.exit(0);
|
|
735
750
|
}
|
|
736
751
|
if (parsed.listModels !== undefined) {
|
|
752
|
+
reportDiagnostics(runtime.diagnostics);
|
|
737
753
|
const searchPattern = typeof parsed.listModels === "string" ? parsed.listModels : undefined;
|
|
738
754
|
await listModels(modelRuntime, searchPattern, AbortSignal.timeout(15_000));
|
|
739
755
|
process.exit(0);
|